--- a/browser/components/originattributes/test/browser/worker_deblobify.js
+++ b/browser/components/originattributes/test/browser/worker_deblobify.js
@@ -1,12 +1,14 @@
// Wait for a blob URL to be posted to this worker.
// Obtain the blob, and read the string contained in it.
// Post back the string.
+/* eslint-env worker */
+
var postStringInBlob = function(blobObject) {
var fileReader = new FileReaderSync();
var result = fileReader.readAsText(blobObject);
postMessage(result);
};
self.addEventListener("message", function(message) {
if ("error" in message.data) {
--- a/devtools/server/worker.js
+++ b/devtools/server/worker.js
@@ -1,15 +1,15 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
-/* eslint-env worker */
+/* eslint-env mozilla/chrome-worker */
/* global worker, loadSubScript, global */
// This function is used to do remote procedure calls from the worker to the
// main thread. It is exposed as a built-in global to every module by the
// worker loader. To make sure the worker loader can access it, it needs to be
// defined before loading the worker loader script below.
this.rpc = function (method, ...params) {
let id = nextId++;
--- a/toolkit/components/ctypes/tests/chrome/ctypes_worker.js
+++ b/toolkit/components/ctypes/tests/chrome/ctypes_worker.js
@@ -1,14 +1,17 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+ /* eslint-env mozilla/chrome-worker */
+
importScripts("xpcshellTestHarnessAdaptor.js");
onmessage = function(event) {
_WORKINGDIR_ = event.data.dir;
_OS_ = event.data.os;
+ /* import-globals-from ../unit/test_jsctypes.js */
importScripts("test_jsctypes.js");
run_test();
postMessage("Done!");
}
--- a/toolkit/components/lz4/lz4.js
+++ b/toolkit/components/lz4/lz4.js
@@ -13,31 +13,29 @@ if (typeof Components != "undefined") {
Cu.import("resource://gre/modules/lz4_internal.js");
Cu.import("resource://gre/modules/ctypes.jsm");
this.EXPORTED_SYMBOLS = [
"Lz4"
];
this.exports = {};
} else if (typeof module != "undefined" && typeof require != "undefined") {
+ /* eslint-env commonjs */
SharedAll = require("resource://gre/modules/osfile/osfile_shared_allthreads.jsm");
Primitives = require("resource://gre/modules/lz4_internal.js");
} else {
throw new Error("Please load this module with Component.utils.import or with require()");
}
const MAGIC_NUMBER = new Uint8Array([109, 111, 122, 76, 122, 52, 48, 0]); // "mozLz4a\0"
const BYTES_IN_SIZE_HEADER = ctypes.uint32_t.size;
const HEADER_SIZE = MAGIC_NUMBER.byteLength + BYTES_IN_SIZE_HEADER;
-const EXPECTED_HEADER_TYPE = new ctypes.ArrayType(ctypes.uint8_t, HEADER_SIZE);
-const EXPECTED_SIZE_BUFFER_TYPE = new ctypes.ArrayType(ctypes.uint8_t, BYTES_IN_SIZE_HEADER);
-
/**
* An error during (de)compression
*
* @param {string} operation The name of the operation ("compress", "decompress")
* @param {string} reason A reason to be used when matching errors. Must start
* with "because", e.g. "becauseInvalidContent".
* @param {string} message A human-readable message.
*/
--- a/toolkit/components/lz4/lz4_internal.js
+++ b/toolkit/components/lz4/lz4_internal.js
@@ -1,12 +1,14 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
+ /* eslint-env commonjs */
+
"use strict";
var Primitives = {};
var SharedAll;
if (typeof Components != "undefined") {
let Cu = Components.utils;
SharedAll = {};
--- a/toolkit/components/lz4/tests/xpcshell/data/worker_lz4.js
+++ b/toolkit/components/lz4/tests/xpcshell/data/worker_lz4.js
@@ -1,8 +1,10 @@
+/* eslint-env mozilla/chrome-worker */
+
importScripts("resource://gre/modules/workers/require.js");
importScripts("resource://gre/modules/osfile.jsm");
function do_print(x) {
// self.postMessage({kind: "do_print", args: [x]});
dump("TEST-INFO: " + x + "\n");
}
--- a/toolkit/components/places/ColorAnalyzer_worker.js
+++ b/toolkit/components/places/ColorAnalyzer_worker.js
@@ -1,12 +1,14 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/* eslint-env mozilla/chrome-worker */
+
"use strict";
importScripts("ClusterLib.js", "ColorConversion.js");
// Offsets in the ImageData pixel array to reach pixel colors
const PIXEL_RED = 0;
const PIXEL_GREEN = 1;
const PIXEL_BLUE = 2;
--- a/toolkit/components/promiseworker/tests/xpcshell/data/worker.js
+++ b/toolkit/components/promiseworker/tests/xpcshell/data/worker.js
@@ -1,11 +1,13 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
+/* eslint-env mozilla/chrome-worker */
+
"use strict";
// Trivial worker definition
importScripts("resource://gre/modules/workers/require.js");
var PromiseWorker = require("resource://gre/modules/workers/PromiseWorker.js");
var worker = new PromiseWorker.AbstractWorker();
--- a/toolkit/components/promiseworker/worker/PromiseWorker.js
+++ b/toolkit/components/promiseworker/worker/PromiseWorker.js
@@ -1,12 +1,14 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
+/* eslint-env commonjs, mozilla/chrome-worker */
+
/**
* A wrapper around `self` with extended capabilities designed
* to simplify main thread-to-worker thread asynchronous function calls.
*
* This wrapper:
* - groups requests and responses as a method `post` that returns a `Promise`;
* - ensures that exceptions thrown on the worker thread are correctly serialized;
* - provides some utilities for benchmarking various operations.
--- a/toolkit/components/reader/ReaderWorker.js
+++ b/toolkit/components/reader/ReaderWorker.js
@@ -1,12 +1,14 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
+/* eslint-env mozilla/chrome-worker */
+
"use strict";
/**
* A worker dedicated to handle parsing documents for reader view.
*/
importScripts("resource://gre/modules/workers/require.js",
"resource://gre/modules/reader/JSDOMParser.js",
--- a/toolkit/components/sqlite/sqlite_internal.js
+++ b/toolkit/components/sqlite/sqlite_internal.js
@@ -1,12 +1,14 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/* eslint-env commonjs, mozilla/chrome-worker */
+
/**
* This file defines an Sqlite object containing js-ctypes bindings for
* sqlite3. It should be included from a worker thread using require.
*
* It serves the following purposes:
* - opens libxul;
* - defines sqlite3 API functions;
* - defines the necessary sqlite3 types.
--- a/toolkit/components/sqlite/tests/xpcshell/data/worker_sqlite_internal.js
+++ b/toolkit/components/sqlite/tests/xpcshell/data/worker_sqlite_internal.js
@@ -1,11 +1,13 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
+/* eslint-env mozilla/chrome-worker */
+
importScripts("worker_sqlite_shared.js",
"resource://gre/modules/workers/require.js");
self.onmessage = function onmessage(msg) {
try {
run_test();
} catch (ex) {
let {message, moduleStack, moduleName, lineNumber} = ex;
--- a/toolkit/components/thumbnails/PageThumbsWorker.js
+++ b/toolkit/components/thumbnails/PageThumbsWorker.js
@@ -1,12 +1,14 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
+/* eslint-env mozilla/chrome-worker */
+
/**
* A worker dedicated for the I/O component of PageThumbs storage.
*
* Do not rely on the API of this worker. In a future version, it might be
* fully replaced by a OS.File global I/O worker.
*/
"use strict";
@@ -168,9 +170,8 @@ var Agent = {
iterator.close();
}
},
exists: function Agent_exists(path) {
return File.exists(path);
},
};
-
--- a/toolkit/components/workerloader/tests/moduleA-depends.js
+++ b/toolkit/components/workerloader/tests/moduleA-depends.js
@@ -1,11 +1,13 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
+/* eslint-env commonjs */
+
// A trivial module that depends on an equally trivial module
var B = require("chrome://mochitests/content/chrome/toolkit/components/workerloader/tests/moduleB-dependency.js");
// Ensure that the initial set of exports is empty
if (Object.keys(exports).length) {
throw new Error("exports should be empty, initially");
}
--- a/toolkit/components/workerloader/tests/moduleB-dependency.js
+++ b/toolkit/components/workerloader/tests/moduleB-dependency.js
@@ -1,11 +1,13 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
+/* eslint-env commonjs */
+
exports.B = true;
exports.foo = "foo";
// Side-effect to detect if we attempt to re-execute this module.
if ("loadedB" in self) {
throw new Error("B has been evaluted twice");
}
self.loadedB = true;
--- a/toolkit/components/workerloader/tests/moduleC-circular.js
+++ b/toolkit/components/workerloader/tests/moduleC-circular.js
@@ -1,11 +1,13 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
+/* eslint-env commonjs */
+
// Module C and module D have circular dependencies.
// This should not prevent from loading them.
// This value is set before any circular dependency, it should be visible
// in D.
exports.enteredC = true;
var D = require("chrome://mochitests/content/chrome/toolkit/components/workerloader/tests/moduleD-circular.js");
--- a/toolkit/components/workerloader/tests/moduleD-circular.js
+++ b/toolkit/components/workerloader/tests/moduleD-circular.js
@@ -1,11 +1,13 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
+/* eslint-env commonjs */
+
// Module C and module D have circular dependencies.
// This should not prevent from loading them.
exports.enteredD = true;
var C = require("chrome://mochitests/content/chrome/toolkit/components/workerloader/tests/moduleC-circular.js");
exports.copiedFromC = JSON.parse(JSON.stringify(C));
exports.exportedFromC = C;
exports.finishedD = true;
--- a/toolkit/components/workerloader/tests/moduleE-throws-during-require.js
+++ b/toolkit/components/workerloader/tests/moduleE-throws-during-require.js
@@ -1,10 +1,12 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
+/* eslint-env commonjs */
+
// Skip a few lines
// 5
// 6
// 7
// 8
// 9
throw new Error("Let's see if this error is obtained with the right origin");
--- a/toolkit/components/workerloader/tests/moduleG-throws-later.js
+++ b/toolkit/components/workerloader/tests/moduleG-throws-later.js
@@ -1,11 +1,13 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
+/* eslint-env commonjs */
+
// Skip a few lines
// 5
// 6
// 7
// 8
// 9
exports.doThrow = function doThrow() {
Array.prototype.sort.apply("foo"); // This will raise a native TypeError
--- a/toolkit/components/workerloader/tests/moduleH-module-dot-exports.js
+++ b/toolkit/components/workerloader/tests/moduleH-module-dot-exports.js
@@ -1,11 +1,13 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
+/* eslint-env commonjs */
+
// This should be overwritten by module.exports
exports.key = "wrong value";
module.exports = {
key: "value"
};
// This should also be overwritten by module.exports
--- a/toolkit/components/workerloader/tests/worker_test_loading.js
+++ b/toolkit/components/workerloader/tests/worker_test_loading.js
@@ -1,11 +1,13 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
+/* eslint-env mozilla/chrome-worker */
+
"use strict";
importScripts("utils_worker.js"); // Test suite code
info("Test suite configured");
importScripts("resource://gre/modules/workers/require.js");
info("Loader imported");
@@ -60,29 +62,29 @@ add_test(function test_exceptions() {
ok(!!exn, "Attempting to load a module that doesn't exist raises an error");
exn = should_throw(() => require(PATH + "moduleE-throws-during-require.js"));
ok(!!exn, "Attempting to load a module that throws at toplevel raises an error");
is(exn.moduleName, PATH + "moduleE-throws-during-require.js",
"moduleName is correct");
isnot(exn.moduleStack.indexOf("moduleE-throws-during-require.js"), -1,
"moduleStack contains the name of the module");
- is(exn.lineNumber, 10, "The error comes with the right line number");
+ is(exn.lineNumber, 12, "The error comes with the right line number");
exn = should_throw(() => require(PATH + "moduleF-syntaxerror.xml"));
ok(!!exn, "Attempting to load a non-well formatted module raises an error");
exn = should_throw(() => require(PATH + "moduleG-throws-later.js").doThrow());
ok(!!exn, "G.doThrow() has raised an error");
info(exn);
ok(exn.toString().startsWith("TypeError"), "The exception is a TypeError.");
is(exn.moduleName, PATH + "moduleG-throws-later.js", "The name of the module is correct");
isnot(exn.moduleStack.indexOf("moduleG-throws-later.js"), -1,
"The name of the right file appears somewhere in the stack");
- is(exn.lineNumber, 11, "The error comes with the right line number");
+ is(exn.lineNumber, 13, "The error comes with the right line number");
});
function get_exn(f) {
try {
f();
return undefined;
} catch (ex) {
return ex;
@@ -111,11 +113,8 @@ self.onmessage = function(message) {
ok(false, "Test " + test.name + " failed");
info(ex);
info(ex.stack);
}
info("Leaving " + test.name);
}
finish();
};
-
-
-
--- a/tools/lint/docs/linters/eslint-plugin-mozilla.rst
+++ b/tools/lint/docs/linters/eslint-plugin-mozilla.rst
@@ -1,12 +1,24 @@
=====================
Mozilla ESLint Plugin
=====================
+Environments
+============
+
+chrome-worker
+-------------
+
+Defines the environment for chrome workers. This differs from normal workers by
+the fact that `ctypes` can be accessed as well.
+
+Rules
+=====
+
avoid-removeChild
-----------------
Rejects using element.parentNode.removeChild(element) when element.remove()
can be used instead.
balanced-listeners
------------------
new file mode 100644
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/environments/chrome-worker.js
@@ -0,0 +1,22 @@
+/**
+ * @fileoverview Defines the environment for chrome workers. This differs
+ * from normal workers by the fact that `ctypes` can be accessed
+ * as well.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+"use strict";
+
+var globals = require('globals');
+var util = require('util');
+
+var workerGlobals = util._extend({
+ ctypes: false
+}, globals.worker);
+
+module.exports = {
+ globals: workerGlobals
+};
--- a/tools/lint/eslint/eslint-plugin-mozilla/lib/globals.js
+++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/globals.js
@@ -67,64 +67,48 @@ const globalCache = new Map();
*
* @param {String} filePath
* The absolute path of the file being parsed.
*/
function GlobalsForNode(filePath) {
this.path = filePath;
this.dirname = path.dirname(this.path)
this.root = helpers.getRootDir(this.path);
- this.isWorker = helpers.getIsWorker(this.path);
}
GlobalsForNode.prototype = {
- Program(node) {
- if (!this.isWorker) {
- return [];
- }
-
- return [
- {name: "importScripts", writable: false},
- // Only available to workers.
- {name: "FileReaderSync", writable: false},
- {name: "onmessage", writable: true},
- // Only available to chrome workers, but since we don't know which is which,
- // we make it available anyway.
- {name: "ctypes", writable: false}
- ];
- },
-
BlockComment(node, parents) {
let value = node.value.trim();
let match = /^import-globals-from\s+(.+)$/.exec(value);
if (!match) {
return [];
}
let filePath = match[1].trim();
if (!path.isAbsolute(filePath)) {
filePath = path.resolve(this.dirname, filePath);
}
return module.exports.getGlobalsForFile(filePath);
},
- ExpressionStatement(node, parents) {
+ ExpressionStatement(node, parents, globalScope) {
let isGlobal = helpers.getIsGlobalScope(parents);
let globals = helpers.convertExpressionToGlobals(node, isGlobal, this.root);
// Map these globals now, as getGlobalsForFile is pre-mapped.
globals = globals.map(name => { return { name, writable: true }});
- if (this.isWorker) {
+ // Here we assume that if importScripts is set in the global scope, then
+ // this is a worker. It would be nice if eslint gave us a way of getting
+ // the environment directly.
+ if (globalScope && globalScope.set.get("importScripts")) {
let workerDetails = helpers.convertWorkerExpressionToGlobals(node,
isGlobal, this.root, this.dirname);
- globals = globals.concat(workerDetails.map(name => {
- return { name, writable: true };
- }));
+ globals = globals.concat(workerDetails);
}
return globals;
},
};
module.exports = {
/**
@@ -177,17 +161,17 @@ module.exports = {
name,
writable: values[name].value
})
}
}
}
if (type in handler) {
- let newGlobals = handler[type](node, parents);
+ let newGlobals = handler[type](node, parents, globalScope);
globals.push.apply(globals, newGlobals);
}
});
globalCache.set(path, globals);
return globals;
},
@@ -211,16 +195,16 @@ module.exports = {
// Install thin wrappers around GlobalsForNode
let handler = new GlobalsForNode(helpers.getAbsoluteFilePath(context));
for (let type of Object.keys(GlobalsForNode.prototype)) {
parser[type] = function(node) {
if (type === "Program") {
globalScope = context.getScope();
}
- let globals = handler[type](node, context.getAncestors());
+ let globals = handler[type](node, context.getAncestors(), globalScope);
helpers.addGlobals(globals, globalScope);
}
}
return parser;
}
};
--- a/tools/lint/eslint/eslint-plugin-mozilla/lib/helpers.js
+++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/helpers.js
@@ -165,17 +165,21 @@ module.exports = {
* @param {Object} node
* The AST node to convert.
* @param {boolean} isGlobal
* True if the current node is in the global scope.
* @param {String} repository
* The root of the repository.
*
* @return {Array}
- * An array of global variable names defined.
+ * An array of objects that contain details about the globals:
+ * - {String} name
+ * The name of the global.
+ * - {Boolean} writable
+ * If the global is writeable or not.
*/
convertWorkerExpressionToGlobals: function(node, isGlobal, repository, dirname) {
var getGlobalsForFile = require("./globals").getGlobalsForFile;
if (!modules) {
modules = require(path.join(repository, "tools", "lint", "eslint", "modules.json"));
}
@@ -191,21 +195,24 @@ module.exports = {
if (match) {
if (!match[1]) {
let filePath = path.resolve(dirname, match[2]);
if (fs.existsSync(filePath)) {
let additionalGlobals = getGlobalsForFile(filePath);
results = results.concat(additionalGlobals);
}
} else if (match[2] in modules) {
- results.push(modules[match[2]]);
+ results = results.concat(modules[match[2]].map(name => {
+ return { name, writable: true };
+ }));
}
}
}
}
+
return results;
},
convertExpressionToGlobals: function(node, isGlobal, repository) {
if (!modules) {
modules = require(path.join(repository, "tools", "lint", "eslint", "modules.json"));
}
--- a/tools/lint/eslint/eslint-plugin-mozilla/lib/index.js
+++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/index.js
@@ -8,16 +8,19 @@
"use strict";
//------------------------------------------------------------------------------
// Plugin Definition
//------------------------------------------------------------------------------
module.exports = {
+ environments: {
+ "chrome-worker": require("../lib/environments/chrome-worker.js"),
+ },
processors: {
".xml": require("../lib/processors/xbl-bindings"),
".js": require("../lib/processors/self-hosted"),
},
rules: {
"avoid-removeChild": require("../lib/rules/avoid-removeChild"),
"balanced-listeners": require("../lib/rules/balanced-listeners"),
"import-browserjs-globals": require("../lib/rules/import-browserjs-globals"),
--- a/tools/lint/eslint/eslint-plugin-mozilla/package.json
+++ b/tools/lint/eslint/eslint-plugin-mozilla/package.json
@@ -1,11 +1,11 @@
{
"name": "eslint-plugin-mozilla",
- "version": "0.2.20",
+ "version": "0.2.21",
"description": "A collection of rules that help enforce JavaScript coding standard in the Mozilla project.",
"keywords": [
"eslint",
"eslintplugin",
"eslint-plugin",
"mozilla",
"firefox"
],
@@ -14,16 +14,17 @@
},
"homepage": "https://bugzilla.mozilla.org/show_bug.cgi?id=1203520",
"author": "Mike Ratcliffe",
"main": "lib/index.js",
"dependencies": {
"escope": "^3.6.0",
"espree": "^3.2.0",
"estraverse": "^4.2.0",
+ "globals": "^9.14.0",
"ini-parser": "^0.0.2",
"sax": "^1.1.4"
},
"engines": {
"node": ">=0.10.0"
},
"scripts": {
"test": "node tests/test-run-all.js"