From 19ea7e8a02e822ca66ecf81937dcf22fc61a2e20 Mon Sep 17 00:00:00 2001 From: Jason <59297610+caracal-js@users.noreply.github.com> Date: Mon, 7 Mar 2022 21:58:14 -0500 Subject: [PATCH] sa --- client/dom/attr.js | 81 +++++++++++++++++++++++++- client/location.js | 8 ++- client/requests/eventsource.js | 9 +++ client/requests/websocket.js | 9 +++ lib/uv.bundle.js | 101 +++++++++++++++++++++++++++++++-- 5 files changed, 200 insertions(+), 8 deletions(-) diff --git a/client/dom/attr.js b/client/dom/attr.js index fa09e82..4316179 100644 --- a/client/dom/attr.js +++ b/client/dom/attr.js @@ -10,8 +10,15 @@ class AttrApi extends EventEmitter { this.attrProto = this.Attr.prototype || {}; this.value = ctx.nativeMethods.getOwnPropertyDescriptor(this.attrProto, 'value'); this.name = ctx.nativeMethods.getOwnPropertyDescriptor(this.attrProto, 'name'); + this.getNamedItem = this.attrProto.getNamedItem || null; + this.setNamedItem = this.attrProto.setNamedItem || null; + this.removeNamedItem = this.attrProto.removeNamedItem || null; + this.getNamedItemNS = this.attrProto.getNamedItemNS || null; + this.setNamedItemNS = this.attrProto.setNamedItemNS || null; + this.removeNamedItemNS = this.attrProto.removeNamedItemNS || null; + this.item = this.attrProto.item || null; }; - override() { + overrideNameValue() { this.ctx.overrideDescriptor(this.attrProto, 'name', { get: (target, that) => { const event = new HookEvent({ value: target.call(that) }, target, that); @@ -39,6 +46,78 @@ class AttrApi extends EventEmitter { } }); }; + overrideItemMethods() { + this.ctx.override(this.attrProto, 'getNamedItem', (target, that, args) => { + if (!args.length) return target.apply(that, args); + let [ name ] = args; + + const event = new HookEvent({ name }, target, that); + this.emit('getNamedItem', event); + + if (event.intercepted) return event.returnValue; + return event.target.call(event.that, event.data.name); + }); + this.ctx.override(this.attrProto, 'setNamedItem', (target, that, args) => { + if (2 > args.length) return target.apply(that, args); + let [ name, value ] = args; + + const event = new HookEvent({ name, value }, target, that); + this.emit('setNamedItem', event); + + if (event.intercepted) return event.returnValue; + return event.target.call(event.that, event.data.name, event.data.value); + }); + this.ctx.override(this.attrProto, 'removeNamedItem', (target, that, args) => { + if (!args.length) return target.apply(that, args); + let [ name ] = args; + + const event = new HookEvent({ name }, target, that); + this.emit('removeNamedItem', event); + + if (event.intercepted) return event.returnValue; + return event.target.call(event.that, event.data.name); + }); + this.ctx.override(this.attrProto, 'item', (target, that, args) => { + if (!args.length) return target.apply(that, args); + let [ index ] = args; + + const event = new HookEvent({ index }, target, that); + this.emit('item', event); + + if (event.intercepted) return event.returnValue; + return event.target.call(event.that, event.data.name); + }); + this.ctx.override(this.attrProto, 'getNamedItemNS', (target, that, args) => { + if (2 > args.length) return target.apply(that, args); + let [ namespace, localName ] = args; + + const event = new HookEvent({ namespace, localName }, target, that); + this.emit('getNamedItemNS', event); + + if (event.intercepted) return event.returnValue; + return event.target.call(event.that, event.data.namespace, event.data.localName); + }); + this.ctx.override(this.attrProto, 'setNamedItemNS', (target, that, args) => { + if (!args.length) return target.apply(that, args); + let [ attr ] = args; + + const event = new HookEvent({ attr }, target, that); + this.emit('setNamedItemNS', event); + + if (event.intercepted) return event.returnValue; + return event.target.call(event.that, event.data.name); + }); + this.ctx.override(this.attrProto, 'removeNamedItemNS', (target, that, args) => { + if (2 > args.length) return target.apply(that, args); + let [ namespace, localName ] = args; + + const event = new HookEvent({ namespace, localName }, target, that); + this.emit('removeNamedItemNS', event); + + if (event.intercepted) return event.returnValue; + return event.target.call(event.that, event.data.namespace, event.data.localName); + }); + }; }; export default AttrApi; \ No newline at end of file diff --git a/client/location.js b/client/location.js index e665179..786a700 100644 --- a/client/location.js +++ b/client/location.js @@ -1,11 +1,15 @@ -class LocationApi { +import EventEmitter from "./events.js"; + +class LocationApi extends EventEmitter { constructor(ctx) { + super(); 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.HashChangeEvent = this.window.HashChangeEvent || null; this.href = this.WorkerLocation ? ctx.nativeMethods.getOwnPropertyDescriptor(this.workerLocProto, 'href') : ctx.nativeMethods.getOwnPropertyDescriptor(this.location, 'href'); }; @@ -42,7 +46,7 @@ class LocationApi { that.location.href = wrap(val); break; case 'hash': - that.location.hash = val; + that.emit('hashchange', emulation.href, (val.trim().startsWith('#') ? new URL(val.trim(), emulation.href).href : new URL('#' + val.trim(), emulation.href).href), that); break; default: const url = new URL(emulation.href); diff --git a/client/requests/eventsource.js b/client/requests/eventsource.js index 3ab3bd6..0b928fd 100644 --- a/client/requests/eventsource.js +++ b/client/requests/eventsource.js @@ -9,6 +9,9 @@ class EventSourceApi extends EventEmitter { this.EventSource = this.window.EventSource || {}; this.esProto = this.EventSource.prototype || {}; this.url = ctx.nativeMethods.getOwnPropertyDescriptor(this.esProto, 'url'); + this.CONNECTING = 0; + this.OPEN = 1; + this.CLOSED = 2; }; overrideConstruct() { this.ctx.override(this.window, 'EventSource', (target, that, args) => { @@ -21,6 +24,12 @@ class EventSourceApi extends EventEmitter { if (event.intercepted) return event.returnValue; return new event.target(event.data.url, event.data.config); }, true); + + if ('EventSource' in this.window) { + this.window.EventSource.CONNECTING = this.CONNECTING; + this.window.EventSource.OPEN = this.OPEN; + this.window.EventSource.CLOSED = this.CLOSED; + }; }; overrideUrl() { this.ctx.overrideDescriptor(this.esProto, 'url', { diff --git a/client/requests/websocket.js b/client/requests/websocket.js index 50d8082..9ba34df 100644 --- a/client/requests/websocket.js +++ b/client/requests/websocket.js @@ -12,6 +12,10 @@ class WebSocketApi extends EventEmitter { this.protocol = ctx.nativeMethods.getOwnPropertyDescriptor(this.wsProto, 'protocol'); this.send = this.wsProto.send; this.close = this.wsProto.close; + this.CONNECTING = 0; + this.OPEN = 1; + this.CLOSING = 2; + this.CLOSED = 3; }; overrideWebSocket() { this.ctx.override(this.window, 'WebSocket', (target, that, args) => { @@ -25,6 +29,11 @@ class WebSocketApi extends EventEmitter { if (event.intercepted) return event.returnValue; return new event.target(event.data.url, event.data.protocols); }, true); + + this.window.WebSocket.CONNECTING = this.CONNECTING; + this.window.WebSocket.OPEN = this.OPEN; + this.window.WebSocket.CLOSING = this.CLOSING; + this.window.WebSocket.CLOSED = this.CLOSED; }; overrideUrl() { this.ctx.overrideDescriptor(this.wsProto, 'url', { diff --git a/lib/uv.bundle.js b/lib/uv.bundle.js index ee061a0..099a868 100644 --- a/lib/uv.bundle.js +++ b/lib/uv.bundle.js @@ -37639,8 +37639,15 @@ class AttrApi extends _events_js__WEBPACK_IMPORTED_MODULE_0__["default"] { this.attrProto = this.Attr.prototype || {}; this.value = ctx.nativeMethods.getOwnPropertyDescriptor(this.attrProto, 'value'); this.name = ctx.nativeMethods.getOwnPropertyDescriptor(this.attrProto, 'name'); + this.getNamedItem = this.attrProto.getNamedItem || null; + this.setNamedItem = this.attrProto.setNamedItem || null; + this.removeNamedItem = this.attrProto.removeNamedItem || null; + this.getNamedItemNS = this.attrProto.getNamedItemNS || null; + this.setNamedItemNS = this.attrProto.setNamedItemNS || null; + this.removeNamedItemNS = this.attrProto.removeNamedItemNS || null; + this.item = this.attrProto.item || null; }; - override() { + overrideNameValue() { this.ctx.overrideDescriptor(this.attrProto, 'name', { get: (target, that) => { const event = new _hook_js__WEBPACK_IMPORTED_MODULE_1__["default"]({ value: target.call(that) }, target, that); @@ -37668,6 +37675,78 @@ class AttrApi extends _events_js__WEBPACK_IMPORTED_MODULE_0__["default"] { } }); }; + overrideItemMethods() { + this.ctx.override(this.attrProto, 'getNamedItem', (target, that, args) => { + if (!args.length) return target.apply(that, args); + let [ name ] = args; + + const event = new _hook_js__WEBPACK_IMPORTED_MODULE_1__["default"]({ name }, target, that); + this.emit('getNamedItem', event); + + if (event.intercepted) return event.returnValue; + return event.target.call(event.that, event.data.name); + }); + this.ctx.override(this.attrProto, 'setNamedItem', (target, that, args) => { + if (2 > args.length) return target.apply(that, args); + let [ name, value ] = args; + + const event = new _hook_js__WEBPACK_IMPORTED_MODULE_1__["default"]({ name, value }, target, that); + this.emit('setNamedItem', event); + + if (event.intercepted) return event.returnValue; + return event.target.call(event.that, event.data.name, event.data.value); + }); + this.ctx.override(this.attrProto, 'removeNamedItem', (target, that, args) => { + if (!args.length) return target.apply(that, args); + let [ name ] = args; + + const event = new _hook_js__WEBPACK_IMPORTED_MODULE_1__["default"]({ name }, target, that); + this.emit('removeNamedItem', event); + + if (event.intercepted) return event.returnValue; + return event.target.call(event.that, event.data.name); + }); + this.ctx.override(this.attrProto, 'item', (target, that, args) => { + if (!args.length) return target.apply(that, args); + let [ index ] = args; + + const event = new _hook_js__WEBPACK_IMPORTED_MODULE_1__["default"]({ index }, target, that); + this.emit('item', event); + + if (event.intercepted) return event.returnValue; + return event.target.call(event.that, event.data.name); + }); + this.ctx.override(this.attrProto, 'getNamedItemNS', (target, that, args) => { + if (2 > args.length) return target.apply(that, args); + let [ namespace, localName ] = args; + + const event = new _hook_js__WEBPACK_IMPORTED_MODULE_1__["default"]({ namespace, localName }, target, that); + this.emit('getNamedItemNS', event); + + if (event.intercepted) return event.returnValue; + return event.target.call(event.that, event.data.namespace, event.data.localName); + }); + this.ctx.override(this.attrProto, 'setNamedItemNS', (target, that, args) => { + if (!args.length) return target.apply(that, args); + let [ attr ] = args; + + const event = new _hook_js__WEBPACK_IMPORTED_MODULE_1__["default"]({ attr }, target, that); + this.emit('setNamedItemNS', event); + + if (event.intercepted) return event.returnValue; + return event.target.call(event.that, event.data.name); + }); + this.ctx.override(this.attrProto, 'removeNamedItemNS', (target, that, args) => { + if (2 > args.length) return target.apply(that, args); + let [ namespace, localName ] = args; + + const event = new _hook_js__WEBPACK_IMPORTED_MODULE_1__["default"]({ namespace, localName }, target, that); + this.emit('removeNamedItemNS', event); + + if (event.intercepted) return event.returnValue; + return event.target.call(event.that, event.data.namespace, event.data.localName); + }); + }; }; /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (AttrApi); @@ -38173,6 +38252,9 @@ class EventSourceApi extends _events_js__WEBPACK_IMPORTED_MODULE_0__["default"] this.EventSource = this.window.EventSource || {}; this.esProto = this.EventSource.prototype || {}; this.url = ctx.nativeMethods.getOwnPropertyDescriptor(this.esProto, 'url'); + this.CONNECTING = 0; + this.OPEN = 1; + this.CLOSED = 2; }; overrideConstruct() { this.ctx.override(this.window, 'EventSource', (target, that, args) => { @@ -38185,6 +38267,12 @@ class EventSourceApi extends _events_js__WEBPACK_IMPORTED_MODULE_0__["default"] if (event.intercepted) return event.returnValue; return new event.target(event.data.url, event.data.config); }, true); + + if ('EventSource' in this.window) { + this.window.EventSource.CONNECTING = this.CONNECTING; + this.window.EventSource.OPEN = this.OPEN; + this.window.EventSource.CLOSED = this.CLOSED; + }; }; overrideUrl() { this.ctx.overrideDescriptor(this.esProto, 'url', { @@ -38298,14 +38386,19 @@ __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) /* harmony export */ }); -class LocationApi { +/* harmony import */ var _events_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(155); + + +class LocationApi extends _events_js__WEBPACK_IMPORTED_MODULE_0__["default"] { constructor(ctx) { + super(); 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.HashChangeEvent = this.window.HashChangeEvent || null; this.href = this.WorkerLocation ? ctx.nativeMethods.getOwnPropertyDescriptor(this.workerLocProto, 'href') : ctx.nativeMethods.getOwnPropertyDescriptor(this.location, 'href'); }; @@ -38342,7 +38435,7 @@ class LocationApi { that.location.href = wrap(val); break; case 'hash': - that.location.hash = val; + that.emit('hashchange', emulation.href, (val.trim().startsWith('#') ? new URL(val.trim(), emulation.href).href : new URL('#' + val.trim(), emulation.href).href), that); break; default: const url = new URL(emulation.href); @@ -39035,7 +39128,6 @@ __webpack_require__.r(__webpack_exports__); -//import { call, destructureDeclaration, dynamicImport, getProperty, importDeclaration, setProperty, sourceMethods, wrapEval, wrapIdentifier } from './rewrite.script.js'; @@ -39049,7 +39141,6 @@ const reserved_chars = "%"; class Ultraviolet { constructor(options = {}) { this.prefix = options.prefix || '/service/'; - //this.urlRegex = /^(#|about:|data:|mailto:|javascript:)/; this.urlRegex = /^(#|about:|data:|mailto:)/ this.rewriteUrl = options.rewriteUrl || this.rewriteUrl; this.sourceUrl = options.sourceUrl || this.sourceUrl;