为什么我的 Chrome 扩展程序不能正确高亮多个关键词?

huangapple go评论61阅读模式
英文:

Why isn't my Chrome extension for highlighting multiple keywords working?

问题

抱歉,我没有检测到明显的代码错误。但是,要确保您的Chrome扩展能够正常工作,您可以尝试以下步骤:

  1. 确保您的扩展已经在Chrome中启用了。您可以在Chrome浏览器的扩展页面中启用它。

  2. 确保您在Chrome浏览器的开发者模式下加载了扩展。在扩展页面右上角,有一个开发者模式的复选框,确保它已经选中。

  3. 在Chrome浏览器的地址栏中输入chrome://extensions/,然后按回车键,确保您的扩展在该页面中列出,并且启用了。

  4. 检查Chrome浏览器的控制台(开发者工具中的"Console"标签)是否有任何错误消息。这可以帮助您找到潜在的问题。

  5. 确保您的扩展的权限(permissions)和匹配的URL(matches)设置正确。您的扩展似乎已经配置为在所有URL上运行,但您可以尝试更具体的URL匹配模式以确保扩展只在您需要的页面上运行。

希望这些步骤有助于您解决问题。如果您需要更多帮助,请提供更多信息或错误消息,以便我可以提供更详细的指导。

英文:

i would need help identifying error in code for Google chrome extension I'm trying to make.

Extension should highlight multiple keywords in different color of choice on active url /tab.

Since i need this for sensitive data I'm reluctant to use similar existing extensions and since im total amateur with coding i used ChatGPT to code some basics.

At the end UI that looks decent but problem is that extension does not highlight anything on page.

Code looks ok, but i cant find the reason why extension does not work. Any help or insight is appreciated.

Here are all files :

Manifest.json:
{
    "manifest_version": 3,
    "name": "Search Word Highlighter",
    "version": "1.0",
    "description": "Chrome extension to find and highlight multiple search words on the current URL.",
    "icons": {
      "16": "icon16.png",
      "48": "icon48.png",
      "128": "icon128.png"
    },
    "action": {
      "default_popup": "popup.html",
      "default_icon": {
        "16": "icon16.png",
        "48": "icon48.png",
        "128": "icon128.png"
      }
    },
    "permissions": [
      "activeTab",
      "storage",
      "scripting"
    ],
    "host_permissions": [
      "<all_urls>"
    ],
    "content_scripts": [
        {
            "matches": ["http://*/*", "https://*/*"],
            "js": ["content.js"],
            "run_at": "document_end"
          }
      ],
      
    "background": {
      "service_worker": "background.js"
    }
  }
 
popup.html:
<!DOCTYPE html>
<html>
<head>
  <title>Highlight multi</title>
  <link rel="stylesheet" type="text/css" href="styles.css">
  <style>
    body {
      font-family: Arial, sans-serif;
      margin: 10px;
    }
    
    form {
      display: flex;
      flex-direction: column;
      margin-bottom: 10px;
    }
    
    .keyword-container {
      display: flex;
      align-items: center;
      margin-bottom: 10px;
    }
    
    input[type="text"] {
      margin-right: 10px;
    }
    
    input[type="color"] {
      padding: 0;
      height: 24px;
      width: 24px;
      border: none;
      border-radius: 50%;
      cursor: pointer;
    }
    
    button {
      margin-top: 10px;
    }
    
    ul {
      margin: 0;
      padding: 0;
      list-style: none;
    }
    
    li {
      margin-bottom: 5px;
    }
  </style>
</head>
<body>
  <form id="add-keyword-form">
    <div class="keyword-container">
      <input type="text" class="keyword-input" placeholder="Enter a keyword">
      <input type="color" class="color-input" value="#ff0000">
    </div>
    <button type="button" id="add-keyword-button">Add Keyword</button>
    <button type="button" id="search-button">Search</button>
  </form>
  
  <ul id="keywords-list"></ul>
  
  <script src="popup.js"></script>
</body>
</html>

