|
@@ -1,227 +1,296 @@
|
|
|
let nowFileName = "";
|
|
|
-let jsonInfo = null;
|
|
|
-fetch('btn.json').then((s) => {
|
|
|
- return s.json()
|
|
|
-}).then((data) => {
|
|
|
- jsonInfo = data
|
|
|
-})
|
|
|
+let jsonInfo = {};
|
|
|
+let tabId = "";
|
|
|
function InitTable() {
|
|
|
- window.TabInstance = $('#filterTable').dxDataGrid({
|
|
|
- dataSource: [],
|
|
|
- keyExpr: 'resource_detail_id',
|
|
|
- remoteOperations: false,
|
|
|
- searchPanel: {
|
|
|
- visible: true,
|
|
|
- highlightCaseSensitive: true,
|
|
|
+ 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,
|
|
|
},
|
|
|
- groupPanel: { visible: true },
|
|
|
- grouping: {
|
|
|
- allowCollapsing: true,
|
|
|
- autoExpandAll: true,
|
|
|
- expandMode: "rowClick"
|
|
|
+ {
|
|
|
+ dataField: "过滤器",
|
|
|
+ caption: "过滤器",
|
|
|
},
|
|
|
- selection: {
|
|
|
- mode: 'single'
|
|
|
+ {
|
|
|
+ dataField: "选择器类型",
|
|
|
+ dataType: "选择器类型",
|
|
|
},
|
|
|
- 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) {
|
|
|
-
|
|
|
+ {
|
|
|
+ dataField: "调用方式",
|
|
|
+ dataType: "调用方式",
|
|
|
},
|
|
|
- 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)
|
|
|
- // }
|
|
|
- }
|
|
|
- }
|
|
|
+ {
|
|
|
+ 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");
|
|
|
+ },
|
|
|
+ })
|
|
|
+ .dxDataGrid("instance");
|
|
|
|
|
|
- window.CSSTabInstance = $('#cssJson').dxDataGrid({
|
|
|
- dataSource: [],
|
|
|
- keyExpr: 'id',
|
|
|
- remoteOperations: false,
|
|
|
- searchPanel: {
|
|
|
- visible: true,
|
|
|
- highlightCaseSensitive: true,
|
|
|
- },
|
|
|
- selection: {
|
|
|
- mode: 'single'
|
|
|
+ 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: "名称",
|
|
|
},
|
|
|
- allowColumnReordering: true,
|
|
|
- rowAlternationEnabled: true,
|
|
|
- showBorders: true,
|
|
|
- height: '100%',
|
|
|
- paging: {
|
|
|
- enabled: false,
|
|
|
- pageSize: 0
|
|
|
+ {
|
|
|
+ dataField: "value",
|
|
|
+ caption: "生效值",
|
|
|
},
|
|
|
- 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 }))
|
|
|
- })
|
|
|
- }
|
|
|
+ ],
|
|
|
+ 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");
|
|
|
+ },
|
|
|
+ })
|
|
|
+ .dxDataGrid("instance");
|
|
|
|
|
|
- window.CSSBelongInstance = $('#cssBelong').dxDataGrid({
|
|
|
- dataSource: [],
|
|
|
- keyExpr: 'id',
|
|
|
- remoteOperations: false,
|
|
|
- searchPanel: {
|
|
|
- visible: true,
|
|
|
- highlightCaseSensitive: true,
|
|
|
+ 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,
|
|
|
},
|
|
|
- selection: {
|
|
|
- mode: 'single'
|
|
|
+ {
|
|
|
+ dataField: "选择器",
|
|
|
+ caption: "选择器",
|
|
|
},
|
|
|
- allowColumnReordering: true,
|
|
|
- rowAlternationEnabled: true,
|
|
|
- showBorders: true,
|
|
|
- paging: {
|
|
|
- enabled: false,
|
|
|
- pageSize: 0
|
|
|
+ {
|
|
|
+ dataField: "属性值",
|
|
|
+ caption: "属性值",
|
|
|
},
|
|
|
- height: '100%',
|
|
|
- columns: [
|
|
|
- {
|
|
|
- dataField: "来源",
|
|
|
- caption: "来源",
|
|
|
- width: 100
|
|
|
- },
|
|
|
- {
|
|
|
- dataField: '选择器',
|
|
|
- caption: '选择器',
|
|
|
- },
|
|
|
- {
|
|
|
- dataField: '属性值',
|
|
|
- caption: '属性值',
|
|
|
- }
|
|
|
- ]
|
|
|
- }).dxDataGrid("instance");
|
|
|
+ ],
|
|
|
+ })
|
|
|
+ .dxDataGrid("instance");
|
|
|
}
|
|
|
-chrome.runtime.onMessage.addListener((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 } = ret;
|
|
|
- parseCodeToAST(jslist.map(item => {
|
|
|
- return {
|
|
|
- code: item.data,
|
|
|
- name: item.fileName
|
|
|
- };
|
|
|
- }))
|
|
|
+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;
|
|
|
+ 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;
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
+ if (classList.length > 0) {
|
|
|
+ for (const classitem of classList) {
|
|
|
+ if (v.includes(classitem)) return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
|
|
|
- TabInstance.option({
|
|
|
- "dataSource": data
|
|
|
- });
|
|
|
+ await attach();
|
|
|
+ await getPathNodeInfo(path);
|
|
|
+ TabInstance.option({
|
|
|
+ dataSource: data,
|
|
|
+ });
|
|
|
|
|
|
- CSSTabInstance.option({
|
|
|
- "dataSource": Object.entries(csslist).map((a, index) => ({ id: index, key: a[0], value: a[1] }))
|
|
|
- })
|
|
|
- }
|
|
|
-})
|
|
|
+ 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);
|
|
|
+ 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);
|
|
|
+ }
|
|
|
+ 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 retArr;
|
|
|
-}
|
|
|
+ );
|
|
|
+ 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();
|
|
|
+ debugger;
|
|
|
+ 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");
|
|
|
+}
|