let nowFileName = ""; let jsonInfo = {}; let tabId = ""; let nodeObj; 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"); } 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, targe, csslist, tabId: _tabId, path } = ret; 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); await findEvent(); TabInstance.option({ dataSource: data, }); CSSTabInstance.option({ dataSource: Object.entries(csslist).map((a, index) => ({ id: index, key: a[0], value: a[1], })), }); } }); 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 = htmlInfo; 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.sendCommand({ tabId }, "DOM.enable"); await chrome.debugger.sendCommand({ tabId }, "CSS.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, } ); return { winEvents: winEvents.listeners, documentEvents: documentEvents.listeners, selfEvents: selfEvents.listeners, }; }