page.js 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. let nowFileName = "";
  2. let jsonInfo = {};
  3. let tabId = "";
  4. let nodeObj;
  5. function InitTable() {
  6. window.TabInstance = $("#filterTable")
  7. .dxDataGrid({
  8. dataSource: [],
  9. keyExpr: "resource_detail_id",
  10. remoteOperations: false,
  11. searchPanel: {
  12. visible: true,
  13. highlightCaseSensitive: true,
  14. },
  15. groupPanel: { visible: true },
  16. grouping: {
  17. allowCollapsing: true,
  18. autoExpandAll: true,
  19. expandMode: "rowClick",
  20. },
  21. selection: {
  22. mode: "single",
  23. },
  24. allowColumnReordering: true,
  25. rowAlternationEnabled: true,
  26. showBorders: true,
  27. height: "100%",
  28. columns: [
  29. {
  30. dataField: "JS文件",
  31. dataType: "JS文件",
  32. groupIndex: 0,
  33. },
  34. {
  35. dataField: "过滤器",
  36. caption: "过滤器",
  37. },
  38. {
  39. dataField: "选择器类型",
  40. dataType: "选择器类型",
  41. },
  42. {
  43. dataField: "调用方式",
  44. dataType: "调用方式",
  45. },
  46. {
  47. dataField: "所在位置",
  48. dataType: "所在位置",
  49. },
  50. {
  51. dataField: "DOM操作分类",
  52. dataType: "DOM操作分类",
  53. },
  54. ],
  55. onContentReady(e) {},
  56. onSelectionChanged: function (selectedItems) {
  57. let data = selectedItems.selectedRowsData[0];
  58. if (data) {
  59. let ast = data.astJSON;
  60. if (data.JS文件 !== nowFileName) {
  61. nowFileName = data.JS文件;
  62. let code = window.fileList.find((o) => o.name === data.JS文件).code;
  63. //更改JS代码
  64. jsCode.SetCode(code);
  65. //更改ast
  66. //window.ShowASTTree(ast, document.getElementById('astJson'))
  67. }
  68. //jscode定位
  69. let {
  70. defineNode: {
  71. iid,
  72. loc: { end, start },
  73. },
  74. } = data.source_data;
  75. {
  76. //移出所有高亮
  77. jsCode.RemoveAllHighlight();
  78. //设置高亮
  79. jsCode.CreateHighlight({
  80. startLine: start?.line,
  81. startColumn: start?.column + 1,
  82. endLine: end?.line,
  83. endColumn: end?.column + 1,
  84. });
  85. }
  86. {
  87. // //ast定位
  88. // let jsonNode = document.getElementById(iid);
  89. // if (jsonNode) {
  90. // let textNode = Array.from(jsonNode.parentNode.childNodes).find(item => item.classList.contains("node-text"));
  91. // $("#astJson").find(".monaco-highlight").removeClass("monaco-highlight");
  92. // textNode?.classList?.add("monaco-highlight");
  93. // scrollTo(jsonNode)
  94. // }
  95. }
  96. }
  97. },
  98. })
  99. .dxDataGrid("instance");
  100. window.CSSTabInstance = $("#cssJson")
  101. .dxDataGrid({
  102. dataSource: [],
  103. keyExpr: "id",
  104. remoteOperations: false,
  105. searchPanel: {
  106. visible: true,
  107. highlightCaseSensitive: true,
  108. },
  109. selection: {
  110. mode: "single",
  111. },
  112. allowColumnReordering: true,
  113. rowAlternationEnabled: true,
  114. showBorders: true,
  115. height: "100%",
  116. paging: {
  117. enabled: false,
  118. pageSize: 0,
  119. },
  120. columns: [
  121. {
  122. dataField: "key",
  123. caption: "名称",
  124. },
  125. {
  126. dataField: "value",
  127. caption: "生效值",
  128. },
  129. ],
  130. onSelectionChanged: function (selectedItems) {
  131. let data = selectedItems.selectedRowsData[0];
  132. if (data) {
  133. CSSBelongInstance.option({
  134. dataSource: findPropRef(data.key, jsonInfo).map((s, i) => ({
  135. ...s,
  136. id: i,
  137. })),
  138. });
  139. }
  140. },
  141. })
  142. .dxDataGrid("instance");
  143. window.CSSBelongInstance = $("#cssBelong")
  144. .dxDataGrid({
  145. dataSource: [],
  146. keyExpr: "id",
  147. remoteOperations: false,
  148. searchPanel: {
  149. visible: true,
  150. highlightCaseSensitive: true,
  151. },
  152. selection: {
  153. mode: "single",
  154. },
  155. allowColumnReordering: true,
  156. rowAlternationEnabled: true,
  157. showBorders: true,
  158. paging: {
  159. enabled: false,
  160. pageSize: 0,
  161. },
  162. height: "100%",
  163. columns: [
  164. {
  165. dataField: "来源",
  166. caption: "来源",
  167. width: 100,
  168. },
  169. {
  170. dataField: "选择器",
  171. caption: "选择器",
  172. },
  173. {
  174. dataField: "属性值",
  175. caption: "属性值",
  176. },
  177. ],
  178. })
  179. .dxDataGrid("instance");
  180. }
  181. chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
  182. if (request.msgToPopup === "发送页面") {
  183. //初始化JS代码编辑器
  184. window.jsCode = new CodeEditor();
  185. jsCode.InitEditor($("#jscode")[0], false, false, [], false);
  186. jsCode.dataType = 3;
  187. InitTable();
  188. let ret = request.data;
  189. console.log(ret);
  190. let { jslist, targe, csslist, tabId: _tabId, path } = ret;
  191. tabId = _tabId;
  192. parseCodeToAST(
  193. jslist.map((item) => {
  194. return {
  195. code: item.data,
  196. name: item.fileName,
  197. };
  198. })
  199. );
  200. let data = window.findSelector();
  201. let id = $(targe).attr("id");
  202. let classList = $(targe).attr("class").split(" ");
  203. data = data.filter((m) => {
  204. let v = m.过滤器;
  205. if (v.includes(id)) return true;
  206. if (classList.length > 0) {
  207. for (const classitem of classList) {
  208. if (v.includes(classitem)) return true;
  209. }
  210. }
  211. });
  212. await attach();
  213. await getPathNodeInfo(path);
  214. await findEvent();
  215. TabInstance.option({
  216. dataSource: data,
  217. });
  218. CSSTabInstance.option({
  219. dataSource: Object.entries(csslist).map((a, index) => ({
  220. id: index,
  221. key: a[0],
  222. value: a[1],
  223. })),
  224. });
  225. }
  226. });
  227. function findPropRef(key, json) {
  228. let matchedCSSRules = json.matchedCSSRules;
  229. let retArr = [];
  230. for (const matchedCSSRule of matchedCSSRules) {
  231. let cssProperties = matchedCSSRule.rule.style.cssProperties;
  232. let cssProp = cssProperties.find((m) => m.name == key);
  233. if (!cssProp) continue;
  234. let ret = {
  235. 来源: "CSS",
  236. 选择器: matchedCSSRule.rule.selectorList.text,
  237. 选中选择器: matchedCSSRule.matchingSelectors[0],
  238. 属性值: cssProp.value,
  239. };
  240. retArr.push(ret);
  241. }
  242. return retArr;
  243. }
  244. async function getPathNodeInfo(path) {
  245. const doc = await getDocument();
  246. const htmlInfo = doc.children.find((m) => m.localName === "html");
  247. let info = htmlInfo;
  248. for (const index of path) {
  249. info = getpath(info, index);
  250. }
  251. nodeObj = info;
  252. let nodeId = info.nodeId;
  253. let cssInfo = await getMatchedStylesForNode(nodeId);
  254. jsonInfo = cssInfo;
  255. function getpath(info, index) {
  256. let children = info.children;
  257. return children[index];
  258. }
  259. }
  260. async function getMatchedStylesForNode(nodeId) {
  261. let ret = await chrome.debugger.sendCommand(
  262. { tabId },
  263. "CSS.getMatchedStylesForNode",
  264. {
  265. nodeId,
  266. }
  267. );
  268. return ret;
  269. }
  270. async function getDocument() {
  271. const doc = await chrome.debugger.sendCommand({ tabId }, "DOM.getDocument", {
  272. pierce: true,
  273. depth: -1,
  274. });
  275. return doc.root;
  276. }
  277. async function attach() {
  278. const targets = await chrome.debugger.getTargets();
  279. let target = targets.find((m) => m.tabId == tabId);
  280. if (target?.attached === true) {
  281. } else {
  282. await chrome.debugger.attach({ tabId }, "1.3");
  283. }
  284. await chrome.debugger.sendCommand({ tabId }, "DOM.enable");
  285. await chrome.debugger.sendCommand({ tabId }, "CSS.enable");
  286. }
  287. async function findEvent() {
  288. let winObj = await chrome.debugger.sendCommand(
  289. { tabId },
  290. "Runtime.evaluate",
  291. {
  292. expression: "self",
  293. objectGroup: "",
  294. includeCommandLineAPI: false,
  295. silent: true,
  296. returnByValue: false,
  297. generatePreview: false,
  298. userGesture: false,
  299. awaitPromise: false,
  300. }
  301. );
  302. let winEvents = await chrome.debugger.sendCommand(
  303. { tabId },
  304. "DOMDebugger.getEventListeners",
  305. {
  306. objectId: winObj.result.objectId,
  307. }
  308. );
  309. let documentObj = await chrome.debugger.sendCommand(
  310. { tabId },
  311. "Runtime.evaluate",
  312. {
  313. expression: "document",
  314. objectGroup: "",
  315. includeCommandLineAPI: false,
  316. silent: true,
  317. returnByValue: false,
  318. generatePreview: false,
  319. userGesture: false,
  320. awaitPromise: false,
  321. }
  322. );
  323. let documentEvents = await chrome.debugger.sendCommand(
  324. { tabId },
  325. "DOMDebugger.getEventListeners",
  326. {
  327. objectId: documentObj.result.objectId,
  328. }
  329. );
  330. let selfObj = await chrome.debugger.sendCommand(
  331. { tabId },
  332. "DOM.resolveNode",
  333. {
  334. nodeId: nodeObj.nodeId,
  335. }
  336. );
  337. let selfEvents = await chrome.debugger.sendCommand(
  338. { tabId },
  339. "DOMDebugger.getEventListeners",
  340. {
  341. objectId: selfObj.object.objectId,
  342. }
  343. );
  344. return {
  345. winEvents: winEvents.listeners,
  346. documentEvents: documentEvents.listeners,
  347. selfEvents: selfEvents.listeners,
  348. };
  349. }