diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..a0612c7 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,4 @@ +**/node_modules/** +react-es6-popup/**/dist +mocha-client-tests +store-collected-images/webextension-plain/deps diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..bd5191f --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,22 @@ +{ + "root": true, + "parserOptions": { + "ecmaVersion": 6 + }, + "env": { + "browser": true, + "es6": true, + "webextensions": true + }, + "extends": [ + "eslint:recommended" + ], + "rules": { + "no-console": 0, + "no-unused-vars": ["warn", { "vars": "all", "args": "all" } ], + "no-undef": ["warn"], + "no-proto": ["error"], + "prefer-arrow-callback": ["warn"], + "prefer-spread": ["warn"] + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..6892e2f --- /dev/null +++ b/.travis.yml @@ -0,0 +1,3 @@ +language: node_js +node_js: stable +sudo: false diff --git a/README.md b/README.md index 505ef63..426b57a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# webextensions-examples +# webextensions-examples [](https://travis-ci.org/mdn/webextensions-examples) [https://github.com/mdn/webextensions-examples](https://github.com/mdn/webextensions-examples) diff --git a/annotate-page/sidebar/panel.js b/annotate-page/sidebar/panel.js index f4fdb46..2af8505 100644 --- a/annotate-page/sidebar/panel.js +++ b/annotate-page/sidebar/panel.js @@ -4,14 +4,14 @@ const contentBox = document.querySelector("#content"); /* Make the content box editable as soon as the user mouses over the sidebar. */ -window.addEventListener("mouseover", (e) => { +window.addEventListener("mouseover", () => { contentBox.setAttribute("contenteditable", true); }); /* When the user mouses out, save the current contents of the box. */ -window.addEventListener("mouseout", (e) => { +window.addEventListener("mouseout", () => { contentBox.setAttribute("contenteditable", false); browser.tabs.query({windowId: myWindowId, active: true}).then((tabs) => { let contentToStore = {}; diff --git a/apply-css/background.js b/apply-css/background.js index 7e936a0..3c0b1aa 100644 --- a/apply-css/background.js +++ b/apply-css/background.js @@ -51,7 +51,7 @@ When first loaded, initialize the page action for all tabs. */ var gettingAllTabs = browser.tabs.query({}); gettingAllTabs.then((tabs) => { - for (tab of tabs) { + for (let tab of tabs) { initializePageAction(tab); } }); diff --git a/bookmark-it/background.js b/bookmark-it/background.js index 9cc9a48..565fa06 100644 --- a/bookmark-it/background.js +++ b/bookmark-it/background.js @@ -16,6 +16,11 @@ function updateIcon() { }, tabId: currentTab.id }); + browser.browserAction.setTitle({ + // Screen readers can see the title + title: currentBookmark ? 'Unbookmark it!' : 'Bookmark it!', + tabId: currentTab.id + }); } /* diff --git a/chill-out/background.js b/chill-out/background.js index bbf453f..d29d949 100644 --- a/chill-out/background.js +++ b/chill-out/background.js @@ -69,6 +69,6 @@ browser.alarms.onAlarm.addListener((alarm) => { /* On page action click, navigate the corresponding tab to the cat gifs. */ -browser.pageAction.onClicked.addListener(function () { +browser.pageAction.onClicked.addListener(() => { browser.tabs.update({url: CATGIFS}); }); diff --git a/commands/README.md b/commands/README.md index 9cb9cc8..db36734 100644 --- a/commands/README.md +++ b/commands/README.md @@ -10,4 +10,4 @@ All it does is: It shows: -* how to use chrome.commands to register keyboard shortcuts for your extension. +* how to use browser.commands to register keyboard shortcuts for your extension. diff --git a/commands/background.js b/commands/background.js index 825c559..a54dc95 100644 --- a/commands/background.js +++ b/commands/background.js @@ -12,7 +12,7 @@ */ var gettingAllCommands = browser.commands.getAll(); gettingAllCommands.then((commands) => { - for (command of commands) { + for (let command of commands) { console.log(command); } }); diff --git a/context-menu-copy-link-with-types/background.js b/context-menu-copy-link-with-types/background.js index b8d1505..9152745 100644 --- a/context-menu-copy-link-with-types/background.js +++ b/context-menu-copy-link-with-types/background.js @@ -3,7 +3,7 @@ browser.contextMenus.create({ title: "Copy link to clipboard", contexts: ["link"], }); -browser.contextMenus.onClicked.addListener(function(info, tab) { +browser.contextMenus.onClicked.addListener((info, tab) => { if (info.menuItemId === "copy-link-to-clipboard") { // Examples: text and HTML to be copied. const text = "This is text: " + info.linkUrl; @@ -22,7 +22,7 @@ browser.contextMenus.onClicked.addListener(function(info, tab) { browser.tabs.executeScript({ code: "typeof copyToClipboard === 'function';", - }).then(function(results) { + }).then((results) => { // The content script's last expression will be true if the function // has been defined. If this is not the case, then we need to run // clipboard-helper.js to define function copyToClipboard. @@ -31,11 +31,11 @@ browser.contextMenus.onClicked.addListener(function(info, tab) { file: "clipboard-helper.js", }); } - }).then(function() { + }).then(() => { return browser.tabs.executeScript(tab.id, { code, }); - }).catch(function(error) { + }).catch((error) => { // This could happen if the extension is not allowed to run code in // the page, for example if the tab is a privileged page. console.error("Failed to copy text: " + error); diff --git a/devtools-panels/README.md b/devtools-panels/README.md new file mode 100644 index 0000000..2cbcc30 --- /dev/null +++ b/devtools-panels/README.md @@ -0,0 +1,29 @@ +# devtools-panels + +**Adds a new panel to the developer tools. The panel contains buttons that demonstrate various basic features of the devtools API.** + +## What it does ## + +This extension adds a new panel to the developer tools. The panel contains four buttons: + +* **Inspect H1**: this injects a script into the active page. The script uses the [`inspect()` helper function](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/devtools.inspectedWindow/eval#Helpers) to select the first <h1> element in the page in the devtools inspector. + +* **Reddinate inspected element**: this injects a script into the active page. The script uses the [`$0` helper](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/devtools.inspectedWindow/eval#Helpers) to get the element that's currently selected in the devtools Inspector, and gives it a red background. + +* **Check for jQuery**: this injects a script into the active page. The script checks whether `jQuery` is defined in the page, and logs a string to the add-on debugging console (note: *not* the web console) recording the result. + +* **Inject content script**: this sends a message to the extension's background script, asking it to inject a given content script in the active page. + +To learn more about the devtools APIs, see [Extending the developer tools](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Extending_the_developer_tools). + +## What it shows ## + +* How to add a new panel to the devtools. + +* How to inject a script into the active page using [`inspectedWindow.eval()`](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/devtools.inspectedWindow/eval). + +* How to use [helpers](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/devtools.inspectedWindow/eval#Helpers) to interact with the devtools. + +* That unlike content scripts, scripts injected with `eval()` can see objects, like `jQuery`, that were added by page scripts. + +* How to send messages to the background script. diff --git a/devtools-panels/background_scripts/background.js b/devtools-panels/background_scripts/background.js new file mode 100644 index 0000000..18297fe --- /dev/null +++ b/devtools-panels/background_scripts/background.js @@ -0,0 +1,23 @@ + +/** +When we receive the message, execute the given script in the given +tab. +*/ +function handleMessage(request, sender, sendResponse) { + + if (sender.url != browser.runtime.getURL("/devtools/panel/panel.html")) { + return; + } + + browser.tabs.executeScript( + request.tabId, + { + code: request.script + }); + +} + +/** +Listen for messages from our devtools panel. +*/ +browser.runtime.onMessage.addListener(handleMessage); diff --git a/devtools-panels/devtools/devtools-page.html b/devtools-panels/devtools/devtools-page.html new file mode 100644 index 0000000..807bd94 --- /dev/null +++ b/devtools-panels/devtools/devtools-page.html @@ -0,0 +1,9 @@ + + +
+ + + + + + diff --git a/devtools-panels/devtools/devtools.js b/devtools-panels/devtools/devtools.js new file mode 100644 index 0000000..ae6bf47 --- /dev/null +++ b/devtools-panels/devtools/devtools.js @@ -0,0 +1,24 @@ +/** +This script is run whenever the devtools are open. +In here, we can create our panel. +*/ + +function handleShown() { + console.log("panel is being shown"); +} + +function handleHidden() { + console.log("panel is being hidden"); +} + +/** +Create a panel, and add listeners for panel show/hide events. +*/ +browser.devtools.panels.create( + "My Panel", + "icons/star.png", + "devtools/panel/panel.html" +).then((newPanel) => { + newPanel.onShown.addListener(handleShown); + newPanel.onHidden.addListener(handleHidden); +}); diff --git a/devtools-panels/devtools/panel/devtools-panel.js b/devtools-panels/devtools/panel/devtools-panel.js new file mode 100644 index 0000000..5a1f35b --- /dev/null +++ b/devtools-panels/devtools/panel/devtools-panel.js @@ -0,0 +1,72 @@ +/** +Handle errors from the injected script. +Errors may come from evaluating the JavaScript itself +or from the devtools framework. +See https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/devtools.inspectedWindow/eval#Return_value +*/ +function handleError(error) { + if (error.isError) { + console.log(`Devtools error: ${error.code}`); + } else { + console.log(`JavaScript error: ${error.value}`); + } +} + +/** +Handle the result of evaluating the script. +If there was an error, call handleError. +*/ +function handleResult(result) { + if (result[1]) { + handleError(result[1]); + } +} + +/** +Handle the result of evaluating the jQuery test script. +Log the result of the test, or +if there was an error, call handleError. +*/ +function handlejQueryResult(result) { + if (result[0] !== undefined) { + console.log(`jQuery: ${result[0]}`); + } else if (result[1]) { + handleError(result[1]); + } +} +/** +When the user clicks the 'jquery' button, +evaluate the jQuery script. +*/ +const checkjQuery = "typeof jQuery != 'undefined'"; +document.getElementById("button_jquery").addEventListener("click", () => { + browser.devtools.inspectedWindow.eval(checkjQuery) + .then(handlejQueryResult); +}); +/** +When the user clicks each of the first three buttons, +evaluate the corresponding script. +*/ +const evalString = "$0.style.backgroundColor = 'red'"; +document.getElementById("button_background").addEventListener("click", () => { + browser.devtools.inspectedWindow.eval(evalString) + .then(handleResult); +}); + +const inspectString = "inspect(document.querySelector('h1'))"; +document.getElementById("button_h1").addEventListener("click", () => { + browser.devtools.inspectedWindow.eval(inspectString) + .then(handleResult); +}); + +/** +When the user clicks the 'message' button, +send a message to the background script. +*/ +const scriptToAttach = "document.body.innerHTML = 'Hi from the devtools';"; +document.getElementById("button_message").addEventListener("click", () => { + browser.runtime.sendMessage({ + tabId: browser.devtools.inspectedWindow.tabId, + script: scriptToAttach + }); +}); diff --git a/devtools-panels/devtools/panel/panel.html b/devtools-panels/devtools/panel/panel.html new file mode 100644 index 0000000..7d71f21 --- /dev/null +++ b/devtools-panels/devtools/panel/panel.html @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/devtools-panels/icons/star.png b/devtools-panels/icons/star.png new file mode 100644 index 0000000..64c4e36 Binary files /dev/null and b/devtools-panels/icons/star.png differ diff --git a/devtools-panels/manifest.json b/devtools-panels/manifest.json new file mode 100644 index 0000000..4723098 --- /dev/null +++ b/devtools-panels/manifest.json @@ -0,0 +1,22 @@ +{ + "description": "Adds a new panel to the developer tools. The panel contains buttons that demonstrate various basic features of the devtools API.", + "manifest_version": 2, + "name": "devtools-panels", + "version": "1.0", + "author": "Christophe Villeneuve", + "homepage_url": "https://github.com/mdn/webextensions-examples/tree/master/devtools-panels", + "icons": { + "48": "icons/star.png" + }, + + "background": { + "scripts": ["background_scripts/background.js"] + }, + + "permissions": [ + "headerURL:.A text paragraph
+{lastMessage.text}
} + + +