Getting selected text in a Chrome extension
Asked Answered
A

1

7

I'm trying to create a Chrome extenstion that allows the user to get the selected text of a web page after clicking on a button and then log this text in the console.

But my code is working only if the text is selected from the HTML pop-up. If i select a text from a random webpage and then click the "Save" button, then a blank line is printed in the console.

I guess my content.js file is not able to interact with the web page when the extension popup is displayed but I don't know how to resolve that. I know there are other similar questions but nothing I tried (message passing between different .js files for example) worked.

Here are my files :

manifest.json :

{
"manifest_version": 3,
"version": "1.0",
"name": "test",
"action": {
    "default_popup": "index.html"
},
"permissions": [
    "tabs",
    "notifications"
],
"content_scripts": [
{   "matches": ["<all_urls>"],
    "js" : ["content.js"]}
],
"background":
{
"service_worker": "background.js"
}}

index.html :

<html>
<head>
    <link rel="stylesheet" href="index.css">
</head>
<body>
    <p>Just some text.</p>
    <button id="save-btn">SAVE SELECTION</button>
    <script src="content.js"></script>
</body>
</html>

content.js :

const saveBtn = document.getElementById("save-btn")

saveBtn.addEventListener("click", function(){
console.log(window.getSelection().toString())
})
Atwitter answered 27/7, 2021 at 9:51 Comment(0)
U
13
  1. Remove content.js from index.html. Content scripts are for web pages, not for extension pages such as the popup.

  2. Create index.js and load it in index.html:

      <script src="index.js"></script>
    </body>
    
  3. index.js:

    document.getElementById("save-btn").onclick = async () => {
      const [tab] = await chrome.tabs.query({active: true, currentWindow: true});
      let result;
      try {
        [{result}] = await chrome.scripting.executeScript({
          target: {tabId: tab.id},
          func: () => getSelection().toString(),
        });
      } catch (e) {
        return; // ignoring an unsupported page like chrome://extensions
      }
      document.body.append('Selection: ' + result);
    };
    
  4. edit manifest.json to allow code injection in the active tab on click:

    "permissions": ["scripting", "activeTab"]
    

Note that the popup is a separate window so it has its own separate devtools and console: right-click inside the popup and select "inspect" in the menu.

Unfreeze answered 27/7, 2021 at 10:18 Comment(2)
Thanks for the answer, It's now working ! Just a question : would it be impossible to just use the window.getSelection() method in the new index.js file ? Is it because the popup has its own DOM ? Is it impossible to access to the DOM of the web page in index.js ?Atwitter
The popup is a completely different page.Unfreeze

© 2022 - 2024 — McMap. All rights reserved.