// ==UserScript== // @name ElementRaid Test // @namespace https://bbs.tampermonkey.net.cn/ // @version 0.0.1 // @description ElementRaid Test // @author EmpyrealTear // @match .*://github.com/.* // @match .*://ebooking.ctrip.com/.* // @require https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js // @require https://scriptcat.org/lib/513/2.0.0/ElementGetter.js // @require https://scriptcat.org/lib/2628/6.2.0.1/moduleRaid.js // @grant unsafeWindow // @grant GM_setValue // @grant GM_getValue // @grant GM_registerMenuCommand // @grant GM_unregisterMenuCommand // ==/UserScript== class ReactRaid { constructor(opts) { let options = { target: document.body, entrypoint: '__react' } if (typeof opts === 'object') { options = Object.assign(Object.assign({}, options), opts) } this.target = options.target this.entrypoint = options.entrypoint this.children = [] this.children = this.closest(this.target) } closest(target) { let queue = [target] let children = [] while (queue.length > 0) { let cur = queue.pop() let elmObjects = Object.keys(cur) elmObjects = elmObjects.filter((obj) => obj.startsWith(this.entrypoint)) if (elmObjects.length > 0) { children.push({ target: cur, instance: this.getReactInstance(cur), stateNode: this.getReactStateNode(cur), children: Array.from(cur.children).map(v => this.closest(v)) }) } else { queue.push(...cur.children) } } return children } getReactInstance(elm) { let key = Object.keys(elm).find(key => key.startsWith("__reactInternalInstance$") || key.startsWith("__reactFiber$")) if (key == null) return null return elm[key] } getReactStateNode(elm) { let internalInstance = this.getReactInstance(elm) if (internalInstance == null) return null return internalInstance._debugOwner ?? internalInstance.return ?? internalInstance._currentElement._owner } } (function () { 'use strict'; unsafeWindow.jQuery = $; unsafeWindow.ModuleRaid = ModuleRaid; unsafeWindow.ReactRaid = ReactRaid; })();