diff --git a/session-state/README.md b/session-state/README.md new file mode 100644 index 0000000..a92bc48 --- /dev/null +++ b/session-state/README.md @@ -0,0 +1,13 @@ +# session-state + +## What it does + +This extension adds a context menu item. When the user clicks the context menu item, the extension adds a border to the page. + +But the extension also uses `sessions.setTabValue` to store the fact that it has added a border to this page. If the user closes the page, then restores it, the extension will retrieve this fact using `sessions.getTabValue`, and use that to reapply the border. + +Note: to restore a tab, press Control+Shift+T (or Command+Shift+T on a Mac). In Firefox you can also restore the tab from your "History->Recently Closed Tabs" menu. + +## What it shows + +This example demonstrates how you can use the [sessions](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/sessions) API to store and retrieve arbitrary state that you want to associate with a tab or window. Then if the tab/window is closed and subsequently restored, you can retrieve the state. diff --git a/session-state/background.js b/session-state/background.js new file mode 100644 index 0000000..29d64e9 --- /dev/null +++ b/session-state/background.js @@ -0,0 +1,51 @@ +/** + * Add a context menu item to borderify the current tab. + */ +browser.menus.create({ + id: "borderify-current-tab", + title: "Borderify current tab", + contexts: ["all"] +}); + +/** + * The borderify CSS. + */ +const borderCSS = 'body { border: 5px solid red };'; + +/* + * Borderifies the current tab, and, using setTabValue, stores the fact + * that this tab was borderified. + */ +async function borderify() { + let tabArray = await browser.tabs.query({currentWindow: true, active: true}); + let tabId = tabArray[0].id; + await browser.tabs.insertCSS(tabId, {code: borderCSS}); + await browser.sessions.setTabValue(tabId, "border-css", borderCSS); +} + +browser.menus.onClicked.addListener(borderify); + +/* + * When new tabs are created, we want to check, using getTabValue, whether + * the tab has the borderified state. That would mean it was borderified, then + * closed, then reopened, so we want to reapply the borderify CSS. + * + * But we can't insertCSS in onCreated, it's too early. So instead we make + * an onUpdated listener, just for this tab. In onUpdated we check the tab ID, + * and if this is our tab, insert the CSS and remove the listener. + */ +browser.tabs.onCreated.addListener((tab) => { + + async function borderifyRestored(targetTabId, thisTabId) { + if (targetTabId === thisTabId) { + let stored = await browser.sessions.getTabValue(targetTabId, "border-css"); + if (stored) { + let result = await browser.tabs.insertCSS(targetTabId, {code: stored}); + } + browser.tabs.onUpdated.removeListener(thisBorderifyRestored); + } + } + + let thisBorderifyRestored = borderifyRestored.bind(null, tab.id); + browser.tabs.onUpdated.addListener(thisBorderifyRestored); +}); diff --git a/session-state/icons/LICENSE b/session-state/icons/LICENSE new file mode 100644 index 0000000..9f3eac1 --- /dev/null +++ b/session-state/icons/LICENSE @@ -0,0 +1 @@ +The icon “border-48.png” is taken from the Google Material Design iconset, and is used under the terms of the Creative Commons Attribution-ShareAlike license: http://creativecommons.org/licenses/by-sa/3.0/. diff --git a/session-state/icons/border-48.png b/session-state/icons/border-48.png new file mode 100644 index 0000000..90687de Binary files /dev/null and b/session-state/icons/border-48.png differ diff --git a/session-state/manifest.json b/session-state/manifest.json new file mode 100644 index 0000000..9f25195 --- /dev/null +++ b/session-state/manifest.json @@ -0,0 +1,23 @@ +{ + "applications": { + "gecko": { + "id": "session-state@example.com", + "strict_min_version": "57.0a1" + } + }, + "manifest_version": 2, + "name": "Session state", + "version": "1.0", + "description": "Demonstrates using the sessions API to store and restore extension-specific tab state.", + "homepage_url": "https://github.com/mdn/webextensions-examples/tree/master/session-state", + "icons": { + "48": "icons/border-48.png" + }, + + "background": { + "scripts": ["background.js"] + }, + + "permissions": ["", "menus", "sessions"] + +}