Browse Source

提交页卡信息

瑞强 吴 8 months ago
parent
commit
802d908b1d
3 changed files with 346 additions and 315 deletions
  1. 1 5
      page.css
  2. 17 29
      page.html
  3. 328 281
      page.js

+ 1 - 5
page.css

@@ -31,7 +31,7 @@ body {
 
 .zl-code {
     /* height: calc(50vh - 17px); */
-    height: calc(50vh - 68px);
+    height: calc(100vh - 98px);
     overflow: auto;
 }
 
@@ -214,10 +214,6 @@ body {
     margin: 0;
 }
 
-div#jscode {
-    height: calc(100vh - 108px);
-}
-
 .table-title{
     position: absolute;
     z-index: 100;

+ 17 - 29
page.html

@@ -30,9 +30,9 @@
 <body>
     <div class="zl-container">
         <div class="tabs">
-            <div class="tab active" data-id="tabFirst">DOM操作及属性</div>
-            <div class="tab" data-id="tabSecond">冒泡事件</div>
-            <!-- <div class="tab" data-id="tabThree"></div> -->
+            <div class="tab active" data-id="tabFirst">DOM操作</div>
+            <div class="tab" data-id="tabSecond">DOM属性</div>
+            <div class="tab" data-id="tabThree">冒泡事件</div>
         </div>
         <div class="tab-container">
             <div class="tab-content active" id="tabFirst">
@@ -41,25 +41,11 @@
                         <div class="zl-row">
                             <div class="zl-table-head table-title">当前DOM操作清单
                             </div>
-                            <div class="zl-table-height">
+                            <div class="zl-table-height-12">
                                 <div class="table table-bordered" id="filterTable">
                                 </div>
                             </div>
                         </div>
-                        <!-- <div class="zl-row">
-                            <div class="zl-table-head">样式属性</div>
-                            <div class="zl-table-height">
-                                <div class="table table-bordered" id="cssJson">
-                                </div>
-                            </div>
-                        </div> -->
-                        <div class="zl-row" style="padding-top: 10px;">
-                            <div class="zl-table-head table-title">样式属性</div>
-                            <div class="zl-table-height">
-                                <div class="table table-bordered" id="cssJson">
-                                </div>
-                            </div>
-                        </div>
                     </div>
                     <div class="zl-col-6">
                         <div class="zl-row">
@@ -68,34 +54,36 @@
                                 <div class="zl-code" id="jscode"></div>
                             </div>
                         </div>
-                        <!-- <div class="zl-row">
-                            <div class="zl-col-12">
-                                <div class="zl-table-head">JS对应AST树</div>
-                                <div class="zl-tree" id="astJson"></div>
-                            </div>
-                        </div> -->
                     </div>
                 </div>
             </div>
             <div class="tab-content" id="tabSecond">
                 <div class="zl-row">
-                    <div class="zl-col-12">
+                    <div class="zl-col-6">
                         <div class="zl-row">
-                            <div class="zl-table-head table-title">JS事件</div>
+                            <div class="zl-table-head table-title">样式属性</div>
                             <div class="zl-table-height-12">
-                                <div class="table table-bordered" id="eventTable">
+                                <div class="table table-bordered" id="cssJson">
                                 </div>
                             </div>
                         </div>
                     </div>
+                    <div class="zl-col-6">
+                        <div class="zl-row">
+                            <div class="zl-col-12">
+                                <div class="zl-table-head">实现代码</div>
+                                <div class="zl-code" id="csscode"></div>
+                            </div>
+                        </div>
+                    </div>
                 </div>
             </div>
             <div class="tab-content" id="tabThree">
                 <div class="zl-row">
                     <div class="zl-col-12">
                         <div class="zl-row">
-                            <div class="zl-table-head">JS事件</div>
-                            <div class="zl-table-height">
+                            <div class="zl-table-head table-title">JS事件</div>
+                            <div class="zl-table-height-12">
                                 <div class="table table-bordered" id="eventTable">
                                 </div>
                             </div>

+ 328 - 281
page.js

@@ -6,292 +6,41 @@ let jslist;
 let cssList;
 let cssFileInfo = {}
 let oldFile; // 记录上一次点击的文件信息
-
+let path;
+let targe;
 // 记录页卡信息
-// let pageTab = new PageTab();
+let pageTab;
 
 chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
   if (request.msgToPopup === "发送页面") {
-    cssFileInfo = {}
-    //初始化JS代码编辑器
-    window.jsCode = new CodeEditor();
-
-    jsCode.InitEditor($("#jscode")[0], false, false, [], false);
-    jsCode.dataType = 3;
-    InitTable();
-
     // 结构接收的信息
-    let { jslist: _jslist, targe, csslist, tabId: _tabId, path } = request.data;
+    let { jslist: _jslist, targe: _targe, csslist: _csslist, tabId: _tabId, path: _path } = request.data;
 
     jslist = _jslist;
     tabId = _tabId;
-    cssList = csslist; // 页面的所有样式信息
-
-    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;
-        }
-      }
-    });
+    cssList = _csslist; // 页面的所有样式信息
+    path = _path;
+    targe = _targe;
+
+    cssFileInfo = {}
 
     await attach();
     await getPathNodeInfo(path);
