"use strict"; const defaultOptions = require("./defaultOptions"); const each = require("promise-each"); const list2Array = require("list-to-array"); const parseMetaRefresh = require("http-equiv-refresh"); const parseSrcset = require("parse-srcset"); function plugin(options) { options = Object.assign({}, defaultOptions, options); if (typeof options.eachURL !== "function") { throw new Error("eachURL must be a function"); } return function PostHTML_URLs(tree) { const promises = []; tree.walk( function(node) { if (node.attrs == null) return node; const tagGroup = options.filter[node.tag]; if (tagGroup === undefined) return node; Object.keys(node.attrs).forEach( function(attrName) { if (tagGroup[attrName] === undefined) return; if (typeof tagGroup[attrName] === "function") { if (tagGroup[attrName](node, attrName) === false) return; } switch (attrName) { case "content": { promises.push( transformMetaRefresh(node, attrName, options.eachURL) ); break; } case "ping": { promises.push( transformCommaSeparated(node, attrName, options.eachURL) ); break; } case "srcset": { promises.push( transformSrcset(node, attrName, options.eachURL) ); break; } default: { promises.push( transformDefault(node, attrName, options.eachURL) ); } } }); return node; }); return Promise.all(promises).then(() => tree); }; } function transformCommaSeparated(node, attrName, transformer) { const values = list2Array( node.attrs[attrName], "," ); if (values.length === 0) return; const promises = []; values.forEach( function(value) { const promise = Promise.resolve( transformer(value, attrName, node.tag) ); promises.push(promise); }); return Promise.all(promises) .then(newValues => node.attrs[attrName] = newValues.join(", ")); } function transformDefault(node, attrName, transformer) { return Promise.resolve( transformer( node.attrs[attrName], attrName, node.tag ) ) .then(newValue => node.attrs[attrName] = newValue); } function transformMetaRefresh(node, attrName, transformer) { const value = parseMetaRefresh( node.attrs[attrName] ); if (value.length === 0) return; return Promise.resolve( transformer(value.url, attrName, node.tag) ) .then(newValue => node.attrs[attrName] = `${value.timeout}; url=${newValue}`); } function transformSrcset(node, attrName, transformer) { const values = parseSrcset( node.attrs[attrName] ); if (values.length === 0) return; const promises = []; values.forEach( function(value) { const promise = Promise.resolve( transformer(value.url, attrName, node.tag) ) .then( function(newValue) { const d = value.d !== undefined ? ` ${value.d}x` : ""; const h = value.h !== undefined ? ` ${value.h}h` : ""; const w = value.w !== undefined ? ` ${value.w}w` : ""; return `${newValue}${w}${h}${d}`; }); promises.push(promise); }); return Promise.all(promises) .then(newValues => node.attrs[attrName] = newValues.join(", ")); } module.exports = plugin;