google-chromegoogle-chrome-extensionchrome-extension-manifest-v3browser-extension

Can `content_scripts` detect if a `command` is set?


My extension currently uses the [esc] key to perform an action.

This is done in the content-script, using addEventListener('keydown').

I'd like the user to be able to choose a different shortcut.

I've updated to Manifest V3, and added a new "commands" key, i.e.

{
    ...
    "manifest_version": 3,
    "background": {
            "service_worker": "background.js"
        },
    "content_scripts": [ {
            "js": [ "screenshot.js" ],
            "matches": [ "http://*/*", "https://*/*" ]
         }],
    "commands": {
        "stop-animations": {
            "description": "Stop Animations"
        }
    }
}

I've updated background.js to use chrome.commands.onCommand, and this works well.

But, how can I get my content-script to determine if the user has set their own shortcut?

Because I should not listen to the 'keydown' event to check if they have pressed the [esc] key.

I've tried using chrome.commands.getAll(), but this method is only available at install time.

A partial option would be to use something like browser.storage to set a simple boolean "custom-command-set" to true whenever onCommand is used, but I cannot think of a way to switch it off again if the user deletes the shortcut command (i.e. they want to go back to using the [esc] key).

At the moment I don't have a toolbar icon (action default_popup), or any other UI, and I'd prefer to not add one just to provide a custom way to set the shortcut.


Solution

  • Content scripts can't call chrome.commands.getAll() directly, so they need to send a message to the service worker. The SW calls chrome.commands.getAll() and sends the result back to the content script.

    manifest.json

    {
        "manifest_version": 3,
        "name": "chrome.commands.getAll",
        "version": "1.0.0",
        "background": {
              "service_worker": "background.js"
        },
        "content_scripts": [
            {
                "js": [ "content_script.js" ],
                "matches": [ "*://*/*" ]
            }
        ],
        "commands": {
            "test": {
                "description": "Test"
            }
        },
        "permissions": ["commands"]
    }
    

    background.js

    function commands_on_command(command) {
        console.log("on_command", command);
    }
    
    function runtime_on_message(message, sender, sendResponse) {
        if (message == "get_all_commands") {
            chrome.commands.getAll()
            .then(commands => {
                console.log("background.js", "runtime_on_message", commands);
                sendResponse(commands);
            });
            return true; // https://developer.chrome.com/docs/extensions/mv3/messaging/#simple
        }
        else {
            console.log("background.js", "runtime_on_message", "unknown command");
            sendResponse("unknown command");
        }
    }
    
    chrome.commands.onCommand.addListener(commands_on_command);
    chrome.runtime.onMessage.addListener(runtime_on_message);
    

    content_script.js

    (async () => {
        let response = await chrome.runtime.sendMessage("get_all_commands");
        console.log("content_script.js", response);
    })();