"use strict"; const cheerio = require("cheerio"); const rewriteCssUrls = require("./rewrite-css-urls"); module.exports = function (body, rewriteUrl) { function patchAttribute(elements, attribute) { elements.get().forEach((element) => { let $element = $(element); let value = $element.attr(attribute); if (value != null) { $element.attr(attribute, rewriteUrl(value)); } }); } function removeAttribute(elements, attribute) { elements.get().forEach((element) => { let $element = $(element); $element.removeAttr(attribute); }); } let $ = cheerio.load(body); patchAttribute($("a"), "href"); patchAttribute($("img"), "src"); /* FIXME: Responsive versions? */ patchAttribute($("link"), "href"); patchAttribute($("script"), "src"); patchAttribute($("form"), "action"); patchAttribute($("iframe"), "src"); patchAttribute($("source"), "src"); /* NOTE: The below is necessary because we're rewriting the contents of CSS and potentially JS files, intentionally. TODO: In the future, just to be safe, we should actually verify the received content against the hashes first, before trying to forward the content to the user. */ removeAttribute($("link"), "integrity"); removeAttribute($("script"), "integrity"); $("style").get().forEach((element) => { let $element = $(element); $element.text(rewriteCssUrls($element.text(), rewriteUrl)); }); $("*[style]").get().forEach((element) => { let $element = $(element); $element.attr("style", rewriteCssUrls($element.attr("style"), rewriteUrl)); }); return $.html(); };