This commit is contained in:
Jason 2022-02-14 00:25:17 -05:00
parent b9b6aee734
commit 82f5f76588
66 changed files with 74967 additions and 1 deletions

119
client/location.js Normal file
View file

@ -0,0 +1,119 @@
class LocationApi {
constructor(ctx) {
this.ctx = ctx;
this.window = ctx.window;
this.location = this.window.location;
this.WorkerLocation = this.ctx.worker ? this.window.WorkerLocation : null;
this.workerLocProto = this.WorkerLocation ? this.WorkerLocation.prototype : {};
this.keys = ['href', 'protocol', 'host', 'hostname', 'port', 'pathname', 'search', 'hash', 'origin'];
this.href = this.WorkerLocation ? ctx.nativeMethods.getOwnPropertyDescriptor(this.workerLocProto, 'href') :
ctx.nativeMethods.getOwnPropertyDescriptor(this.location, 'href');
};
overrideWorkerLocation(parse) {
if (!this.WorkerLocation) return false;
const uv = this;
for (const key of this.keys) {
this.ctx.overrideDescriptor(this.workerLocProto, key, {
get: (target, that) => {
return parse(
uv.href.get.call(this.location)
)[key]
},
});
};
return true;
};
emulate(parse, wrap) {
const emulation = {};
const that = this;
for (const key of that.keys) {
this.ctx.nativeMethods.defineProperty(emulation, key, {
get() {
return parse(
that.href.get.call(that.location)
)[key];
},
set: key !== 'origin' ? function (val) {
switch(key) {
case 'href':
that.location.href = wrap(val);
break;
case 'hash':
that.location.hash = val;
break;
default:
const url = new URL(emulation.href);
url[key] = val;
that.location.href = wrap(url.href);
};
} : undefined,
configurable: false,
enumerable: true,
});
};
if ('reload' in this.location) {
this.ctx.nativeMethods.defineProperty(emulation, 'reload', {
value: this.ctx.wrap(this.location, 'reload', (target, that) => {
return target.call(that === emulation ? this.location : that);
}),
writable: false,
enumerable: true,
});
};
if ('replace' in this.location) {
this.ctx.nativeMethods.defineProperty(emulation, 'replace', {
value: this.ctx.wrap(this.location, 'assign', (target, that, args) => {
if (!args.length || that !== emulation) target.call(that);
that = this.location;
let [ input ] = args;
const url = new URL(input, emulation.href);
return target.call(that === emulation ? this.location : that, wrap(url.href));
}),
writable: false,
enumerable: true,
});
};
if ('assign' in this.location) {
this.ctx.nativeMethods.defineProperty(emulation, 'assign', {
value: this.ctx.wrap(this.location, 'assign', (target, that, args) => {
if (!args.length || that !== emulation) target.call(that);
that = this.location;
let [ input ] = args;
const url = new URL(input, emulation.href);
return target.call(that === emulation ? this.location : that, wrap(url.href));
}),
writable: false,
enumerable: true,
});
};
this.ctx.nativeMethods.defineProperty(emulation, 'toString', {
value: this.ctx.wrap(this.location, 'toString', () => {
return emulation.href;
}),
enumerable: true,
writable: false,
});
this.ctx.nativeMethods.defineProperty(emulation, Symbol.toPrimitive, {
value: () => emulation.href,
writable: false,
enumerable: false,
});
if (this.ctx.window.Location) this.ctx.nativeMethods.setPrototypeOf(emulation, this.ctx.window.Location.prototype);
return emulation;
};
};
export default LocationApi;