diff --git a/addon-sdk/source/app-extension/bootstrap.js b/addon-sdk/source/app-extension/bootstrap.js index 49d0f97373e7..87b3a9c24ec0 100644 --- a/addon-sdk/source/app-extension/bootstrap.js +++ b/addon-sdk/source/app-extension/bootstrap.js @@ -354,7 +354,6 @@ function nukeModules() { // the addon is unload. unloadSandbox(cuddlefishSandbox.loaderSandbox); - unloadSandbox(cuddlefishSandbox.xulappSandbox); // Bug 764840: We need to unload cuddlefish otherwise it will stay alive // and keep a reference to this compartment. diff --git a/addon-sdk/source/bin/jpm-test.js b/addon-sdk/source/bin/jpm-test.js index 3b83639d1377..f9836e10234a 100644 --- a/addon-sdk/source/bin/jpm-test.js +++ b/addon-sdk/source/bin/jpm-test.js @@ -3,8 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ "use strict"; -var readParam = require("./node-scripts/utils").readParam; -var path = require("path"); +var Promise = require("promise"); var Mocha = require("mocha"); var mocha = new Mocha({ ui: "bdd", @@ -12,16 +11,19 @@ var mocha = new Mocha({ timeout: 900000 }); -var type = readParam("type"); +exports.run = function(type) { + return new Promise(function(resolve) { + type = type || ""; + [ + (/^(modules)?$/.test(type)) && require.resolve("../bin/node-scripts/test.modules"), + (/^(addons)?$/.test(type)) && require.resolve("../bin/node-scripts/test.addons"), + (/^(examples)?$/.test(type)) && require.resolve("../bin/node-scripts/test.examples"), + ].sort().forEach(function(filepath) { + filepath && mocha.addFile(filepath); + }) -[ - (!type || type == "modules") && require.resolve("../bin/node-scripts/test.modules"), - (!type || type == "addons") && require.resolve("../bin/node-scripts/test.addons"), - (!type || type == "examples") && require.resolve("../bin/node-scripts/test.examples"), -].sort().forEach(function(filepath) { - filepath && mocha.addFile(filepath); -}) - -mocha.run(function (failures) { - process.exit(failures); -}); + mocha.run(function(failures) { + resolve(failures); + }); + }); +} diff --git a/addon-sdk/source/examples/debug-client/data/client.js b/addon-sdk/source/examples/debug-client/data/client.js index 022f9a1c35c6..baec09105320 100644 --- a/addon-sdk/source/examples/debug-client/data/client.js +++ b/addon-sdk/source/examples/debug-client/data/client.js @@ -202,7 +202,7 @@ var Connection = Class({ }, poolFor: function(id) { for (let pool of this.pools.values()) { - if (pool.has(id)) + if pool.has(id) return pool; } }, @@ -797,7 +797,7 @@ var Tab = Client.from({ "storageActor": "storage", "gcliActor": "gcli", "memoryActor": "memory", - "eventLoopLag": "eventLoopLag", + "eventLoopLag": "eventLoopLag" "trace": "trace", // missing } diff --git a/addon-sdk/source/gulpfile.js b/addon-sdk/source/gulpfile.js new file mode 100644 index 000000000000..fc1b89e79d93 --- /dev/null +++ b/addon-sdk/source/gulpfile.js @@ -0,0 +1,23 @@ +/* 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 gulp = require('gulp'); + +gulp.task('test', function(done) { + require("./bin/jpm-test").run().then(done); +}); + +gulp.task('test:addons', function(done) { + require("./bin/jpm-test").run("addons").then(done); +}); + +gulp.task('test:examples', function(done) { + require("./bin/jpm-test").run("examples").then(done); +}); + +gulp.task('test:modules', function(done) { + require("./bin/jpm-test").run("modules").then(done); +}); + diff --git a/addon-sdk/source/lib/sdk/content/l10n-html.js b/addon-sdk/source/lib/sdk/content/l10n-html.js index ccb1551027ec..cf0aae941dd3 100644 --- a/addon-sdk/source/lib/sdk/content/l10n-html.js +++ b/addon-sdk/source/lib/sdk/content/l10n-html.js @@ -16,6 +16,31 @@ const assetsURI = require('../self').data.url(); const hideSheetUri = "data:text/css,:root {visibility: hidden !important;}"; +function translateElementAttributes(element) { + // Translateable attributes + const attrList = ['title', 'accesskey', 'alt', 'label', 'placeholder']; + const ariaAttrMap = { + 'ariaLabel': 'aria-label', + 'ariaValueText': 'aria-valuetext', + 'ariaMozHint': 'aria-moz-hint' + }; + const attrSeparator = '.'; + + // Try to translate each of the attributes + for (let attribute of attrList) { + const data = core.get(element.dataset.l10nId + attrSeparator + attribute); + if (data) + element.setAttribute(attribute, data); + } + + // Look for the aria attribute translations that match fxOS's aliases + for (let attrAlias in ariaAttrMap) { + const data = core.get(element.dataset.l10nId + attrSeparator + attrAlias); + if (data) + element.setAttribute(ariaAttrMap[attrAlias], data); + } +} + // Taken from Gaia: // https://github.com/andreasgal/gaia/blob/04fde2640a7f40314643016a5a6c98bf3755f5fd/webapi.js#L1470 function translateElement(element) { @@ -32,6 +57,8 @@ function translateElement(element) { var data = core.get(key); if (data) child.textContent = data; + + translateElementAttributes(child); } } exports.translateElement = translateElement; diff --git a/addon-sdk/source/lib/sdk/deprecated/unit-test.js b/addon-sdk/source/lib/sdk/deprecated/unit-test.js index d6d1c048ab01..33bb6d7dd50d 100644 --- a/addon-sdk/source/lib/sdk/deprecated/unit-test.js +++ b/addon-sdk/source/lib/sdk/deprecated/unit-test.js @@ -320,6 +320,8 @@ TestRunner.prototype = { }); PromiseDebugging.flushUncaughtErrors(); + PromiseDebugging.removeUncaughtErrorObserver(this._uncaughtErrorObserver); + return all(winPromises).then(() => { let browserWins = wins.filter(isBrowser); @@ -537,7 +539,8 @@ TestRunner.prototype = { this.test.errors = {}; this.test.last = 'START'; PromiseDebugging.clearUncaughtErrorObservers(); - PromiseDebugging.addUncaughtErrorObserver(this._uncaughtErrorObserver.bind(this)); + this._uncaughtErrorObserver = this._uncaughtErrorObserver.bind(this); + PromiseDebugging.addUncaughtErrorObserver(this._uncaughtErrorObserver); this.isDone = false; this.onDone = function(self) { diff --git a/addon-sdk/source/lib/sdk/event/dom.js b/addon-sdk/source/lib/sdk/event/dom.js index 54963230ff3c..01c162be4c38 100644 --- a/addon-sdk/source/lib/sdk/event/dom.js +++ b/addon-sdk/source/lib/sdk/event/dom.js @@ -21,6 +21,10 @@ let getWindowFrom = x => null; function removeFromListeners() { + this.removeEventListener("DOMWindowClose", removeFromListeners); + for (let cleaner of listeners.get(this)) + cleaner(); + listeners.delete(this); } @@ -45,26 +49,25 @@ function open(target, type, options) { if (!window) throw new Error("Unable to obtain the owner window from the target given."); - let cleaners = listeners.get(window) || []; + let cleaners = listeners.get(window); + if (!cleaners) { + cleaners = []; + listeners.set(window, cleaners); + + // We need to remove from our map the `window` once is closed, to prevent + // memory leak + window.addEventListener("DOMWindowClose", removeFromListeners); + } + cleaners.push(() => target.removeEventListener(type, listener, capture)); - - listeners.set(window, cleaners); - - // We need to remove from our map the `window` once is closed, to prevent - // memory leak - window.addEventListener("DOMWindowClose", removeFromListeners); - target.addEventListener(type, listener, capture); return output; } unload(() => { - for (let [window, cleaners] of listeners) { - cleaners.forEach(callback => callback()) - } - - listeners.clear(); + for (let window of listeners.keys()) + removeFromListeners.call(window); }); exports.open = open; diff --git a/addon-sdk/source/lib/sdk/io/fs.js b/addon-sdk/source/lib/sdk/io/fs.js index 7a8db312b9dd..7d7e28932e52 100644 --- a/addon-sdk/source/lib/sdk/io/fs.js +++ b/addon-sdk/source/lib/sdk/io/fs.js @@ -692,8 +692,6 @@ function writeSync(fd, buffer, offset, length, position) { else if (length + offset !== buffer.length) { buffer = buffer.slice(offset, offset + length); } - let writeStream = new WriteStream(fd, { position: position, - length: length }); let output = BinaryOutputStream(nsIFileOutputStream(fd)); nsIBinaryOutputStream(fd, output); diff --git a/addon-sdk/source/lib/sdk/places/events.js b/addon-sdk/source/lib/sdk/places/events.js index 610ce0f79669..6f3e11bcf1bd 100644 --- a/addon-sdk/source/lib/sdk/places/events.js +++ b/addon-sdk/source/lib/sdk/places/events.js @@ -23,6 +23,7 @@ const historyService = Cc['@mozilla.org/browser/nav-history-service;1'] const { mapBookmarkItemType } = require('./utils'); const { EventTarget } = require('../event/target'); const { emit } = require('../event/core'); +const { when } = require('../system/unload'); const emitter = EventTarget(); @@ -119,4 +120,9 @@ historyService.addObserver(historyObserver, false); let bookmarkObserver = createObserverInstance(BOOKMARK_EVENTS, BOOKMARK_ARGS); bookmarkService.addObserver(bookmarkObserver, false); +when(() => { + historyService.removeObserver(historyObserver); + bookmarkService.removeObserver(bookmarkObserver); +}); + exports.events = emitter; diff --git a/addon-sdk/source/lib/toolkit/loader.js b/addon-sdk/source/lib/toolkit/loader.js index 1c8f122aea30..2aec555d93b1 100644 --- a/addon-sdk/source/lib/toolkit/loader.js +++ b/addon-sdk/source/lib/toolkit/loader.js @@ -169,6 +169,15 @@ function serializeStack(frames) { Loader.serializeStack = serializeStack; function readURI(uri) { + let nsURI = NetUtil.newURI(uri); + if (nsURI.scheme == "resource") { + // Resolve to a real URI, this will catch any obvious bad paths without + // logging assertions in debug builds, see bug 1135219 + let proto = Cc["@mozilla.org/network/protocol;1?name=resource"]. + getService(Ci.nsIResProtocolHandler); + uri = proto.resolveURI(nsURI); + } + let stream = NetUtil.newChannel2(uri, 'UTF-8', null, @@ -420,6 +429,10 @@ const nodeResolve = iced(function nodeResolve(id, requirer, { rootURI }) { // Resolve again id = Loader.resolve(id, requirer); + // If this is already an absolute URI then there is no resolution to do + if (isAbsoluteURI(id)) + return void 0; + // we assume that extensions are correct, i.e., a directory doesnt't have '.js' // and a js file isn't named 'file.json.js' let fullId = join(rootURI, id); @@ -431,9 +444,14 @@ const nodeResolve = iced(function nodeResolve(id, requirer, { rootURI }) { if ((resolvedPath = loadAsDirectory(fullId))) return stripBase(rootURI, resolvedPath); + // If the requirer is an absolute URI then the node module resolution below + // won't work correctly as we prefix everything with rootURI + if (isAbsoluteURI(requirer)) + return void 0; + // If manifest has dependencies, attempt to look up node modules // in the `dependencies` list - let dirs = getNodeModulePaths(dirname(join(rootURI, requirer))).map(dir => join(dir, id)); + let dirs = getNodeModulePaths(dirname(requirer)).map(dir => join(rootURI, dir, id)); for (let i = 0; i < dirs.length; i++) { if ((resolvedPath = loadAsFile(dirs[i]))) return stripBase(rootURI, resolvedPath); @@ -509,6 +527,7 @@ function getNodeModulePaths (start) { let dir = join(parts.slice(0, i + 1).join('/'), moduleDir); dirs.push(dir); } + dirs.push(moduleDir); return dirs; } diff --git a/addon-sdk/source/package.json b/addon-sdk/source/package.json index 0e0c1f0e30dc..f2faebc753c1 100644 --- a/addon-sdk/source/package.json +++ b/addon-sdk/source/package.json @@ -8,10 +8,7 @@ "license": "MPL 2.0", "unpack": true, "scripts": { - "test": "node ./bin/jpm-test.js", - "modules": "node ./bin/jpm-test.js --type modules", - "addons": "node ./bin/jpm-test.js --type addons", - "examples": "node ./bin/jpm-test.js --type examples" + "test": "gulp test" }, "homepage": "https://github.com/mozilla/addon-sdk", "repository": { @@ -25,6 +22,7 @@ "async": "0.9.0", "chai": "2.1.1", "glob": "4.4.2", + "gulp": "3.8.11", "jpm": "0.0.29", "lodash": "3.3.1", "mocha": "2.1.0", diff --git a/addon-sdk/source/python-lib/cuddlefish/prefs.py b/addon-sdk/source/python-lib/cuddlefish/prefs.py index bb0417201572..5e1a5e01f34f 100644 --- a/addon-sdk/source/python-lib/cuddlefish/prefs.py +++ b/addon-sdk/source/python-lib/cuddlefish/prefs.py @@ -56,6 +56,7 @@ DEFAULT_NO_CONNECTIONS_PREFS = { 'browser.aboutHomeSnippets.updateUrl': 'https://localhost/snippet-dummy', 'browser.newtab.url' : 'about:blank', 'browser.search.update': False, + 'browser.search.suggest.enabled' : False, 'browser.safebrowsing.enabled' : False, 'browser.safebrowsing.updateURL': 'http://localhost/safebrowsing-dummy/update', 'browser.safebrowsing.gethashURL': 'http://localhost/safebrowsing-dummy/gethash', diff --git a/addon-sdk/source/test/addons/e10s-l10n/data/test-localization.html b/addon-sdk/source/test/addons/e10s-l10n/data/test-localization.html index 5428863ad8e2..5646946da35d 100644 --- a/addon-sdk/source/test/addons/e10s-l10n/data/test-localization.html +++ b/addon-sdk/source/test/addons/e10s-l10n/data/test-localization.html @@ -20,5 +20,10 @@