epiphany/node_modules/posthtml-urls/lib/index.js

143 lines
3.1 KiB
JavaScript
Raw Normal View History

2023-12-09 22:19:03 -08:00
"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;