popup.js:
document.addEventListener("DOMContentLoaded", function () {
    const form = document.getElementById("add-keyword-form");
    const addKeywordButton = document.getElementById("add-keyword-button");
    const searchButton = document.getElementById("search-button");
    const keywordsList = document.getElementById("keywords-list");
  
    let keywordIndex = 1;
  
    // Handle add keyword button click
    addKeywordButton.addEventListener("click", function () {
      addKeywordField();
    });
  
    // Handle search button click to trigger the search function
    searchButton.addEventListener("click", function () {
      const keywordInputs = document.querySelectorAll(".keyword-input");
      const colorInputs = document.querySelectorAll(".color-input");
      const keywords = [];
      for (let i = 0; i < keywordInputs.length; i++) {
        const keyword = keywordInputs[i].value.trim();
        const color = colorInputs[i].value;
        if (keyword && color) {
          keywords.push({ keyword, color });
        }
      }
      if (keywords.length > 0 || keywordInputs[0].value.trim() !== "") {
        searchKeywords(keywords);
      }
    });
  
    // Function to add a new keyword field
    function addKeywordField() {
      const container = document.createElement("div");
      container.classList.add("keyword-container");
  
      const keywordInput = document.createElement("input");
      keywordInput.setAttribute("type", "text");
      keywordInput.setAttribute("placeholder", "Enter a keyword");
      keywordInput.classList.add("keyword-input");
  
      const colorInput = document.createElement("input");
      colorInput.setAttribute("type", "color");
      colorInput.setAttribute("value", "#ff0000");
      colorInput.classList.add("color-input");
  
      container.appendChild(keywordInput);
      container.appendChild(colorInput);
      form.insertBefore(container, addKeywordButton);
    }
  
    // Function to search the keywords
    function searchKeywords(keywords) {
      // Send a message to the content script to highlight the keywords on the page
      chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
        chrome.tabs.sendMessage(tabs[0].id, { action: "highlightKeyWords", keywords: keywords }, function (response) {
          // Handle the response if needed
        });
      });
  
      // Display the keywords in the list
      keywordsList.innerHTML = "";
      keywords.forEach(keyword => {
        const li = document.createElement("li");
        li.textContent = keyword.keyword;
        li.style.color = keyword.color;
        keywordsList.appendChild(li);
      });
    }
  });
  
content.js:
// Function to highlight all occurrences of a keyword
function highlightKeyword(keyword, color) {
  const regex = new RegExp(`\\b${keyword}\\b`, "gi");
  const matches = document.body.innerText.match(regex);
  if (matches) {
    for (const match of matches) {
      const span = document.createElement("span");
      span.style.backgroundColor = color;
      span.style.color = "yellow";
      span.textContent = match;

      const replacedHtml = document.body.innerHTML.replace(new RegExp(match, "g"), span.outerHTML);
      document.body.innerHTML = replacedHtml;
    }
  }
}

// Function to search the keywords and highlight them on the page
function searchKeywords(keywords) {
  keywords.forEach(keyword => {
    highlightKeyword(keyword.keyword, keyword.color);
  });
}

// Listen for messages from the extension popup
chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) {
  if (message.action === "highlightWords") {
    const keywords = message.keywords;
    searchKeywords(keywords);
  }
});

background.js:
chrome.action.onClicked.addListener((tab) => {
  chrome.scripting.executeScript({
    target: { tabId: tab.id },
    files: ["content.js"]
  });
});

chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) {
  if (message.action === "getKeywords") {
    chrome.storage.local.get("keywords", function (data) {
      sendResponse({ keywords: data.keywords });
    });
    return true; // Needed to indicate that the response will be sent asynchronously
  } else if (message.action === "saveKeywords") {
    chrome.storage.local.set({ keywords: message.keywords });
  } else if (message.action === "highlightKeywords") {
    // Forward the message to the content script
    chrome.tabs.sendMessage(sender.tab.id, message);
  }
});

chrome.runtime.onInstalled.addListener(function () {
  // Check if persistent storage is available and request it if necessary
  if (navigator.storage && navigator.storage.persist) {
    navigator.storage.persist().then((persistent) => {
      if (persistent) {
        console.log("Persistent storage granted.");
      } else {
        console.log("Persistent storage not granted.");
      }
    });
  }
});

css:
body {
    font-family: Arial, sans-serif;
    margin: 20px;
  }
  
  h1 {
    font-size: 18px;
    margin-bottom: 10px;
  }
  
  form {
    margin-bottom: 20px;
  }
  
  input[type="text"] {
    width: 200px;
  }
  
  
  button {
    padding: 6px 12px;
    background-color: #007bff;
    color: #fff;
    border: none;
    cursor: pointer;
  }
  

Thank you for help

I found some explanations for previous manifest version 2 here but that does not help.
Chat GPT cant detect any errors

答案1

得分: 1

如果chatGPT可以阅读文档,它会知道"如果扩展操作已指定在当前选项卡上单击时显示弹出窗口,则不会触发action.onClicked事件。"
您需要从background.js中删除invokation,
然后添加以下内容

chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
    chrome.scripting.executeScript({
      target: { tabId: tabs[0].id },
      files: ["content.js"],
    });
  });

在popup.js中的let keywordIndex = 1;之后。

而且JavaScript实际上是大小写敏感的语言,因此您需要在所有JavaScript文件中确切地将action更改为"highlightKeywords"。例如,在您的content.js文件中,它是"highlightWords",没有Key并且有大写的W,当然,在代码的其他地方也不存在这样的操作。

英文:

If chatGPT could read docs, it would know that "The action.onClicked event will not be dispatched if the extension action has specified a popup to show on click on the current tab."
You need delete invokation from background.js
then add this

chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
    chrome.scripting.executeScript({
      target: { tabId: tabs[0].id },
      files: ["content.js"],
    });
  });

after let keywordIndex = 1; in popup.js

And JS is actually case sensitive language, so you need to change action to "highlightKeywords" in exactly this case in all js files. For example in your content.js it is "highlightWords" without Key and with capital W, and of course such action not exist anywhere else in code.

huangapple
  • 本文由 发表于 2023年6月1日 22:39:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/76383072.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定