Path: blob/main/src/rewrite/rewrite.script.js
304 views
/**1* @typedef {import('./index').default} Ultraviolet2*/34/**5*6* @param {Ultraviolet} ctx7*/8function property(ctx) {9const { js } = ctx;10js.on("MemberExpression", (node, data, type) => {11if (node.object.type === "Super") return false;1213if (type === "rewrite" && computedProperty(node)) {14data.changes.push({15node: "__uv.$wrap((",16start: node.property.start,17end: node.property.start,18});19node.iterateEnd = function () {20data.changes.push({21node: "))",22start: node.property.end,23end: node.property.end,24});25};26}2728if (29(!node.computed &&30node.property.name === "location" &&31type === "rewrite") ||32(node.property.name === "__uv$location" && type === "source")33) {34data.changes.push({35start: node.property.start,36end: node.property.end,37node:38type === "rewrite"39? "__uv$setSource(__uv).__uv$location"40: "location",41});42}4344if (45(!node.computed && node.property.name === "top" && type === "rewrite") ||46(node.property.name === "__uv$top" && type === "source")47) {48data.changes.push({49start: node.property.start,50end: node.property.end,51node: type === "rewrite" ? "__uv$setSource(__uv).__uv$top" : "top",52});53}5455if (56(!node.computed &&57node.property.name === "parent" &&58type === "rewrite") ||59(node.property.name === "__uv$parent" && type === "source")60) {61data.changes.push({62start: node.property.start,63end: node.property.end,64node:65type === "rewrite" ? "__uv$setSource(__uv).__uv$parent" : "parent",66});67}6869if (70!node.computed &&71node.property.name === "postMessage" &&72type === "rewrite"73) {74data.changes.push({75start: node.property.start,76end: node.property.end,77node: "__uv$setSource(__uv).postMessage",78});79}8081if (82(!node.computed && node.property.name === "eval" && type === "rewrite") ||83(node.property.name === "__uv$eval" && type === "source")84) {85data.changes.push({86start: node.property.start,87end: node.property.end,88node: type === "rewrite" ? "__uv$setSource(__uv).__uv$eval" : "eval",89});90}9192if (93!node.computed &&94node.property.name === "__uv$setSource" &&95type === "source" &&96node.parent.type === "CallExpression"97) {98const { parent, property } = node;99data.changes.push({100start: property.start - 1,101end: parent.end,102});103104node.iterateEnd = function () {105data.changes.push({106start: property.start,107end: parent.end,108});109};110}111});112}113114/**115*116* @param {Ultraviolet} ctx117*/118function identifier(ctx) {119const { js } = ctx;120js.on("Identifier", (node, data, type) => {121if (type !== "rewrite") return false;122const { parent } = node;123if (!["location", "eval", "parent", "top"].includes(node.name))124return false;125if (parent.type === "VariableDeclarator" && parent.id === node)126return false;127if (128(parent.type === "AssignmentExpression" ||129parent.type === "AssignmentPattern") &&130parent.left === node131)132return false;133if (134(parent.type === "FunctionExpression" ||135parent.type === "FunctionDeclaration") &&136parent.id === node137)138return false;139if (140parent.type === "MemberExpression" &&141parent.property === node &&142!parent.computed143)144return false;145if (146node.name === "eval" &&147parent.type === "CallExpression" &&148parent.callee === node149)150return false;151if (parent.type === "Property" && parent.key === node) return false;152if (parent.type === "Property" && parent.value === node && parent.shorthand)153return false;154if (155parent.type === "UpdateExpression" &&156(parent.operator === "++" || parent.operator === "--")157)158return false;159if (160(parent.type === "FunctionExpression" ||161parent.type === "FunctionDeclaration" ||162parent.type === "ArrowFunctionExpression") &&163parent.params.indexOf(node) !== -1164)165return false;166if (parent.type === "MethodDefinition") return false;167if (parent.type === "ClassDeclaration") return false;168if (parent.type === "RestElement") return false;169if (parent.type === "ExportSpecifier") return false;170if (parent.type === "ImportSpecifier") return false;171172data.changes.push({173start: node.start,174end: node.end,175node: "__uv.$get(" + node.name + ")",176});177});178}179180/**181*182* @param {Ultraviolet} ctx183*/184function wrapEval(ctx) {185const { js } = ctx;186js.on("CallExpression", (node, data, type) => {187if (type !== "rewrite") return false;188if (!node.arguments.length) return false;189if (node.callee.type !== "Identifier") return false;190if (node.callee.name !== "eval") return false;191192const [script] = node.arguments;193194data.changes.push({195node: "__uv.js.rewrite(",196start: script.start,197end: script.start,198});199node.iterateEnd = function () {200data.changes.push({201node: ")",202start: script.end,203end: script.end,204});205};206});207}208209/**210*211* @param {Ultraviolet} ctx212*/213function importDeclaration(ctx) {214const { js } = ctx;215js.on("Literal", (node, data, type) => {216if (217!(218(node.parent.type === "ImportDeclaration" ||219node.parent.type === "ExportAllDeclaration" ||220node.parent.type === "ExportNamedDeclaration") &&221node.parent.source === node222)223)224return false;225226data.changes.push({227start: node.start + 1,228end: node.end - 1,229node:230type === "rewrite"231? ctx.rewriteUrl(node.value)232: ctx.sourceUrl(node.value),233});234});235}236237/**238*239* @param {Ultraviolet} ctx240*/241function dynamicImport(ctx) {242const { js } = ctx;243js.on("ImportExpression", (node, data, type) => {244if (type !== "rewrite") return false;245data.changes.push({246// pass script URL to dynamicImport247// import() is always relative to script URL248node: `__uv.rewriteImport(${JSON.stringify(ctx.meta.url)},`,249start: node.source.start,250end: node.source.start,251});252node.iterateEnd = function () {253data.changes.push({254node: ")",255start: node.source.end,256end: node.source.end,257});258};259});260}261262/**263* @param {Ultraviolet} ctx264*/265function importMeta(ctx) {266const { js } = ctx;267js.on("MemberExpression", (node, data, type) => {268if (269node.object.type == "MetaProperty" &&270node.property.type === "Identifier" &&271node.property.name === "url"272) {273if (type === "rewrite") {274data.changes.push({275start: node.start,276end: node.end,277node: `__uv.sourceUrl(import.meta.url)`,278});279} else if (type === "source") {280data.changes.push({281start: node.start,282end: node.end,283node: `import.meta.url`,284});285}286}287});288}289290/**291*292* @param {Ultraviolet} ctx293*/294function unwrap(ctx) {295const { js } = ctx;296js.on("CallExpression", (node, data, type) => {297if (type !== "source") return false;298if (!isWrapped(node.callee)) return false;299300switch (node.callee.property.name) {301case "$wrap":302{303if (304!node.arguments ||305node.parent.type !== "MemberExpression" ||306node.parent.property !== node307)308return false;309const [property] = node.arguments;310311data.changes.push({312start: node.callee.start,313end: property.start,314});315316node.iterateEnd = function () {317data.changes.push({318start: node.end - 2,319end: node.end,320});321};322}323break;324case "$get":325case "rewriteUrl":326{327const [arg] = node.arguments;328329data.changes.push({330start: node.callee.start,331end: arg.start,332});333334node.iterateEnd = function () {335data.changes.push({336start: node.end - 1,337end: node.end,338});339};340}341break;342case "rewrite":343{344const [script] = node.arguments;345data.changes.push({346start: node.callee.start,347end: script.start,348});349node.iterateEnd = function () {350data.changes.push({351start: node.end - 1,352end: node.end,353});354};355}356break;357}358});359}360361function isWrapped(node) {362if (node.type !== "MemberExpression") return false;363if (node.property.name === "rewrite" && isWrapped(node.object)) return true;364if (node.object.type !== "Identifier" || node.object.name !== "__uv")365return false;366if (!["js", "$get", "$wrap", "rewriteUrl"].includes(node.property.name))367return false;368return true;369}370371function computedProperty(parent) {372if (!parent.computed) return false;373const { property: node } = parent;374if (node.type === "Literal" && !["location", "top", "parent"]) return false;375return true;376}377378export {379property,380wrapEval,381dynamicImport,382importDeclaration,383importMeta,384identifier,385unwrap,386};387388389