Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
titaniumnetwork-dev
GitHub Repository: titaniumnetwork-dev/Ludicrous
Path: blob/main/corrosion/lib/browser/document.js
1223 views
1
function createDocumentRewriter(ctx) {
2
return function rewriteDocument() {
3
if (ctx.serviceWorker) return;
4
const {
5
HTMLMediaElement,
6
HTMLScriptElement,
7
HTMLAudioElement,
8
HTMLVideoElement,
9
HTMLInputElement,
10
HTMLEmbedElement,
11
HTMLTrackElement,
12
HTMLAnchorElement,
13
HTMLIFrameElement,
14
HTMLAreaElement,
15
HTMLLinkElement,
16
HTMLBaseElement,
17
HTMLFormElement,
18
HTMLImageElement,
19
HTMLSourceElement,
20
} = ctx.window;
21
const cookie = Object.getOwnPropertyDescriptor(ctx.window.Document.prototype, 'cookie');
22
const domain = Object.getOwnPropertyDescriptor(ctx.window.Document.prototype, 'domain');
23
const title = Object.getOwnPropertyDescriptor(ctx.window.Document.prototype, 'title');
24
const baseURI = Object.getOwnPropertyDescriptor(ctx.window.Node.prototype, 'baseURI');
25
const cookieEnabled = Object.getOwnPropertyDescriptor(ctx.window.Navigator.prototype, 'cookieEnabled');
26
let spoofTitle = '';
27
let spoofDomain = ctx.location.hostname;
28
29
if (ctx.window.Document.prototype.write) {
30
ctx.window.Document.prototype.write = new Proxy(ctx.window.Document.prototype.write, {
31
apply: (target, that , args) => {
32
if (args.length) args = [ ctx.html.process(args.join(''), ctx.meta) ];
33
return Reflect.apply(target, that, args);
34
},
35
});
36
};
37
if (ctx.window.Document.prototype.hasOwnProperty('cookie')) {
38
Object.defineProperty(ctx.window.Document.prototype, 'cookie', {
39
get: new Proxy(cookie.get, {
40
apply: (target, that, args) => {
41
const cookies = Reflect.apply(target, that, args);
42
return ctx.config.cookie ? ctx.cookies.decode(cookies, ctx.meta) : '';
43
},
44
}),
45
set: new Proxy(cookie.set, {
46
apply: (target, that, [ val ]) => {
47
return Reflect.apply(target, that, [ ctx.config.cookie ? ctx.cookies.encode(val, ctx.meta) : '' ]);
48
},
49
}),
50
});
51
};
52
if (ctx.window.Document.prototype.writeln) {
53
ctx.window.Document.prototype.writeln = new Proxy(ctx.window.Document.prototype.writeln, {
54
apply: (target, that , args) => {
55
if (args.length) args = [ ctx.html.process(args.join(''), ctx.meta) ];
56
return Reflect.apply(target, that, args);
57
},
58
});
59
};
60
if (ctx.window.Element.prototype.setAttribute) {
61
ctx.window.Element.prototype.setAttribute = new Proxy(ctx.window.Element.prototype.setAttribute, {
62
apply: (target, that, args) => {
63
if (args[0] && args[1]) {
64
const handler = ctx.html.attributeRoute({
65
name: args[0],
66
value: args[1],
67
node: that,
68
});
69
switch(handler) {
70
case 'url':
71
Reflect.apply(target, that, [`corrosion-${args[0]}`, args[1]]);
72
//if (that.tagName == 'SCRIPT' && args[0] == 'src') flags.push('js');
73
args[1] = ctx.url.wrap(args[1], ctx.meta);
74
break;
75
case 'srcset':
76
Reflect.apply(target, that, [`corrosion-${args[0]}`, args[1]]);
77
args[1] = ctx.html.srcset(args[1], ctx.meta);
78
break;
79
case 'css':
80
Reflect.apply(target, that, [`corrosion-${args[0]}`, args[1]]);
81
args[1] = ctx.css.process(args[1], { ...ctx.meta, context: 'declarationList' });
82
break;
83
case 'html':
84
Reflect.apply(target, that, [`corrosion-${args[0]}`, args[1]]);
85
args[1] = ctx.html.process(args[1], ctx.meta);
86
break;
87
case 'delete':
88
return Reflect.apply(target, that, [`corrosion-${args[0]}`, args[1]]);
89
};
90
};
91
return Reflect.apply(target, that, args);
92
},
93
});
94
};
95
if (ctx.window.Element.prototype.getAttribute) {
96
ctx.window.Element.prototype.getAttribute = new Proxy(ctx.window.Element.prototype.getAttribute, {
97
apply: (target, that, args) => {
98
if (args[0] && that.hasAttribute(`corrosion-${args[0]}`)) args[0] = `corrosion-${args[0]}`;
99
return Reflect.apply(target, that, args);
100
},
101
});
102
};
103
ctx.window.CSSStyleDeclaration.prototype.setProperty = new Proxy(ctx.window.CSSStyleDeclaration.prototype.setProperty, {
104
apply: (target, that, args) => {
105
if (args[1]) args[1] = ctx.css.process(args[1], { context: 'value', ...ctx.meta, });
106
return Reflect.apply(target, that, args);
107
},
108
});
109
if (ctx.window.Audio) {
110
ctx.window.Audio = new Proxy(ctx.window.Audio, {
111
construct: (target, args) => {
112
if (args[0]) args[0] = ctx.url.wrap(args[0], ctx.meta);
113
return Reflect.construct(target, args);
114
},
115
});
116
};
117
[
118
'innerHTML',
119
'outerHTML',
120
].forEach(html => {
121
const descriptor = Object.getOwnPropertyDescriptor(ctx.window.Element.prototype, html);
122
Object.defineProperty(ctx.window.Element.prototype, html, {
123
get: new Proxy(descriptor.get, {
124
apply: (target, that, args) => {
125
const body = Reflect.apply(target, that, args);
126
if (!body || html == 'innerHTML' && that.tagName == 'SCRIPT') return body;
127
return ctx.html.source(body, ctx.meta);
128
},
129
}),
130
set: new Proxy(descriptor.set, {
131
apply(target, that, [ val ]) {
132
return Reflect.apply(target, that, [ val ? ctx.html.process(val.toString(), ctx.meta) : val, ]);
133
},
134
}),
135
});
136
});
137
[
138
['background', 'background'],
139
['backgroundImage', 'background-image'],
140
['listStyleImage', 'list-style-image'],
141
].forEach(([key, cssProperty]) => {
142
Object.defineProperty(ctx.window.CSS2Properties ? ctx.window.CSS2Properties.prototype : ctx.window.CSSStyleDeclaration.prototype, key, {
143
get() {
144
return this.getPropertyValue(cssProperty);
145
},
146
set(val) {
147
return this.setProperty(cssProperty, val);
148
},
149
});
150
});
151
Object.defineProperty(ctx.window.Document.prototype, 'domain', {
152
get: new Proxy(domain.get, {
153
apply: () => spoofDomain,
154
}),
155
set: new Proxy(domain.set, {
156
apply: (target, that, [ val ]) => {
157
if (!val.toString().endsWith(ctx.location.hostname.split('.').slice(-2).join('.'))) return Reflect.apply(target, that, ['']);
158
return spoofDomain = val;
159
},
160
}),
161
});
162
if (ctx.config.title) Object.defineProperty(ctx.window.Document.prototype, 'title', {
163
get: new Proxy(title.get, {
164
apply: () => spoofTitle,
165
}),
166
set: new Proxy(title.set, {
167
apply: (target, that, [ val ]) => spoofTitle = val,
168
}),
169
});
170
Object.defineProperty(ctx.window.Navigator.prototype, 'cookieEnabled', {
171
get: new Proxy(cookieEnabled.get, {
172
apply: () => ctx.config.cookie,
173
}),
174
});
175
Object.defineProperty(ctx.window.Node.prototype, 'baseURI', {
176
get: new Proxy(baseURI.get, {
177
apply: (target, that, args) => {
178
const val = Reflect.apply(target, that, args);
179
return val.startsWith(ctx.meta.origin) ? ctx.url.unwrap(val, ctx.meta) : val;
180
},
181
}),
182
});
183
[
184
{
185
elements: [ HTMLScriptElement, HTMLMediaElement, HTMLImageElement, HTMLAudioElement, HTMLVideoElement, HTMLInputElement, HTMLEmbedElement, HTMLIFrameElement, HTMLTrackElement, HTMLSourceElement],
186
properties: ['src'],
187
handler: 'url',
188
},
189
{
190
elements: [ HTMLFormElement ],
191
properties: ['action'],
192
handler: 'url',
193
},
194
{
195
elements: [ HTMLAnchorElement, HTMLAreaElement, HTMLLinkElement, HTMLBaseElement ],
196
properties: ['href'],
197
handler: 'url',
198
},
199
{
200
elements: [ HTMLImageElement, HTMLSourceElement ],
201
properties: ['srcset'],
202
handler: 'srcset',
203
},
204
{
205
elements: [ HTMLScriptElement ],
206
properties: ['integrity'],
207
handler: 'delete',
208
},
209
{
210
elements: [ HTMLIFrameElement ],
211
properties: ['contentWindow'],
212
handler: 'window',
213
},
214
].forEach(entry => {
215
entry.elements.forEach(element => {
216
if (!element) return;
217
entry.properties.forEach(property => {
218
if (!element.prototype.hasOwnProperty(property)) return;
219
const descriptor = Object.getOwnPropertyDescriptor(element.prototype, property);
220
Object.defineProperty(element.prototype, property, {
221
get: descriptor.get ? new Proxy(descriptor.get, {
222
apply: (target, that, args) => {
223
let val = Reflect.apply(target, that, args);
224
let flags = [];
225
switch(entry.handler) {
226
case 'url':
227
//if (that.tagName == 'SCRIPT' && property == 'src') flags.push('js');
228
val = ctx.url.unwrap(val, ctx.meta);
229
break;
230
case 'srcset':
231
val = ctx.html.unsrcset(val, ctx.meta);
232
break;
233
case 'delete':
234
val = that.getAttribute(`corrosion-${property}`);
235
break;
236
case 'window':
237
try {
238
if (!val.$corrosion) {
239
val.$corrosion = new ctx.constructor({ ...ctx.config, window: val, });
240
val.$corrosion.init();
241
val.$corrosion.meta = ctx.meta;
242
};
243
} catch(e) {};
244
};
245
return val;
246
},
247
}) : undefined,
248
set: descriptor.set ? new Proxy(descriptor.set, {
249
apply(target, that, [ val ]) {
250
let newVal = val;
251
switch(entry.handler) {
252
case 'url':
253
newVal = ctx.url.wrap(newVal, ctx.meta);
254
break;
255
case 'srcset':
256
newVal = ctx.html.srcset(newVal, ctx.meta);
257
break;
258
case 'delete':
259
that.setAttribute(property, newVal);
260
return newVal;
261
};
262
return Reflect.apply(target, that, [ newVal ]);
263
},
264
}) : undefined,
265
});
266
});
267
});
268
});
269
};
270
};
271
module.exports = createDocumentRewriter;
272