-    let events = await findEvent();
 
-    TabInstance.option({
-      dataSource: data,
-    });
-    let cssJsonData = CssJsonData(jsonInfo)
-    CSSTabInstance.option({
-      dataSource: cssJsonData,
-    });
-
-    eventTableInstance.option({
-      dataSource: translateEventData(events),
-    });
+    if (!pageTab) {
+      // 创建页卡实例
+      let tabs = [
+        new Tab({ id: 'tabFirst', isAlived: true, activeEvent: () => { domOptionTab() } }),
+        new Tab({ id: 'tabSecond', isAlived: true, activeEvent: () => { domPropTab() } }),
+        new Tab({ id: 'tabThree', isAlived: true, activeEvent: () => { domEventTab() } })
+      ]
+      pageTab = new PageTab({ tabs });
+    }
+    pageTab.reset();
+    pageTab.activeTabById("tabFirst");
   }
 });
 
-function InitTable() {
-  window.TabInstance = $("#filterTable")
-    .dxDataGrid({
-      dataSource: [],
-      keyExpr: "resource_detail_id",
-      remoteOperations: false,
-      searchPanel: {
-        visible: true,
-        highlightCaseSensitive: true,
-      },
-      groupPanel: { visible: false },
-      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: "DOM操作分类",
-          dataType: "DOM操作分类",
-        },
-        {
-          dataField: "过滤器",
-          caption: "过滤器",
-        },
-        {
-          dataField: "所在位置",
-          dataType: "所在位置",
-        },
-      ],
-      onContentReady(e) { },
-      onSelectionChanged: function (selectedItems) {
-        let data = selectedItems.selectedRowsData[0];
-        if (data) {
-          oldFile = ""
-          jsCode.dataType = 3;
-          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);
-          }
-          //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,
-            });
-          }
-        }
-      },
-    })
-    .dxDataGrid("instance");
-
-  window.CSSTabInstance = $("#cssJson")
-    .dxDataGrid({
-      dataSource: [],
-      keyExpr: "id",
-      remoteOperations: false,
-      searchPanel: {
-        visible: true,
-        highlightCaseSensitive: true,
-      },
-      selection: {
-        mode: "single",
-      },
-      groupPanel: { visible: false },
-      grouping: {
-        allowCollapsing: true,
-        autoExpandAll: true,
-        expandMode: "rowClick",
-      },
-      allowColumnReordering: true,
-      rowAlternationEnabled: true,
-      showBorders: true,
-      height: "100%",
-      paging: {
-        enabled: false,
-        pageSize: 0,
-      },
-      columns: [
-        {
-          dataField: "文件",
-          caption: "来源文件",
-          groupCellTemplate: function (tdom, tdMsg) {
-            let name = tdMsg.value;
-            try {
-              name = (name === "用户自定义" ? name : name.match(/\/([^\/]+\.css)(\?[^ ]*)?$/)[1])
-            } catch {
-            }
-            tdom.text(name)
-          },
-          groupIndex: 0
-        },
-        {
-          dataField: "分类",
-          caption: "分类"
-        },
-        {
-          dataField: "选择器",
-          caption: "选择器"
-        }, {
-          dataField: "样式属性",
-          caption: "样式属性",
-          cellTemplate: function (tdom, tdMsg) {
-            let styles = tdMsg.value;
-            let html = styles.map(({ name, value }) => `<li>${name}: ${value}</li>`).join('')
-            tdom.html(`<ul>${html}</ul>`)
-          }
-        },
-      ],
-      onSelectionChanged: async function (selectedItems) {
-        let data = selectedItems.selectedRowsData[0];
-        if (data) {
-          if (data.文件) {
-            let fileName = data.文件;
-            let code = ""
-            if (!cssFileInfo[fileName]) {
-              code = fileName === "用户自定义" ? "" : await (await fetch(fileName)).text();
-              cssFileInfo[fileName] = {
-                code
-              }
-            } else {
-              code = cssFileInfo[fileName].code
-            }
-            // 设置显示css
-            jsCode.dataType = 2;
-            if (oldFile !== fileName) {
-              //更改JS代码
-              jsCode.SetCode(code);
-            }
-            //移出所有高亮
-            jsCode.RemoveAllHighlight();
-
-            oldFile = fileName;
-            // 定位使用
-            let selectors = [];
-            if (!cssFileInfo[fileName].selectors) {
-              selectors = await cssCodeToAST(jsCode.GetCode());
-              cssFileInfo[fileName].selectors = selectors
-            } else {
-              selectors = cssFileInfo[fileName].selectors
-            }
-            let location = selectors.find(a => a.name === data.选择器);
-            if (location) {
-              setTimeout(() => {
-                let { loc: { start, end } } = location;
-                //设置高亮
-                jsCode.CreateHighlight({
-                  startLine: start?.line,
-                  startColumn: start?.column,
-                  endLine: end?.line,
-                  endColumn: end?.column,
-                });
-              }, 500);
-            }
-          }
-        }
-      },
-    })
-    .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");
-}
-
 function findPropRef(key, json) {
   let matchedCSSRules = json.matchedCSSRules;
   let retArr = [];
@@ -355,7 +104,7 @@ async function getPathNodeInfo(path) {
     info = getpath(info, index);
   }
   nodeObj = info;
-  let nodeId = info.nodeId;
+  nodeId = info.nodeId;
   let cssInfo = await getMatchedStylesForNode(nodeId);
   jsonInfo = cssInfo;
 
@@ -950,23 +699,30 @@ class PageTab {
     }
   }
 
