70 lines
2.2 KiB
TypeScript
70 lines
2.2 KiB
TypeScript
|
|
||
|
import { unified } from "unified";
|
||
|
import type { Plugin } from "unified";
|
||
|
import parse from "rehype-parse";
|
||
|
import stringify from "rehype-stringify";
|
||
|
import { visit } from 'unist-util-visit'
|
||
|
import { fromSelector } from 'hast-util-from-selector';
|
||
|
import { generateSizesString, generateSrcsetString } from "./srcset";
|
||
|
|
||
|
const sizes = [300, 600, 1000, 1500, 2000];
|
||
|
|
||
|
const embedSrcs = [
|
||
|
/'*player.vimeo.com.*/,
|
||
|
/.*youtube.com.*/,
|
||
|
/.*youtube-nocookie.com.*/,
|
||
|
/.*kickstarter.com.*video.html.*/,
|
||
|
];
|
||
|
|
||
|
const processEmbed = (parent: any, node: any) => {
|
||
|
const wrapper = fromSelector('div');
|
||
|
wrapper.children = [node];
|
||
|
|
||
|
const width = node.properties.width;
|
||
|
const height = node.properties.height;
|
||
|
const aspect = height / width;
|
||
|
wrapper.properties = {
|
||
|
class: ['fluid-width-video-wrapper'],
|
||
|
style: `padding-top: ${aspect * 100}%`
|
||
|
};
|
||
|
node.properties.height = null;
|
||
|
node.properties.width = null;
|
||
|
|
||
|
parent.children = parent.children.filter((x: any) => x != node);
|
||
|
parent.children.unshift(wrapper);
|
||
|
}
|
||
|
|
||
|
export const postProcessor: Plugin = () => {
|
||
|
return (tree) => {
|
||
|
visit(tree, 'element', (node: any, i: number, parent: any) => {
|
||
|
// Responsive
|
||
|
if (node.tagName == 'img') {
|
||
|
const src = node.properties.src;
|
||
|
const srcsetString = generateSrcsetString(src);
|
||
|
const sizesString = generateSizesString();
|
||
|
node.properties.srcset = srcsetString;
|
||
|
node.properties.sizes = `${sizesString}`;
|
||
|
}
|
||
|
// Embeds
|
||
|
if (node.tagName == 'iframe') {
|
||
|
embedSrcs.forEach(x => {
|
||
|
if (node.properties.src.match(x)) {
|
||
|
processEmbed(parent, node);
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
if (node.tagName == 'object' || node.tagName == 'embed') {
|
||
|
processEmbed(parent, node);
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
export const processPostHtml = async (postHtml: string) => {
|
||
|
const processor = unified()
|
||
|
.use(parse)
|
||
|
.use(postProcessor)
|
||
|
.use(stringify);
|
||
|
|
||
|
const result = await processor.process(postHtml);
|
||
|
return result.toString();
|
||
|
}
|