mirror of
https://github.com/MercuryWorkshop/scramjet.git
synced 2025-05-16 15:40:02 -04:00
feat: start proxying a lot more things & scramjet-data -> scramjet-attr
This commit is contained in:
parent
ccefa04690
commit
f43637fed7
3 changed files with 88 additions and 40 deletions
|
@ -52,8 +52,8 @@ export default function (client: ScramjetClient, _self: typeof window) {
|
||||||
},
|
},
|
||||||
has(target, prop) {
|
has(target, prop) {
|
||||||
if (typeof prop === "symbol") return Reflect.has(target, prop);
|
if (typeof prop === "symbol") return Reflect.has(target, prop);
|
||||||
if (prop.startsWith("scramjet-data-")) return false;
|
if (prop.startsWith("scramjet-attr-")) return false;
|
||||||
if (map[prop]?.name?.startsWith("scramjet-data-")) return false;
|
if (map[prop]?.name?.startsWith("scramjet-attr-")) return false;
|
||||||
|
|
||||||
return Reflect.has(target, prop);
|
return Reflect.has(target, prop);
|
||||||
},
|
},
|
||||||
|
@ -65,10 +65,10 @@ export default function (client: ScramjetClient, _self: typeof window) {
|
||||||
|
|
||||||
client.Trap("Attr.prototype.value", {
|
client.Trap("Attr.prototype.value", {
|
||||||
get(ctx) {
|
get(ctx) {
|
||||||
return ctx.this.ownerElement.getAttribute(ctx.this.name);
|
return ctx.this.ownerElement?.getAttribute(ctx.this.name);
|
||||||
},
|
},
|
||||||
set(ctx, value) {
|
set(ctx, value) {
|
||||||
return ctx.this.ownerElement.setAttribute(ctx.this.name, value);
|
return ctx.this.ownerElement?.setAttribute(ctx.this.name, value);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,6 +114,34 @@ export default function (client: ScramjetClient, self: typeof window) {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
client.Proxy("Element.prototype.getAttribute", {
|
||||||
|
apply(ctx) {
|
||||||
|
const [name] = ctx.args;
|
||||||
|
|
||||||
|
if (name.startsWith("scramjet-attr")) {
|
||||||
|
return ctx.return(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nativeHasAttribute.call(ctx.this, `scramjet-attr-${name}`)) {
|
||||||
|
const attrib = ctx.fn.call(ctx.this, `scramjet-attr-${name}`);
|
||||||
|
if (attrib === null) return ctx.return("");
|
||||||
|
|
||||||
|
return ctx.return(attrib);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
client.Proxy("Element.prototype.getAttributeNames", {
|
||||||
|
apply(ctx) {
|
||||||
|
const attrNames = ctx.call() as string[];
|
||||||
|
const cleaned = attrNames.filter(
|
||||||
|
(attr) => !attr.startsWith("scramjet-attr")
|
||||||
|
);
|
||||||
|
|
||||||
|
ctx.return(cleaned);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
client.Proxy("Element.prototype.setAttribute", {
|
client.Proxy("Element.prototype.setAttribute", {
|
||||||
apply(ctx) {
|
apply(ctx) {
|
||||||
const [name, value] = ctx.args;
|
const [name, value] = ctx.args;
|
||||||
|
@ -129,10 +157,16 @@ export default function (client: ScramjetClient, self: typeof window) {
|
||||||
|
|
||||||
if (ruleList) {
|
if (ruleList) {
|
||||||
ctx.args[1] = ruleList.fn(value, client.meta, client.cookieStore);
|
ctx.args[1] = ruleList.fn(value, client.meta, client.cookieStore);
|
||||||
ctx.fn.call(ctx.this, `scramjet-data-${ctx.args[0]}`, value);
|
ctx.fn.call(ctx.this, `scramjet-attr-${ctx.args[0]}`, value);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// i actually need to do something with this
|
||||||
|
client.Proxy("Element.prototype.setAttributeNode", {
|
||||||
|
apply(ctx) {},
|
||||||
|
});
|
||||||
|
|
||||||
client.Proxy("Element.prototype.setAttributeNS", {
|
client.Proxy("Element.prototype.setAttributeNS", {
|
||||||
apply(ctx) {
|
apply(ctx) {
|
||||||
const [_namespace, name, value] = ctx.args;
|
const [_namespace, name, value] = ctx.args;
|
||||||
|
@ -150,27 +184,22 @@ export default function (client: ScramjetClient, self: typeof window) {
|
||||||
ctx.args[2] = ruleList.fn(value, client.meta, client.cookieStore);
|
ctx.args[2] = ruleList.fn(value, client.meta, client.cookieStore);
|
||||||
nativeSetAttribute.call(
|
nativeSetAttribute.call(
|
||||||
ctx.this,
|
ctx.this,
|
||||||
`scramjet-data-${ctx.args[1]}`,
|
`scramjet-attr-${ctx.args[1]}`,
|
||||||
value
|
value
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
client.Proxy("Element.prototype.getAttribute", {
|
client.Proxy("Element.prototype.removeAttribute", {
|
||||||
apply(ctx) {
|
apply(ctx) {
|
||||||
const [name] = ctx.args;
|
if (ctx.args[0].startsWith("scramjet-attr")) return ctx.return(undefined);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
if (name.startsWith("scramjet-data")) {
|
client.Proxy("Element.prototype.toggleAttribute", {
|
||||||
return ctx.return(null);
|
apply(ctx) {
|
||||||
}
|
if (ctx.args[0].startsWith("scramjet-attr")) return ctx.return(false);
|
||||||
|
|
||||||
if (nativeHasAttribute.call(ctx.this, `scramjet-data-${name}`)) {
|
|
||||||
const attrib = ctx.fn.call(ctx.this, `scramjet-data-${name}`);
|
|
||||||
if (attrib === null) return ctx.return("");
|
|
||||||
|
|
||||||
return ctx.return(attrib);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -195,7 +224,7 @@ export default function (client: ScramjetClient, self: typeof window) {
|
||||||
if (ctx.this instanceof self.HTMLScriptElement) {
|
if (ctx.this instanceof self.HTMLScriptElement) {
|
||||||
const scriptSource = client.natives[
|
const scriptSource = client.natives[
|
||||||
"Element.prototype.getAttribute"
|
"Element.prototype.getAttribute"
|
||||||
].call(ctx.this, "scramjet-data-script-source-src");
|
].call(ctx.this, "scramjet-attr-script-source-src");
|
||||||
|
|
||||||
if (scriptSource) {
|
if (scriptSource) {
|
||||||
return atob(scriptSource);
|
return atob(scriptSource);
|
||||||
|
@ -220,6 +249,19 @@ export default function (client: ScramjetClient, self: typeof window) {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
client.Proxy("Element.prototype.setHTMLUnsafe", {
|
||||||
|
apply(ctx) {
|
||||||
|
try {
|
||||||
|
ctx.args[0] = rewriteHtml(
|
||||||
|
ctx.args[0],
|
||||||
|
client.cookieStore,
|
||||||
|
client.meta,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
} catch {}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
client.Proxy("Element.prototype.getHTML", {
|
client.Proxy("Element.prototype.getHTML", {
|
||||||
apply(ctx) {
|
apply(ctx) {
|
||||||
ctx.return(unrewriteHtml(ctx.call()));
|
ctx.return(unrewriteHtml(ctx.call()));
|
||||||
|
@ -380,18 +422,24 @@ export default function (client: ScramjetClient, self: typeof window) {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
client.Proxy("DOMParser.prototype.parseFromString", {
|
client.Proxy(
|
||||||
apply(ctx) {
|
[
|
||||||
if (ctx.args[1] === "text/html") {
|
"DOMParser.prototype.parseFromString",
|
||||||
try {
|
"Document.prototype.parseHTMLUnsafe",
|
||||||
ctx.args[0] = rewriteHtml(
|
],
|
||||||
ctx.args[0],
|
{
|
||||||
client.cookieStore,
|
apply(ctx) {
|
||||||
client.meta,
|
if (ctx.args[1] === "text/html") {
|
||||||
false
|
try {
|
||||||
);
|
ctx.args[0] = rewriteHtml(
|
||||||
} catch {}
|
ctx.args[0],
|
||||||
}
|
client.cookieStore,
|
||||||
},
|
client.meta,
|
||||||
});
|
false
|
||||||
|
);
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,14 +81,14 @@ export function unrewriteHtml(html: string) {
|
||||||
function traverse(node: ChildNode) {
|
function traverse(node: ChildNode) {
|
||||||
if ("attribs" in node) {
|
if ("attribs" in node) {
|
||||||
for (const key in node.attribs) {
|
for (const key in node.attribs) {
|
||||||
if (key == "scramjet-data-script-source-src") {
|
if (key == "scramjet-attr-script-source-src") {
|
||||||
if (node.children[0] && "data" in node.children[0])
|
if (node.children[0] && "data" in node.children[0])
|
||||||
node.children[0].data = atob(node.attribs[key]);
|
node.children[0].data = atob(node.attribs[key]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key.startsWith("scramjet-data-")) {
|
if (key.startsWith("scramjet-attr-")) {
|
||||||
node.attribs[key.slice("scramjet-data-".length)] = node.attribs[key];
|
node.attribs[key.slice("scramjet-attr-".length)] = node.attribs[key];
|
||||||
delete node.attribs[key];
|
delete node.attribs[key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -219,14 +219,14 @@ function traverseParsedHtml(
|
||||||
else {
|
else {
|
||||||
node.attribs[attr] = v;
|
node.attribs[attr] = v;
|
||||||
}
|
}
|
||||||
node.attribs[`scramjet-data-${attr}`] = value;
|
node.attribs[`scramjet-attr-${attr}`] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const [attr, value] of Object.entries(node.attribs)) {
|
for (const [attr, value] of Object.entries(node.attribs)) {
|
||||||
if (eventAttributes.includes(attr)) {
|
if (eventAttributes.includes(attr)) {
|
||||||
node.attribs[`scramjet-data-${attr}`] = value;
|
node.attribs[`scramjet-attr-${attr}`] = value;
|
||||||
node.attribs[attr] = rewriteJs(
|
node.attribs[attr] = rewriteJs(
|
||||||
value as string,
|
value as string,
|
||||||
`(inline ${attr} on element)`,
|
`(inline ${attr} on element)`,
|
||||||
|
@ -247,8 +247,8 @@ function traverseParsedHtml(
|
||||||
node.children[0] !== undefined
|
node.children[0] !== undefined
|
||||||
) {
|
) {
|
||||||
let js = node.children[0].data;
|
let js = node.children[0].data;
|
||||||
// node.attribs[`scramjet-data-script-source-src`] = btoa(js);
|
// node.attribs[`scramjet-attr-script-source-src`] = btoa(js);
|
||||||
node.attribs["scramjet-data-script-source-src"] = bytesToBase64(
|
node.attribs["scramjet-attr-script-source-src"] = bytesToBase64(
|
||||||
new TextEncoder().encode(js)
|
new TextEncoder().encode(js)
|
||||||
);
|
);
|
||||||
const htmlcomment = /<!--[\s\S]*?-->/g;
|
const htmlcomment = /<!--[\s\S]*?-->/g;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue