Holy-Unblocker/lib/browser/index.js
2021-11-29 23:40:38 -08:00

195 lines
No EOL
7.6 KiB
JavaScript

const createDocumentRewriter = require('./document');
const createHistoryRewriter = require('./history');
const createHttpRewriter = require('./http');
const createLocation = require('./location');
const createWorkerRewriter = require('./worker');
const defaultConfig = {
prefix: '/service/',
codec: 'plain',
ws: true,
cookie: true,
title: 'Service',
serviceWorker: false,
url: null,
window: false,
};
class Corrosion extends require('../rewrite') {
constructor(config = defaultConfig) {
super(Object.assign(defaultConfig, config));
const corrosion = this;
if (!this.config.window) throw 'Corrosion Error: No window was given.';
this.serviceWorker = this.config.serviceWorker || false;
this.window = this.config.window;
this.document = this.serviceWorker ? this.window.document : {};
this._url = new URL((this.config.url || this.url.unwrap(this.window.location.href, { origin: this.window.location.origin, })));
this.originalXhr = this.window.XMLHttpRequest;
this.meta = {
origin: this.window.location.origin,
get base() {
if (corrosion.serviceWorker) return corrosion._url;
return corrosion.window.document.baseURI != corrosion.location.href ? new URL(corrosion.window.document.baseURI) : corrosion._url;
},
url: this._url,
};
this.location = createLocation(this, this._url);
this.rewriteHttp = createHttpRewriter(this);
this.rewriteDocument = createDocumentRewriter(this);
this.rewriteHistory = createHistoryRewriter(this);
this.rewriteWorker = createWorkerRewriter(this);
if (!this.serviceWorker && this.window.document.currentScript) this.window.document.currentScript.remove();
};
get parent() {
if (this.serviceWorker) return false;
try {
return this.window.parent.$corrosion ? this.window.parent : this.window;
} catch(e) {
return this.window;
};
};
get top() {
if (this.serviceWorker) return false;
try {
return this.window.top.$corrosion ? this.window.top : this.parent;
} catch(e) {
return this.parent;
};
};
init() {
this.rewriteHttp();
this.rewriteDocument();
this.rewriteHistory();
this.rewriteWorker();
this.window.Location = createLocation.Location;
this.window.$corrosionGet$ = this.get$.bind(this);
this.window.$corrosionSet$ = this.set$.bind(this);
this.window.$corrosionGet$m = this.get$m.bind(this);
this.window.$corrosionSet$m = this.set$m.bind(this);
this.window.$corrosionCall$m = this.call$m.bind(this);
};
get$m(obj, key) {
if (!this.serviceWorker && this.window != this.window.parent && obj == this.window.parent) {
return this.parent.$corrosion.get$m(this.parent, key);
};
if (!this.serviceWorker && this.window != this.window.top && obj == this.window.top) {
return this.top.$corrosion.get$m(this.top, key);
};
if (obj == this.window && key == 'location' || !this.serviceWorker && obj == this.window.document && key == 'location') return this.location;
if (!this.serviceWorker && obj == this.window && key == 'parent' && this.window != this.window.parent) return this.parent;
if (!this.serviceWorker && obj == this.window && key == 'top' && this.window != this.window.top) return this.top;
return obj[key];
};
set$m(obj, key, val, operator) {
if (!this.serviceWorker && this.window != this.window.parent && obj == this.window.parent) {
return this.parent.$corrosion.set$m(this.parent, key, val, operator);
};
if (!this.serviceWorker && this.window != this.window.top && obj == this.window.top) {
return this.top.$corrosion.set$m(this.top, key, val, operator);
};
if (obj == this.window && key == 'location' || !this.serviceWorker && obj == this.window.document && key == 'location') obj = this;
switch(operator) {
case '+=':
return obj[key] += val;
case '-=':
return obj[key] -= val;
case '*=':
return obj[key] *= val;
case '/=':
return obj[key] /= val;
case '%=':
return obj[key] %= val;
case '**=':
return obj[key] **= val;
case '<<=':
return obj[key] <<= val;
case '>>=':
return obj[key] >>= val;
case '>>>=':
return obj[key] >>>= val;
case '&=':
return obj[key] &= val;
case '^=':
return obj[key] ^= val;
case '|=':
return obj[key] |= val;
case '&&=':
return obj[key] &&= val;
case '||=':
return obj[key] ||= val;
case '??=':
return obj[key] ??= val;
case '++':
return obj[key]++;
case '--':
return obj[key]--;
case '=':
default:
return obj[key] = val;
};
};
call$m(obj, key, args) {
if (!this.serviceWorker && this.window != this.window.parent && obj == this.window.parent) {
return this.parent.$corrosion.call$m(this.parent, key, args);
};
if (!this.serviceWorker && this.window != this.window.top && obj == this.window.top) {
return this.top.$corrosion.call$m(this.top, key, args);
};
return obj[key](...args);
};
get$(obj) {
if (obj == this.window.location) return this.location;
if (!this.serviceWorker && obj == this.window.parent) return this.parent;
if (!this.serviceWorker && obj == this.window.top) return this.top;
return obj;
};
set$(obj, val, operator) {
if (obj == this.window.location) return this.set$(this.location, val, operator);
if (!this.serviceWorker && this.window != this.window.parent && obj == this.window.parent) return this.parent.set$(this.parent, val, operator);
if (!this.serviceWorker && this.window != this.window.top && obj == this.window.top) return this.top.set$(this.top, val, operator);
switch(operator) {
case '+=':
return obj += val;
case '-=':
return obj -= val;
case '*=':
return obj *= val;
case '/=':
return obj /= val;
case '%=':
return obj %= val;
case '**=':
return obj **= val;
case '<<=':
return obj <<= val;
case '>>=':
return obj >>= val;
case '>>>=':
return obj >>>= val;
case '&=':
return obj &= val;
case '^=':
return obj ^= val;
case '|=':
return obj |= val;
case '&&=':
return obj &&= val;
case '||=':
return obj ||= val;
case '??=':
return obj ??= val;
case '++':
return obj++;
case '--':
return obj--;
case '=':
default:
return obj = val;
};
};
updateLocation() {
this._url = new URL(this.url.unwrap(this.window.location.href, this.meta));
this.location = createLocation(this, this._url);
};
};
globalThis.Corrosion = Corrosion;