diff --git a/forget-it/README.md b/forget-it/README.md new file mode 100644 index 0000000..9fd03d0 --- /dev/null +++ b/forget-it/README.md @@ -0,0 +1,5 @@ +# Forget it! + +This add-on adds a button to the browser's toolbar. When the user clicks the button, the add-on clears some browsing data using the browsingData API. The details of what exactly it clears are determined by the add-on's settings, which can be accessed and modified in its options page. + +The example shows how to use the browsingData API, and how to use the options page to handle settings. diff --git a/forget-it/background.js b/forget-it/background.js new file mode 100644 index 0000000..9390e11 --- /dev/null +++ b/forget-it/background.js @@ -0,0 +1,89 @@ +/* +Default settings. If there is nothing in storage, use these values. +*/ +var defaultSettings = { + since: "hour", + dataTypes: ["history", "downloads"] +}; + +/* +Generic error logger. +*/ +function onError(e) { + console.error(e); +} + +/* +On startup, check whether we have stored settings. +If we don't, then store the default settings. +*/ +function checkStoredSettings(storedSettings) { + if (!storedSettings.since || !storedSettings.dataTypes) { + browser.storage.local.set(defaultSettings); + } +} + +const gettingStoredSettings = browser.storage.local.get(); +gettingStoredSettings.then(checkStoredSettings, onError); + +/* +Forget browsing data, according to the settings passed in as storedSettings +or, if this is empty, according to the default settings. +*/ +function forget(storedSettings) { + + /* + Convert from a string to a time. + The string is one of: "hour", "day", "week", "forever". + The time is given in milliseconds since the epoch. + */ + function getSince(selectedSince) { + if (selectedSince === "forever") { + return 0; + } + + const times = { + hour: () => { return 1000 * 60 * 60 }, + day: () => { return 1000 * 60 * 60 * 24 }, + week: () => { return 1000 * 60 * 60 * 24 * 7} + } + + const sinceMilliseconds = times[selectedSince].call(); + return Date.now() - sinceMilliseconds; + } + + /* + Convert from an array of strings, representing data types, + to an object suitable for passing into browsingData.remove(). + */ + function getTypes(selectedTypes) { + let dataTypes = {}; + for (let item of selectedTypes) { + dataTypes[item] = true; + } + return dataTypes; + } + + const since = getSince(storedSettings.since); + const dataTypes = getTypes(storedSettings.dataTypes); + + function notify() { + let dataTypesString = Object.keys(dataTypes).join(", "); + let sinceString = new Date(since).toLocaleString(); + browser.notifications.create({ + "type": "basic", + "title": "Removed browsing data", + "message": `Removed ${dataTypesString}\nsince ${sinceString}` + }); + } + + browser.browsingData.remove({since}, dataTypes).then(notify); +} + +/* +On click, fetch stored settings and forget browsing data. +*/ +browser.browserAction.onClicked.addListener(() => { + const gettingStoredSettings = browser.storage.local.get(); + gettingStoredSettings.then(forget, onError); +}); diff --git a/forget-it/icons/LICENSE b/forget-it/icons/LICENSE new file mode 100644 index 0000000..a37916c --- /dev/null +++ b/forget-it/icons/LICENSE @@ -0,0 +1 @@ +The trash.svg” icon is taken from the miu iconset and is used under the terms of its license: https://www.iconfinder.com/iconsets/miu. diff --git a/forget-it/icons/trash.svg b/forget-it/icons/trash.svg new file mode 100644 index 0000000..072d731 --- /dev/null +++ b/forget-it/icons/trash.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/forget-it/manifest.json b/forget-it/manifest.json new file mode 100644 index 0000000..f540a8d --- /dev/null +++ b/forget-it/manifest.json @@ -0,0 +1,30 @@ +{ + + "description": "Forget it!", + "manifest_version": 2, + "name": "forget-it", + "version": "2.0", + "homepage_url": "https://github.com/mdn/webextensions-examples/tree/master/forget-it", + "icons": { + "48": "icons/trash.svg" + }, + + "background": { + "scripts": ["background.js"] + }, + + "browser_action": { + "default_icon": "icons/trash.svg", + "default_title": "Forget it!" + }, + + "options_ui": { + "page": "options/options.html" + }, + + "permissions": [ + "browsingData", + "notifications", + "storage" + ] +} diff --git a/forget-it/options/options.css b/forget-it/options/options.css new file mode 100644 index 0000000..d224a51 --- /dev/null +++ b/forget-it/options/options.css @@ -0,0 +1,36 @@ + +body { + width: 25em; + font-family: "Open Sans Light", sans-serif; + font-size: 0.9em; + font-weight: 300; +} + +section.clear-options { + padding: 0.5em 0; + margin: 1em 0; +} + +#clear-button { + margin: 0 1.3em 1em 0; +} + +section.clear-options input, +section.clear-options>select, +#clear-button { + float: right; +} + +label { + display: block; + padding: 0.2em 0; +} + +label:hover { + background-color: #EAEFF2; +} + +.title { + font-size: 1.2em; + margin-bottom: 0.5em; +} diff --git a/forget-it/options/options.html b/forget-it/options/options.html new file mode 100644 index 0000000..aea0636 --- /dev/null +++ b/forget-it/options/options.html @@ -0,0 +1,40 @@ + + + +
+ + + + + + + + + + + + + + + + diff --git a/forget-it/options/options.js b/forget-it/options/options.js new file mode 100644 index 0000000..aad693e --- /dev/null +++ b/forget-it/options/options.js @@ -0,0 +1,62 @@ +/* +Store the currently selected settings using browser.storage.local. +*/ +function storeSettings() { + + function getSince() { + const since = document.querySelector("#since"); + return since.value; + } + + function getTypes() { + let dataTypes = []; + const checkboxes = document.querySelectorAll(".data-types [type=checkbox]"); + for (let item of checkboxes) { + if (item.checked) { + dataTypes.push(item.getAttribute("data-type")); + } + } + return dataTypes; + } + + const since = getSince(); + const dataTypes = getTypes(); + browser.storage.local.set({ + since, + dataTypes + }); +} + +/* +Update the options UI with the settings values retrieved from storage, +or the default settings if the stored settings are empty. +*/ +function updateUI(restoredSettings) { + const selectList = document.querySelector("#since"); + selectList.value = restoredSettings.since; + + const checkboxes = document.querySelectorAll(".data-types [type=checkbox]"); + for (let item of checkboxes) { + if (restoredSettings.dataTypes.indexOf(item.getAttribute("data-type")) != -1) { + item.checked = true; + } else { + item.checked = false; + } + } +} + +function onError(e) { + console.error(e); +} + +/* +On opening the options page, fetch stored settings and update the UI with them. +*/ +const gettingStoredSettings = browser.storage.local.get(); +gettingStoredSettings.then(updateUI, onError); + +/* +On clicking the save button, save the currently selected settings. +*/ +const saveButton = document.querySelector("#save-button"); +saveButton.addEventListener("click", storeSettings);