Path: blob/main/src/client/dom/document.js
305 views
import EventEmitter from "events";1import HookEvent from "../hook.js";23/**4* @typedef {import('../index').default} UVClient5*/67class DocumentHook extends EventEmitter {8/**9*10* @param {UVClient} ctx11*/12constructor(ctx) {13super();14this.ctx = ctx;15this.window = ctx.window;16this.document = this.window.document;17this.Document = this.window.Document || {};18this.DOMParser = this.window.DOMParser || {};19this.docProto = this.Document.prototype || {};20this.domProto = this.DOMParser.prototype || {};21this.title = ctx.nativeMethods.getOwnPropertyDescriptor(22this.docProto,23"title"24);25this.cookie = ctx.nativeMethods.getOwnPropertyDescriptor(26this.docProto,27"cookie"28);29this.referrer = ctx.nativeMethods.getOwnPropertyDescriptor(30this.docProto,31"referrer"32);33this.domain = ctx.nativeMethods.getOwnPropertyDescriptor(34this.docProto,35"domain"36);37this.documentURI = ctx.nativeMethods.getOwnPropertyDescriptor(38this.docProto,39"documentURI"40);41this.write = this.docProto.write;42this.writeln = this.docProto.writeln;43this.querySelector = this.docProto.querySelector;44this.querySelectorAll = this.docProto.querySelectorAll;45this.parseFromString = this.domProto.parseFromString;46this.URL = ctx.nativeMethods.getOwnPropertyDescriptor(this.docProto, "URL");47}48overrideParseFromString() {49this.ctx.override(50this.domProto,51"parseFromString",52(target, that, args) => {53if (2 > args.length) return target.apply(that, args);54let [string, type] = args;5556const event = new HookEvent({ string, type }, target, that);57this.emit("parseFromString", event);5859if (event.intercepted) return event.returnValue;60return event.target.call(61event.that,62event.data.string,63event.data.type64);65}66);67}68overrideQuerySelector() {69this.ctx.override(this.docProto, "querySelector", (target, that, args) => {70if (!args.length) return target.apply(that, args);71let [selectors] = args;7273const event = new HookEvent({ selectors }, target, that);74this.emit("querySelector", event);7576if (event.intercepted) return event.returnValue;77return event.target.call(event.that, event.data.selectors);78});79}80overrideDomain() {81this.ctx.overrideDescriptor(this.docProto, "domain", {82get: (target, that) => {83const event = new HookEvent({ value: target.call(that) }, target, that);84this.emit("getDomain", event);8586if (event.intercepted) return event.returnValue;87return event.data.value;88},89set: (target, that, [val]) => {90const event = new HookEvent({ value: val }, target, that);91this.emit("setDomain", event);9293if (event.intercepted) return event.returnValue;94return event.target.call(event.that, event.data.value);95},96});97}98overrideReferrer() {99this.ctx.overrideDescriptor(this.docProto, "referrer", {100get: (target, that) => {101const event = new HookEvent({ value: target.call(that) }, target, that);102this.emit("referrer", event);103104if (event.intercepted) return event.returnValue;105return event.data.value;106},107});108}109overrideCreateTreeWalker() {110this.ctx.override(111this.docProto,112"createTreeWalker",113(target, that, args) => {114if (!args.length) return target.apply(that, args);115let [root, show = 0xffffffff, filter, expandEntityReferences] = args;116117const event = new HookEvent(118{ root, show, filter, expandEntityReferences },119target,120that121);122this.emit("createTreeWalker", event);123124if (event.intercepted) return event.returnValue;125return event.target.call(126event.that,127event.data.root,128event.data.show,129event.data.filter,130event.data.expandEntityReferences131);132}133);134}135overrideWrite() {136this.ctx.override(this.docProto, "write", (target, that, args) => {137if (!args.length) return target.apply(that, args);138let [...html] = args;139140const event = new HookEvent({ html }, target, that);141this.emit("write", event);142143if (event.intercepted) return event.returnValue;144return event.target.apply(event.that, event.data.html);145});146this.ctx.override(this.docProto, "writeln", (target, that, args) => {147if (!args.length) return target.apply(that, args);148let [...html] = args;149150const event = new HookEvent({ html }, target, that);151this.emit("writeln", event);152153if (event.intercepted) return event.returnValue;154return event.target.apply(event.that, event.data.html);155});156}157overrideDocumentURI() {158this.ctx.overrideDescriptor(this.docProto, "documentURI", {159get: (target, that) => {160const event = new HookEvent({ value: target.call(that) }, target, that);161this.emit("documentURI", event);162163if (event.intercepted) return event.returnValue;164return event.data.value;165},166});167}168overrideURL() {169this.ctx.overrideDescriptor(this.docProto, "URL", {170get: (target, that) => {171const event = new HookEvent({ value: target.call(that) }, target, that);172this.emit("url", event);173174if (event.intercepted) return event.returnValue;175return event.data.value;176},177});178}179overrideCookie() {180this.ctx.overrideDescriptor(this.docProto, "cookie", {181get: (target, that) => {182const event = new HookEvent({ value: target.call(that) }, target, that);183this.emit("getCookie", event);184185if (event.intercepted) return event.returnValue;186return event.data.value;187},188set: (target, that, [value]) => {189const event = new HookEvent({ value }, target, that);190this.emit("setCookie", event);191192if (event.intercepted) return event.returnValue;193return event.target.call(event.that, event.data.value);194},195});196}197overrideTitle() {198this.ctx.overrideDescriptor(this.docProto, "title", {199get: (target, that) => {200const event = new HookEvent({ value: target.call(that) }, target, that);201this.emit("getTitle", event);202203if (event.intercepted) return event.returnValue;204return event.data.value;205},206set: (target, that, [value]) => {207const event = new HookEvent({ value }, target, that);208this.emit("setTitle", event);209210if (event.intercepted) return event.returnValue;211return event.target.call(event.that, event.data.value);212},213});214}215}216217export default DocumentHook;218219220