Home > Blockchain >  Create a detached/attached window toggle button for Chrome extension
Create a detached/attached window toggle button for Chrome extension

Time:01-04

I have a Chrome extension that was originally a 'default_popup' attached popup window, when you click the icon in the extensions bar, the popup would appear underneath and be attached to the button.

Recently, I successfully changed that to be a fully detached window due to some feedback.

I was using the 'default_popup' setting in manifest.json to have it attached, and chrome.windows.create() in a chrome.action.onClicked.addListener() in my background service worker to make it a detached window.

Now some users are telling me they much preferred the attached version. So I want to create a button to let them persistently set a preference (I know how to record preferences, so I don't need help with that part) for them to switch between attached and detached.

The problem is that if I set 'default_popup' in the manifest, it completely ignores my chrome.action.onClicked.addListener(), and if i don't fill in 'default_popup', I can't find a way to have the window come up attached via code.

CodePudding user response:

Right-click the extension action and then left-click "Attach Popup to Action". This will toggle the popup mode (attached / detached).

manifest.json

{
    "manifest_version": 3,
    "name": "Popup (togglable)",
    "version": "1.0.0",
    "action": {
        "default_popup": "popup.html"
    },
    "background": {
        "service_worker": "background.js"
    },
    "permissions": [
        "contextMenus"
    ]
}

background.js

/* This function will only be called if no popup is set */
async function action_on_clicked(tab) {
    await chrome.windows.create(
        {
            height: 200,
            type: "popup",
            url: "popup.html",
            width: 200
        },
    );
}

async function context_menus_on_clicked(info, tab) {
    let popup_html = info.checked ? "popup.html" : "";
    await chrome.action.setPopup({popup: popup_html});
}

async function runtime_on_installed(details) {
    let popup_html = await chrome.action.getPopup({});
    
    chrome.contextMenus.create({
        checked: (popup_html != ""),
        contexts: ["action"],
        id: "attach_popup_to_action",
        title: "Attach Popup to Action",
        type: "checkbox"
    });
}

chrome.action.onClicked.addListener(action_on_clicked);
chrome.contextMenus.onClicked.addListener(context_menus_on_clicked);
chrome.runtime.onInstalled.addListener(runtime_on_installed);

popup.html

<!DOCTYPE html>
<html>
    <head>
        <title>Popup</title>
    </head>
    <body>
        <p>Test Popup</p>
        <script src="popup.js"></script>
    </body>
</html>

popup.js

console.log("popup.js");

CodePudding user response:

Yours can be implemented without a service worker.

popup.js

const createDate = {
  url: "window.html",
  type: "popup"
};
chrome.windows.create(createDate, () => { });
window.close();

popup.html

<html>
<body">
  <script src="popup.js"></script>
</body>
</html>
  • Related