content.js 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. let overDiv;
  2. chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  3. if (request.action === "highlight") {
  4. if (request.message && !isOpen) {
  5. overDiv = document.createElement("div");
  6. overDiv.classList.add("bg-overDiv");
  7. // CSS样式内容
  8. var css = `
  9. .bg-overDiv{
  10. position: fixed;
  11. opacity: 0.5;
  12. background: rgb(20 122 218 / 85%);
  13. backdrop-filter: blur(5px);
  14. cursor: pointer;
  15. z-index: 99999999999;
  16. display: none;
  17. }`;
  18. // 创建一个style元素
  19. var style = document.createElement("style");
  20. style.classList.add("bg-style");
  21. // 为style元素添加CSS内容
  22. if (style.styleSheet) {
  23. style.styleSheet.cssText = css;
  24. } else {
  25. style.appendChild(document.createTextNode(css));
  26. }
  27. // 将style元素添加到body的末尾
  28. document.body.appendChild(style); //把这个样式加入body的最后
  29. document.body.appendChild(overDiv);
  30. isOpen = true;
  31. window.addEventListener("click", clickHandler);
  32. window.addEventListener("mousemove", mouseMoveHandler);
  33. }
  34. if (!request.message && isOpen) {
  35. document.querySelector(".bg-overDiv")?.remove();
  36. document.querySelector(".bg-style")?.remove();
  37. window.removeEventListener("click", clickHandler);
  38. window.removeEventListener("mousemove", mouseMoveHandler);
  39. isOpen = false;
  40. }
  41. }
  42. });
  43. let myComputedStyle = (function () {
  44. let map = new Map();
  45. let excludeValues = ["rgb(0, 0, 0)"];
  46. return (element) => {
  47. let tagName = element.tagName;
  48. let defaultStyles = map.get(tagName);
  49. if (!defaultStyles) {
  50. defaultStyles = {};
  51. let dummy = document.createElement(tagName);
  52. document.body.appendChild(dummy);
  53. let dummyStyles = getComputedStyle(dummy);
  54. for (const key of dummyStyles) {
  55. defaultStyles[key] = dummyStyles[key];
  56. }
  57. dummy.remove();
  58. }
  59. let elementStyles = getComputedStyle(element);
  60. let diff = {};
  61. for (let key of elementStyles) {
  62. if (key.startsWith("--")) continue;
  63. if (key.startsWith("-webkit")) continue;
  64. let value = elementStyles[key];
  65. if (excludeValues.includes(value)) continue;
  66. if (elementStyles.hasOwnProperty(key) && defaultStyles[key] !== value) {
  67. diff[key] = value;
  68. }
  69. }
  70. return diff;
  71. };
  72. })();
  73. const jsRequests = []; // 使用 Set 以避免重复的 URL
  74. // 观察 DOM 的变化
  75. const observer = new MutationObserver((mutations) => {
  76. for (const mutation of mutations) {
  77. if (mutation.type === "childList") {
  78. mutation.addedNodes.forEach((node) => {
  79. if (node.nodeName === "SCRIPT" && node.src) {
  80. const url = new URL(node.src);
  81. if (url.pathname.startsWith("/lib")) return;
  82. fetch(node.src)
  83. .then((res) => res.text())
  84. .then((data) => {
  85. jsRequests.push({
  86. fileName: getFileName(node.src),
  87. url: node.src,
  88. data,
  89. });
  90. });
  91. //jsRequests.add(node.src);
  92. }
  93. });
  94. }
  95. }
  96. });
  97. function getFileName(url) {
  98. // 创建一个URL对象
  99. const urlObj = new URL(url);
  100. // 获取路径部分
  101. const pathname = urlObj.pathname;
  102. // 提取文件名
  103. const fileName = pathname.substring(pathname.lastIndexOf("/") + 1);
  104. return fileName;
  105. }
  106. // 观察整个文档
  107. observer.observe(document, { childList: true, subtree: true });
  108. // 获取当前加载的脚本
  109. const scripts = Array.from(document.getElementsByTagName("script"));
  110. scripts.forEach((script) => {
  111. if (script.src) {
  112. const url = new URL(script.src);
  113. if (url.pathname.startsWith("/lib")) return;
  114. fetch(script.src)
  115. .then((res) => res.text())
  116. .then((data) => {
  117. jsRequests.push({
  118. fileName: getFileName(script.src),
  119. url: script.src,
  120. data,
  121. });
  122. });
  123. // jsRequests.add(script.src);
  124. }
  125. });
  126. let isOpen = false;
  127. function clickHandler(e) {
  128. // console.log(jsRequests);
  129. // console.log(oldTarget);
  130. chrome.runtime.sendMessage({
  131. action: "show_popup",
  132. jslist: jsRequests,
  133. targe: oldTarget.outerHTML,
  134. csslist: Array.from(document.styleSheets).map(({ href, cssRules }) => {
  135. return {
  136. href,
  137. selectorTexts: Array.from(cssRules).map(({ selectorText }) => selectorText)
  138. }
  139. }),
  140. path: getNodePosition(oldTarget),
  141. });
  142. }
  143. function getNodePosition(element) {
  144. let id = [];
  145. if (element === document) {
  146. return [];
  147. } else {
  148. let parentNode = element.parentNode;
  149. let index = 0;
  150. for (let i = 0; parentNode.childNodes.length; i++) {
  151. let child = parentNode.childNodes[i];
  152. if (child.nodeName === "#text") continue;
  153. if (child === element) {
  154. id = [index];
  155. break;
  156. }
  157. index++;
  158. }
  159. return getNodePosition(element.parentNode).concat(id);
  160. }
  161. }
  162. // window.addEventListener("click", function (e) {
  163. // // e.preventDefault();
  164. // // e.stopPropagation();
  165. // console.log("点击");
  166. // });
  167. let oldTarget;
  168. function mouseMoveHandler(e) {
  169. if (!isOpen) return;
  170. let target =
  171. findTarget(document.elementsFromPoint(e.clientX, e.clientY)) || e.target;
  172. if (oldTarget !== target) {
  173. overDiv.style.cssText = "";
  174. oldTarget = target;
  175. let rect = target.getClientRects();
  176. if (rect.length > 0) {
  177. rect = rect[0];
  178. overDiv.style.cssText =
  179. "display: block; top:" +
  180. rect.top +
  181. "px;left: " +
  182. rect.left +
  183. "px; width: " +
  184. rect.width +
  185. "px; height: " +
  186. rect.height +
  187. "px;";
  188. }
  189. }
  190. oldTarget = target;
  191. let oldEle = document.querySelector(".bg-overlay");
  192. if (oldEle) {
  193. oldEle.classList.remove("bg-overlay");
  194. }
  195. target.classList.add("bg-overlay");
  196. }
  197. function findTarget(eles) {
  198. for (let i = 0; i < eles.length; i++) {
  199. if (eles[i].classList.contains("bg-overDiv") === false) return eles[i];
  200. }
  201. }
  202. function findChildren(ele, x, y) {
  203. let clds = ele.children;
  204. let findEle = ele;
  205. if (clds.length > 0) {
  206. let len = clds.length;
  207. let cur = null;
  208. for (let i = 0; i < len; i++) {
  209. let rect = clds[i].getClientRects();
  210. if (!rect[0]) continue;
  211. if (
  212. rect[0].x + rect[0].width >= x &&
  213. rect[0].x <= x &&
  214. rect[0].y + rect[0].height >= y &&
  215. rect[0].y <= y
  216. ) {
  217. findEle = findChildren(clds[i], x, y);
  218. break;
  219. }
  220. }
  221. }
  222. return findEle;
  223. }