0

I'm building a Chrome extension and I want to get the currently selected text after the user click on a context menu. I'm trying to do it by sending a message from the background script to the content script but the object returned from the content script is always empty.

Here's the relevant code:

background_script.js:

function onClickHandler(info, tab){
    chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
        chrome.tabs.sendMessage(tabs[0].id, {method: "getSelection"}, undefined, function(response){
            console.log(response.data); // <--- this is undefined
        });
    });
}

chrome.contextMenus.onClicked.addListener(onClickHandler);

content_script.js:

chrome.runtime.onMessage.addListener( 
    function(request, sender, sendResponse) {
        if (request.method == "getSelection"){
            var selection = window.getSelection(); // <--- this is ok
            sendResponse({data: selection}); 
            return true;
        }
    }
)

manifest.json

{
    "manifest_version": 2,

    "name": "Browser Extension",
    "description": "Browser Extension",
    "version": "0.1",

    "background": {
        "scripts": [
            "background_script.js"
        ]
    },

    "content_scripts": [
        {
            "matches": ["<all_urls>"],
            "js": ["content_script.js"]
        }
    ],

    "permissions": [
        "activeTab",
        "contextMenus",
        "storage"
    ]
}

The main issue in similar cases seems to be a missing return true; statement but I've added that. Also, the chrome.tabs.sendMessage function has a new parameter options but it makes no difference whether I omit it or pass an undefined or empty value.

Thank you :)

EDIT:chrome.runtime.lastError in the sendMessage function is undefined so no apparent errors!

squeck
  • 37
  • 1
  • 10
  • 1
    Don't use undefined as the 3rd argument of `chrome.tabs.sendMessage`. Simply eliminate that argument, i.e: `chrome.tabs.sendMessage(tabs[0].id, {method: "getSelection"}, function(response){` – Iván Nokonoko Dec 27 '17 at 15:54
  • Thanks @iván, that's how I did it in the first place but unfortunately it isn't working anyway :( – squeck Dec 27 '17 at 16:02
  • `Selection` is a complex DOM class, it's not JSON'ifiable, so you need to add `.toString()` – wOxxOm Dec 28 '17 at 07:40
  • This was it, thank you @wOxxOm! I had also tried with just a string but probably that was before fixing other errors. Also I thought that JSON.stringify could stringify anything :D – squeck Dec 28 '17 at 19:46

1 Answers1

1

As pointed out by @wOxxOm, the problem here was that I was trying to JSONify a complex object. Adding .toString works. My bad!

squeck
  • 37
  • 1
  • 10