Merge pull request #244 from yfdyh000/travisCI

Add ESLint & Travis CI
This commit is contained in:
Andy McKay
2017-07-14 09:50:02 -07:00
committed by GitHub
33 changed files with 178 additions and 48 deletions

3
.eslintignore Normal file
View File

@@ -0,0 +1,3 @@
**/node_modules/**
react-es6-popup/**/dist
mocha-client-tests

22
.eslintrc.json Normal file
View File

@@ -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"]
}
}

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
node_modules

7
.travis.yml Normal file
View File

@@ -0,0 +1,7 @@
language: node_js
node_js:
- "8"
sudo: false
script:
- "npm test"

View File

@@ -1,4 +1,4 @@
# webextensions-examples # webextensions-examples [![Build Status](https://travis-ci.org/mdn/webextensions-examples.svg?branch=master)](https://travis-ci.org/mdn/webextensions-examples)
[https://github.com/mdn/webextensions-examples](https://github.com/mdn/webextensions-examples) [https://github.com/mdn/webextensions-examples](https://github.com/mdn/webextensions-examples)

View File

@@ -4,14 +4,14 @@ const contentBox = document.querySelector("#content");
/* /*
Make the content box editable as soon as the user mouses over the sidebar. 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); contentBox.setAttribute("contenteditable", true);
}); });
/* /*
When the user mouses out, save the current contents of the box. When the user mouses out, save the current contents of the box.
*/ */
window.addEventListener("mouseout", (e) => { window.addEventListener("mouseout", () => {
contentBox.setAttribute("contenteditable", false); contentBox.setAttribute("contenteditable", false);
browser.tabs.query({windowId: myWindowId, active: true}).then((tabs) => { browser.tabs.query({windowId: myWindowId, active: true}).then((tabs) => {
let contentToStore = {}; let contentToStore = {};

View File

@@ -51,7 +51,7 @@ When first loaded, initialize the page action for all tabs.
*/ */
var gettingAllTabs = browser.tabs.query({}); var gettingAllTabs = browser.tabs.query({});
gettingAllTabs.then((tabs) => { gettingAllTabs.then((tabs) => {
for (tab of tabs) { for (let tab of tabs) {
initializePageAction(tab); initializePageAction(tab);
} }
}); });

View File

@@ -69,6 +69,6 @@ browser.alarms.onAlarm.addListener((alarm) => {
/* /*
On page action click, navigate the corresponding tab to the cat gifs. 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}); browser.tabs.update({url: CATGIFS});
}); });

View File

@@ -12,7 +12,7 @@
*/ */
var gettingAllCommands = browser.commands.getAll(); var gettingAllCommands = browser.commands.getAll();
gettingAllCommands.then((commands) => { gettingAllCommands.then((commands) => {
for (command of commands) { for (let command of commands) {
console.log(command); console.log(command);
} }
}); });

View File

@@ -3,7 +3,7 @@ browser.contextMenus.create({
title: "Copy link to clipboard", title: "Copy link to clipboard",
contexts: ["link"], contexts: ["link"],
}); });
browser.contextMenus.onClicked.addListener(function(info, tab) { browser.contextMenus.onClicked.addListener((info, tab) => {
if (info.menuItemId === "copy-link-to-clipboard") { if (info.menuItemId === "copy-link-to-clipboard") {
// Examples: text and HTML to be copied. // Examples: text and HTML to be copied.
const text = "This is text: " + info.linkUrl; const text = "This is text: " + info.linkUrl;
@@ -22,7 +22,7 @@ browser.contextMenus.onClicked.addListener(function(info, tab) {
browser.tabs.executeScript({ browser.tabs.executeScript({
code: "typeof copyToClipboard === 'function';", code: "typeof copyToClipboard === 'function';",
}).then(function(results) { }).then((results) => {
// The content script's last expression will be true if the function // 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 // has been defined. If this is not the case, then we need to run
// clipboard-helper.js to define function copyToClipboard. // clipboard-helper.js to define function copyToClipboard.
@@ -31,11 +31,11 @@ browser.contextMenus.onClicked.addListener(function(info, tab) {
file: "clipboard-helper.js", file: "clipboard-helper.js",
}); });
} }
}).then(function() { }).then(() => {
return browser.tabs.executeScript(tab.id, { return browser.tabs.executeScript(tab.id, {
code, code,
}); });
}).catch(function(error) { }).catch((error) => {
// This could happen if the extension is not allowed to run code in // This could happen if the extension is not allowed to run code in
// the page, for example if the tab is a privileged page. // the page, for example if the tab is a privileged page.
console.error("Failed to copy text: " + error); console.error("Failed to copy text: " + error);

View File

@@ -2,7 +2,7 @@
Called when the item has been created, or when creation failed due to an error. Called when the item has been created, or when creation failed due to an error.
We'll just log success/failure here. We'll just log success/failure here.
*/ */
function onCreated(n) { function onCreated() {
if (browser.runtime.lastError) { if (browser.runtime.lastError) {
console.log(`Error: ${browser.runtime.lastError}`); console.log(`Error: ${browser.runtime.lastError}`);
} else { } else {
@@ -127,7 +127,7 @@ function updateCheckUncheck() {
The click event listener, where we perform the appropriate action given the The click event listener, where we perform the appropriate action given the
ID of the menu item that was clicked. ID of the menu item that was clicked.
*/ */
browser.contextMenus.onClicked.addListener(function(info, tab) { browser.contextMenus.onClicked.addListener((info, tab) => {
switch (info.menuItemId) { switch (info.menuItemId) {
case "log-selection": case "log-selection":
console.log(info.selectionText); console.log(info.selectionText);

View File

@@ -0,0 +1,8 @@
{
"env": {
"browser": true,
"es6": true,
"amd": true,
"webextensions": true
}
}

View File

@@ -0,0 +1,8 @@
{
"env": {
"browser": true,
"es6": true,
"amd": true,
"webextensions": true
}
}

View File

@@ -2,6 +2,8 @@
* This file contains the Map of word --> emoji substitutions. * This file contains the Map of word --> emoji substitutions.
*/ */
/* exported sortedEmojiMap */
let dictionary = new Map(); let dictionary = new Map();
dictionary.set('apple', '🍎'); dictionary.set('apple', '🍎');
dictionary.set('banana', '🍌'); dictionary.set('banana', '🍌');

View File

@@ -3,6 +3,8 @@
* all occurrences of each mapped word with its emoji counterpart. * all occurrences of each mapped word with its emoji counterpart.
*/ */
/*global sortedEmojiMap*/
// emojiMap.js defines the 'sortedEmojiMap' variable. // emojiMap.js defines the 'sortedEmojiMap' variable.
// Referenced here to reduce confusion. // Referenced here to reduce confusion.
const emojiMap = sortedEmojiMap; const emojiMap = sortedEmojiMap;

View File

@@ -1,3 +1,5 @@
/* exported getAccessToken */
const REDIRECT_URL = browser.identity.getRedirectURL(); const REDIRECT_URL = browser.identity.getRedirectURL();
const CLIENT_ID = "YOUR-CLIENT-ID"; const CLIENT_ID = "YOUR-CLIENT-ID";
const SCOPES = ["openid", "email", "profile"]; const SCOPES = ["openid", "email", "profile"];

View File

@@ -1,3 +1,5 @@
/*global getAccessToken*/
function notifyUser(user) { function notifyUser(user) {
browser.notifications.create({ browser.notifications.create({
"type": "basic", "type": "basic",

View File

@@ -2,6 +2,9 @@
Fetch the user's info, passing in the access token in the Authorization Fetch the user's info, passing in the access token in the Authorization
HTTP request header. HTTP request header.
*/ */
/* exported getUserInfo */
function getUserInfo(accessToken) { function getUserInfo(accessToken) {
const requestURL = "https://www.googleapis.com/oauth2/v1/userinfo?alt=json"; const requestURL = "https://www.googleapis.com/oauth2/v1/userinfo?alt=json";
const requestHeaders = new Headers(); const requestHeaders = new Headers();

View File

@@ -7,7 +7,7 @@ function get_hostname(url) {
} }
function set_domain(domain) { function set_domain(domain) {
spans = document.getElementsByClassName('domain'); const spans = document.getElementsByClassName('domain');
[].slice.call(spans).forEach((span) => { [].slice.call(spans).forEach((span) => {
span.textContent = domain; span.textContent = domain;
}); });
@@ -65,7 +65,7 @@ function clearAll(e) {
// Loop through them and delete them one by one. // Loop through them and delete them one by one.
var searchingHistory = browser.history.search({text: hostname}) var searchingHistory = browser.history.search({text: hostname})
searchingHistory.then((results) => { searchingHistory.then((results) => {
for (k = 0; k < results.length; k++) { for (let k of results) {
browser.history.deleteUrl({url: results[k].url}); browser.history.deleteUrl({url: results[k].url});
} }
// Clear out the UI. // Clear out the UI.

View File

@@ -1,6 +1,6 @@
function showCookiesForTab(tabs) { function showCookiesForTab(tabs) {
//get the first tab object in the array //get the first tab object in the array
tab = tabs.pop(); let tab = tabs.pop();
//get all cookies in the domain //get all cookies in the domain
var gettingAllCookies = browser.cookies.getAll({url: tab.url}); var gettingAllCookies = browser.cookies.getAll({url: tab.url});
@@ -14,22 +14,22 @@ function showCookiesForTab(tabs) {
if (cookies.length > 0) { if (cookies.length > 0) {
//add an <li> item with the name and value of the cookie to the list //add an <li> item with the name and value of the cookie to the list
for (cookie of cookies) { for (let cookie of cookies) {
var li = document.createElement("li"); let li = document.createElement("li");
var content = document.createTextNode(cookie.name + ": "+ cookie.value); let content = document.createTextNode(cookie.name + ": "+ cookie.value);
li.appendChild(content); li.appendChild(content);
cookieList.appendChild(li); cookieList.appendChild(li);
} }
} else { } else {
var p = document.createElement("p"); let p = document.createElement("p");
var content = document.createTextNode("No cookies in this tab."); let content = document.createTextNode("No cookies in this tab.");
var parent = cookieList.parentNode; let parent = cookieList.parentNode;
p.appendChild(content); p.appendChild(content);
parent.appendChild(p); parent.appendChild(p);
} }
}); });
}; }
//get active tab to run an callback function. //get active tab to run an callback function.
//it sends to our callback an array of tab objects //it sends to our callback an array of tab objects

View File

@@ -0,0 +1,8 @@
{
"env": {
"browser": true,
"es6": true,
"amd": true,
"webextensions": true
}
}

32
package.json Normal file
View File

@@ -0,0 +1,32 @@
{
"name": "webextensions-examples",
"title": "WebExtensions Examples",
"version": "1.0.0",
"description": "Example Firefox add-ons created using the WebExtensions API",
"devDependencies": {
"eslint": "^3.19.0"
},
"repository": {
"type": "git",
"url": "git+https://github.com/mdn/webextensions-examples.git"
},
"scripts": {
"test": "eslint .",
"lint": "eslint ."
},
"license": "MIT",
"bugs": {
"url": "https://github.com/mdn/webextensions-examples/issues"
},
"keywords": [
"webextensions",
"webextensions-apis",
"mdn",
"firefox",
"mozilla"
],
"homepage": "https://developer.mozilla.org/Add-ons/WebExtensions/Examples",
"dependencies": {
"babel-eslint": "^7.2.3"
}
}

View File

@@ -2,7 +2,7 @@
Listen for messages from the page. Listen for messages from the page.
If the message was from the page script, show an alert. If the message was from the page script, show an alert.
*/ */
window.addEventListener("message", function(event) { window.addEventListener("message", (event) => {
if (event.source == window && if (event.source == window &&
event.data && event.data &&
event.data.direction == "from-page-script") { event.data.direction == "from-page-script") {

View File

@@ -0,0 +1,5 @@
{
"parserOptions": {
"ecmaVersion": 8
}
}

View File

@@ -15,7 +15,7 @@ browser.proxy.onProxyError.addListener(error => {
}); });
// Initialize the proxy // Initialize the proxy
function handleInit(message) { function handleInit() {
// update the proxy whenever stored settings change // update the proxy whenever stored settings change
browser.storage.onChanged.addListener((newSettings) => { browser.storage.onChanged.addListener((newSettings) => {
browser.runtime.sendMessage(newSettings.blockedHosts.newValue, {toProxyScript: true}); browser.runtime.sendMessage(newSettings.blockedHosts.newValue, {toProxyScript: true});

View File

@@ -1,3 +1,5 @@
/* exported FindProxyForURL */
var blockedHosts = []; var blockedHosts = [];
const allow = "DIRECT 1234"; const allow = "DIRECT 1234";
const deny = "PROXY 127.0.0.1:65535"; const deny = "PROXY 127.0.0.1:65535";

View File

@@ -27,7 +27,7 @@ function initialize() {
var gettingAllStorageItems = browser.storage.local.get(null); var gettingAllStorageItems = browser.storage.local.get(null);
gettingAllStorageItems.then((results) => { gettingAllStorageItems.then((results) => {
var noteKeys = Object.keys(results); var noteKeys = Object.keys(results);
for(noteKey of noteKeys) { for (let noteKey of noteKeys) {
var curValue = results[noteKey]; var curValue = results[noteKey];
displayNote(noteKey,curValue); displayNote(noteKey,curValue);
} }
@@ -88,8 +88,8 @@ function displayNote(title, body) {
/* set up listener for the delete functionality */ /* set up listener for the delete functionality */
deleteBtn.addEventListener('click',function(e){ deleteBtn.addEventListener('click',(e) => {
evtTgt = e.target; const evtTgt = e.target;
evtTgt.parentNode.parentNode.parentNode.removeChild(evtTgt.parentNode.parentNode); evtTgt.parentNode.parentNode.parentNode.removeChild(evtTgt.parentNode.parentNode);
browser.storage.local.remove(title); browser.storage.local.remove(title);
}) })
@@ -125,24 +125,24 @@ function displayNote(title, body) {
/* set up listeners for the update functionality */ /* set up listeners for the update functionality */
noteH.addEventListener('click',function(){ noteH.addEventListener('click',() => {
noteDisplay.style.display = 'none'; noteDisplay.style.display = 'none';
noteEdit.style.display = 'block'; noteEdit.style.display = 'block';
}) })
notePara.addEventListener('click',function(){ notePara.addEventListener('click',() => {
noteDisplay.style.display = 'none'; noteDisplay.style.display = 'none';
noteEdit.style.display = 'block'; noteEdit.style.display = 'block';
}) })
cancelBtn.addEventListener('click',function(){ cancelBtn.addEventListener('click',() => {
noteDisplay.style.display = 'block'; noteDisplay.style.display = 'block';
noteEdit.style.display = 'none'; noteEdit.style.display = 'none';
noteTitleEdit.value = title; noteTitleEdit.value = title;
noteBodyEdit.value = body; noteBodyEdit.value = body;
}) })
updateBtn.addEventListener('click',function(){ updateBtn.addEventListener('click',() => {
if(noteTitleEdit.value !== title || noteBodyEdit.value !== body) { if(noteTitleEdit.value !== title || noteBodyEdit.value !== body) {
updateNote(title,noteTitleEdit.value,noteBodyEdit.value); updateNote(title,noteTitleEdit.value,noteBodyEdit.value);
note.parentNode.removeChild(note); note.parentNode.removeChild(note);

View File

@@ -0,0 +1,15 @@
{
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
}
},
"env": {
"browser": true,
"es6": true,
"amd": true,
"webextensions": true
}
}

View File

@@ -1,7 +1,7 @@
/* /*
copy the selected text to clipboard copy the selected text to clipboard
*/ */
function copySelection(e) { function copySelection() {
var selectedText = window.getSelection().toString().trim(); var selectedText = window.getSelection().toString().trim();
if (selectedText) { if (selectedText) {

View File

@@ -47,7 +47,7 @@ function getCurrentWindowTabs() {
return browser.tabs.query({currentWindow: true}); return browser.tabs.query({currentWindow: true});
} }
document.addEventListener("click", function(e) { document.addEventListener("click", (e) => {
function callOnActiveTab(callback) { function callOnActiveTab(callback) {
getCurrentWindowTabs().then((tabs) => { getCurrentWindowTabs().then((tabs) => {
for (var tab of tabs) { for (var tab of tabs) {
@@ -163,7 +163,7 @@ document.addEventListener("click", function(e) {
// Currently (11/2/2016) only supported by Chrome // Currently (11/2/2016) only supported by Chrome
else if (e.target.id === "tabs-highlight") { // highlights current tab and next tab (cycles back to first tab if current tab is the last one) else if (e.target.id === "tabs-highlight") { // highlights current tab and next tab (cycles back to first tab if current tab is the last one)
callOnActiveTab((tab, tabs) => { callOnActiveTab((tab, tabs) => {
next = (tab.index+1) % tabs.length; let next = (tab.index+1) % tabs.length;
browser.tabs.highlight({tabs:[tab.index, next]}); browser.tabs.highlight({tabs:[tab.index, next]});
}); });
} }
@@ -173,7 +173,7 @@ document.addEventListener("click", function(e) {
chrome.tabs.query({ chrome.tabs.query({
currentWindow: true currentWindow: true
}, function(tabs) { }, (tabs) => {
for (var tab of tabs) { for (var tab of tabs) {
if (tab.id === tabId) { if (tab.id === tabId) {
chrome.tabs.update(tabId, { chrome.tabs.update(tabId, {
@@ -188,7 +188,7 @@ document.addEventListener("click", function(e) {
}); });
//onRemoved listener. fired when tab is removed //onRemoved listener. fired when tab is removed
browser.tabs.onRemoved.addListener(function(tabId, removeInfo){ browser.tabs.onRemoved.addListener((tabId, removeInfo) => {
console.log(`The tab with id: ${tabId}, is closing`); console.log(`The tab with id: ${tabId}, is closing`);
if(removeInfo.isWindowClosing) { if(removeInfo.isWindowClosing) {
@@ -199,7 +199,7 @@ browser.tabs.onRemoved.addListener(function(tabId, removeInfo){
}); });
//onMoved listener. fired when tab is moved into the same window //onMoved listener. fired when tab is moved into the same window
browser.tabs.onMoved.addListener(function(tabId, moveInfo){ browser.tabs.onMoved.addListener((tabId, moveInfo) => {
var startIndex = moveInfo.fromIndex; var startIndex = moveInfo.fromIndex;
var endIndex = moveInfo.toIndex; var endIndex = moveInfo.toIndex;
console.log(`Tab with id: ${tabId} moved from index: ${startIndex} to index: ${endIndex}`); console.log(`Tab with id: ${tabId} moved from index: ${startIndex} to index: ${endIndex}`);

View File

@@ -4,7 +4,7 @@ If the user clicks on an element which has the class "ua-choice":
* fetch the element's textContent: for example, "IE 11" * fetch the element's textContent: for example, "IE 11"
* pass it into the background page's setUaString() function * pass it into the background page's setUaString() function
*/ */
document.addEventListener("click", function(e) { document.addEventListener("click", (e) => {
if (!e.target.classList.contains("ua-choice")) { if (!e.target.classList.contains("ua-choice")) {
return; return;
} }

View File

@@ -0,0 +1,8 @@
{
"env": {
"browser": true,
"es6": true,
"amd": true,
"webextensions": true
}
}

View File

@@ -26,48 +26,48 @@ document.addEventListener("click", (e) => {
} }
else if (e.target.id === "window-create-normal") { else if (e.target.id === "window-create-normal") {
var createData = {}; let createData = {};
var creating = browser.windows.create(createData); let creating = browser.windows.create(createData);
creating.then(() => { creating.then(() => {
console.log("The normal window has been created"); console.log("The normal window has been created");
}); });
} }
else if (e.target.id === "window-create-incognito") { else if (e.target.id === "window-create-incognito") {
var createData = { let createData = {
incognito: true, incognito: true,
}; };
var creating = browser.windows.create(createData); let creating = browser.windows.create(createData);
creating.then(() => { creating.then(() => {
console.log("The incognito window has been created"); console.log("The incognito window has been created");
}); });
} }
else if (e.target.id === "window-create-panel") { else if (e.target.id === "window-create-panel") {
var createData = { let createData = {
type: "panel", type: "panel",
}; };
var creating = browser.windows.create(createData); let creating = browser.windows.create(createData);
creating.then(() => { creating.then(() => {
console.log("The panel has been created"); console.log("The panel has been created");
}); });
} }
else if (e.target.id === "window-create-detached-panel") { else if (e.target.id === "window-create-detached-panel") {
var createData = { let createData = {
type: "detached_panel", type: "detached_panel",
}; };
var creating = browser.windows.create(createData); let creating = browser.windows.create(createData);
creating.then(() => { creating.then(() => {
console.log("The detached panel has been created"); console.log("The detached panel has been created");
}); });
} }
else if (e.target.id === "window-create-popup") { else if (e.target.id === "window-create-popup") {
var createData = { let createData = {
type: "popup", type: "popup",
}; };
var creating = browser.windows.create(createData); let creating = browser.windows.create(createData);
creating.then(() => { creating.then(() => {
console.log("The popup has been created"); console.log("The popup has been created");
}); });