move to src directory

This commit is contained in:
David Reed 2022-09-15 17:11:11 -04:00
parent 5e04dcb798
commit 7674c39372
33 changed files with 0 additions and 0 deletions

165
src/client/dom/element.js Normal file
View file

@ -0,0 +1,165 @@
import EventEmitter from "../events.js";
import HookEvent from "../hook.js";
class ElementApi extends EventEmitter {
constructor(ctx) {
super();
this.ctx = ctx;
this.window = ctx.window;
this.Audio = this.window.Audio;
this.Element = this.window.Element;
this.elemProto = this.Element ? this.Element.prototype : {};
this.innerHTML = ctx.nativeMethods.getOwnPropertyDescriptor(this.elemProto, 'innerHTML');
this.outerHTML = ctx.nativeMethods.getOwnPropertyDescriptor(this.elemProto, 'outerHTML');
this.setAttribute = this.elemProto.setAttribute;
this.getAttribute = this.elemProto.getAttribute;
this.removeAttribute = this.elemProto.removeAttribute;
this.hasAttribute = this.elemProto.hasAttribute;
this.querySelector = this.elemProto.querySelector;
this.querySelectorAll = this.elemProto.querySelectorAll;
this.insertAdjacentHTML = this.elemProto.insertAdjacentHTML;
this.insertAdjacentText = this.elemProto.insertAdjacentText;
};
overrideQuerySelector() {
this.ctx.override(this.elemProto, 'querySelector', (target, that, args) => {
if (!args.length) return target.apply(that, args);
let [ selectors ] = args;
const event = new HookEvent({ selectors }, target, that);
this.emit('querySelector', event);
if (event.intercepted) return event.returnValue;
return event.target.call(event.that, event.data.selectors);
});
};
overrideAttribute() {
this.ctx.override(this.elemProto, 'getAttribute', (target, that, args) => {
if (!args.length) return target.apply(that, args);
let [ name ] = args;
const event = new HookEvent({ name }, target, that);
this.emit('getAttribute', event);
if (event.intercepted) return event.returnValue;
return event.target.call(event.that, event.data.name);
});
this.ctx.override(this.elemProto, 'setAttribute', (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('setAttribute', event);
if (event.intercepted) return event.returnValue;
return event.target.call(event.that, event.data.name, event.data.value);
});
this.ctx.override(this.elemProto, 'hasAttribute', (target, that, args) => {
if (!args.length) return target.apply(that, args);
let [ name ] = args;
const event = new HookEvent({ name }, target, that);
this.emit('hasAttribute', event);
if (event.intercepted) return event.returnValue;
return event.target.call(event.that, event.data.name);
});
this.ctx.override(this.elemProto, 'removeAttribute', (target, that, args) => {
if (!args.length) return target.apply(that, args);
let [ name ] = args;
const event = new HookEvent({ name }, target, that);
this.emit('removeAttribute', event);
if (event.intercepted) return event.returnValue;
return event.target.call(event.that, event.data.name);
});
};
overrideAudio() {
this.ctx.override(this.window, 'Audio', (target, that, args) => {
if (!args.length) return new target(...args);
let [ url ] = args;
const event = new HookEvent({ url }, target, that);
this.emit('audio', event);
if (event.intercepted) return event.returnValue;
return new event.target(event.data.url);
}, true);
};
overrideHtml() {
this.hookProperty(this.Element, 'innerHTML', {
get: (target, that) => {
const event = new HookEvent({ value: target.call(that) }, target, that);
this.emit('getInnerHTML', event);
if (event.intercepted) return event.returnValue;
return event.data.value;
},
set: (target, that, [ val ]) => {
const event = new HookEvent({ value: val }, target, that);
this.emit('setInnerHTML', event);
if (event.intercepted) return event.returnValue;
target.call(that, event.data.value);
},
});
this.hookProperty(this.Element, 'outerHTML', {
get: (target, that) => {
const event = new HookEvent({ value: target.call(that) }, target, that);
this.emit('getOuterHTML', event);
if (event.intercepted) return event.returnValue;
return event.data.value;
},
set: (target, that, [ val ]) => {
const event = new HookEvent({ value: val }, target, that);
this.emit('setOuterHTML', event);
if (event.intercepted) return event.returnValue;
target.call(that, event.data.value);
},
});
};
overrideInsertAdjacentHTML() {
this.ctx.override(this.elemProto, 'insertAdjacentHTML', (target, that, args) => {
if (2 > args.length) return target.apply(that, args);
let [ position, html ] = args;
const event = new HookEvent({ position, html }, target, that);
this.emit('insertAdjacentHTML', event);
if (event.intercepted) return event.returnValue;
return event.target.call(event.that, event.data.position, event.data.html);
});
};
overrideInsertAdjacentText() {
this.ctx.override(this.elemProto, 'insertAdjacentText', (target, that, args) => {
if (2 > args.length) return target.apply(that, args);
let [ position, text ] = args;
const event = new HookEvent({ position, text }, target, that);
this.emit('insertAdjacentText', event);
if (event.intercepted) return event.returnValue;
return event.target.call(event.that, event.data.position, event.data.text);
});
};
hookProperty(element, prop, handler) {
if (!element || !prop in element) return false;
if (this.ctx.nativeMethods.isArray(element)) {
for (const elem of element) {
this.hookProperty(elem, prop, handler);
};
return true;
};
const proto = element.prototype;
this.ctx.overrideDescriptor(proto, prop, handler);
return true;
};
};
export default ElementApi;