+  reset() {
+    this.tabs.forEach(s => { s.changeLived(false) })
+  }
 }
 
-class tab {
+class Tab {
   #id // 页卡id
   #tabEle // tab页卡元素
   #contentEle // tab内容元素
   #isAlived // 是否保持持久化(为true表示 页卡激活事件只执行一次,当前内容会一直存在,如果为false,则表示每次点击页卡都会重新执行激活事件)
-  activeEvent // 激活页卡执行事件
+  #event // 激活页卡执行事件
   #isActived // 是否选中
+  #isLived
 
+  get id() {
+    return this.#id;
+  }
   constructor({ id, isAlived, activeEvent }) {
     this.#id = id;
-    this.#tabEle = tab.getTabEleById(id);
-    this.#contentEle = tab.getTabContentById(id);
+    this.#tabEle = Tab.getTabEleById(id);
+    this.#contentEle = Tab.getTabContentById(id);
     this.#isAlived = isAlived;
     this.#isActived = false;
-    this.activeEvent = activeEvent;
+    this.#event = activeEvent;
   }
 
   get tabInfo() {
@@ -991,14 +747,19 @@ class tab {
     this.#contentEle.classList.add('active');
     this.#isActived = true;
     this.activeEvent();
+    this.#isLived = true;
   }
 
   activeEvent() {
-    if (this.#isAlived === true) {
+    if (this.#isAlived === true && this.#isLived === true) {
       // 如果开启了持久化,表示只执行一次
-      this.activeEvent = function () { }
+      return
     }
-    typeof this.activeEvent === 'function' && this.activeEvent();
+    typeof this.#event === 'function' && this.#event();
+  }
+
+  changeLived(val) {
+    this.#isLived = val
   }
 
   /**
@@ -1011,10 +772,296 @@ class tab {
   }
 
   static getTabEleById(id) {
-    return document.querySelector(`.tabs tab[data-id="${id}"]`);
+    return document.querySelector(`.tabs .tab[data-id="${id}"]`);
   }
 
   static getTabContentById(id) {
     return document.querySelector(`.tab-container #${id}`);
   }
+}
+
+/**
+ * 执行DOM操作页卡事件
+ */
+async function domOptionTab() {
+  //初始化JS代码编辑器
+  let jsCode = new CodeEditor();
+  jsCode.InitEditor($("#jscode")[0], false, false, [], false);
+  jsCode.dataType = 3;
+
+  // 初始化表格
+  let TabInstance = $("#filterTable")
+    .dxDataGrid({
+      dataSource: [],
+      keyExpr: "resource_detail_id",
+      remoteOperations: false,
+      searchPanel: {
+        visible: true,
+        highlightCaseSensitive: true,
+      },
+      groupPanel: { visible: false },
+      grouping: {
+        allowCollapsing: true,
+        autoExpandAll: true,
+        expandMode: "rowClick",
+      },
+      selection: {
+        mode: "single",
+      },
+      allowColumnReordering: true,
+      rowAlternationEnabled: false,
+      noDataText: "无数据",
+      showBorders: true,
+      height: "100%",
+      columns: [
+        {
+          dataField: "JS文件",
+          dataType: "JS文件",
+          groupIndex: 0
+        },
+        {
+          dataField: "DOM操作分类",
+          dataType: "DOM操作分类",
+        },
+        {
+          dataField: "过滤器",
+          caption: "过滤器",
+        },
+        {
+          dataField: "所在位置",
+          dataType: "所在位置",
+        },
+      ],
+      onContentReady(e) { },
+      onSelectionChanged: function (selectedItems) {
+        let data = selectedItems.selectedRowsData[0];
+        if (data) {
+          oldFile = "";
+          if (data.JS文件 !== nowFileName) {
+            nowFileName = data.JS文件;
+            let code = window.fileList.find((o) => o.name === data.JS文件).code;
+            //更改JS代码
+            jsCode.SetCode(code);
+          }
+          //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,
+            });
+          }
+        }
+      },
+    })
+    .dxDataGrid("instance");
+
+  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;
+      }
+    }
+  });
+
+  TabInstance.option({
+    dataSource: data,
+  });
+}
+
+/**
+ * 执行DOM属性页卡事件
+ */
+async function domPropTab() {
+
+  let cssCode = new CodeEditor();
+  cssCode.InitEditor($("#csscode")[0], false, false, [], false);
+  cssCode.dataType = 2;
+
+  let CSSTabInstance = $("#cssJson")
+    .dxDataGrid({
+      dataSource: [],
+      keyExpr: "id",
+      remoteOperations: false,
+      searchPanel: {
+        visible: true,
+        highlightCaseSensitive: true,
+      },
+      selection: {
+        mode: "single",
+      },
+      groupPanel: { visible: false },
+      grouping: {
+        allowCollapsing: true,
+        autoExpandAll: true,
+        expandMode: "rowClick",
+      },
+      allowColumnReordering: true,
+      rowAlternationEnabled: true,
+      showBorders: true,
+      height: "100%",
+      paging: {
+        enabled: false,
+        pageSize: 0,
+      },
+      columns: [
+        {
+          dataField: "文件",
+          caption: "来源文件",
+          groupCellTemplate: function (tdom, tdMsg) {
+            let name = tdMsg.value;
+            try {
+              name = (name === "用户自定义" ? name : name.match(/\/([^\/]+\.css)(\?[^ ]*)?$/)[1])
+            } catch {
+            }
+            tdom.text(name)
+          },
+          groupIndex: 0
+        },
+        {
+          dataField: "分类",
+          caption: "分类"
+        },
+        {
+          dataField: "选择器",
+          caption: "选择器"
+        }, {
+          dataField: "样式属性",
+          caption: "样式属性",
+          cellTemplate: function (tdom, tdMsg) {
+            let styles = tdMsg.value;
+            let html = styles.map(({ name, value }) => `<li>${name}: ${value}</li>`).join('')
+            tdom.html(`<ul>${html}</ul>`)
+          }
+        },
+      ],
+      onSelectionChanged: async function (selectedItems) {
+        let data = selectedItems.selectedRowsData[0];
+        if (data) {
+          if (data.文件) {
+            let fileName = data.文件;
+            let code = ""
+            if (!cssFileInfo[fileName]) {
+              code = fileName === "用户自定义" ? "" : await (await fetch(fileName)).text();
+              cssFileInfo[fileName] = {
+                code
+              }
+            } else {
+              code = cssFileInfo[fileName].code
+            }
+            // 设置显示css
+            cssCode.dataType = 2;
+            if (oldFile !== fileName) {
+              //更改JS代码
+              cssCode.SetCode(code);
+            }
+            //移出所有高亮
+            cssCode.RemoveAllHighlight();
+
+            oldFile = fileName;
+            // 定位使用
+            let selectors = [];
+            if (!cssFileInfo[fileName].selectors) {
+              selectors = await cssCodeToAST(cssCode.GetCode());
+              cssFileInfo[fileName].selectors = selectors
+            } else {
+              selectors = cssFileInfo[fileName].selectors
+            }
+            let location = selectors.find(a => a.name === data.选择器);
+            if (location) {
+              setTimeout(() => {
+                let { loc: { start, end } } = location;
+                //设置高亮
+                cssCode.CreateHighlight({
+                  startLine: start?.line,
+                  startColumn: start?.column,
+                  endLine: end?.line,
+                  endColumn: end?.column,
+                });
+              }, 500);
+            }
+          }
+        }
+      },
+    })
+    .dxDataGrid("instance");
+  let cssInfo = await getMatchedStylesForNode(nodeId);
+  let cssJsonData = CssJsonData(cssInfo)
+  CSSTabInstance.option({
+    dataSource: cssJsonData,
+  });
+
+}
+
+/**
+ * 执行冒泡事件页卡事件
+ */
+async function domEventTab() {
+  let eventTableInstance = $("#eventTable")
+    .dxDataGrid({
+      dataSource: [],
+      keyExpr: "id",
+      remoteOperations: false,
+      searchPanel: {
+        visible: true,
+        highlightCaseSensitive: true,
+      },
+      selection: {
+        mode: "single",
+      },
+      allowColumnReordering: true,
+      rowAlternationEnabled: false,
+      noDataText: "无数据",
+      showBorders: true,
+      paging: {
+        enabled: false,
+        pageSize: 0,
+      },
+      height: "100%",
+      columns: [
+        {
+          dataField: "事件名称",
+          caption: "事件名称",
+        },
+        {
+          dataField: "绑定对象",
+          caption: "绑定对象",
+        },
+        {
+          dataField: "事件文件",
+          caption: "事件文件",
+        },
+      ],
+    })
+    .dxDataGrid("instance");
+
+  let events = await findEvent();
+  eventTableInstance.option({
+    dataSource: translateEventData(events),
+  });
 }