123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500 |
- let nowFileName = "";
- let jsonInfo = {};
- let tabId = "";
- let nodeObj;
- let jslist;
- function InitTable() {
- window.TabInstance = $("#filterTable")
- .dxDataGrid({
- dataSource: [],
- keyExpr: "resource_detail_id",
- remoteOperations: false,
- searchPanel: {
- visible: true,
- highlightCaseSensitive: true,
- },
- groupPanel: { visible: true },
- grouping: {
- allowCollapsing: true,
- autoExpandAll: true,
- expandMode: "rowClick",
- },
- selection: {
- mode: "single",
- },
- allowColumnReordering: true,
- rowAlternationEnabled: true,
- showBorders: true,
- height: "100%",
- columns: [
- {
- dataField: "JS文件",
- dataType: "JS文件",
- groupIndex: 0,
- },
- {
- dataField: "过滤器",
- caption: "过滤器",
- },
- {
- dataField: "选择器类型",
- dataType: "选择器类型",
- },
- {
- dataField: "调用方式",
- dataType: "调用方式",
- },
- {
- dataField: "所在位置",
- dataType: "所在位置",
- },
- {
- dataField: "DOM操作分类",
- dataType: "DOM操作分类",
- },
- ],
- onContentReady(e) {},
- onSelectionChanged: function (selectedItems) {
- let data = selectedItems.selectedRowsData[0];
- if (data) {
- let ast = data.astJSON;
- if (data.JS文件 !== nowFileName) {
- nowFileName = data.JS文件;
- let code = window.fileList.find((o) => o.name === data.JS文件).code;
- //更改JS代码
- jsCode.SetCode(code);
- //更改ast
- //window.ShowASTTree(ast, document.getElementById('astJson'))
- }
- //jscode定位
- let {
- defineNode: {
- iid,
- loc: { end, start },
- },
- } = data.source_data;
- {
- //移出所有高亮
- jsCode.RemoveAllHighlight();
- //设置高亮
- jsCode.CreateHighlight({
- startLine: start?.line,
- startColumn: start?.column + 1,
- endLine: end?.line,
- endColumn: end?.column + 1,
- });
- }
- {
- // //ast定位
- // let jsonNode = document.getElementById(iid);
- // if (jsonNode) {
- // let textNode = Array.from(jsonNode.parentNode.childNodes).find(item => item.classList.contains("node-text"));
- // $("#astJson").find(".monaco-highlight").removeClass("monaco-highlight");
- // textNode?.classList?.add("monaco-highlight");
- // scrollTo(jsonNode)
- // }
- }
- }
- },
- })
- .dxDataGrid("instance");
- window.CSSTabInstance = $("#cssJson")
- .dxDataGrid({
- dataSource: [],
- keyExpr: "id",
- remoteOperations: false,
- searchPanel: {
- visible: true,
- highlightCaseSensitive: true,
- },
- selection: {
- mode: "single",
- },
- allowColumnReordering: true,
- rowAlternationEnabled: true,
- showBorders: true,
- height: "100%",
- paging: {
- enabled: false,
- pageSize: 0,
- },
- columns: [
- {
- dataField: "key",
- caption: "名称",
- },
- {
- dataField: "value",
- caption: "生效值",
- },
- ],
- onSelectionChanged: function (selectedItems) {
- let data = selectedItems.selectedRowsData[0];
- if (data) {
- CSSBelongInstance.option({
- dataSource: findPropRef(data.key, jsonInfo).map((s, i) => ({
- ...s,
- id: i,
- })),
- });
- }
- },
- })
- .dxDataGrid("instance");
- window.CSSBelongInstance = $("#cssBelong")
- .dxDataGrid({
- dataSource: [],
- keyExpr: "id",
- remoteOperations: false,
- searchPanel: {
- visible: true,
- highlightCaseSensitive: true,
- },
- selection: {
- mode: "single",
- },
- allowColumnReordering: true,
- rowAlternationEnabled: true,
- showBorders: true,
- paging: {
- enabled: false,
- pageSize: 0,
- },
- height: "100%",
- columns: [
- {
- dataField: "来源",
- caption: "来源",
- width: 100,
- },
- {
- dataField: "选择器",
- caption: "选择器",
- },
- {
- dataField: "属性值",
- caption: "属性值",
- },
- ],
- })
- .dxDataGrid("instance");
- window.eventTableInstance = $("#eventTable")
- .dxDataGrid({
- dataSource: [],
- keyExpr: "id",
- remoteOperations: false,
- searchPanel: {
- visible: true,
- highlightCaseSensitive: true,
- },
- selection: {
- mode: "single",
- },
- allowColumnReordering: true,
- rowAlternationEnabled: true,
- showBorders: true,
- paging: {
- enabled: false,
- pageSize: 0,
- },
- height: "100%",
- columns: [
- {
- dataField: "事件名称",
- caption: "事件名称",
- },
- {
- dataField: "绑定对象",
- caption: "绑定对象",
- },
- {
- dataField: "事件文件",
- caption: "事件文件",
- },
- ],
- })
- .dxDataGrid("instance");
- }
- chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
- if (request.msgToPopup === "发送页面") {
- //初始化JS代码编辑器
- window.jsCode = new CodeEditor();
- jsCode.InitEditor($("#jscode")[0], false, false, [], false);
- jsCode.dataType = 3;
- InitTable();
- let ret = request.data;
- console.log(ret);
- let { jslist: _jslist, targe, csslist, tabId: _tabId, path } = ret;
- jslist = _jslist;
- tabId = _tabId;
- parseCodeToAST(
- jslist.map((item) => {
- return {
- code: item.data,
- name: item.fileName,
- };
- })
- );
- let data = window.findSelector();
- let id = $(targe).attr("id");
- let classList = $(targe).attr("class").split(" ");
- data = data.filter((m) => {
- let v = m.过滤器;
- if (v.includes(id)) return true;
- if (classList.length > 0) {
- for (const classitem of classList) {
- if (v.includes(classitem)) return true;
- }
- }
- });
- await attach();
- await getPathNodeInfo(path);
- let events = await findEvent();
- TabInstance.option({
- dataSource: data,
- });
- CSSTabInstance.option({
- dataSource: Object.entries(csslist).map((a, index) => ({
- id: index,
- key: a[0],
- value: a[1],
- })),
- });
- eventTableInstance.option({
- dataSource: translateEventData(events),
- });
- }
- });
- function findPropRef(key, json) {
- let matchedCSSRules = json.matchedCSSRules;
- let retArr = [];
- for (const matchedCSSRule of matchedCSSRules) {
- let cssProperties = matchedCSSRule.rule.style.cssProperties;
- let cssProp = cssProperties.find((m) => m.name == key);
- if (!cssProp) continue;
- let ret = {
- 来源: "CSS",
- 选择器: matchedCSSRule.rule.selectorList.text,
- 选中选择器: matchedCSSRule.matchingSelectors[0],
- 属性值: cssProp.value,
- };
- retArr.push(ret);
- }
- return retArr;
- }
- async function getPathNodeInfo(path) {
- const doc = await getDocument();
- // const htmlInfo = doc.children.find((m) => m.localName === "html");
- let info = doc;
- for (const index of path) {
- info = getpath(info, index);
- }
- nodeObj = info;
- let nodeId = info.nodeId;
- let cssInfo = await getMatchedStylesForNode(nodeId);
- jsonInfo = cssInfo;
- function getpath(info, index) {
- let children = info.children;
- return children[index];
- }
- }
- async function getMatchedStylesForNode(nodeId) {
- let ret = await chrome.debugger.sendCommand(
- { tabId },
- "CSS.getMatchedStylesForNode",
- {
- nodeId,
- }
- );
- return ret;
- }
- async function getDocument() {
- const doc = await chrome.debugger.sendCommand({ tabId }, "DOM.getDocument", {
- pierce: true,
- depth: -1,
- });
- return doc.root;
- }
- async function attach() {
- // const targets = await chrome.debugger.getTargets();
- // let target = targets.find((m) => m.tabId == tabId);
- // if (target?.attached === true) {
- // } else {
- // await chrome.debugger.attach({ tabId }, "1.3");
- // }
- await chrome.debugger.attach({ tabId }, "1.3").catch(() => {});
- await chrome.debugger.sendCommand({ tabId }, "DOM.enable");
- await chrome.debugger.sendCommand({ tabId }, "CSS.enable");
- await chrome.debugger.sendCommand({ tabId }, "Debugger.enable");
- }
- async function findEvent() {
- let winObj = await chrome.debugger.sendCommand(
- { tabId },
- "Runtime.evaluate",
- {
- expression: "self",
- objectGroup: "",
- includeCommandLineAPI: false,
- silent: true,
- returnByValue: false,
- generatePreview: false,
- userGesture: false,
- awaitPromise: false,
- }
- );
- let winEvents = await chrome.debugger.sendCommand(
- { tabId },
- "DOMDebugger.getEventListeners",
- {
- objectId: winObj.result.objectId,
- }
- );
- let documentObj = await chrome.debugger.sendCommand(
- { tabId },
- "Runtime.evaluate",
- {
- expression: "document",
- objectGroup: "",
- includeCommandLineAPI: false,
- silent: true,
- returnByValue: false,
- generatePreview: false,
- userGesture: false,
- awaitPromise: false,
- }
- );
- let documentEvents = await chrome.debugger.sendCommand(
- { tabId },
- "DOMDebugger.getEventListeners",
- {
- objectId: documentObj.result.objectId,
- }
- );
- let selfObj = await chrome.debugger.sendCommand(
- { tabId },
- "DOM.resolveNode",
- {
- nodeId: nodeObj.nodeId,
- }
- );
- let selfEvents = await chrome.debugger.sendCommand(
- { tabId },
- "DOMDebugger.getEventListeners",
- {
- objectId: selfObj.object.objectId,
- }
- );
- for (const listener of winEvents.listeners) {
- await listenerGetFile(listener);
- }
- for (const listener of documentEvents.listeners) {
- await listenerGetFile(listener);
- }
- for (const listener of selfEvents.listeners) {
- await listenerGetFile(listener);
- }
- return {
- winEvents: winEvents.listeners,
- documentEvents: documentEvents.listeners,
- selfEvents: selfEvents.listeners,
- };
- }
- async function listenerGetFile(listener) {
- let ret = await chrome.debugger.sendCommand(
- { tabId },
- "Debugger.getScriptSource",
- {
- scriptId: listener.scriptId,
- }
- );
- let js = jslist.find((m) => m.data == ret.scriptSource);
- if (js) {
- debugger;
- js.scriptId = listener.scriptId;
- listener.fileName = js.fileName;
- listener.fileUrl = js.url;
- listener.fileData = js.data;
- }
- }
- function translateEventData(eventObj) {
- debugger;
- let { winEvents, documentEvents, selfEvents } = eventObj;
- let result = [];
- result.push(
- ...winEvents.map((even) => ({
- 事件名称: even.type,
- 绑定对象: "window",
- 事件文件: even.fileName,
- }))
- );
- result.push(
- ...documentEvents.map((even) => ({
- 事件名称: even.type,
- 绑定对象: "document",
- 事件文件: even.fileName,
- }))
- );
- result.push(
- ...selfEvents.map((even) => ({
- 事件名称: even.type,
- 绑定对象: "selft",
- 事件文件: even.fileName,
- }))
- );
- return result.map((a, index) => ({ ...a, id: index }));
- }
- window.onload = function () {
- InitTabOperation();
- };
- /**
- * 设置操作页卡功能
- */
- function InitTabOperation() {
- document.querySelector(".tabs").addEventListener("click", function (e) {
- let target = e.target;
- if (target.classList.contains("tab")) {
- showContent(target);
- }
- });
- }
- function showContent(tab) {
- let id = tab.dataset.id; // 获取点击的页卡ID
- // 获取选中的页卡元素
- let activeTab = document.querySelector(".tabs .active");
- if (activeTab !== null) {
- if (id === activeTab.dataset.id) return;
- activeTab.classList.remove("active");
- }
- // 获取选中的容器的元素
- let activeContent = document.querySelector(".tab-container .active");
- if (activeContent !== null) {
- if (activeContent.id === id) return;
- activeContent.classList.remove("active");
- }
- // 给新选中的页卡加入选中效果
- tab.classList.add("active");
- let curActiveContent = document.querySelector(`.tab-container #${id}`);
- if (curActiveContent !== null) {
- curActiveContent.classList.add("active");
- }
- }
|