|
|
@@ -0,0 +1,75 @@ |
|
|
|
/* Helper to manage the visibility and icon of a pageAction button. |
|
|
|
* Each callback is evaluated whenever the tab has changed. |
|
|
|
* Callbacks may be async (i.e. return a Promise). |
|
|
|
* |
|
|
|
* Arguments: |
|
|
|
* - options.visible: Tab => boolean; whether to show the pageAction button |
|
|
|
* - options.icon: Tab => either a string (the icon path), or null (to get the |
|
|
|
* default icon from the manifest), or an object (with path or imageData, see |
|
|
|
* docs of browser.pageAction.setIcon). |
|
|
|
* - options.onClicked: Tab => void (or Promise of void); run on click, after |
|
|
|
* which the button state is automatically updated on all tabs. |
|
|
|
* |
|
|
|
* Returns an object with the following methods: |
|
|
|
* - update(tab?): update visibility, icons, etcetera of a given tab, or of |
|
|
|
* all tabs if the tab argument is omitted. |
|
|
|
* |
|
|
|
* Example usage: |
|
|
|
* const pageActionButton = PageActionButton({ |
|
|
|
* visible: tab => tab.url.startsWith('https'), |
|
|
|
* icon: tab => isEnabled(tab.url) ? '/icon_enabled.svg' : '/icon_disabled.svg', |
|
|
|
* onClicked: tab => toggleEnabled(tab.url), |
|
|
|
* }) |
|
|
|
* // Manually trigger an update of a tab. |
|
|
|
* pageActionButton.update(tab) |
|
|
|
*/ |
|
|
|
|
|
|
|
import browser from 'webextension-polyfill' |
|
|
|
|
|
|
|
|
|
|
|
export default function PageActionButton({ visible, icon, onClicked }) { |
|
|
|
async function setIcon(tab) { |
|
|
|
let iconSetting = await icon(tab) |
|
|
|
if (typeof iconSetting === 'string' || iconSetting === null) { |
|
|
|
iconSetting = { path: iconSetting } |
|
|
|
} |
|
|
|
browser.pageAction.setIcon({ |
|
|
|
...iconSetting, |
|
|
|
tabId: tab.id, |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
async function checkTab(tab) { |
|
|
|
if (await visible(tab)) { |
|
|
|
setIcon(tab) |
|
|
|
browser.pageAction.show(tab.id) |
|
|
|
} else { |
|
|
|
browser.pageAction.hide(tab.id) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
async function checkAllTabs() { |
|
|
|
const tabs = await browser.tabs.query({}) |
|
|
|
for (const tab of tabs) { |
|
|
|
await checkTab(tab) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Show/hide the button on current tabs (XXX not awaiting it's completion) |
|
|
|
checkAllTabs() |
|
|
|
|
|
|
|
// Show/hide the button whenever a tab changes. |
|
|
|
browser.tabs.onUpdated.addListener((id, changeInfo, tab) => { |
|
|
|
checkTab(tab) |
|
|
|
}); |
|
|
|
|
|
|
|
// Handle button clicks |
|
|
|
browser.pageAction.onClicked.addListener(async tab => { |
|
|
|
await onClicked(tab) |
|
|
|
await checkAllTabs(tab) |
|
|
|
}) |
|
|
|
|
|
|
|
return { |
|
|
|
update: tab => tab ? checkTab(tab) : checkAllTabs() |
|
|
|
} |
|
|
|
} |