Path: blob/main/src/rewrite/rewrite.html.js
304 views
/**1* @typedef {import('./index').default} Ultraviolet2*/34/**5*6* @param {Ultraviolet} ctx7*/8export function attributes(ctx, meta = ctx.meta) {9const { html, js, attributePrefix } = ctx;10const origPrefix = attributePrefix + "-attr-";1112html.on("attr", (attr, type) => {13if (14attr.node.tagName === "base" &&15attr.name === "href" &&16attr.options.document17) {18meta.base = new URL(attr.value, meta.url);19}2021if (type === "rewrite" && isUrl(attr.name, attr.tagName)) {22attr.node.setAttribute(origPrefix + attr.name, attr.value);23attr.value = ctx.rewriteUrl(attr.value, meta);24}2526if (type === "rewrite" && isSrcset(attr.name)) {27attr.node.setAttribute(origPrefix + attr.name, attr.value);28attr.value = html.wrapSrcset(attr.value, meta);29}3031if (type === "rewrite" && isHtml(attr.name)) {32attr.node.setAttribute(origPrefix + attr.name, attr.value);33attr.value = html.rewrite(attr.value, {34...meta,35document: true,36injectHead: attr.options.injectHead || [],37});38}3940if (type === "rewrite" && isStyle(attr.name)) {41attr.node.setAttribute(origPrefix + attr.name, attr.value);42attr.value = ctx.rewriteCSS(attr.value, {43context: "declarationList",44});45}4647if (type === "rewrite" && isForbidden(attr.name)) {48attr.name = origPrefix + attr.name;49}5051if (type === "rewrite" && isEvent(attr.name)) {52attr.node.setAttribute(origPrefix + attr.name, attr.value);53attr.value = js.rewrite(attr.value, meta);54}5556if (type === "source" && attr.name.startsWith(origPrefix)) {57if (attr.node.hasAttribute(attr.name.slice(origPrefix.length)))58attr.node.removeAttribute(attr.name.slice(origPrefix.length));59attr.name = attr.name.slice(origPrefix.length);60}6162/*63if (isHtml(attr.name)) {6465};6667if (isStyle(attr.name)) {6869};7071if (isSrcset(attr.name)) {7273};74*/75});76}7778/**79*80* @param {Ultraviolet} ctx81*/82export function text(ctx) {83const { html, js, css } = ctx;8485html.on("text", (text, type) => {86if (text.element.tagName === "script") {87text.value =88type === "rewrite" ? js.rewrite(text.value) : js.source(text.value);89}9091if (text.element.tagName === "style") {92text.value =93type === "rewrite" ? css.rewrite(text.value) : css.source(text.value);94}95});96return true;97}9899export function isUrl(name, tag) {100return (101(tag === "object" && name === "data") ||102[103"src",104"href",105"ping",106"movie",107"action",108"poster",109"profile",110"background",111].indexOf(name) > -1112);113}114115export function isEvent(name) {116return (117[118"onafterprint",119"onbeforeprint",120"onbeforeunload",121"onerror",122"onhashchange",123"onload",124"onmessage",125"onoffline",126"ononline",127"onpagehide",128"onpopstate",129"onstorage",130"onunload",131"onblur",132"onchange",133"oncontextmenu",134"onfocus",135"oninput",136"oninvalid",137"onreset",138"onsearch",139"onselect",140"onsubmit",141"onkeydown",142"onkeypress",143"onkeyup",144"onclick",145"ondblclick",146"onmousedown",147"onmousemove",148"onmouseout",149"onmouseover",150"onmouseup",151"onmousewheel",152"onwheel",153"ondrag",154"ondragend",155"ondragenter",156"ondragleave",157"ondragover",158"ondragstart",159"ondrop",160"onscroll",161"oncopy",162"oncut",163"onpaste",164"onabort",165"oncanplay",166"oncanplaythrough",167"oncuechange",168"ondurationchange",169"onemptied",170"onended",171"onerror",172"onloadeddata",173"onloadedmetadata",174"onloadstart",175"onpause",176"onplay",177"onplaying",178"onprogress",179"onratechange",180"onseeked",181"onseeking",182"onstalled",183"onsuspend",184"ontimeupdate",185"onvolumechange",186"onwaiting",187].indexOf(name) > -1188);189}190191/**192*193* @param {Ultraviolet} ctx194*/195export function injectHead(ctx) {196const { html } = ctx;197html.on("element", (element, type) => {198if (type !== "rewrite") return false;199if (element.tagName !== "head") return false;200if (!("injectHead" in element.options)) return false;201202element.childNodes.unshift(...element.options.injectHead);203});204}205206export function createJsInject(cookies = "", referrer = "") {207return (208`self.__uv$cookies = ${JSON.stringify(cookies)};` +209`self.__uv$referrer = ${JSON.stringify(referrer)};`210);211}212213export function createHtmlInject(214handlerScript,215bundleScript,216clientScript,217configScript,218cookies,219referrer220) {221return [222{223tagName: "script",224nodeName: "script",225childNodes: [226{227nodeName: "#text",228value: createJsInject(cookies, referrer),229},230],231attrs: [232{233name: "__uv-script",234value: "1",235skip: true,236},237],238skip: true,239},240{241tagName: "script",242nodeName: "script",243childNodes: [],244attrs: [245{ name: "src", value: bundleScript, skip: true },246{247name: "__uv-script",248value: "1",249skip: true,250},251],252},253{254tagName: "script",255nodeName: "script",256childNodes: [],257attrs: [258{ name: "src", value: clientScript, skip: true },259{260name: "__uv-script",261value: "1",262skip: true,263},264],265},266{267tagName: "script",268nodeName: "script",269childNodes: [],270attrs: [271{ name: "src", value: configScript, skip: true },272{273name: "__uv-script",274value: "1",275skip: true,276},277],278},279{280tagName: "script",281nodeName: "script",282childNodes: [],283attrs: [284{ name: "src", value: handlerScript, skip: true },285{286name: "__uv-script",287value: "1",288skip: true,289},290],291},292];293}294295export function isForbidden(name) {296return (297["http-equiv", "integrity", "sandbox", "nonce", "crossorigin"].indexOf(298name299) > -1300);301}302303export function isHtml(name) {304return name === "srcdoc";305}306307export function isStyle(name) {308return name === "style";309}310311export function isSrcset(name) {312return name === "srcSet" || name === "srcset" || name === "imagesrcset";313}314315316