Unable to perform action after selecting from context menu

89 views
Skip to first unread message

Charlie Clynes

unread,
Dec 25, 2023, 11:27:41 AM12/25/23
to Chromium Extensions
Hello,

I'm trying to insert a div element onto the current webpage when the user selects the corresponding option in the context menu, but I keep getting the error "Unchecked runtime.lastError: Could not establish connection. Receiving end does not exist." I'm new to both Chrome extension development and JS, and am really lost as to what's going on here; any help would be greatly appreciated.

manifest.json

{

    "manifest_version": 3,

    "name": "myextension",

    "description": "text will go here",

    "version": "1.0",

    "action": {

      "default_popup": "logo_popup.html",

      "default_icon": "images/icon256c.png"

    },

    "permissions": [

        "contextMenus", "tabs", "activeTab"

    ],

    "background": {

      "service_worker": "service_worker.js"

    },

    "content_scripts": [{

      "matches": ["<all_urls>"],

      "js": ["content.js"]

    }],

    "icons": {

        "16": "images/icon16.png",

        "32": "images/icon32.png",

        "48": "images/icon48.png",

        "128": "images/icon128.png",

        "256": "images/icon256c.png"

    },

    "web_accessible_resources": [

      {

        "resources": ["popup_shop.html"],

        "matches": ["<all_urls>"]

      }

    ]

  }


service_worker.js

chrome.contextMenus.create({

    title: "Shop",

    contexts: ["all"],

    id: "shopMenuItem"

});


// open div element on selection of corresponding menu item

chrome.contextMenus.onClicked.addListener(function(info, tab) {

    chrome.tabs.query(

        { active: true, currentWindow: true },

        function (tabs) {

            var activeTab = tabs[0]

            console.log(activeTab)

        if (info.menuItemId === "shopMenuItem") {

            chrome.tabs.sendMessage(activeTab.id, { msg: "openDiv"}, 

                function(response) {

                console.log(response)}

            );

        }}

    )

});


content.js

// create the popup page

function createDiv() {

    const divElt = document.createElement("divElt");

    divElt.id = "divElt";

    divElt.innerHTML = "divElt.html";

    document.body.appendChild(divElt)

    // style the popup

    divElt.style.position = "fixed";

    divElt.style.bottom = "20px";

    divElt.style.right = "20px"

    divElt.style.zIndex = "1000";

    divElt.style.color = "white";

}

function removeDiv() {

    const divElt = document.getElementById("divElt");

    if (divElt) {

        divElt.remove();

    }

}

chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {

  console.log(message);

  createDiv();

  sendResponse({ message : "content.js successfully received message"});

})

document.addEventListener('click', (event) => {

  const divElt = document.getElementById('divElt');

  if (divElt && !divElt.contains(event.target)) {

    removeDiv();

  }

});


I'm just trying to get this div element to appear for now, and then I'll fill it with interactive content that depends on the contents of the user's page. Like I said, I'm not sure how to fix this. Thanks in advance for any advice you can provide.

wOxxOm

unread,
Dec 25, 2023, 11:03:43 PM12/25/23
to Chromium Extensions, Charlie Clynes
Unlike other more dev-friendly browsers, Chrome/ium doesn't automatically inject content scripts after you install or reload the extension, so you'll need to do it explicitly. However, it's the wrong approach in case you need the content script only on demand e.g. after the user has clicked the context menu. Switch to programmatic injection instead of sendMessage and remove content_scripts from manifest.json so that the scripts don't run automatically on page load.

Charlie Clynes

unread,
Dec 26, 2023, 9:14:30 AM12/26/23
to Chromium Extensions, wOxxOm, Charlie Clynes
Hi wOxxOm,

Thanks for your help; this worked for calling the div element. Still, there are certain things that I want to run all the time — for instance, I'd like one of my content scripts to log the coordinates of right clicks, so that the div element can be centered in the corresponding location. These scripts still don't seem to run when I want them to (i.e. always), even after a page refresh, so message sending is still failing, despite listing them among "content_scripts" in the manifest. Do I have to call these scripts explicitly, too? The link you sent seems to imply this is only necessary if I want the scripts to run after updates without having to refresh the page. I also wasn't able to get it to work even with explicit sending.

Thanks again!

wOxxOm

unread,
Dec 26, 2023, 9:24:49 AM12/26/23
to Chromium Extensions, Charlie Clynes, wOxxOm
>   don't seem to run when I want them to (i.e. always), even after a page refresh

Add "run_at": "document_start" for your content_scripts declaration, because the default is document_end (DOMContentLoaded), which may take a very long time on a slow connection or a big page. Otherwise, the posted code seems fine to me, assuming you want to intercept the main button click (for the right-click you need to use mousedown event) so you need to debug it. Chrome has a built-in debugger in devtools -> Sources -> Content scripts panel, where you can set a breakpoint, so that when it triggers you would step through the code and look at the state like variables, DOM, storage, etc. You can also use Ctrl-P (Cmd-P) when devtools is focused to quickly open your script by name.
Reply all
Reply to author
Forward
Message has been deleted
0 new messages