content_20250812165154.ts 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. export default defineContentScript({
  2. matches: ["<all_urls>"],
  3. main() {
  4. // 辅助函数:提取背景图片URL
  5. const extractBackgroundUrl = (element: Element): string | null => {
  6. const computedStyle = window.getComputedStyle(element);
  7. const backgroundImage = computedStyle.backgroundImage;
  8. if (backgroundImage && backgroundImage !== 'none' && backgroundImage.includes('url')) {
  9. // 处理包含转义字符的URL
  10. const urlMatch = backgroundImage.match(/url\(["']?(.*?)["']?\)/);
  11. if (urlMatch && urlMatch[1]) {
  12. // 解码HTML实体
  13. let url = urlMatch[1];
  14. const textarea = document.createElement('textarea');
  15. textarea.innerHTML = url;
  16. return textarea.value;
  17. }
  18. }
  19. return null;
  20. };
  21. // 监听来自popup的消息
  22. browser.runtime.onMessage.addListener((request, sender, sendResponse) => {
  23. if (request.action === "getImages") {
  24. // 获取页面上所有图片元素
  25. const images = Array.from(document.querySelectorAll('img'))
  26. .map(img => ({
  27. src: img.src,
  28. alt: img.alt,
  29. width: img.width,
  30. height: img.height
  31. }))
  32. .filter(img => img.src);
  33. sendResponse({ images });
  34. }
  35. if (request.action === "getImageById") {
  36. // 根据ID获取特定图片元素
  37. const imageElement = document.getElementById(request.imageId);
  38. if (imageElement && imageElement.tagName.toLowerCase() === 'img') {
  39. const image = {
  40. src: (imageElement as HTMLImageElement).src,
  41. alt: (imageElement as HTMLImageElement).alt,
  42. width: (imageElement as HTMLImageElement).width,
  43. height: (imageElement as HTMLImageElement).height
  44. };
  45. sendResponse({ image });
  46. } else {
  47. sendResponse({ image: null });
  48. }
  49. }
  50. if (request.action === "getTbodyData") {
  51. // 获取所有tbody中的数据,包括背景图片
  52. const tables = Array.from(document.querySelectorAll('table')).map((table, tableIndex) => {
  53. const tbodies = Array.from(table.querySelectorAll('tbody'));
  54. return tbodies.map(tbody => {
  55. const rows = Array.from(tbody.querySelectorAll('tr'));
  56. return rows.map((row, rowIndex) => {
  57. const cells = Array.from(row.querySelectorAll('td, th'));
  58. return cells.map((cell, cellIndex) => {
  59. // 获取单元格文本内容
  60. const textContent = cell.textContent?.trim() || '';
  61. // 查找单元格内所有带有背景图片的div元素
  62. const divsWithBackground = Array.from(cell.querySelectorAll('div[style*="background-image"]'))
  63. .map((div, divIndex) => {
  64. const backgroundUrl = extractBackgroundUrl(div);
  65. if (backgroundUrl) {
  66. return {
  67. url: backgroundUrl,
  68. className: div.className || '',
  69. style: div.getAttribute('style') || ''
  70. };
  71. }
  72. return null;
  73. })
  74. .filter(item => item !== null);
  75. // 如果找到带背景图片的div,返回包含这些信息的对象
  76. if (divsWithBackground.length > 0) {
  77. return {
  78. text: textContent,
  79. backgroundImages: divsWithBackground
  80. };
  81. }
  82. // 检查单元格本身是否有背景图片
  83. const cellBackgroundUrl = extractBackgroundUrl(cell);
  84. if (cellBackgroundUrl) {
  85. return {
  86. text: textContent,
  87. cellBackgroundUrl: cellBackgroundUrl
  88. };
  89. }
  90. // 否则返回文本内容
  91. return textContent;
  92. });
  93. });
  94. }).flat();
  95. }).flat();
  96. // 过滤掉空表格
  97. const nonEmptyTables = tables.filter(table => table.length > 0);
  98. sendResponse({ tables: nonEmptyTables });
  99. }
  100. if (request.action === "getBackgroundImages") {
  101. // 获取所有带有background-image的元素
  102. const allElements = Array.from(document.querySelectorAll('*'));
  103. const backgroundImages: Array<{url: string, element: string, class: string, id: string}> = [];
  104. allElements.forEach(element => {
  105. const computedStyle = window.getComputedStyle(element);
  106. const backgroundImage = computedStyle.backgroundImage;
  107. // 检查是否有background-image
  108. if (backgroundImage && backgroundImage !== 'none' && backgroundImage.includes('url')) {
  109. // 提取URL
  110. const urlMatch = backgroundImage.match(/url\(["']?(.*?)["']?\)/);
  111. if (urlMatch && urlMatch[1]) {
  112. // 解码HTML实体
  113. const textarea = document.createElement('textarea');
  114. textarea.innerHTML = urlMatch[1];
  115. const decodedUrl = textarea.value;
  116. backgroundImages.push({
  117. url: decodedUrl,
  118. element: element.tagName.toLowerCase(),
  119. class: element.className || '',
  120. id: element.id || ''
  121. });
  122. }
  123. }
  124. });
  125. sendResponse({ backgroundImages });
  126. }
  127. });
  128. }
  129. });