Merge mozilla-central to mozilla-inbound on a CLOSED TREE

This commit is contained in:
Carsten "Tomcat" Book 2015-07-02 15:47:27 +02:00
Родитель ccac184650 90ad3cb68a
Коммит ad3fbbadfa
130 изменённых файлов: 2417 добавлений и 2017 удалений

Просмотреть файл

@ -29,7 +29,6 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] != "gonk":
EXTRA_JS_MODULES.commonjs.sdk.deprecated += [ EXTRA_JS_MODULES.commonjs.sdk.deprecated += [
'source/lib/sdk/deprecated/api-utils.js', 'source/lib/sdk/deprecated/api-utils.js',
'source/lib/sdk/deprecated/memory.js',
'source/lib/sdk/deprecated/sync-worker.js', 'source/lib/sdk/deprecated/sync-worker.js',
'source/lib/sdk/deprecated/unit-test-finder.js', 'source/lib/sdk/deprecated/unit-test-finder.js',
'source/lib/sdk/deprecated/unit-test.js', 'source/lib/sdk/deprecated/unit-test.js',
@ -258,6 +257,10 @@ EXTRA_JS_MODULES.commonjs.sdk.content += [
'source/lib/sdk/content/worker.js', 'source/lib/sdk/content/worker.js',
] ]
EXTRA_JS_MODULES.commonjs.sdk.content.sandbox += [
'source/lib/sdk/content/sandbox/events.js',
]
EXTRA_JS_MODULES.commonjs.sdk['context-menu'] += [ EXTRA_JS_MODULES.commonjs.sdk['context-menu'] += [
'source/lib/sdk/context-menu/context.js', 'source/lib/sdk/context-menu/context.js',
'source/lib/sdk/context-menu/core.js', 'source/lib/sdk/context-menu/core.js',
@ -307,7 +310,6 @@ EXTRA_JS_MODULES.commonjs.sdk.input += [
EXTRA_JS_MODULES.commonjs.sdk.io += [ EXTRA_JS_MODULES.commonjs.sdk.io += [
'source/lib/sdk/io/buffer.js', 'source/lib/sdk/io/buffer.js',
'source/lib/sdk/io/byte-streams.js', 'source/lib/sdk/io/byte-streams.js',
'source/lib/sdk/io/data.js',
'source/lib/sdk/io/file.js', 'source/lib/sdk/io/file.js',
'source/lib/sdk/io/fs.js', 'source/lib/sdk/io/fs.js',
'source/lib/sdk/io/stream.js', 'source/lib/sdk/io/stream.js',
@ -453,7 +455,6 @@ EXTRA_JS_MODULES.commonjs.sdk.url += [
EXTRA_JS_MODULES.commonjs.sdk.util += [ EXTRA_JS_MODULES.commonjs.sdk.util += [
'source/lib/sdk/util/array.js', 'source/lib/sdk/util/array.js',
'source/lib/sdk/util/bond.js',
'source/lib/sdk/util/collection.js', 'source/lib/sdk/util/collection.js',
'source/lib/sdk/util/contract.js', 'source/lib/sdk/util/contract.js',
'source/lib/sdk/util/deprecate.js', 'source/lib/sdk/util/deprecate.js',

Просмотреть файл

@ -1,7 +1,7 @@
sudo: false sudo: false
language: node_js language: node_js
node_js: node_js:
- "0.10" - "0.12"
env: env:
- JPM_FX_DEBUG=0 - JPM_FX_DEBUG=0

Просмотреть файл

@ -17,12 +17,13 @@ exports.run = function(type) {
return new Promise(function(resolve) { return new Promise(function(resolve) {
type = type || ""; type = type || "";
[ [
(!isDebug && /^(modules)?$/.test(type)) && require.resolve("../bin/node-scripts/test.modules"), (!isDebug && /^(firefox-bin)?$/.test(type)) && require.resolve("../bin/node-scripts/test.firefox-bin"),
(!isDebug && /^(addons)?$/.test(type)) && require.resolve("../bin/node-scripts/test.addons"),
(/^(examples)?$/.test(type)) && require.resolve("../bin/node-scripts/test.examples"),
(!isDebug && /^(docs)?$/.test(type)) && require.resolve("../bin/node-scripts/test.docs"), (!isDebug && /^(docs)?$/.test(type)) && require.resolve("../bin/node-scripts/test.docs"),
(!isDebug && /^(ini)?$/.test(type)) && require.resolve("../bin/node-scripts/test.ini"), (!isDebug && /^(ini)?$/.test(type)) && require.resolve("../bin/node-scripts/test.ini"),
].sort().forEach(function(filepath) { (/^(examples)?$/.test(type)) && require.resolve("../bin/node-scripts/test.examples"),
(!isDebug && /^(addons)?$/.test(type)) && require.resolve("../bin/node-scripts/test.addons"),
(!isDebug && /^(modules)?$/.test(type)) && require.resolve("../bin/node-scripts/test.modules"),
].forEach(function(filepath) {
filepath && mocha.addFile(filepath); filepath && mocha.addFile(filepath);
}) })

Просмотреть файл

@ -0,0 +1,37 @@
/* 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 fs = require("fs");
var Promise = require("promise");
var chai = require("chai");
var expect = chai.expect;
var normalizeBinary = require("fx-runner/lib/utils").normalizeBinary;
//var firefox_binary = process.env["JPM_FIREFOX_BINARY"] || normalizeBinary("nightly");
describe("Checking Firefox binary", function () {
it("using matching fx-runner version with jpm", function () {
var sdkPackageJSON = require("../../package.json");
var jpmPackageINI = require("jpm/package.json");
expect(sdkPackageJSON.devDependencies["fx-runner"]).to.be.equal(jpmPackageINI.dependencies["fx-runner"]);
});
it("exists", function (done) {
var useEnvVar = new Promise(function(resolve) {
resolve(process.env["JPM_FIREFOX_BINARY"]);
});
var firefox_binary = process.env["JPM_FIREFOX_BINARY"] ? useEnvVar : normalizeBinary("nightly");
firefox_binary.then(function(path) {
expect(path).to.be.ok;
fs.exists(path, function (exists) {
expect(exists).to.be.ok;
done();
});
})
});
});

Просмотреть файл

@ -11,6 +11,7 @@ var expect = chai.expect;
var ini = require("./update-ini"); var ini = require("./update-ini");
var addonINI = path.resolve("./test/addons/jetpack-addon.ini"); var addonINI = path.resolve("./test/addons/jetpack-addon.ini");
var packageINI = path.resolve("./test/jetpack-package.ini");
describe("Checking ini files", function () { describe("Checking ini files", function () {
@ -20,7 +21,10 @@ describe("Checking ini files", function () {
if (err) { if (err) {
throw err; throw err;
} }
var text = data.toString(); // filter comments
var text = data.toString().split("\n").filter(function(line) {
return !/^\s*#/.test(line);
}).join("\n");
var expected = ""; var expected = "";
ini.makeAddonIniContent() ini.makeAddonIniContent()
@ -28,7 +32,32 @@ describe("Checking ini files", function () {
expected = contents; expected = contents;
setTimeout(function end() { setTimeout(function end() {
expect(expected.trim()).to.be.equal(text.trim()); expect(text.trim()).to.be.equal(expected.trim());
done();
});
});
});
});
it("Check test/jetpack-package.ini", function (done) {
fs.readFile(packageINI, function (err, data) {
if (err) {
throw err;
}
// filter comments
var text = data.toString().split("\n").filter(function(line) {
return !/^\s*#/.test(line);
}).join("\n");
var expected = "";
ini.makePackageIniContent()
.then(function(contents) {
expected = contents;
setTimeout(function end() {
expect(text.trim()).to.be.equal(expected.trim());
done(); done();
}); });
}); });

Просмотреть файл

@ -11,6 +11,14 @@ var parser = require("ini-parser");
var addonINI = path.resolve("./test/addons/jetpack-addon.ini"); var addonINI = path.resolve("./test/addons/jetpack-addon.ini");
var addonsDir = path.resolve("./test/addons/"); var addonsDir = path.resolve("./test/addons/");
var packageINI = path.resolve("./test/jetpack-package.ini");
var packageDir = path.resolve("./test/");
var packageIgnorables = [ "addons", "preferences" ];
var packageSupportFiles = [
"fixtures.js",
"test-context-menu.html",
"util.js"
]
function updateAddonINI() { function updateAddonINI() {
return new Promise(function(resolve) { return new Promise(function(resolve) {
@ -32,16 +40,18 @@ function makeAddonIniContent() {
var result = {}; var result = {};
fs.readdir(addonsDir, function(err, files) { fs.readdir(addonsDir, function(err, files) {
// get a list of folders
var folders = files.filter(function(file) { var folders = files.filter(function(file) {
return fs.statSync(path.resolve(addonsDir, file)).isDirectory(); return fs.statSync(path.resolve(addonsDir, file)).isDirectory();
}).sort(); }).sort();
// copy any related data from the existing ini
folders.forEach(function(folder) { folders.forEach(function(folder) {
var oldData = data[folder + ".xpi"]; var oldData = data[folder + ".xpi"];
result[folder] = oldData ? oldData : {}; result[folder] = oldData ? oldData : {};
}); });
// build ini file // build a new ini file
var contents = []; var contents = [];
Object.keys(result).sort().forEach(function(key) { Object.keys(result).sort().forEach(function(key) {
contents.push("[" + key + ".xpi]"); contents.push("[" + key + ".xpi]");
@ -56,3 +66,76 @@ function makeAddonIniContent() {
}); });
} }
exports.makeAddonIniContent = makeAddonIniContent; exports.makeAddonIniContent = makeAddonIniContent;
function makePackageIniContent() {
return new Promise(function(resolve) {
var data = parser.parse(fs.readFileSync(packageINI, { encoding: "utf8" }).toString());
var result = {};
fs.readdir(packageDir, function(err, files) {
// get a list of folders
var folders = files.filter(function(file) {
var ignore = (packageIgnorables.indexOf(file) >= 0);
var isDir = fs.statSync(path.resolve(packageDir, file)).isDirectory();
return (isDir && !ignore);
}).sort();
// get a list of "test-"" files
var files = files.filter(function(file) {
var ignore = !/^test\-.*\.js$/i.test(file);
var isDir = fs.statSync(path.resolve(packageDir, file)).isDirectory();
return (!isDir && !ignore);
}).sort();
// get a list of the support files
var support_files = packageSupportFiles.map(function(file) {
return " " + file;
});
folders.forEach(function(folder) {
support_files.push(" " + folder + "/**");
});
support_files = support_files.sort();
// copy any related data from the existing ini
files.forEach(function(file) {
var oldData = data[file];
result[file] = oldData ? oldData : {};
});
// build a new ini file
var contents = [
"[DEFAULT]",
"support-files ="
];
support_files.forEach(function(support_file) {
contents.push(support_file);
});
contents.push("");
Object.keys(result).sort().forEach(function(key) {
contents.push("[" + key + "]");
Object.keys(result[key]).forEach(function(dataKey) {
contents.push(dataKey + " = " + result[key][dataKey]);
});
});
contents = contents.join("\n") + "\n";
return resolve(contents);
});
});
}
exports.makePackageIniContent = makePackageIniContent;
function updatePackageINI() {
return new Promise(function(resolve) {
console.log("Start updating " + packageINI);
makeAddonIniContent().
then(function(contents) {
fs.writeFileSync(packageINI, contents, { encoding: "utf8" });
console.log("Done updating " + packageINI);
resolve();
});
})
}
exports.updatePackageINI = updatePackageINI;

Просмотреть файл

@ -65,6 +65,9 @@ function run (cmd, options, p) {
if (p) { if (p) {
proc.stdout.pipe(p.stdout); proc.stdout.pipe(p.stdout);
} }
else if (!isDebug) {
proc.stdout.pipe(DEFAULT_PROCESS.stdout);
}
else { else {
proc.stdout.on("data", function (data) { proc.stdout.on("data", function (data) {
data = (data || "") + ""; data = (data || "") + "";

Просмотреть файл

@ -28,7 +28,11 @@ gulp.task('test:modules', function(done) {
}); });
gulp.task('test:ini', function(done) { gulp.task('test:ini', function(done) {
test("ini").catch(console.error).then(done); require("./bin/jpm-test").run("ini").catch(console.error).then(done);
});
gulp.task('test:firefox-bin', function(done) {
require("./bin/jpm-test").run("firefox-bin").catch(console.error).then(done);
}); });
gulp.task('patch:clean', function(done) { gulp.task('patch:clean', function(done) {
@ -38,7 +42,3 @@ gulp.task('patch:clean', function(done) {
gulp.task('patch:apply', function(done) { gulp.task('patch:apply', function(done) {
patch.apply().catch(console.error).then(done); patch.apply().catch(console.error).then(done);
}); });
gulp.task('update:ini', function(done) {
ini.updateAddonINI().catch(console.error).then(done);
});

Просмотреть файл

@ -1,19 +1,16 @@
/* This Source Code Form is subject to the terms of the Mozilla Public /* 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 * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict"; "use strict";
module.metadata = { module.metadata = {
"stability": "experimental" "stability": "experimental"
}; };
const { Cc, Ci, components } = require("chrome"); const { Ci, components } = require("chrome");
const { parseStack, sourceURI } = require("toolkit/loader"); const { parseStack, sourceURI } = require("toolkit/loader");
const { readURISync } = require("../net/url"); const { readURISync } = require("../net/url");
exports.sourceURI = sourceURI
function safeGetFileLine(path, line) { function safeGetFileLine(path, line) {
try { try {
var scheme = require("../url").URL(path).scheme; var scheme = require("../url").URL(path).scheme;

Просмотреть файл

@ -10,6 +10,7 @@ module.metadata = {
const { Class } = require('../core/heritage'); const { Class } = require('../core/heritage');
const { EventTarget } = require('../event/target'); const { EventTarget } = require('../event/target');
const { on, off, emit } = require('../event/core'); const { on, off, emit } = require('../event/core');
const { events } = require('./sandbox/events');
const { requiresAddonGlobal } = require('./utils'); const { requiresAddonGlobal } = require('./utils');
const { delay: async } = require('../lang/functional'); const { delay: async } = require('../lang/functional');
const { Ci, Cu, Cc } = require('chrome'); const { Ci, Cu, Cc } = require('chrome');
@ -20,8 +21,7 @@ const { merge } = require('../util/object');
const { getTabForContentWindow } = require('../tabs/utils'); const { getTabForContentWindow } = require('../tabs/utils');
const { getInnerId } = require('../window/utils'); const { getInnerId } = require('../window/utils');
const { PlainTextConsole } = require('../console/plain-text'); const { PlainTextConsole } = require('../console/plain-text');
const { data } = require('../self'); const { data } = require('../self');const { isChildLoader } = require('../remote/core');
const { isChildLoader } = require('../remote/core');
// WeakMap of sandboxes so we can access private values // WeakMap of sandboxes so we can access private values
const sandboxes = new WeakMap(); const sandboxes = new WeakMap();
@ -166,6 +166,7 @@ const WorkerSandbox = Class({
get top() top, get top() top,
get parent() parent get parent() parent
}); });
// Use the Greasemonkey naming convention to provide access to the // Use the Greasemonkey naming convention to provide access to the
// unwrapped window object so the content script can access document // unwrapped window object so the content script can access document
// JavaScript values. // JavaScript values.
@ -261,6 +262,11 @@ const WorkerSandbox = Class({
win.console = con; win.console = con;
}; };
emit(events, "content-script-before-inserted", {
window: window,
worker: worker
});
// The order of `contentScriptFile` and `contentScript` evaluation is // The order of `contentScriptFile` and `contentScript` evaluation is
// intentional, so programs can load libraries like jQuery from script URLs // intentional, so programs can load libraries like jQuery from script URLs
// and use them in scripts. // and use them in scripts.
@ -273,6 +279,7 @@ const WorkerSandbox = Class({
if (contentScriptFile) if (contentScriptFile)
importScripts.apply(null, [this].concat(contentScriptFile)); importScripts.apply(null, [this].concat(contentScriptFile));
if (contentScript) { if (contentScript) {
evaluateIn( evaluateIn(
this, this,

Просмотреть файл

@ -2,6 +2,11 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
exports.minimalTest = function(test) { "use strict";
test.assert(true);
module.metadata = {
"stability": "experimental"
}; };
const events = {};
exports.events = events;

Просмотреть файл

@ -1,129 +0,0 @@
/* 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";
module.metadata = {
"stability": "deprecated"
};
const { Cc, Ci, Cu, components } = require("chrome");
const { when: unload } = require("../system/unload")
var trackedObjects = {};
const Compacter = {
notify: function() {
var newTrackedObjects = {};
for (let name in trackedObjects) {
let oldBin = trackedObjects[name];
let newBin = [];
let strongRefs = [];
for (let i = 0, l = oldBin.length; i < l; i++) {
let strongRef = oldBin[i].weakref.get();
if (strongRef && strongRefs.indexOf(strongRef) == -1) {
strongRefs.push(strongRef);
newBin.push(oldBin[i]);
}
}
if (newBin.length)
newTrackedObjects[name] = newBin;
}
trackedObjects = newTrackedObjects;
}
};
var timer = Cc["@mozilla.org/timer;1"]
.createInstance(Ci.nsITimer);
timer.initWithCallback(Compacter,
5000,
Ci.nsITimer.TYPE_REPEATING_SLACK);
function track(object, bin, stackFrameNumber) {
var frame = components.stack.caller;
var weakref = Cu.getWeakReference(object);
if (!bin && 'constructor' in object)
bin = object.constructor.name;
if (bin == "Object")
bin = frame.name;
if (!bin)
bin = "generic";
if (!(bin in trackedObjects))
trackedObjects[bin] = [];
if (stackFrameNumber > 0)
for (var i = 0; i < stackFrameNumber; i++)
frame = frame.caller;
trackedObjects[bin].push({weakref: weakref,
created: new Date(),
filename: frame.filename,
lineNo: frame.lineNumber,
bin: bin});
}
exports.track = track;
var getBins = exports.getBins = function getBins() {
var names = [];
for (let name in trackedObjects)
names.push(name);
return names;
};
function getObjects(bin) {
var results = [];
function getLiveObjectsInBin(bin) {
for (let i = 0, l = bin.length; i < l; i++) {
let object = bin[i].weakref.get();
if (object) {
results.push(bin[i]);
}
}
}
if (bin) {
if (bin in trackedObjects)
getLiveObjectsInBin(trackedObjects[bin]);
}
else {
for (let name in trackedObjects)
getLiveObjectsInBin(trackedObjects[name]);
}
return results;
}
exports.getObjects = getObjects;
function gc() {
// Components.utils.forceGC() doesn't currently perform
// cycle collection, which means that e.g. DOM elements
// won't be collected by it. Fortunately, there are
// other ways...
var test_utils = Cc["@mozilla.org/appshell/appShellService;1"]
.getService(Ci.nsIAppShellService)
.hiddenDOMWindow
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
test_utils.garbageCollect();
// Clean metadata for dead objects
Compacter.notify();
// Not sure why, but sometimes it appears that we don't get
// them all with just one CC, so let's do it again.
test_utils.garbageCollect();
};
exports.gc = gc;
unload(_ => {
trackedObjects = {};
if (timer) {
timer.cancel();
timer = null;
}
});

Просмотреть файл

@ -30,7 +30,6 @@ const unload = require('../system/unload');
const events = require('../system/events'); const events = require('../system/events');
const { getInnerId } = require("../window/utils"); const { getInnerId } = require("../window/utils");
const { WorkerSandbox } = require('../content/sandbox'); const { WorkerSandbox } = require('../content/sandbox');
const { getTabForWindow } = require('../tabs/helpers');
const { isPrivate } = require('../private-browsing/utils'); const { isPrivate } = require('../private-browsing/utils');
// A weak map of workers to hold private attributes that // A weak map of workers to hold private attributes that
@ -118,14 +117,6 @@ const Worker = Class({
return model.window ? model.window.document.URL : null; return model.window ? model.window.document.URL : null;
}, },
get tab () {
let model = modelFor(this);
// model.window will be null after detach
if (model.window)
return getTabForWindow(model.window);
return null;
},
// Implemented to provide some of the previous features of exposing sandbox // Implemented to provide some of the previous features of exposing sandbox
// so that Worker can be extended // so that Worker can be extended
getSandbox: function () { getSandbox: function () {

Просмотреть файл

@ -8,7 +8,6 @@ module.metadata = {
}; };
const file = require("../io/file"); const file = require("../io/file");
const memory = require('./memory');
const { Loader } = require("../test/loader"); const { Loader } = require("../test/loader");
const { isNative } = require('@loader/options'); const { isNative } = require('@loader/options');
@ -132,7 +131,6 @@ let loader = Loader(module);
const NOT_TESTS = ['setup', 'teardown']; const NOT_TESTS = ['setup', 'teardown'];
var TestFinder = exports.TestFinder = function TestFinder(options) { var TestFinder = exports.TestFinder = function TestFinder(options) {
memory.track(this);
this.filter = options.filter; this.filter = options.filter;
this.testInProcess = options.testInProcess === false ? false : true; this.testInProcess = options.testInProcess === false ? false : true;
this.testOutOfProcess = options.testOutOfProcess === true ? true : false; this.testOutOfProcess = options.testOutOfProcess === true ? true : false;

Просмотреть файл

@ -7,7 +7,6 @@ module.metadata = {
"stability": "deprecated" "stability": "deprecated"
}; };
const memory = require("./memory");
const timer = require("../timers"); const timer = require("../timers");
const cfxArgs = require("../test/options"); const cfxArgs = require("../test/options");
const { getTabs, closeTab, getURI, getTabId, getSelectedTab } = require("../tabs/utils"); const { getTabs, closeTab, getURI, getTabId, getSelectedTab } = require("../tabs/utils");
@ -47,7 +46,6 @@ const TestRunner = function TestRunner(options) {
this.fs = options.fs; this.fs = options.fs;
this.console = options.console || console; this.console = options.console || console;
memory.track(this);
this.passed = 0; this.passed = 0;
this.failed = 0; this.failed = 0;
this.testRunSummary = []; this.testRunSummary = [];
@ -283,40 +281,46 @@ TestRunner.prototype = {
} }
this.isDone = true; this.isDone = true;
this.pass("This test is done.");
if (this.test.teardown) { if (this.test.teardown) {
this.test.teardown(this); this.test.teardown(this);
} }
if (this.waitTimeout !== null) { if (this.waitTimeout !== null) {
timer.clearTimeout(this.waitTimeout); timer.clearTimeout(this.waitTimeout);
this.waitTimeout = null; this.waitTimeout = null;
} }
// Do not leave any callback set when calling to `waitUntil` // Do not leave any callback set when calling to `waitUntil`
this.waitUntilCallback = null; this.waitUntilCallback = null;
if (this.test.passed == 0 && this.test.failed == 0) { if (this.test.passed == 0 && this.test.failed == 0) {
this._logTestFailed("empty test"); this._logTestFailed("empty test");
if ("testMessage" in this.console) { if ("testMessage" in this.console) {
this.console.testMessage(false, false, this.test.name, "Empty test"); this.console.testMessage(false, false, this.test.name, "Empty test");
} }
else { else {
this.console.error("fail:", "Empty test") this.console.error("fail:", "Empty test")
} }
this.failed++; this.failed++;
this.test.failed++; this.test.failed++;
} }
let wins = windows(null, { includePrivate: true }); let wins = windows(null, { includePrivate: true });
let winPromises = wins.map(win => { let winPromises = wins.map(win => {
let { promise, resolve } = defer(); return new Promise(resolve => {
if (["interactive", "complete"].indexOf(win.document.readyState) >= 0) { if (["interactive", "complete"].indexOf(win.document.readyState) >= 0) {
resolve() resolve()
} }
else { else {
win.addEventListener("DOMContentLoaded", function onLoad() { win.addEventListener("DOMContentLoaded", function onLoad() {
win.removeEventListener("DOMContentLoaded", onLoad, false); win.removeEventListener("DOMContentLoaded", onLoad, false);
resolve(); resolve();
}, false); }, false);
} }
return promise; });
}); });
PromiseDebugging.flushUncaughtErrors(); PromiseDebugging.flushUncaughtErrors();
@ -358,9 +362,17 @@ TestRunner.prototype = {
} }
} }
return null; return failure;
}).
then(failure => {
if (!failure) {
this.pass("There was a clean UI.");
return null;
}
return cleanUI().then(() => {
this.pass("There is a clean UI.");
});
}). }).
then(cleanUI).
then(() => { then(() => {
this.testRunSummary.push({ this.testRunSummary.push({
name: this.test.name, name: this.test.name,

Просмотреть файл

@ -1,90 +0,0 @@
/* 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";
module.metadata = {
"stability": "unstable"
};
const { Cc, Ci, Cu } = require("chrome");
const base64 = require("../base64");
const IOService = Cc["@mozilla.org/network/io-service;1"].
getService(Ci.nsIIOService);
const { deprecateFunction } = require('../util/deprecate');
const { NetUtil } = Cu.import("resource://gre/modules/NetUtil.jsm");
const { Services } = Cu.import("resource://gre/modules/Services.jsm");
const FaviconService = Cc["@mozilla.org/browser/favicon-service;1"].
getService(Ci.nsIFaviconService);
const PNG_B64 = "data:image/png;base64,";
const DEF_FAVICON_URI = "chrome://mozapps/skin/places/defaultFavicon.png";
let DEF_FAVICON = null;
/**
* Takes URI of the page and returns associated favicon URI.
* If page under passed uri has no favicon then base64 encoded data URI of
* default faveicon is returned.
* @param {String} uri
* @returns {String}
*/
function getFaviconURIForLocation(uri) {
let pageURI = NetUtil.newURI(uri);
try {
return FaviconService.getFaviconDataAsDataURL(
FaviconService.getFaviconForPage(pageURI));
}
catch(e) {
if (!DEF_FAVICON) {
DEF_FAVICON = PNG_B64 +
base64.encode(getChromeURIContent(DEF_FAVICON_URI));
}
return DEF_FAVICON;
}
}
exports.getFaviconURIForLocation = getFaviconURIForLocation;
/**
* Takes chrome URI and returns content under that URI.
* @param {String} chromeURI
* @returns {String}
*/
function getChromeURIContent(chromeURI) {
let channel = IOService.newChannel2(chromeURI,
null,
null,
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
let input = channel.open();
let stream = Cc["@mozilla.org/binaryinputstream;1"].
createInstance(Ci.nsIBinaryInputStream);
stream.setInputStream(input);
let content = stream.readBytes(input.available());
stream.close();
input.close();
return content;
}
exports.getChromeURIContent = deprecateFunction(getChromeURIContent,
'getChromeURIContent is deprecated, ' +
'please use require("sdk/net/url").readURI instead.'
);
/**
* Creates a base-64 encoded ASCII string from a string of binary data.
*/
exports.base64Encode = deprecateFunction(base64.encode,
'base64Encode is deprecated, ' +
'please use require("sdk/base64").encode instead.'
);
/**
* Decodes a string of data which has been encoded using base-64 encoding.
*/
exports.base64Decode = deprecateFunction(base64.decode,
'base64Dencode is deprecated, ' +
'please use require("sdk/base64").decode instead.'
);

Просмотреть файл

@ -1,17 +1,15 @@
/* This Source Code Form is subject to the terms of the Mozilla Public /* 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 * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict"; "use strict";
module.metadata = { module.metadata = {
"stability": "experimental" "stability": "experimental"
}; };
const {Cc,Ci,Cu,components} = require("chrome"); const { Cc, Ci, Cu, components } = require("chrome");
var NetUtil = {}; const { ensure } = require("../system/unload");
Cu.import("resource://gre/modules/NetUtil.jsm", NetUtil); const { NetUtil } = Cu.import("resource://gre/modules/NetUtil.jsm", {});
NetUtil = NetUtil.NetUtil;
// NetUtil.asyncCopy() uses this buffer length, and since we call it, for best // NetUtil.asyncCopy() uses this buffer length, and since we call it, for best
// performance we use it, too. // performance we use it, too.
@ -19,8 +17,6 @@ const BUFFER_BYTE_LEN = 0x8000;
const PR_UINT32_MAX = 0xffffffff; const PR_UINT32_MAX = 0xffffffff;
const DEFAULT_CHARSET = "UTF-8"; const DEFAULT_CHARSET = "UTF-8";
exports.TextReader = TextReader;
exports.TextWriter = TextWriter;
/** /**
* An input stream that reads text from a backing stream using a given text * An input stream that reads text from a backing stream using a given text
@ -35,7 +31,6 @@ exports.TextWriter = TextWriter;
* documentation on how to determine other valid values for this. * documentation on how to determine other valid values for this.
*/ */
function TextReader(inputStream, charset) { function TextReader(inputStream, charset) {
const self = this;
charset = checkCharset(charset); charset = checkCharset(charset);
let stream = Cc["@mozilla.org/intl/converter-input-stream;1"]. let stream = Cc["@mozilla.org/intl/converter-input-stream;1"].
@ -89,6 +84,7 @@ function TextReader(inputStream, charset) {
return str; return str;
}; };
} }
exports.TextReader = TextReader;
/** /**
* A buffered output stream that writes text to a backing stream using a given * A buffered output stream that writes text to a backing stream using a given
@ -103,7 +99,6 @@ function TextReader(inputStream, charset) {
* for documentation on how to determine other valid values for this. * for documentation on how to determine other valid values for this.
*/ */
function TextWriter(outputStream, charset) { function TextWriter(outputStream, charset) {
const self = this;
charset = checkCharset(charset); charset = checkCharset(charset);
let stream = outputStream; let stream = outputStream;
@ -169,7 +164,7 @@ function TextWriter(outputStream, charset) {
this.writeAsync = function TextWriter_writeAsync(str, callback) { this.writeAsync = function TextWriter_writeAsync(str, callback) {
manager.ensureOpened(); manager.ensureOpened();
let istream = uconv.convertToInputStream(str); let istream = uconv.convertToInputStream(str);
NetUtil.asyncCopy(istream, stream, function (result) { NetUtil.asyncCopy(istream, stream, (result) => {
let err = components.isSuccessCode(result) ? undefined : let err = components.isSuccessCode(result) ? undefined :
new Error("An error occured while writing to the stream: " + result); new Error("An error occured while writing to the stream: " + result);
if (err) if (err)
@ -180,7 +175,7 @@ function TextWriter(outputStream, charset) {
if (typeof(callback) === "function") { if (typeof(callback) === "function") {
try { try {
callback.call(self, err); callback.call(this, err);
} }
catch (exc) { catch (exc) {
console.exception(exc); console.exception(exc);
@ -189,34 +184,32 @@ function TextWriter(outputStream, charset) {
}); });
}; };
} }
exports.TextWriter = TextWriter;
// This manages the lifetime of stream, a TextReader or TextWriter. It defines // This manages the lifetime of stream, a TextReader or TextWriter. It defines
// closed and close() on stream and registers an unload listener that closes // closed and close() on stream and registers an unload listener that closes
// rawStream if it's still opened. It also provides ensureOpened(), which // rawStream if it's still opened. It also provides ensureOpened(), which
// throws an exception if the stream is closed. // throws an exception if the stream is closed.
function StreamManager(stream, rawStream) { function StreamManager(stream, rawStream) {
const self = this;
this.rawStream = rawStream; this.rawStream = rawStream;
this.opened = true; this.opened = true;
/** /**
* True iff the stream is closed. * True iff the stream is closed.
*/ */
stream.__defineGetter__("closed", function stream_closed() { stream.__defineGetter__("closed", () => !this.opened);
return !self.opened;
});
/** /**
* Closes both the stream and its backing stream. If the stream is already * Closes both the stream and its backing stream. If the stream is already
* closed, an exception is thrown. For TextWriters, this first flushes the * closed, an exception is thrown. For TextWriters, this first flushes the
* backing stream's buffer. * backing stream's buffer.
*/ */
stream.close = function stream_close() { stream.close = () => {
self.ensureOpened(); this.ensureOpened();
self.unload(); this.unload();
}; };
require("../system/unload").ensure(this); ensure(this);
} }
StreamManager.prototype = { StreamManager.prototype = {

Просмотреть файл

@ -1,7 +1,6 @@
/* This Source Code Form is subject to the terms of the Mozilla Public /* 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 * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict"; "use strict";
module.metadata = { module.metadata = {
@ -13,7 +12,7 @@ module.metadata = {
}; };
const { Cc, Ci } = require('chrome'); const { Cc, Ci } = require('chrome');
const { defer, all, resolve } = require('../../core/promise'); const { all } = require('../../core/promise');
const { safeMerge, omit } = require('../../util/object'); const { safeMerge, omit } = require('../../util/object');
const historyService = Cc['@mozilla.org/browser/nav-history-service;1'] const historyService = Cc['@mozilla.org/browser/nav-history-service;1']
.getService(Ci.nsINavHistoryService); .getService(Ci.nsINavHistoryService);
@ -45,13 +44,11 @@ const PLACES_PROPERTIES = [
]; ];
function execute (queries, options) { function execute (queries, options) {
let deferred = defer(); return new Promise(resolve => {
let root = historyService let root = historyService
.executeQueries(queries, queries.length, options).root; .executeQueries(queries, queries.length, options).root;
resolve(collect([], root));
let items = collect([], root); });
deferred.resolve(items);
return deferred.promise;
} }
function collect (acc, node) { function collect (acc, node) {
@ -69,40 +66,35 @@ function collect (acc, node) {
} }
function query (queries, options) { function query (queries, options) {
queries = queries || []; return new Promise((resolve, reject) => {
options = options || {}; queries = queries || [];
let deferred = defer(); options = options || {};
let optionsObj, queryObjs; let optionsObj, queryObjs;
try {
optionsObj = historyService.getNewQueryOptions(); optionsObj = historyService.getNewQueryOptions();
queryObjs = [].concat(queries).map(createQuery); queryObjs = [].concat(queries).map(createQuery);
if (!queryObjs.length) { if (!queryObjs.length) {
queryObjs = [historyService.getNewQuery()]; queryObjs = [historyService.getNewQuery()];
} }
safeMerge(optionsObj, options); safeMerge(optionsObj, options);
} catch (e) {
deferred.reject(e);
return deferred.promise;
}
/* /*
* Currently `places:` queries are not supported * Currently `places:` queries are not supported
*/ */
optionsObj.excludeQueries = true; optionsObj.excludeQueries = true;
execute(queryObjs, optionsObj).then(function (results) { execute(queryObjs, optionsObj).then((results) => {
if (optionsObj.queryType === 0) { if (optionsObj.queryType === 0) {
return results.map(normalize); return results.map(normalize);
} else if (optionsObj.queryType === 1) { }
// Formats query results into more standard else if (optionsObj.queryType === 1) {
// data structures for returning // Formats query results into more standard
return all(results.map(({itemId}) => // data structures for returning
send('sdk-places-bookmarks-get', { id: itemId }))); return all(results.map(({itemId}) =>
} send('sdk-places-bookmarks-get', { id: itemId })));
}).then(deferred.resolve, deferred.reject); }
}).then(resolve, reject);
return deferred.promise; });
} }
exports.query = query; exports.query = query;
@ -140,7 +132,7 @@ function queryReceiver (message) {
/* /*
* Converts a nsINavHistoryResultNode into a plain object * Converts a nsINavHistoryResultNode into a plain object
* *
* https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsINavHistoryResultNode * https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsINavHistoryResultNode
*/ */
function normalize (historyObj) { function normalize (historyObj) {
@ -150,7 +142,8 @@ function normalize (historyObj) {
else if (prop === 'time') { else if (prop === 'time') {
// Cast from microseconds to milliseconds // Cast from microseconds to milliseconds
obj.time = Math.floor(historyObj.time / 1000) obj.time = Math.floor(historyObj.time / 1000)
} else if (prop === 'accessCount') }
else if (prop === 'accessCount')
obj.visitCount = historyObj[prop]; obj.visitCount = historyObj[prop];
else else
obj[prop] = historyObj[prop]; obj[prop] = historyObj[prop];

Просмотреть файл

@ -51,14 +51,14 @@ exports.TreeNode = TreeNode;
/* /*
* Descends down from `node` applying `fn` to each in order. * Descends down from `node` applying `fn` to each in order.
* `fn` can return values or promises -- if promise returned, * `fn` can return values or promises -- if promise returned,
* children are not processed until resolved. `fn` is passed * children are not processed until resolved. `fn` is passed
* one argument, the current node, `curr`. * one argument, the current node, `curr`.
*/ */
function walk (curr, fn) { function walk (curr, fn) {
return promised(fn)(curr).then(val => { return promised(fn)(curr).then(val => {
return all(curr.children.map(child => walk(child, fn))); return all(curr.children.map(child => walk(child, fn)));
}); });
} }
/* /*
* Descends from the TreeNode `node`, returning * Descends from the TreeNode `node`, returning
@ -122,7 +122,7 @@ exports.isRootGroup = isRootGroup;
/* /*
* Merges appropriate options into query based off of url * Merges appropriate options into query based off of url
* 4 scenarios: * 4 scenarios:
* *
* 'moz.com' // domain: moz.com, domainIsHost: true * 'moz.com' // domain: moz.com, domainIsHost: true
* --> 'http://moz.com', 'http://moz.com/thunderbird' * --> 'http://moz.com', 'http://moz.com/thunderbird'
* '*.moz.com' // domain: moz.com, domainIsHost: false * '*.moz.com' // domain: moz.com, domainIsHost: false
@ -177,9 +177,9 @@ function createQuery (type, query) {
let qObj = { let qObj = {
searchTerms: query.query searchTerms: query.query
}; };
urlQueryParser(qObj, query.url); urlQueryParser(qObj, query.url);
// 0 === history // 0 === history
if (type === 0) { if (type === 0) {
// PRTime used by query is in microseconds, not milliseconds // PRTime used by query is in microseconds, not milliseconds
@ -194,7 +194,7 @@ function createQuery (type, query) {
else if (type === 1) { else if (type === 1) {
qObj.tags = query.tags; qObj.tags = query.tags;
qObj.folder = query.group && query.group.id; qObj.folder = query.group && query.group.id;
} }
// 2 === unified (not implemented on platform) // 2 === unified (not implemented on platform)
else if (type === 2) { else if (type === 2) {

Просмотреть файл

@ -27,6 +27,9 @@ const metadata = options.metadata || {};
const permissions = metadata.permissions || {}; const permissions = metadata.permissions || {};
const isPacked = rootURI && rootURI.indexOf("jar:") === 0; const isPacked = rootURI && rootURI.indexOf("jar:") === 0;
const isPrivateBrowsingSupported = 'private-browsing' in permissions &&
permissions['private-browsing'] === true;
const uri = (path="") => const uri = (path="") =>
path.includes(":") ? path : addonDataURI + path.replace(/^\.\//, ""); path.includes(":") ? path : addonDataURI + path.replace(/^\.\//, "");
@ -55,4 +58,4 @@ exports.data = Object.freeze({
return readURISync(uri(path)); return readURISync(uri(path));
} }
}); });
exports.isPrivateBrowsingSupported = permissions['private-browsing'] === true; exports.isPrivateBrowsingSupported = isPrivateBrowsingSupported;

Просмотреть файл

@ -14,16 +14,6 @@ module.metadata = {
const { getTabForContentWindow, getTabForBrowser: getRawTabForBrowser } = require('./utils'); const { getTabForContentWindow, getTabForBrowser: getRawTabForBrowser } = require('./utils');
const { modelFor } = require('../model/core'); const { modelFor } = require('../model/core');
function getTabForWindow(win) {
let tab = getTabForContentWindow(win);
// We were unable to find the related tab!
if (!tab)
return null;
return modelFor(tab);
}
exports.getTabForWindow = getTabForWindow;
exports.getTabForRawTab = modelFor; exports.getTabForRawTab = modelFor;
function getTabForBrowser(browser) { function getTabForBrowser(browser) {

Просмотреть файл

@ -71,26 +71,6 @@ const Tab = Class({
}, },
set url(url) setTabURL(tabNS(this).tab, url), set url(url) setTabURL(tabNS(this).tab, url),
/**
* URI of the favicon for the page currently loaded in this tab.
* @type {String}
*/
get favicon() {
/*
* Synchronous favicon services were never supported on Fennec,
* and as of FF22, are now deprecated. When/if favicon services
* are supported for Fennec, this getter should reference
* `require('sdk/places/favicon').getFavicon`
*/
console.error(
'tab.favicon is deprecated, and currently ' +
'favicon helpers are not yet supported by Fennec'
);
// return 16x16 blank default
return 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAEklEQVQ4jWNgGAWjYBSMAggAAAQQAAF/TXiOAAAAAElFTkSuQmCC';
},
getThumbnail: function() { getThumbnail: function() {
// TODO: implement! // TODO: implement!
console.error(ERR_FENNEC_MSG); console.error(ERR_FENNEC_MSG);

Просмотреть файл

@ -15,8 +15,6 @@ const { getBrowserForTab, setTabURL, getTabId, getTabURL, getTabForBrowser,
getTabs, getTabTitle, setTabTitle, getIndex, closeTab, reload, move, getTabs, getTabTitle, setTabTitle, getIndex, closeTab, reload, move,
activateTab, pin, unpin, isTab } = require('./utils'); activateTab, pin, unpin, isTab } = require('./utils');
const { isBrowser, getInnerId, isWindowPrivate } = require('../window/utils'); const { isBrowser, getInnerId, isWindowPrivate } = require('../window/utils');
const { getFaviconURIForLocation } = require("../io/data");
const { deprecateUsage } = require('../util/deprecate');
const { getThumbnailURIForWindow, BLANK } = require("../content/thumbnail"); const { getThumbnailURIForWindow, BLANK } = require("../content/thumbnail");
const { when } = require('../system/unload'); const { when } = require('../system/unload');
const { ignoreWindow, isPrivate } = require('../private-browsing/utils') const { ignoreWindow, isPrivate } = require('../private-browsing/utils')
@ -96,14 +94,6 @@ const Tab = Class({
setTabURL(viewsFor.get(this), val); setTabURL(viewsFor.get(this), val);
}, },
get favicon() {
deprecateUsage(
'tab.favicon is deprecated, ' +
'please use require("sdk/places/favicon").getFavicon instead.'
);
return isDestroyed(this) ? undefined : getFaviconURIForLocation(this.url);
},
get contentType() { get contentType() {
return isDestroyed(this) ? undefined : browser(this).documentContentType; return isDestroyed(this) ? undefined : browser(this).documentContentType;
}, },

Просмотреть файл

@ -15,7 +15,6 @@ const { PlainTextConsole } = require("../console/plain-text");
const { when: unload } = require("../system/unload"); const { when: unload } = require("../system/unload");
const { format, fromException } = require("../console/traceback"); const { format, fromException } = require("../console/traceback");
const system = require("../system"); const system = require("../system");
const memory = require('../deprecated/memory');
const { gc: gcPromise } = require('./memory'); const { gc: gcPromise } = require('./memory');
const { defer } = require('../core/promise'); const { defer } = require('../core/promise');
const { extend } = require('../core/heritage'); const { extend } = require('../core/heritage');
@ -150,7 +149,7 @@ function reportMemoryUsage() {
return emptyPromise(); return emptyPromise();
} }
return gcPromise().then((function () { return gcPromise().then((() => {
var mgr = Cc["@mozilla.org/memory-reporter-manager;1"] var mgr = Cc["@mozilla.org/memory-reporter-manager;1"]
.getService(Ci.nsIMemoryReporterManager); .getService(Ci.nsIMemoryReporterManager);
let count = 0; let count = 0;
@ -158,11 +157,6 @@ function reportMemoryUsage() {
print(((++count == 1) ? "\n" : "") + description + ": " + amount + "\n"); print(((++count == 1) ? "\n" : "") + description + ": " + amount + "\n");
} }
mgr.getReportsForThisProcess(logReporter, null, /* anonymize = */ false); mgr.getReportsForThisProcess(logReporter, null, /* anonymize = */ false);
var weakrefs = [info.weakref.get()
for (info of memory.getObjects())];
weakrefs = [weakref for (weakref of weakrefs) if (weakref)];
print("Tracked memory objects in testing sandbox: " + weakrefs.length + "\n");
})); }));
} }
@ -216,16 +210,6 @@ function showResults() {
function cleanup() { function cleanup() {
let coverObject = {}; let coverObject = {};
try { try {
for (let name in loader.modules)
memory.track(loader.modules[name],
"module global scope: " + name);
memory.track(loader, "Cuddlefish Loader");
if (profileMemory) {
gWeakrefInfo = [{ weakref: info.weakref, bin: info.bin }
for (info of memory.getObjects())];
}
loader.unload(); loader.unload();
if (loader.globals.console.errorsLogged && !results.failed) { if (loader.globals.console.errorsLogged && !results.failed) {
@ -251,7 +235,7 @@ function cleanup() {
consoleListener.unregister(); consoleListener.unregister();
memory.gc(); Cu.forceGC();
} }
catch (e) { catch (e) {
results.failed++; results.failed++;
@ -278,7 +262,7 @@ function cleanup() {
} }
function getPotentialLeaks() { function getPotentialLeaks() {
memory.gc(); Cu.forceGC();
// Things we can assume are part of the platform and so aren't leaks // Things we can assume are part of the platform and so aren't leaks
let GOOD_BASE_URLS = [ let GOOD_BASE_URLS = [

Просмотреть файл

@ -4,17 +4,8 @@
'use strict'; 'use strict';
const { Cu } = require("chrome"); const { Cu } = require("chrome");
const memory = require('../deprecated/memory');
const { defer } = require('../core/promise');
function gc() { function gc() {
let { promise, resolve } = defer(); return new Promise(resolve => Cu.schedulePreciseGC(resolve));
Cu.forceGC();
memory.gc();
Cu.schedulePreciseGC(_ => resolve());
return promise;
} }
exports.gc = gc; exports.gc = gc;

Просмотреть файл

@ -1,36 +0,0 @@
/* 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";
module.metadata = {
"stability": "experimental"
};
const makeDescriptor = (name, method) => ({
get() {
if (!Object.hasOwnProperty.call(this, name)) {
Object.defineProperty(this, name, {value: method.bind(this)});
return this[name];
} else {
return method;
}
}
});
const Bond = function(methods) {
let descriptor = {};
let members = [...Object.getOwnPropertyNames(methods),
...Object.getOwnPropertySymbols(methods)];
for (let name of members) {
let method = methods[name];
if (typeof(method) !== "function") {
throw new TypeError(`Property named "${name}" passed to Bond must be a function`);
}
descriptor[name] = makeDescriptor(name, method);
}
return Object.create(Bond.prototype, descriptor);
}
exports.Bond = Bond;

Просмотреть файл

@ -1,7 +1,6 @@
/* This Source Code Form is subject to the terms of the Mozilla Public /* 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 * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict"; "use strict";
module.metadata = { module.metadata = {
@ -10,9 +9,7 @@ module.metadata = {
const { Class } = require('../core/heritage'); const { Class } = require('../core/heritage');
const { MatchPattern } = require('./match-pattern'); const { MatchPattern } = require('./match-pattern');
const { on, off, emit } = require('../event/core'); const { emit } = require('../event/core');
const { method } = require('../lang/functional');
const objectUtil = require('./object');
const { EventTarget } = require('../event/target'); const { EventTarget } = require('../event/target');
const { List, addListItem, removeListItem } = require('./list'); const { List, addListItem, removeListItem } = require('./list');

Просмотреть файл

@ -1,22 +1,16 @@
/* This Source Code Form is subject to the terms of the Mozilla Public /* 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 * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
'use strict'; "use strict";
const { Cc, Ci, Cu } = require("chrome"); const { Cc, Ci } = require("chrome");
const { defer } = require("../core/promise");
const getZipReader = function getZipReader(aFile) { function getZipReader(aFile) {
let { promise, resolve, reject } = defer(); return new Promise(resolve => {
let zipReader = Cc["@mozilla.org/libjar/zip-reader;1"]. let zipReader = Cc["@mozilla.org/libjar/zip-reader;1"].
createInstance(Ci.nsIZipReader); createInstance(Ci.nsIZipReader);
try {
zipReader.open(aFile); zipReader.open(aFile);
} resolve(zipReader);
catch(e){ });
reject(e);
}
resolve(zipReader);
return promise;
}; };
exports.getZipReader = getZipReader; exports.getZipReader = getZipReader;

Просмотреть файл

@ -874,7 +874,8 @@ function Loader(options) {
metadata: { metadata: {
addonID: options.id, addonID: options.id,
URI: "Addon-SDK" URI: "Addon-SDK"
} },
prototype: options.sandboxPrototype || {}
}); });
} }

Просмотреть файл

@ -13,7 +13,6 @@
"l10n/prefs": "sdk/l10n/prefs", "l10n/prefs": "sdk/l10n/prefs",
"list": "sdk/util/list", "list": "sdk/util/list",
"loader": "sdk/loader/loader", "loader": "sdk/loader/loader",
"memory": "sdk/deprecated/memory",
"namespace": "sdk/core/namespace", "namespace": "sdk/core/namespace",
"preferences-service": "sdk/preferences/service", "preferences-service": "sdk/preferences/service",
"promise": "sdk/core/promise", "promise": "sdk/core/promise",

Просмотреть файл

@ -22,6 +22,7 @@
"async": "0.9.0", "async": "0.9.0",
"chai": "2.1.1", "chai": "2.1.1",
"fs-extra": "0.18.2", "fs-extra": "0.18.2",
"fx-runner": "0.0.7",
"glob": "4.4.2", "glob": "4.4.2",
"gulp": "3.8.11", "gulp": "3.8.11",
"ini-parser": "0.0.2", "ini-parser": "0.0.2",

Просмотреть файл

@ -236,10 +236,6 @@ parser_groups = (
help="Where to put the finished .xpi", help="Where to put the finished .xpi",
default=None, default=None,
cmds=['xpi'])), cmds=['xpi'])),
(("", "--manifest-overload",), dict(dest="manifest_overload",
help="JSON file to overload package.json properties",
default=None,
cmds=['xpi'])),
(("", "--abort-on-missing-module",), dict(dest="abort_on_missing", (("", "--abort-on-missing-module",), dict(dest="abort_on_missing",
help="Abort if required module is missing", help="Abort if required module is missing",
action="store_true", action="store_true",
@ -661,10 +657,6 @@ def run(arguments=sys.argv[1:], target_cfg=None, pkg_cfg=None,
target_cfg_json = os.path.join(options.pkgdir, 'package.json') target_cfg_json = os.path.join(options.pkgdir, 'package.json')
target_cfg = packaging.get_config_in_dir(options.pkgdir) target_cfg = packaging.get_config_in_dir(options.pkgdir)
if options.manifest_overload:
for k, v in packaging.load_json_file(options.manifest_overload).items():
target_cfg[k] = v
# At this point, we're either building an XPI or running Jetpack code in # At this point, we're either building an XPI or running Jetpack code in
# a Mozilla application (which includes running tests). # a Mozilla application (which includes running tests).

Просмотреть файл

@ -1,17 +0,0 @@
/* 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/. */
const { Cc, Ci } = require("chrome");
exports.main = function(options, callbacks) {
// Close Firefox window. Firefox should quit.
require("sdk/deprecated/window-utils").activeBrowserWindow.close();
// But not on Mac where it stay alive! We have to request application quit.
if (require("sdk/system/runtime").OS == "Darwin") {
let appStartup = Cc['@mozilla.org/toolkit/app-startup;1'].
getService(Ci.nsIAppStartup);
appStartup.quit(appStartup.eAttemptQuit);
}
}

Просмотреть файл

@ -1,3 +0,0 @@
{
"version": "1.0-nightly"
}

Просмотреть файл

@ -1,6 +0,0 @@
{
"id": "simplest-test",
"directories": {
"lib": "."
}
}

Просмотреть файл

@ -182,35 +182,6 @@ class TestCfxQuits(unittest.TestCase):
container) container)
self.fail(standardMsg) self.fail(standardMsg)
def test_cfx_run(self):
addon_path = os.path.join(tests_path,
"addons", "simplest-test")
rc, out, err = self.run_cfx(addon_path, ["run"])
self.assertEqual(rc, 0)
self.assertIn("Program terminated successfully.", err)
def test_cfx_test(self):
addon_path = os.path.join(tests_path, "addons", "simplest-test")
rc, out, err = self.run_cfx(addon_path, ["test"])
self.assertEqual(rc, 0)
self.assertIn("1 of 1 tests passed.", err)
self.assertIn("Program terminated successfully.", err)
def test_cfx_xpi(self):
addon_path = os.path.join(tests_path,
"addons", "simplest-test")
rc, out, err = self.run_cfx(addon_path, \
["xpi", "--manifest-overload", "manifest-overload.json"])
self.assertEqual(rc, 0)
# Ensure that the addon version from our manifest overload is used
# in install.rdf
xpi_path = os.path.join(addon_path, "simplest-test.xpi")
xpi = zipfile.ZipFile(xpi_path, "r")
manifest = xpi.read("install.rdf")
self.assertIn("<em:version>1.0-nightly</em:version>", manifest)
xpi.close()
os.remove(xpi_path)
def test_cfx_init(self): def test_cfx_init(self):
# Create an empty test directory # Create an empty test directory
addon_path = os.path.abspath(os.path.join(".test_tmp", "test-cfx-init")) addon_path = os.path.abspath(os.path.join(".test_tmp", "test-cfx-init"))
@ -232,7 +203,7 @@ class TestCfxQuits(unittest.TestCase):
# run cfx test # run cfx test
rc, out, err = self.run_cfx(addon_path, ["test"]) rc, out, err = self.run_cfx(addon_path, ["test"])
self.assertEqual(rc, 0) self.assertEqual(rc, 0)
self.assertIn("2 of 2 tests passed.", err) self.assertIn("6 of 6 tests passed.", err)
self.assertIn("Program terminated successfully.", err) self.assertIn("Program terminated successfully.", err)

Просмотреть файл

@ -6,3 +6,5 @@
self.port.on('echo', _ => { self.port.on('echo', _ => {
self.port.emit('echo', ''); self.port.emit('echo', '');
}); });
self.port.emit('start', '');

Просмотреть файл

@ -67,23 +67,31 @@ exports.testChromeLocale = function(assert) {
'locales en-US folder was copied correctly'); 'locales en-US folder was copied correctly');
} }
exports.testChromeInPanel = function(assert, done) { exports.testChromeInPanel = function*(assert) {
let panel = Panel({ let panel = Panel({
contentURL: 'chrome://test/content/panel.html', contentURL: 'chrome://test/content/panel.html',
contentScriptWhen: 'start', contentScriptWhen: 'end',
contentScriptFile: data.url('panel.js') contentScriptFile: data.url('panel.js')
}); });
panel.once('show', _ => {
assert.pass('panel shown'); yield new Promise(resolve => panel.port.once('start', resolve));
panel.port.once('echo', _ => { assert.pass('start was emitted');
assert.pass('got echo');
panel.destroy(); yield new Promise(resolve => {
assert.pass('panel is destroyed'); panel.once('show', resolve);
done(); panel.show();
}); });
assert.pass('panel shown');
yield new Promise(resolve => {
panel.port.once('echo', resolve);
panel.port.emit('echo'); panel.port.emit('echo');
}); });
panel.show();
assert.pass('got echo');
panel.destroy();
assert.pass('panel is destroyed');
} }
require('sdk/test/runner').runTestsFromModule(module); require('sdk/test/runner').runTestsFromModule(module);

Просмотреть файл

@ -1,122 +1,17 @@
/* This Source Code Form is subject to the terms of the Mozilla Public /* 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 * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict"; "use strict";
const tabs = require("sdk/tabs"); // From addon-kit const tabs = require("sdk/tabs"); // From addon-kit
const windowUtils = require("sdk/deprecated/window-utils"); const windowUtils = require("sdk/deprecated/window-utils");
const { getTabForWindow } = require('sdk/tabs/helpers');
const app = require("sdk/system/xul-app"); const app = require("sdk/system/xul-app");
const { viewFor } = require("sdk/view/core"); const { viewFor } = require("sdk/view/core");
const { modelFor } = require("sdk/model/core"); const { modelFor } = require("sdk/model/core");
const { getTabId, isTab } = require("sdk/tabs/utils"); const { getTabId, isTab } = require("sdk/tabs/utils");
const { defer } = require("sdk/lang/functional"); const { defer } = require("sdk/lang/functional");
// The primary test tab
var primaryTab;
// We have an auxiliary tab to test background tabs.
var auxTab;
// The window for the outer iframe in the primary test page
var iframeWin;
exports["test GetTabForWindow"] = function(assert, done) {
assert.equal(getTabForWindow(windowUtils.activeWindow), null,
"getTabForWindow return null on topwindow");
assert.equal(getTabForWindow(windowUtils.activeBrowserWindow), null,
"getTabForWindow return null on topwindow");
let subSubDocument = encodeURIComponent(
'Sub iframe<br/>'+
'<iframe id="sub-sub-iframe" src="data:text/html;charset=utf-8,SubSubIframe" />');
let subDocument = encodeURIComponent(
'Iframe<br/>'+
'<iframe id="sub-iframe" src="data:text/html;charset=utf-8,'+subSubDocument+'" />');
let url = 'data:text/html;charset=utf-8,' + encodeURIComponent(
'Content<br/><iframe id="iframe" src="data:text/html;charset=utf-8,'+subDocument+'" />');
// Open up a new tab in the background.
//
// This lets us test whether GetTabForWindow works even when the tab in
// question is not active.
tabs.open({
inBackground: true,
url: "about:mozilla",
onReady: function(tab) { auxTab = tab; step2(url, assert);},
onActivate: function(tab) { step3(assert, done); }
});
};
function step2(url, assert) {
tabs.open({
url: url,
onReady: function(tab) {
primaryTab = tab;
let window = windowUtils.activeBrowserWindow.content;
let matchedTab = getTabForWindow(window);
assert.equal(matchedTab, tab,
"We are able to find the tab with his content window object");
let timer = require("sdk/timers");
function waitForFrames() {
let iframe = window.document.getElementById("iframe");
if (!iframe) {
timer.setTimeout(waitForFrames, 100);
return;
}
iframeWin = iframe.contentWindow;
let subIframe = iframeWin.document.getElementById("sub-iframe");
if (!subIframe) {
timer.setTimeout(waitForFrames, 100);
return;
}
let subIframeWin = subIframe.contentWindow;
let subSubIframe = subIframeWin.document.getElementById("sub-sub-iframe");
if (!subSubIframe) {
timer.setTimeout(waitForFrames, 100);
return;
}
let subSubIframeWin = subSubIframe.contentWindow;
matchedTab = getTabForWindow(iframeWin);
assert.equal(matchedTab, tab,
"We are able to find the tab with an iframe window object");
matchedTab = getTabForWindow(subIframeWin);
assert.equal(matchedTab, tab,
"We are able to find the tab with a sub-iframe window object");
matchedTab = getTabForWindow(subSubIframeWin);
assert.equal(matchedTab, tab,
"We are able to find the tab with a sub-sub-iframe window object");
// Put our primary tab in the background and test again.
// The onActivate listener will take us to step3.
auxTab.activate();
}
waitForFrames();
}
});
}
function step3(assert, done) {
let matchedTab = getTabForWindow(iframeWin);
assert.equal(matchedTab, primaryTab,
"We get the correct tab even when it's in the background");
primaryTab.close(function () {
auxTab.close(function () { done();});
});
}
exports["test behavior on close"] = function(assert, done) { exports["test behavior on close"] = function(assert, done) {
tabs.open({ tabs.open({
url: "about:mozilla", url: "about:mozilla",
onReady: function(tab) { onReady: function(tab) {
@ -156,7 +51,6 @@ exports["test viewFor(tab)"] = (assert, done) => {
tabs.open({ url: "about:mozilla" }); tabs.open({ url: "about:mozilla" });
}; };
exports["test modelFor(xulTab)"] = (assert, done) => { exports["test modelFor(xulTab)"] = (assert, done) => {
tabs.open({ tabs.open({
url: "about:mozilla", url: "about:mozilla",

Просмотреть файл

@ -147,19 +147,9 @@ exports["test compatibility"] = function(assert) {
assert.equal(require("tabs/tab.js"), assert.equal(require("tabs/tab.js"),
require("sdk/tabs/tab"), "sdk/tabs/tab -> tabs/tab.js"); require("sdk/tabs/tab"), "sdk/tabs/tab -> tabs/tab.js");
assert.equal(require("memory"),
require("sdk/deprecated/memory"), "sdk/deprecated/memory -> memory");
assert.equal(require("environment"), assert.equal(require("environment"),
require("sdk/system/environment"), "sdk/system/environment -> environment"); require("sdk/system/environment"), "sdk/system/environment -> environment");
if (app.is("Firefox")) {
// This module fails on fennec because of favicon xpcom component
// being not implemented on it.
assert.equal(require("utils/data"),
require("sdk/io/data"), "sdk/io/data -> utils/data");
}
assert.equal(require("test/assert"), assert.equal(require("test/assert"),
require("sdk/test/assert"), "sdk/test/assert -> test/assert"); require("sdk/test/assert"), "sdk/test/assert -> test/assert");

Просмотреть файл

@ -33,13 +33,6 @@ function invalidResolve (assert) {
} }
exports.invalidResolve = invalidResolve; exports.invalidResolve = invalidResolve;
function invalidReject (assert) {
return function (e) {
assert.fail('Reject state should not be called: ' + e);
};
}
exports.invalidReject = invalidReject;
// Removes all children of group // Removes all children of group
function clearBookmarks (group) { function clearBookmarks (group) {
group group

Просмотреть файл

@ -24,7 +24,7 @@ const {
MENU, TOOLBAR, UNSORTED MENU, TOOLBAR, UNSORTED
} = require('sdk/places/bookmarks'); } = require('sdk/places/bookmarks');
const { const {
invalidResolve, invalidReject, createTree, invalidResolve, createTree,
compareWithHost, createBookmark, createBookmarkItem, compareWithHost, createBookmark, createBookmarkItem,
createBookmarkTree, addVisits, resetPlaces createBookmarkTree, addVisits, resetPlaces
} = require('./places-helper'); } = require('./places-helper');
@ -369,28 +369,27 @@ exports.testPromisedSave = function (assert, done) {
}).then(done).catch(assert.fail); }).then(done).catch(assert.fail);
}; };
exports.testPromisedErrorSave = function (assert, done) { exports.testPromisedErrorSave = function*(assert) {
let bookmarks = [ let bookmarks = [
{ title: 'moz1', url: 'http://moz1.com', type: 'bookmark'}, { title: 'moz1', url: 'http://moz1.com', type: 'bookmark'},
{ title: 'moz2', url: 'invalidurl', type: 'bookmark'}, { title: 'moz2', url: 'invalidurl', type: 'bookmark'},
{ title: 'moz3', url: 'http://moz3.com', type: 'bookmark'} { title: 'moz3', url: 'http://moz3.com', type: 'bookmark'}
]; ];
saveP(bookmarks).then(invalidResolve, reason => { yield saveP(bookmarks).then(() => {
assert.fail("should not resolve");
}, reason => {
assert.ok( assert.ok(
/The `url` property must be a valid URL/.test(reason), /The `url` property must be a valid URL/.test(reason),
'Error event called with correct reason'); 'Error event called with correct reason');
});
bookmarks[1].url = 'http://moz2.com'; bookmarks[1].url = 'http://moz2.com';
return saveP(bookmarks); yield saveP(bookmarks);
}).
then(res => searchP({ query: 'moz' })). let res = yield searchP({ query: 'moz' });
then(res => { assert.equal(res.length, 3, 'all 3 should be saved upon retry');
assert.equal(res.length, 3, 'all 3 should be saved upon retry'); res.map(item => assert.ok(/moz\d\.com/.test(item.url), 'correct item'));
res.map(item => assert.ok(/moz\d\.com/.test(item.url), 'correct item'));
done();
}, invalidReject).
catch(assert.fail);
}; };
exports.testMovingChildren = function (assert, done) { exports.testMovingChildren = function (assert, done) {
@ -692,61 +691,63 @@ exports.testSearchTags = function (assert, done) {
* 'http://mozilla.com/' * 'http://mozilla.com/'
* 'http://mozilla.com/*' * 'http://mozilla.com/*'
*/ */
exports.testSearchURL = function (assert, done) { exports.testSearchURLForBookmarks = function*(assert) {
createBookmarkTree().then(() => { yield createBookmarkTree()
return searchP({ url: 'mozilla.org' }); let data = yield searchP({ url: 'mozilla.org' });
}).then(data => {
assert.equal(data.length, 2, 'only URLs with host domain'); assert.equal(data.length, 2, 'only URLs with host domain');
assert.equal(data[0].url, 'http://mozilla.org/'); assert.equal(data[0].url, 'http://mozilla.org/');
assert.equal(data[1].url, 'http://mozilla.org/thunderbird/'); assert.equal(data[1].url, 'http://mozilla.org/thunderbird/');
return searchP({ url: '*.mozilla.org' });
}).then(data => { data = yield searchP({ url: '*.mozilla.org' });
assert.equal(data.length, 3, 'returns domain and when host is other than domain');
assert.equal(data[0].url, 'http://mozilla.org/'); assert.equal(data.length, 3, 'returns domain and when host is other than domain');
assert.equal(data[1].url, 'http://mozilla.org/thunderbird/'); assert.equal(data[0].url, 'http://mozilla.org/');
assert.equal(data[2].url, 'http://developer.mozilla.org/en-US/'); assert.equal(data[1].url, 'http://mozilla.org/thunderbird/');
return searchP({ url: 'http://mozilla.org' }); assert.equal(data[2].url, 'http://developer.mozilla.org/en-US/');
}).then(data => {
assert.equal(data.length, 1, 'only exact URL match'); data = yield searchP({ url: 'http://mozilla.org' });
assert.equal(data[0].url, 'http://mozilla.org/');
return searchP({ url: 'http://mozilla.org/*' }); assert.equal(data.length, 1, 'only exact URL match');
}).then(data => { assert.equal(data[0].url, 'http://mozilla.org/');
assert.equal(data.length, 2, 'only URLs that begin with query');
assert.equal(data[0].url, 'http://mozilla.org/'); data = yield searchP({ url: 'http://mozilla.org/*' });
assert.equal(data[1].url, 'http://mozilla.org/thunderbird/');
return searchP([{ url: 'mozilla.org' }, { url: 'component.fm' }]); assert.equal(data.length, 2, 'only URLs that begin with query');
}).then(data => { assert.equal(data[0].url, 'http://mozilla.org/');
assert.equal(data.length, 3, 'returns URLs that match EITHER query'); assert.equal(data[1].url, 'http://mozilla.org/thunderbird/');
assert.equal(data[0].url, 'http://mozilla.org/');
assert.equal(data[1].url, 'http://mozilla.org/thunderbird/'); data = yield searchP([{ url: 'mozilla.org' }, { url: 'component.fm' }]);
assert.equal(data[2].url, 'http://component.fm/');
}).then(done).catch(assert.fail); assert.equal(data.length, 3, 'returns URLs that match EITHER query');
assert.equal(data[0].url, 'http://mozilla.org/');
assert.equal(data[1].url, 'http://mozilla.org/thunderbird/');
assert.equal(data[2].url, 'http://component.fm/');
}; };
/* /*
* Searches url, title, tags * Searches url, title, tags
*/ */
exports.testSearchQuery = function (assert, done) { exports.testSearchQueryForBookmarks = function*(assert) {
createBookmarkTree().then(() => { yield createBookmarkTree();
return searchP({ query: 'thunder' });
}).then(data => { let data = yield searchP({ query: 'thunder' });
assert.equal(data.length, 3); assert.equal(data.length, 3);
assert.equal(data[0].title, 'mozilla.com', 'query matches tag, url, or title'); assert.equal(data[0].title, 'mozilla.com', 'query matches tag, url, or title');
assert.equal(data[1].title, 'mozilla.org', 'query matches tag, url, or title'); assert.equal(data[1].title, 'mozilla.org', 'query matches tag, url, or title');
assert.equal(data[2].title, 'thunderbird', 'query matches tag, url, or title'); assert.equal(data[2].title, 'thunderbird', 'query matches tag, url, or title');
return searchP([{ query: 'rust' }, { query: 'component' }]);
}).then(data => { data = yield searchP([{ query: 'rust' }, { query: 'component' }]);
// rust OR component // rust OR component
assert.equal(data.length, 3); assert.equal(data.length, 3);
assert.equal(data[0].title, 'mozilla.com', 'query matches tag, url, or title'); assert.equal(data[0].title, 'mozilla.com', 'query matches tag, url, or title');
assert.equal(data[1].title, 'mozilla.org', 'query matches tag, url, or title'); assert.equal(data[1].title, 'mozilla.org', 'query matches tag, url, or title');
assert.equal(data[2].title, 'web audio components', 'query matches tag, url, or title'); assert.equal(data[2].title, 'web audio components', 'query matches tag, url, or title');
return searchP([{ query: 'moz', tags: ['javascript']}]);
}).then(data => { data = yield searchP([{ query: 'moz', tags: ['javascript']}]);
assert.equal(data.length, 1); assert.equal(data.length, 1);
assert.equal(data[0].title, 'mdn', assert.equal(data[0].title, 'mdn',
'only one item matches moz query AND has a javascript tag'); 'only one item matches moz query AND has a javascript tag');
}).then(done).catch(assert.fail);
}; };
/* /*
@ -827,7 +828,7 @@ exports.testSearchCount = function (assert, done) {
} }
}; };
exports.testSearchSort = function (assert, done) { exports.testSearchSortForBookmarks = function (assert, done) {
let urls = [ let urls = [
'http://mozilla.com/', 'http://webaud.io/', 'http://mozilla.com/webfwd/', 'http://mozilla.com/', 'http://webaud.io/', 'http://mozilla.com/webfwd/',
'http://developer.mozilla.com/', 'http://bandcamp.com/' 'http://developer.mozilla.com/', 'http://bandcamp.com/'

Просмотреть файл

@ -27,7 +27,7 @@ const isOSX10_6 = (() => {
const { search } = require('sdk/places/history'); const { search } = require('sdk/places/history');
const { const {
invalidResolve, invalidReject, createTree, createBookmark, invalidResolve, createTree, createBookmark,
compareWithHost, addVisits, resetPlaces, createBookmarkItem, compareWithHost, addVisits, resetPlaces, createBookmarkItem,
removeVisits, historyBatch removeVisits, historyBatch
} = require('./places-helper'); } = require('./places-helper');

Просмотреть файл

@ -19,45 +19,44 @@ const {
search search
} = require('sdk/places/history'); } = require('sdk/places/history');
const { const {
invalidResolve, invalidReject, createTree, invalidResolve, createTree,
compareWithHost, addVisits, resetPlaces compareWithHost, addVisits, resetPlaces
} = require('./places-helper'); } = require('./places-helper');
const { promisedEmitter } = require('sdk/places/utils'); const { promisedEmitter } = require('sdk/places/utils');
exports.testEmptyQuery = function (assert, done) { exports.testEmptyQuery = function*(assert) {
let within = toBeWithin(); let within = toBeWithin();
addVisits([ yield addVisits([
'http://simplequery-1.com', 'http://simplequery-2.com' 'http://simplequery-1.com', 'http://simplequery-2.com'
]).then(searchP).then(results => { ]);
assert.equal(results.length, 2, 'Correct number of entries returned');
assert.equal(results[0].url, 'http://simplequery-1.com/', let results = yield searchP();
'matches url'); assert.equal(results.length, 2, 'Correct number of entries returned');
assert.equal(results[1].url, 'http://simplequery-2.com/', assert.equal(results[0].url, 'http://simplequery-1.com/',
'matches url'); 'matches url');
assert.equal(results[0].title, 'Test visit for ' + results[0].url, assert.equal(results[1].url, 'http://simplequery-2.com/',
'title matches'); 'matches url');
assert.equal(results[1].title, 'Test visit for ' + results[1].url, assert.equal(results[0].title, 'Test visit for ' + results[0].url,
'title matches'); 'title matches');
assert.equal(results[0].visitCount, 1, 'matches access'); assert.equal(results[1].title, 'Test visit for ' + results[1].url,
assert.equal(results[1].visitCount, 1, 'matches access'); 'title matches');
assert.ok(within(results[0].time), 'accurate access time'); assert.equal(results[0].visitCount, 1, 'matches access');
assert.ok(within(results[1].time), 'accurate access time'); assert.equal(results[1].visitCount, 1, 'matches access');
assert.equal(Object.keys(results[0]).length, 4, assert.ok(within(results[0].time), 'accurate access time');
'no addition exposed properties on history result'); assert.ok(within(results[1].time), 'accurate access time');
done(); assert.equal(Object.keys(results[0]).length, 4,
}, invalidReject); 'no addition exposed properties on history result');
}; };
exports.testVisitCount = function (assert, done) { exports.testVisitCount = function*(assert) {
addVisits([ yield addVisits([
'http://simplequery-1.com', 'http://simplequery-1.com', 'http://simplequery-1.com', 'http://simplequery-1.com',
'http://simplequery-1.com', 'http://simplequery-1.com' 'http://simplequery-1.com', 'http://simplequery-1.com'
]).then(searchP).then(results => { ]);
assert.equal(results.length, 1, 'Correct number of entries returned'); let results = yield searchP();
assert.equal(results[0].url, 'http://simplequery-1.com/', 'correct url'); assert.equal(results.length, 1, 'Correct number of entries returned');
assert.equal(results[0].visitCount, 4, 'matches access count'); assert.equal(results[0].url, 'http://simplequery-1.com/', 'correct url');
done(); assert.equal(results[0].visitCount, 4, 'matches access count');
}, invalidReject);
}; };
/* /*
@ -67,24 +66,23 @@ exports.testVisitCount = function (assert, done) {
* 'http://mozilla.org/' * 'http://mozilla.org/'
* 'http://mozilla.org/*' * 'http://mozilla.org/*'
*/ */
exports.testSearchURL = function (assert, done) { exports.testSearchURLForHistory = function*(assert) {
addVisits([ yield addVisits([
'http://developer.mozilla.org', 'http://mozilla.org', 'http://developer.mozilla.org', 'http://mozilla.org',
'http://mozilla.org/index', 'https://mozilla.org' 'http://mozilla.org/index', 'https://mozilla.org'
]).then(() => searchP({ url: '*.mozilla.org' })) ]);
.then(results => {
assert.equal(results.length, 4, 'returns all entries'); let results = yield searchP({ url: 'http://mozilla.org/' });
return searchP({ url: 'mozilla.org' }); assert.equal(results.length, 1, 'should just be an exact match');
}).then(results => {
assert.equal(results.length, 3, 'returns entries where mozilla.org is host'); results = yield searchP({ url: '*.mozilla.org' });
return searchP({ url: 'http://mozilla.org/' }); assert.equal(results.length, 4, 'returns all entries');
}).then(results => {
assert.equal(results.length, 1, 'should just be an exact match'); results = yield searchP({ url: 'mozilla.org' });
return searchP({ url: 'http://mozilla.org/*' }); assert.equal(results.length, 3, 'returns entries where mozilla.org is host');
}).then(results => {
assert.equal(results.length, 2, 'should match anything starting with substring'); results = yield searchP({ url: 'http://mozilla.org/*' });
done(); assert.equal(results.length, 2, 'should match anything starting with substring');
});
}; };
// Disabling due to intermittent Bug 892619 // Disabling due to intermittent Bug 892619
@ -124,23 +122,21 @@ exports.testSearchTimeRange = function (assert, done) {
}); });
}; };
*/ */
exports.testSearchQuery = function (assert, done) { exports.testSearchQueryForHistory = function*(assert) {
addVisits([ yield addVisits([
'http://mozilla.com', 'http://webaud.io', 'http://mozilla.com/webfwd' 'http://mozilla.com', 'http://webaud.io', 'http://mozilla.com/webfwd'
]).then(() => { ]);
return searchP({ query: 'moz' });
}).then(results => { let results = yield searchP({ query: 'moz' });
assert.equal(results.length, 2, 'should return urls that match substring'); assert.equal(results.length, 2, 'should return urls that match substring');
results.map(({url}) => { results.map(({url}) => {
assert.ok(/moz/.test(url), 'correct item'); assert.ok(/moz/.test(url), 'correct item');
}); });
return searchP([{ query: 'webfwd' }, { query: 'aud.io' }]);
}).then(results => { results = yield searchP([{ query: 'webfwd' }, { query: 'aud.io' }]);
assert.equal(results.length, 2, 'should OR separate queries'); assert.equal(results.length, 2, 'should OR separate queries');
results.map(({url}) => { results.map(({url}) => {
assert.ok(/webfwd|aud\.io/.test(url), 'correct item'); assert.ok(/webfwd|aud\.io/.test(url), 'correct item');
});
done();
}); });
}; };
@ -168,51 +164,50 @@ exports.testSearchCount = function (assert, done) {
} }
}; };
exports.testSearchSort = function (assert, done) { exports.testSearchSortForHistory = function*(assert) {
let places = [
'http://mozilla.com/', 'http://webaud.io/', 'http://mozilla.com/webfwd/',
'http://developer.mozilla.com/', 'http://bandcamp.com/'
];
addVisits(places).then(() => {
return searchP({}, { sort: 'title' });
}).then(results => {
checkOrder(results, [4,3,0,2,1]);
return searchP({}, { sort: 'title', descending: true });
}).then(results => {
checkOrder(results, [1,2,0,3,4]);
return searchP({}, { sort: 'url' });
}).then(results => {
checkOrder(results, [4,3,0,2,1]);
return searchP({}, { sort: 'url', descending: true });
}).then(results => {
checkOrder(results, [1,2,0,3,4]);
return addVisits('http://mozilla.com') // for visit conut
.then(() => addVisits('http://github.com')); // for checking date
}).then(() => {
return searchP({}, { sort: 'visitCount' });
}).then(results => {
assert.equal(results[5].url, 'http://mozilla.com/',
'last entry is the highest visit count');
return searchP({}, { sort: 'visitCount', descending: true });
}).then(results => {
assert.equal(results[0].url, 'http://mozilla.com/',
'first entry is the highest visit count');
return searchP({}, { sort: 'date' });
}).then(results => {
assert.equal(results[5].url, 'http://github.com/',
'latest visited should be first');
return searchP({}, { sort: 'date', descending: true });
}).then(results => {
assert.equal(results[0].url, 'http://github.com/',
'latest visited should be at the end');
}).then(done);
function checkOrder (results, nums) { function checkOrder (results, nums) {
assert.equal(results.length, nums.length, 'expected return count'); assert.equal(results.length, nums.length, 'expected return count');
for (let i = 0; i < nums.length; i++) { for (let i = 0; i < nums.length; i++) {
assert.equal(results[i].url, places[nums[i]], 'successful order'); assert.equal(results[i].url, places[nums[i]], 'successful order');
} }
} }
let places = [
'http://mozilla.com/', 'http://webaud.io/', 'http://mozilla.com/webfwd/',
'http://developer.mozilla.com/', 'http://bandcamp.com/'
];
yield addVisits(places);
let results = yield searchP({}, { sort: 'title' });
checkOrder(results, [4,3,0,2,1]);
results = yield searchP({}, { sort: 'title', descending: true });
checkOrder(results, [1,2,0,3,4]);
results = yield searchP({}, { sort: 'url' });
checkOrder(results, [4,3,0,2,1]);
results = yield searchP({}, { sort: 'url', descending: true });
checkOrder(results, [1,2,0,3,4]);
yield addVisits('http://mozilla.com'); // for visit conut
yield addVisits('http://github.com'); // for checking date
results = yield searchP({}, { sort: 'visitCount' });
assert.equal(results[5].url, 'http://mozilla.com/',
'last entry is the highest visit count');
results = yield searchP({}, { sort: 'visitCount', descending: true });
assert.equal(results[0].url, 'http://mozilla.com/',
'first entry is the highest visit count');
results = yield searchP({}, { sort: 'date' });
assert.equal(results[5].url, 'http://github.com/',
'latest visited should be first');
results = yield searchP({}, { sort: 'date', descending: true });
assert.equal(results[0].url, 'http://github.com/',
'latest visited should be at the end');
}; };
exports.testEmitters = function (assert, done) { exports.testEmitters = function (assert, done) {

Просмотреть файл

@ -21,7 +21,7 @@ require('sdk/places/host/host-bookmarks');
require('sdk/places/host/host-tags'); require('sdk/places/host/host-tags');
require('sdk/places/host/host-query'); require('sdk/places/host/host-query');
const { const {
invalidResolve, invalidReject, createTree, invalidResolve, createTree,
compareWithHost, createBookmark, createBookmarkTree, resetPlaces compareWithHost, createBookmark, createBookmarkTree, resetPlaces
} = require('./places-helper'); } = require('./places-helper');
@ -32,7 +32,7 @@ const hsrv = Cc['@mozilla.org/browser/nav-history-service;1'].
const tagsrv = Cc['@mozilla.org/browser/tagging-service;1']. const tagsrv = Cc['@mozilla.org/browser/tagging-service;1'].
getService(Ci.nsITaggingService); getService(Ci.nsITaggingService);
exports.testBookmarksCreate = function (assert, done) { exports.testBookmarksCreate = function*(assert) {
let items = [{ let items = [{
title: 'my title', title: 'my title',
url: 'http://test-places-host.com/testBookmarksCreate/', url: 'http://test-places-host.com/testBookmarksCreate/',
@ -47,13 +47,11 @@ exports.testBookmarksCreate = function (assert, done) {
group: bmsrv.unfiledBookmarksFolder group: bmsrv.unfiledBookmarksFolder
}]; }];
all(items.map(function (item) { yield all(items.map((item) => {
return send('sdk-places-bookmarks-create', item).then(function (data) { return send('sdk-places-bookmarks-create', item).then((data) => {
compareWithHost(assert, data); compareWithHost(assert, data);
}, invalidReject(assert)); });
})).then(function () { }));
done();
}, invalidReject(assert));
}; };
exports.testBookmarksCreateFail = function (assert, done) { exports.testBookmarksCreateFail = function (assert, done) {

Просмотреть файл

@ -1,5 +1,6 @@
/* This Source Code Form is subject to the terms of the Mozilla Public /* 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 * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
exports.local = true; exports.local = true;

Просмотреть файл

@ -6,10 +6,10 @@
var { isNative } = require("@loader/options"); var { isNative } = require("@loader/options");
exports["test local vs sdk module"] = function (assert) { exports["test local vs sdk module"] = function (assert) {
assert.notEqual(require("memory"), assert.notEqual(require("list"),
require("sdk/deprecated/memory"), require("sdk/util/list"),
"Local module takes the priority over sdk modules"); "Local module takes the priority over sdk modules");
assert.ok(require("memory").local, assert.ok(require("list").local,
"this module is really the local one"); "this module is really the local one");
} }

5
addon-sdk/source/test/fixtures/index.html поставляемый
Просмотреть файл

@ -9,5 +9,10 @@
</head> </head>
<body> <body>
<p>This is an add-on page test!</p> <p>This is an add-on page test!</p>
<script>
function getTestURL() {
return window.document.documentURI + "";
}
</script>
</body> </body>
</html> </html>

Просмотреть файл

@ -4,3 +4,4 @@
'use strict'; 'use strict';
exports.console = console; exports.console = console;
exports.globalFoo = (typeof globalFoo !== "undefined") ? globalFoo : null;

21
addon-sdk/source/test/fixtures/test-addon-extras-window.html поставляемый Normal file
Просмотреть файл

@ -0,0 +1,21 @@
<!-- 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/. -->
<html>
<head>
<meta charset="UTF-8">
<title>Worker test</title>
</head>
<body>
<p id="paragraph">Lorem ipsum dolor sit amet.</p>
<script>
if ("addon" in window) {
var count = 1;
addon.port.on("get-result", () => {
addon.port.emit("result" + count++, extras.test().getTestURL())
});
}
</script>
</body>
</html>

31
addon-sdk/source/test/fixtures/test-addon-extras.html поставляемый Normal file
Просмотреть файл

@ -0,0 +1,31 @@
<!-- 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/. -->
<html>
<head>
<meta charset="UTF-8">
<title>Worker test</title>
</head>
<body>
<p id="paragraph">Lorem ipsum dolor sit amet.</p>
<script>
if ("addon" in window) {
var count = 1;
addon.port.on("get-result", () => {
console.log("get-result recieved");
addon.port.emit("result" + count++, extras && extras.test())
});
}
window.addEventListener("message", function getMessage({ data }) {
if (data.name == "start") {
window.postMessage({
name: "extras",
result: window.extras === undefined
}, '*');
}
}, false);
</script>
</body>
</html>

12
addon-sdk/source/test/fixtures/test.html поставляемый
Просмотреть файл

@ -9,5 +9,17 @@
</head> </head>
<body> <body>
<p>bar</p> <p>bar</p>
<script>
function getTestURL() {
return window.document.documentURI + "";
}
function changesInWindow() {
window.document.documentElement.setAttribute('test', 'changes in window');
return null;
}
function getAUQLUE() {
return "AUQLUE" in window;
}
</script>
</body> </body>
</html> </html>

Просмотреть файл

@ -4,26 +4,27 @@ support-files =
commonjs-test-adapter/** commonjs-test-adapter/**
context-menu/** context-menu/**
event/** event/**
fixtures.js
fixtures/** fixtures/**
framescript-manager/** framescript-manager/**
framescript-util/** framescript-util/**
loader/**
lib/** lib/**
loader/**
modules/** modules/**
page-mod/**
path/** path/**
private-browsing/** private-browsing/**
querystring/** querystring/**
sidebar/** sidebar/**
tabs/** tabs/**
test-context-menu.html
traits/** traits/**
util.js
windows/** windows/**
zip/** zip/**
fixtures.js
pagemod-test-helpers.js
test-context-menu.html
util.js
[test-addon-bootstrap.js] [test-addon-bootstrap.js]
[test-addon-extras.js]
[test-addon-installer.js] [test-addon-installer.js]
[test-addon-window.js] [test-addon-window.js]
[test-api-utils.js] [test-api-utils.js]
@ -33,7 +34,6 @@ support-files =
[test-browser-events.js] [test-browser-events.js]
[test-buffer.js] [test-buffer.js]
[test-byte-streams.js] [test-byte-streams.js]
[test-bond.js]
[test-child_process.js] [test-child_process.js]
[test-chrome.js] [test-chrome.js]
[test-clipboard.js] [test-clipboard.js]
@ -72,19 +72,20 @@ skip-if = true
[test-hotkeys.js] [test-hotkeys.js]
[test-httpd.js] [test-httpd.js]
[test-indexed-db.js] [test-indexed-db.js]
[test-jetpack-id.js]
[test-keyboard-observer.js] [test-keyboard-observer.js]
[test-keyboard-utils.js] [test-keyboard-utils.js]
[test-lang-type.js]
[test-l10n-locale.js] [test-l10n-locale.js]
[test-l10n-plural-rules.js] [test-l10n-plural-rules.js]
[test-lang-type.js]
[test-libxul.js] [test-libxul.js]
[test-list.js] [test-list.js]
[test-loader.js] [test-loader.js]
[test-match-pattern.js] [test-match-pattern.js]
[test-memory.js]
[test-method.js] [test-method.js]
[test-module.js] [test-module.js]
[test-modules.js] [test-modules.js]
[test-mozilla-toolkit-versioning.js]
[test-mpl2-license-header.js] [test-mpl2-license-header.js]
skip-if = true skip-if = true
[test-namespace.js] [test-namespace.js]
@ -95,6 +96,7 @@ skip-if = true
[test-notifications.js] [test-notifications.js]
[test-object.js] [test-object.js]
[test-observers.js] [test-observers.js]
[test-page-mod-debug.js]
[test-page-mod.js] [test-page-mod.js]
[test-page-worker.js] [test-page-worker.js]
[test-panel.js] [test-panel.js]
@ -116,6 +118,7 @@ skip-if = true
[test-self.js] [test-self.js]
[test-sequence.js] [test-sequence.js]
[test-set-exports.js] [test-set-exports.js]
[test-shared-require.js]
[test-simple-prefs.js] [test-simple-prefs.js]
[test-simple-storage.js] [test-simple-storage.js]
[test-system-events.js] [test-system-events.js]

Просмотреть файл

@ -0,0 +1,11 @@
/* 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";
// Test module to check presense of user defined globals.
// Related to bug 827792.
exports.getCom = function() {
return com;
};

Просмотреть файл

@ -9,7 +9,7 @@ const { Loader } = require("sdk/test/loader");
const { openTab, getBrowserForTab, closeTab } = require("sdk/tabs/utils"); const { openTab, getBrowserForTab, closeTab } = require("sdk/tabs/utils");
const { getMostRecentBrowserWindow } = require("sdk/window/utils"); const { getMostRecentBrowserWindow } = require("sdk/window/utils");
const { merge } = require("sdk/util/object"); const { merge } = require("sdk/util/object");
const httpd = require("./lib/httpd"); const httpd = require("../lib/httpd");
const { cleanUI } = require("sdk/test/utils"); const { cleanUI } = require("sdk/test/utils");
const PORT = 8099; const PORT = 8099;
@ -17,7 +17,7 @@ const PATH = '/test-contentScriptWhen.html';
function createLoader () { function createLoader () {
let options = merge({}, require('@loader/options'), let options = merge({}, require('@loader/options'),
{ id: "testloader", prefixURI: require('./fixtures').url() }); { id: "testloader", prefixURI: require('../fixtures').url() });
return Loader(module, null, options); return Loader(module, null, options);
} }
exports.createLoader = createLoader; exports.createLoader = createLoader;
@ -32,7 +32,7 @@ exports.openNewTab = openNewTab;
// an evil function enables the creation of tests // an evil function enables the creation of tests
// that depend on delicate event timing. do not use. // that depend on delicate event timing. do not use.
function testPageMod(assert, done, testURL, pageModOptions, function testPageMod(assert, done, testURL, pageModOptions,
testCallback, timeout) { testCallback, timeout) {
let loader = createLoader(); let loader = createLoader();
let { PageMod } = loader.require("sdk/page-mod"); let { PageMod } = loader.require("sdk/page-mod");
let pageMods = [new PageMod(opts) for each (opts in pageModOptions)]; let pageMods = [new PageMod(opts) for each (opts in pageModOptions)];
@ -46,7 +46,7 @@ function testPageMod(assert, done, testURL, pageModOptions,
// If we delay even more contentScriptWhen:'end', we may want to modify // If we delay even more contentScriptWhen:'end', we may want to modify
// this code again. // this code again.
setTimeout(testCallback, timeout, setTimeout(testCallback, timeout,
b.contentWindow.wrappedJSObject, b.contentWindow.wrappedJSObject, // TODO: remove this CPOW
function () { function () {
pageMods.forEach(function(mod) mod.destroy()); pageMods.forEach(function(mod) mod.destroy());
// XXX leaks reported if we don't close the tab? // XXX leaks reported if we don't close the tab?

Просмотреть файл

@ -11,6 +11,7 @@ const { browserWindows: windows } = require('sdk/windows');
const { defer } = require('sdk/core/promise'); const { defer } = require('sdk/core/promise');
const tabs = require('sdk/tabs'); const tabs = require('sdk/tabs');
const { getMostRecentBrowserWindow } = require('sdk/window/utils'); const { getMostRecentBrowserWindow } = require('sdk/window/utils');
const { cleanUI } = require("sdk/test/utils");
// test openDialog() from window/utils with private option // test openDialog() from window/utils with private option
// test isActive state in pwpb case // test isActive state in pwpb case
@ -42,15 +43,18 @@ exports.testPerWindowPrivateBrowsingGetter = function*(assert) {
yield close(win) yield close(win)
} }
exports.testIsPrivateOnWindowOpen = function(assert, done) { exports.testIsPrivateOnWindowOpen = function*(assert) {
windows.open({ let window = yield new Promise(resolve => {
isPrivate: true, windows.open({
onOpen: function(window) { isPrivate: true,
assert.equal(isPrivate(window), false, 'isPrivate for a window is true when it should be'); onOpen: resolve
assert.equal(isPrivate(window.tabs[0]), false, 'isPrivate for a tab is false when it should be'); });
window.close(done);
}
}); });
assert.equal(isPrivate(window), false, 'isPrivate for a window is true when it should be');
assert.equal(isPrivate(window.tabs[0]), false, 'isPrivate for a tab is false when it should be');
yield cleanUI();
} }
exports.testIsPrivateOnWindowOpenFromPrivate = function(assert, done) { exports.testIsPrivateOnWindowOpenFromPrivate = function(assert, done) {

Просмотреть файл

@ -98,10 +98,6 @@ exports.testAutomaticDestroy = function(assert, done) {
// TEST: tab properties // TEST: tab properties
exports.testTabProperties = function(assert, done) { exports.testTabProperties = function(assert, done) {
setPref(DEPRECATE_PREF, true);
let { loader, messages } = LoaderWithHookedConsole();
let tabs = loader.require('sdk/tabs');
let url = "data:text/html;charset=utf-8,<html><head><title>foo</title></head><body>foo</body></html>"; let url = "data:text/html;charset=utf-8,<html><head><title>foo</title></head><body>foo</body></html>";
let tabsLen = tabs.length; let tabsLen = tabs.length;
tabs.open({ tabs.open({
@ -109,13 +105,6 @@ exports.testTabProperties = function(assert, done) {
onReady: function(tab) { onReady: function(tab) {
assert.equal(tab.title, "foo", "title of the new tab matches"); assert.equal(tab.title, "foo", "title of the new tab matches");
assert.equal(tab.url, url, "URL of the new tab matches"); assert.equal(tab.url, url, "URL of the new tab matches");
assert.ok(tab.favicon, "favicon of the new tab is not empty");
// TODO: remove need for this test by implementing the favicon feature
assert.equal(messages[0].msg,
"tab.favicon is deprecated, and " +
"currently favicon helpers are not yet supported " +
"by Fennec",
"favicon logs an error for now");
assert.equal(tab.style, null, "style of the new tab matches"); assert.equal(tab.style, null, "style of the new tab matches");
assert.equal(tab.index, tabsLen, "index of the new tab matches"); assert.equal(tab.index, tabsLen, "index of the new tab matches");
assert.notEqual(tab.getThumbnail(), null, "thumbnail of the new tab matches"); assert.notEqual(tab.getThumbnail(), null, "thumbnail of the new tab matches");

Просмотреть файл

@ -12,12 +12,16 @@ const { viewFor } = require('sdk/view/core');
const { getOwnerWindow } = require('sdk/tabs/utils'); const { getOwnerWindow } = require('sdk/tabs/utils');
const { windows, onFocus, getMostRecentBrowserWindow } = require('sdk/window/utils'); const { windows, onFocus, getMostRecentBrowserWindow } = require('sdk/window/utils');
const { open, focus, close } = require('sdk/window/helpers'); const { open, focus, close } = require('sdk/window/helpers');
const { observer: windowObserver } = require("sdk/windows/observer");
const tabs = require('sdk/tabs'); const tabs = require('sdk/tabs');
const { browserWindows } = require('sdk/windows'); const { browserWindows } = require('sdk/windows');
const { set: setPref } = require("sdk/preferences/service"); const { set: setPref, get: getPref, reset: resetPref } = require("sdk/preferences/service");
const DEPRECATE_PREF = "devtools.errorconsole.deprecation_warnings"; const DEPRECATE_PREF = "devtools.errorconsole.deprecation_warnings";
const OPEN_IN_NEW_WINDOW_PREF = 'browser.link.open_newwindow';
const DISABLE_POPUP_PREF = 'dom.disable_open_during_load';
const fixtures = require("../fixtures"); const fixtures = require("../fixtures");
const { base64jpeg } = fixtures; const { base64jpeg } = fixtures;
const { cleanUI, before, after } = require("sdk/test/utils");
// Bug 682681 - tab.title should never be empty // Bug 682681 - tab.title should never be empty
exports.testBug682681_aboutURI = function(assert, done) { exports.testBug682681_aboutURI = function(assert, done) {
@ -160,11 +164,8 @@ exports.testAutomaticDestroyEventClose = function(assert, done) {
}; };
exports.testTabPropertiesInNewWindow = function(assert, done) { exports.testTabPropertiesInNewWindow = function(assert, done) {
let warning = "DEPRECATED: tab.favicon is deprecated, please use require(\"sdk/places/favicon\").getFavicon instead.\n"
const { LoaderWithFilteredConsole } = require("sdk/test/loader"); const { LoaderWithFilteredConsole } = require("sdk/test/loader");
let loader = LoaderWithFilteredConsole(module, function(type, message) { let loader = LoaderWithFilteredConsole(module, function(type, message) {
if (type == "error" && message.substring(0, warning.length) == warning)
return false;
return true; return true;
}); });
@ -185,7 +186,7 @@ exports.testTabPropertiesInNewWindow = function(assert, done) {
onReady: function(tab) { onReady: function(tab) {
assert.equal(tab.title, "foo", "title of the new tab matches"); assert.equal(tab.title, "foo", "title of the new tab matches");
assert.equal(tab.url, url, "URL of the new tab matches"); assert.equal(tab.url, url, "URL of the new tab matches");
assert.ok(tab.favicon, "favicon of the new tab is not empty"); assert.equal(tab.favicon, undefined, "favicon of the new tab is undefined");
assert.equal(tab.style, null, "style of the new tab matches"); assert.equal(tab.style, null, "style of the new tab matches");
assert.equal(tab.index, 0, "index of the new tab matches"); assert.equal(tab.index, 0, "index of the new tab matches");
assert.notEqual(tab.getThumbnail(), null, "thumbnail of the new tab matches"); assert.notEqual(tab.getThumbnail(), null, "thumbnail of the new tab matches");
@ -196,7 +197,7 @@ exports.testTabPropertiesInNewWindow = function(assert, done) {
onLoad: function(tab) { onLoad: function(tab) {
assert.equal(tab.title, "foo", "title of the new tab matches"); assert.equal(tab.title, "foo", "title of the new tab matches");
assert.equal(tab.url, url, "URL of the new tab matches"); assert.equal(tab.url, url, "URL of the new tab matches");
assert.ok(tab.favicon, "favicon of the new tab is not empty"); assert.equal(tab.favicon, undefined, "favicon of the new tab is undefined");
assert.equal(tab.style, null, "style of the new tab matches"); assert.equal(tab.style, null, "style of the new tab matches");
assert.equal(tab.index, 0, "index of the new tab matches"); assert.equal(tab.index, 0, "index of the new tab matches");
assert.notEqual(tab.getThumbnail(), null, "thumbnail of the new tab matches"); assert.notEqual(tab.getThumbnail(), null, "thumbnail of the new tab matches");
@ -208,11 +209,8 @@ exports.testTabPropertiesInNewWindow = function(assert, done) {
}; };
exports.testTabPropertiesInSameWindow = function(assert, done) { exports.testTabPropertiesInSameWindow = function(assert, done) {
let warning = "DEPRECATED: tab.favicon is deprecated, please use require(\"sdk/places/favicon\").getFavicon instead.\n"
const { LoaderWithFilteredConsole } = require("sdk/test/loader"); const { LoaderWithFilteredConsole } = require("sdk/test/loader");
let loader = LoaderWithFilteredConsole(module, function(type, message) { let loader = LoaderWithFilteredConsole(module, function(type, message) {
if (type == "error" && message.substring(0, warning.length) == warning)
return false;
return true; return true;
}); });
@ -234,7 +232,7 @@ exports.testTabPropertiesInSameWindow = function(assert, done) {
onReady: function(tab) { onReady: function(tab) {
assert.equal(tab.title, "foo", "title of the new tab matches"); assert.equal(tab.title, "foo", "title of the new tab matches");
assert.equal(tab.url, url, "URL of the new tab matches"); assert.equal(tab.url, url, "URL of the new tab matches");
assert.ok(tab.favicon, "favicon of the new tab is not empty"); assert.equal(tab.favicon, undefined, "favicon of the new tab is undefined");
assert.equal(tab.style, null, "style of the new tab matches"); assert.equal(tab.style, null, "style of the new tab matches");
assert.equal(tab.index, tabCount, "index of the new tab matches"); assert.equal(tab.index, tabCount, "index of the new tab matches");
assert.notEqual(tab.getThumbnail(), null, "thumbnail of the new tab matches"); assert.notEqual(tab.getThumbnail(), null, "thumbnail of the new tab matches");
@ -245,7 +243,7 @@ exports.testTabPropertiesInSameWindow = function(assert, done) {
onLoad: function(tab) { onLoad: function(tab) {
assert.equal(tab.title, "foo", "title of the new tab matches"); assert.equal(tab.title, "foo", "title of the new tab matches");
assert.equal(tab.url, url, "URL of the new tab matches"); assert.equal(tab.url, url, "URL of the new tab matches");
assert.ok(tab.favicon, "favicon of the new tab is not empty"); assert.equal(tab.favicon, undefined, "favicon of the new tab is undefined");
assert.equal(tab.style, null, "style of the new tab matches"); assert.equal(tab.style, null, "style of the new tab matches");
assert.equal(tab.index, tabCount, "index of the new tab matches"); assert.equal(tab.index, tabCount, "index of the new tab matches");
assert.notEqual(tab.getThumbnail(), null, "thumbnail of the new tab matches"); assert.notEqual(tab.getThumbnail(), null, "thumbnail of the new tab matches");
@ -372,31 +370,28 @@ exports.testTabMove = function(assert, done) {
}).then(null, assert.fail); }).then(null, assert.fail);
}; };
exports.testIgnoreClosing = function(assert, done) { exports.testIgnoreClosing = function*(assert) {
let originalWindow = viewFor(browserWindows.activeWindow); let url = "data:text/html;charset=utf-8,foobar";
openBrowserWindow(function(window, browser) { let originalWindow = getMostRecentBrowserWindow();
onFocus(window).then(() => {
let url = "data:text/html;charset=utf-8,foobar";
assert.equal(tabs.length, 2, "should be two windows open each with one tab"); let window = yield open().then(focus);
tabs.on('ready', function onReady(tab) { assert.equal(tabs.length, 2, "should be two windows open each with one tab");
tabs.removeListener('ready', onReady);
let win = tab.window; yield new Promise(resolve => {
assert.equal(win.tabs.length, 2, "should be two tabs in the new window"); tabs.once("ready", (tab) => {
assert.equal(tabs.length, 3, "should be three tabs in total"); let win = tab.window;
assert.equal(win.tabs.length, 2, "should be two tabs in the new window");
assert.equal(tabs.length, 3, "should be three tabs in total");
tab.close(function() { tab.close(() => {
assert.equal(win.tabs.length, 1, "should be one tab in the new window"); assert.equal(win.tabs.length, 1, "should be one tab in the new window");
assert.equal(tabs.length, 2, "should be two tabs in total"); assert.equal(tabs.length, 2, "should be two tabs in total");
resolve();
close(window).then(onFocus(originalWindow)).then(done).then(null, assert.fail);
});
}); });
tabs.open(url);
}); });
tabs.open(url);
}); });
}; };
@ -537,23 +532,23 @@ exports.testTabsEvent_onOpen = function(assert, done) {
}; };
// TEST: onClose event handler // TEST: onClose event handler
exports.testTabsEvent_onClose = function(assert, done) { exports.testTabsEvent_onClose = function*(assert) {
open().then(focus).then(window => { let window = yield open().then(focus);
let url = "data:text/html;charset=utf-8,onclose"; let url = "data:text/html;charset=utf-8,onclose";
let eventCount = 0; let eventCount = 0;
// add listener via property assignment // add listener via property assignment
function listener1(tab) { function listener1(tab) {
eventCount++; eventCount++;
} }
tabs.on('close', listener1); tabs.on("close", listener1);
yield new Promise(resolve => {
// add listener via collection add // add listener via collection add
tabs.on('close', function listener2(tab) { tabs.on("close", function listener2(tab) {
assert.equal(++eventCount, 2, "both listeners notified"); assert.equal(++eventCount, 2, "both listeners notified");
tabs.removeListener('close', listener1); tabs.removeListener("close", listener2);
tabs.removeListener('close', listener2); resolve();
close(window).then(done).then(null, assert.fail);
}); });
tabs.on('ready', function onReady(tab) { tabs.on('ready', function onReady(tab) {
@ -562,7 +557,13 @@ exports.testTabsEvent_onClose = function(assert, done) {
}); });
tabs.open(url); tabs.open(url);
}).then(null, assert.fail); });
tabs.removeListener("close", listener1);
assert.pass("done test!");
yield close(window);
assert.pass("window was closed!");
}; };
// TEST: onClose event handler when a window is closed // TEST: onClose event handler when a window is closed
@ -671,32 +672,38 @@ exports.testTabsEvent_onActivate = function(assert, done) {
}; };
// onDeactivate event handler // onDeactivate event handler
exports.testTabsEvent_onDeactivate = function(assert, done) { exports.testTabsEvent_onDeactivate = function*(assert) {
open().then(focus).then(window => { let window = yield open().then(focus);
let url = "data:text/html;charset=utf-8,ondeactivate";
let eventCount = 0;
// add listener via property assignment let url = "data:text/html;charset=utf-8,ondeactivate";
function listener1(tab) { let eventCount = 0;
eventCount++;
};
tabs.on('deactivate', listener1);
// add listener via property assignment
function listener1(tab) {
eventCount++;
assert.pass("listener1 was called " + eventCount);
};
tabs.on('deactivate', listener1);
yield new Promise(resolve => {
// add listener via collection add // add listener via collection add
tabs.on('deactivate', function listener2(tab) { tabs.on('deactivate', function listener2(tab) {
assert.equal(++eventCount, 2, "both listeners notified"); assert.equal(++eventCount, 2, "both listeners notified");
tabs.removeListener('deactivate', listener1);
tabs.removeListener('deactivate', listener2); tabs.removeListener('deactivate', listener2);
close(window).then(done).then(null, assert.fail); resolve();
}); });
tabs.on('open', function onOpen(tab) { tabs.on('open', function onOpen(tab) {
assert.pass("tab opened");
tabs.removeListener('open', onOpen); tabs.removeListener('open', onOpen);
tabs.open("data:text/html;charset=utf-8,foo"); tabs.open("data:text/html;charset=utf-8,foo");
}); });
tabs.open(url); tabs.open(url);
}).then(null, assert.fail); });
tabs.removeListener('deactivate', listener1);
assert.pass("listeners were removed");
}; };
// pinning // pinning
@ -726,13 +733,16 @@ exports.testTabsEvent_pinning = function(assert, done) {
}; };
// TEST: per-tab event handlers // TEST: per-tab event handlers
exports.testPerTabEvents = function(assert, done) { exports.testPerTabEvents = function*(assert) {
open().then(focus).then(window => { let window = yield open().then(focus);
let eventCount = 0; let eventCount = 0;
let tab = yield new Promise(resolve => {
tabs.open({ tabs.open({
url: "data:text/html;charset=utf-8,foo", url: "data:text/html;charset=utf-8,foo",
onOpen: function(tab) { onOpen: (tab) => {
assert.pass("the tab was opened");
// add listener via property assignment // add listener via property assignment
function listener1() { function listener1() {
eventCount++; eventCount++;
@ -741,14 +751,18 @@ exports.testPerTabEvents = function(assert, done) {
// add listener via collection add // add listener via collection add
tab.on('ready', function listener2() { tab.on('ready', function listener2() {
assert.equal(eventCount, 1, "both listeners notified"); assert.equal(eventCount, 1, "listener1 called before listener2");
tab.removeListener('ready', listener1); tab.removeListener('ready', listener1);
tab.removeListener('ready', listener2); tab.removeListener('ready', listener2);
close(window).then(done).then(null, assert.fail); assert.pass("removed listeners");
eventCount++;
resolve();
}); });
} }
}); });
}).then(null, assert.fail); });
assert.equal(eventCount, 2, "both listeners were notified.");
}; };
exports.testAttachOnOpen = function (assert, done) { exports.testAttachOnOpen = function (assert, done) {
@ -1038,29 +1052,6 @@ exports.testOnLoadEventWithImage = function(assert, done) {
}); });
}; };
exports.testFaviconGetterDeprecation = function (assert, done) {
setPref(DEPRECATE_PREF, true);
const { LoaderWithHookedConsole } = require("sdk/test/loader");
let { loader, messages } = LoaderWithHookedConsole(module);
let tabs = loader.require('sdk/tabs');
tabs.open({
url: 'data:text/html;charset=utf-8,',
onOpen: function (tab) {
let favicon = tab.favicon;
assert.equal(messages.length, 1, 'only one error is dispatched');
assert.ok(messages[0].type, 'error', 'the console message is an error');
let msg = messages[0].msg;
assert.ok(msg.indexOf('tab.favicon is deprecated') !== -1,
'message contains the given message');
tab.close(done);
loader.unload();
}
});
}
exports.testNoDeadObjects = function(assert, done) { exports.testNoDeadObjects = function(assert, done) {
let loader = Loader(module); let loader = Loader(module);
let myTabs = loader.require("sdk/tabs"); let myTabs = loader.require("sdk/tabs");
@ -1203,6 +1194,56 @@ exports.testTabDestroy = function(assert, done) {
}) })
}; };
// related to bug 942511
// https://bugzilla.mozilla.org/show_bug.cgi?id=942511
exports['test active tab properties defined on popup closed'] = function (assert, done) {
setPref(OPEN_IN_NEW_WINDOW_PREF, 2);
setPref(DISABLE_POPUP_PREF, false);
let tabID = "";
let popupClosed = false;
tabs.open({
url: 'about:blank',
onReady: function (tab) {
tabID = tab.id;
tab.attach({
contentScript: 'var popup = window.open("about:blank");' +
'popup.close();'
});
windowObserver.once('close', () => {
popupClosed = true;
});
windowObserver.on('activate', () => {
// Only when the 'activate' event is fired after the popup was closed.
if (popupClosed) {
popupClosed = false;
let activeTabID = tabs.activeTab.id;
if (activeTabID) {
assert.equal(tabID, activeTabID, 'ActiveTab properties are correct');
}
else {
assert.fail('ActiveTab properties undefined on popup closed');
}
tab.close(done);
}
});
}
});
};
after(exports, function*(name, assert) {
resetPopupPrefs();
yield cleanUI();
});
const resetPopupPrefs = () => {
resetPref(OPEN_IN_NEW_WINDOW_PREF);
resetPref(DISABLE_POPUP_PREF);
};
/******************* helpers *********************/ /******************* helpers *********************/
// Utility function to open a new browser window. // Utility function to open a new browser window.

Просмотреть файл

@ -0,0 +1,171 @@
/* 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";
const { Ci, Cu, Cc, components } = require("chrome");
const self = require("sdk/self");
const { before, after } = require("sdk/test/utils");
const fixtures = require("./fixtures");
const { Loader } = require("sdk/test/loader");
const { merge } = require("sdk/util/object");
exports["test changing result from addon extras in panel"] = function(assert, done) {
let loader = Loader(module, null, null, {
modules: {
"sdk/self": merge({}, self, {
data: merge({}, self.data, {url: fixtures.url})
})
}
});
const { Panel } = loader.require("sdk/panel");
const { events } = loader.require("sdk/content/sandbox/events");
const { on } = loader.require("sdk/event/core");
const { isAddonContent } = loader.require("sdk/content/utils");
var result = 1;
var extrasVal = {
test: function() {
return result;
}
};
on(events, "content-script-before-inserted", ({ window, worker }) => {
assert.pass("content-script-before-inserted");
if (isAddonContent({ contentURL: window.location.href })) {
let extraStuff = Cu.cloneInto(extrasVal, window, {
cloneFunctions: true
});
getUnsafeWindow(window).extras = extraStuff;
assert.pass("content-script-before-inserted done!");
}
});
let panel = Panel({
contentURL: "./test-addon-extras.html"
});
panel.port.once("result1", (result) => {
assert.equal(result, 1, "result is a number");
result = true;
panel.port.emit("get-result");
});
panel.port.once("result2", (result) => {
assert.equal(result, true, "result is a boolean");
loader.unload();
done();
});
panel.port.emit("get-result");
}
exports["test window result from addon extras in panel"] = function*(assert) {
let loader = Loader(module, null, null, {
modules: {
"sdk/self": merge({}, self, {
data: merge({}, self.data, {url: fixtures.url})
})
}
});
const { Panel } = loader.require('sdk/panel');
const { Page } = loader.require('sdk/page-worker');
const { getActiveView } = loader.require("sdk/view/core");
const { getDocShell } = loader.require('sdk/frame/utils');
const { events } = loader.require("sdk/content/sandbox/events");
const { on } = loader.require("sdk/event/core");
const { isAddonContent } = loader.require("sdk/content/utils");
// make a page worker and wait for it to load
var page = yield new Promise(resolve => {
assert.pass("Creating the background page");
let page = Page({
contentURL: "./test.html",
contentScriptWhen: "end",
contentScript: "self.port.emit('end', unsafeWindow.getTestURL() + '')"
});
page.port.once("end", (url) => {
assert.equal(url, fixtures.url("./test.html"), "url is correct");
resolve(page);
});
});
assert.pass("Created the background page");
var extrasVal = {
test: function() {
assert.pass("start test function");
let frame = getActiveView(page);
let window = getUnsafeWindow(frame.contentWindow);
assert.equal(typeof window.getTestURL, "function", "window.getTestURL is a function");
return window;
}
};
on(events, "content-script-before-inserted", ({ window, worker }) => {
let url = window.location.href;
assert.pass("content-script-before-inserted " + url);
if (isAddonContent({ contentURL: url })) {
let extraStuff = Cu.cloneInto(extrasVal, window, {
cloneFunctions: true
});
getUnsafeWindow(window).extras = extraStuff;
assert.pass("content-script-before-inserted done!");
}
});
let panel = Panel({
contentURL: "./test-addon-extras-window.html"
});
yield new Promise(resolve => {
panel.port.once("result1", (result) => {
assert.equal(result, fixtures.url("./test.html"), "result1 is a window");
resolve();
});
assert.pass("emit get-result");
panel.port.emit("get-result");
});
page.destroy();
page = yield new Promise(resolve => {
let page = Page({
contentURL: "./index.html",
contentScriptWhen: "end",
contentScript: "self.port.emit('end')"
});
page.port.once("end", () => resolve(page));
});
yield new Promise(resolve => {
panel.port.once("result2", (result) => {
assert.equal(result, fixtures.url("./index.html"), "result2 is a window");
resolve();
});
assert.pass("emit get-result");
panel.port.emit("get-result");
});
loader.unload();
}
function getUnsafeWindow (win) {
return win.wrappedJSObject || win;
}
require("sdk/test").run(exports);

Просмотреть файл

@ -1,169 +0,0 @@
/* 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";
const { Bond } = require("sdk/util/bond");
const { Class } = require("sdk/core/heritage");
exports["test bonds on constructors"] = assert => {
const MyClass = function(name) {
this.name = name;
}
MyClass.prototype = Bond({
hello() {
return `Hello my name is ${this.name}`
}
})
Object.assign(MyClass.prototype, {
constructor: MyClass,
readName() {
return this.name
}
});
const i1 = new MyClass("James Bond");
assert.equal(i1.hello(), "Hello my name is James Bond");
assert.equal(i1.hello.call({name: "Hack"}), "Hello my name is James Bond");
assert.equal(i1.readName(), "James Bond");
assert.equal(i1.readName.call({name: "Hack"}), "Hack");
const hello = i1.hello
assert.equal(hello(), "Hello my name is James Bond");
};
exports["test subclassing"] = assert => {
const MyClass = function(name) {
this.name = name;
}
MyClass.prototype = Bond({
hello() {
return `Hello my name is ${this.name}`
}
});
const i1 = new MyClass("James Bond");
assert.equal(i1.hello(), "Hello my name is James Bond");
assert.equal(i1.hello.call({name: "Hack"}), "Hello my name is James Bond");
const i1Hello = i1.hello
assert.equal(i1Hello(), "Hello my name is James Bond");
const MySubClass = function(...args) {
MyClass.call(this, ...args)
}
MySubClass.prototype = Object.create(MyClass.prototype)
const i2 = new MySubClass("Your father");
assert.equal(i2.hello(), "Hello my name is Your father");
assert.equal(i2.hello.call({name: "Hack"}), "Hello my name is Your father");
const i2Hello = i2.hello
assert.equal(i2Hello(), "Hello my name is Your father");
};
exports["test access on prototype"] = assert => {
const MyClass = function(name) {
this.name = name;
}
MyClass.prototype = Bond({
hello() {
return `Hello my name is ${this.name}`
}
});
assert.equal(MyClass.prototype.hello(), "Hello my name is undefined");
assert.ok(Object.getOwnPropertyDescriptor(MyClass.prototype, "hello").get,
"hello is still a getter");
assert.equal(MyClass.prototype.hello.call({name: "this"}),
"Hello my name is this",
"passing `this` on prototype methods work");
const i1 = new MyClass("James Bond");
assert.equal(i1.hello(), "Hello my name is James Bond");
assert.ok(!Object.getOwnPropertyDescriptor(i1, "hello").get,
"hello is not a getter on instance");
assert.equal(i1.hello.call({name: "Hack"}), "Hello my name is James Bond");
const i1Hello = i1.hello
assert.equal(i1Hello(), "Hello my name is James Bond");
};
exports["test bonds with Class"] = assert => {
const MyClass = Class({
extends: Bond({
hello() {
return `Hello my name is ${this.name}`
}
}),
initialize(name) {
this.name = name;
}
});
const i1 = new MyClass("James Bond");
assert.equal(i1.hello(), "Hello my name is James Bond");
assert.equal(i1.hello.call({name: "Hack"}), "Hello my name is James Bond");
const hello = i1.hello
assert.equal(hello(), "Hello my name is James Bond");
};
exports["test with mixin"] = assert => {
const MyClass = Class({
implements: [
Bond({
hello() {
return `Hello my name is ${this.name}`
}
})
],
initialize(name) {
this.name = name;
}
});
const i1 = new MyClass("James Bond");
assert.equal(i1.hello(), "Hello my name is James Bond");
assert.equal(i1.hello.call({name: "Hack"}), "Hello my name is James Bond");
const hello = i1.hello
assert.equal(hello(), "Hello my name is James Bond");
const MyComposedClass = Class({
implements: [
MyClass,
Bond({
bye() {
return `Bye ${this.name}`
}
})
],
initialize(name) {
this.name = name;
}
});
const i2 = new MyComposedClass("Major Tom");
assert.equal(i2.hello(), "Hello my name is Major Tom");
assert.equal(i2.hello.call({name: "Hack"}), "Hello my name is Major Tom");
const i2Hello = i2.hello
assert.equal(i2Hello(), "Hello my name is Major Tom");
assert.equal(i2.bye(), "Bye Major Tom");
assert.equal(i2.bye.call({name: "Hack"}), "Bye Major Tom");
const i2Bye = i2.bye
assert.equal(i2Bye(), "Bye Major Tom");
};
require("sdk/test").run(exports);

Просмотреть файл

@ -1,7 +1,6 @@
/* This Source Code Form is subject to the terms of the Mozilla Public /* 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 * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict"; "use strict";
const { pathFor } = require('sdk/system'); const { pathFor } = require('sdk/system');

Просмотреть файл

@ -6,11 +6,11 @@
const { Hotkey } = require("sdk/hotkeys"); const { Hotkey } = require("sdk/hotkeys");
const { keyDown } = require("sdk/dom/events/keys"); const { keyDown } = require("sdk/dom/events/keys");
const { Loader } = require('sdk/test/loader'); const { Loader } = require('sdk/test/loader');
const timer = require("sdk/timers"); const { getMostRecentBrowserWindow } = require("sdk/window/utils");
const winUtils = require("sdk/deprecated/window-utils");
const element = getMostRecentBrowserWindow().document.documentElement;
exports["test hotkey: function key"] = function(assert, done) { exports["test hotkey: function key"] = function(assert, done) {
var element = winUtils.activeBrowserWindow.document.documentElement;
var showHotKey = Hotkey({ var showHotKey = Hotkey({
combo: "f1", combo: "f1",
onPress: function() { onPress: function() {
@ -35,7 +35,6 @@ exports["test hotkey: function key"] = function(assert, done) {
}; };
exports["test hotkey: accel alt shift"] = function(assert, done) { exports["test hotkey: accel alt shift"] = function(assert, done) {
var element = winUtils.activeBrowserWindow.document.documentElement;
var showHotKey = Hotkey({ var showHotKey = Hotkey({
combo: "accel-shift-6", combo: "accel-shift-6",
onPress: function() { onPress: function() {
@ -58,7 +57,6 @@ exports["test hotkey: accel alt shift"] = function(assert, done) {
}; };
exports["test hotkey meta & control"] = function(assert, done) { exports["test hotkey meta & control"] = function(assert, done) {
var element = winUtils.activeBrowserWindow.document.documentElement;
var showHotKey = Hotkey({ var showHotKey = Hotkey({
combo: "meta-3", combo: "meta-3",
onPress: function() { onPress: function() {
@ -81,7 +79,6 @@ exports["test hotkey meta & control"] = function(assert, done) {
}; };
exports["test hotkey: control-1 / meta--"] = function(assert, done) { exports["test hotkey: control-1 / meta--"] = function(assert, done) {
var element = winUtils.activeBrowserWindow.document.documentElement;
var showHotKey = Hotkey({ var showHotKey = Hotkey({
combo: "control-1", combo: "control-1",
onPress: function() { onPress: function() {
@ -125,27 +122,23 @@ exports["test invalid combos"] = function(assert) {
}; };
exports["test no exception on unmodified keypress"] = function(assert) { exports["test no exception on unmodified keypress"] = function(assert) {
var element = winUtils.activeBrowserWindow.document.documentElement;
var someHotkey = Hotkey({ var someHotkey = Hotkey({
combo: "control-alt-1", combo: "control-alt-1",
onPress: function() { onPress: () => {}
}
}); });
keyDown(element, "a"); keyDown(element, "a");
assert.pass("No exception throw, unmodified keypress passed"); assert.pass("No exception throw, unmodified keypress passed");
someHotkey.destroy();
}; };
exports["test hotkey: automatic destroy"] = function(assert, done) { exports["test hotkey: automatic destroy"] = function*(assert) {
// Hacky way to be able to create unloadable modules via makeSandboxedLoader. // Hacky way to be able to create unloadable modules via makeSandboxedLoader.
let loader = Loader(module); let loader = Loader(module);
var called = false; var called = false;
var element = loader.require("sdk/deprecated/window-utils").activeBrowserWindow.document.documentElement;
var hotkey = loader.require("sdk/hotkeys").Hotkey({ var hotkey = loader.require("sdk/hotkeys").Hotkey({
combo: "accel-shift-x", combo: "accel-shift-x",
onPress: function() { onPress: () => called = true
called = true;
}
}); });
// Unload the module so that previous hotkey is automatically destroyed // Unload the module so that previous hotkey is automatically destroyed
@ -154,10 +147,37 @@ exports["test hotkey: automatic destroy"] = function(assert, done) {
// Ensure that the hotkey is really destroyed // Ensure that the hotkey is really destroyed
keyDown(element, "accel-shift-x"); keyDown(element, "accel-shift-x");
timer.setTimeout(function () { assert.ok(!called, "Hotkey is destroyed and not called.");
assert.ok(!called, "Hotkey is destroyed and not called.");
done(); // create a new hotkey for a different set
}, 0); yield new Promise(resolve => {
let key = Hotkey({
combo: "accel-shift-y",
onPress: () => {
key.destroy();
assert.pass("accel-shift-y was pressed.");
resolve();
}
});
keyDown(element, "accel-shift-y");
});
assert.ok(!called, "Hotkey is still not called, in time it would take.");
// create a new hotkey for the same set
yield new Promise(resolve => {
let key = Hotkey({
combo: "accel-shift-x",
onPress: () => {
key.destroy();
assert.pass("accel-shift-x was pressed.");
resolve();
}
});
keyDown(element, "accel-shift-x");
});
assert.ok(!called, "Hotkey is still not called, and reusing is ok.");
}; };
require("sdk/test").run(exports); require("sdk/test").run(exports);

Просмотреть файл

@ -3,10 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict"; "use strict";
let xulApp = require("sdk/system/xul-app");
if (xulApp.versionInRange(xulApp.platformVersion, "16.0a1", "*")) {
new function tests() {
const { indexedDB, IDBKeyRange, DOMException const { indexedDB, IDBKeyRange, DOMException
} = require("sdk/indexed-db"); } = require("sdk/indexed-db");
@ -183,11 +179,4 @@ function testRead(assert, done) {
}; };
}; };
}
} else {
exports.testDB = function(assert) {
assert.pass("IndexedDB is not implemented")
}
}
require("sdk/test").run(exports); require("sdk/test").run(exports);

Просмотреть файл

@ -367,6 +367,16 @@ exports['test shared globals'] = function(assert) {
unload(loader); unload(loader);
} }
exports['test prototype of global'] = function (assert) {
let uri = root + '/fixtures/loader/globals/';
let loader = Loader({ paths: { '': uri }, sharedGlobal: true,
sandboxPrototype: { globalFoo: 5 }});
let program = main(loader, 'main');
assert.ok(program.globalFoo === 5, '`globalFoo` exists');
};
exports["test require#resolve"] = function(assert) { exports["test require#resolve"] = function(assert) {
let foundRoot = require.resolve("sdk/tabs").replace(/sdk\/tabs.js$/, ""); let foundRoot = require.resolve("sdk/tabs").replace(/sdk\/tabs.js$/, "");
assert.ok(root, foundRoot, "correct resolution root"); assert.ok(root, foundRoot, "correct resolution root");
@ -524,4 +534,22 @@ exports['test lazy globals'] = function (assert) {
assert.ok(gotFoo, "foo has been accessed only when we first try to use it"); assert.ok(gotFoo, "foo has been accessed only when we first try to use it");
}; };
exports['test user global'] = function(assert) {
// Test case for bug 827792
let com = {};
let loader = require('toolkit/loader');
let loadOptions = require('@loader/options');
let options = loader.override(loadOptions,
{globals: loader.override(loadOptions.globals,
{com: com,
console: console,
dump: dump})});
let subloader = loader.Loader(options);
let userRequire = loader.Require(subloader, module);
let userModule = userRequire("./loader/user-global");
assert.equal(userModule.getCom(), com,
"user module returns expected `com` global");
};
require('sdk/test').run(exports); require('sdk/test').run(exports);

Просмотреть файл

@ -1,22 +0,0 @@
/* 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";
const memory = require("sdk/deprecated/memory");
const { gc } = require("sdk/test/memory");
exports.testMemory = function(assert) {
var obj = {};
memory.track(obj, "testMemory.testObj");
var objs = memory.getObjects("testMemory.testObj");
assert.equal(objs[0].weakref.get(), obj);
obj = null;
gc().then(function() {
assert.equal(objs[0].weakref.get(), null);
});
};
require('sdk/test').run(exports);

Просмотреть файл

@ -10,6 +10,8 @@ const { id } = require("sdk/self");
const { getAddonByID } = require("sdk/addon/manager"); const { getAddonByID } = require("sdk/addon/manager");
const { mapcat, map, filter, fromEnumerator } = require("sdk/util/sequence"); const { mapcat, map, filter, fromEnumerator } = require("sdk/util/sequence");
const { readURISync } = require('sdk/net/url'); const { readURISync } = require('sdk/net/url');
const { Request } = require('sdk/request');
const { defer } = require("sdk/core/promise");
const ios = Cc['@mozilla.org/network/io-service;1']. const ios = Cc['@mozilla.org/network/io-service;1'].
getService(Ci.nsIIOService); getService(Ci.nsIIOService);
@ -57,26 +59,42 @@ const getEntries = directory => mapcat(entry => {
return []; return [];
}, filter(() => true, getDirectoryEntries(directory))); }, filter(() => true, getDirectoryEntries(directory)));
function readURL(url) {
let { promise, resolve } = defer();
Request({
url: url,
overrideMimeType: "text/plain",
onComplete: (response) => resolve(response.text)
}).get();
return promise;
}
exports["test MPL2 license header"] = function*(assert) { exports["test MPL2 license header"] = function*(assert) {
let addon = yield getAddonByID(id); let addon = yield getAddonByID(id);
let xpiURI = addon.getResourceURI(); let xpiURI = addon.getResourceURI();
let rootURL = xpiURI.spec; let rootURL = xpiURI.spec;
assert.ok(rootURL, rootURL);
let files = [...getEntries(xpiURI.QueryInterface(Ci.nsIFileURL).file)]; let files = [...getEntries(xpiURI.QueryInterface(Ci.nsIFileURL).file)];
assert.ok(files.length > 1, files.length + " files found."); assert.ok(files.length > 1, files.length + " files found.");
let failures = []; let failures = [];
let success = 0; let success = 0;
files.forEach(file => { for (let i = 0, len = files.length; i < len; i++) {
const URI = ios.newFileURI(file); let file = files[i];
let leafName = URI.spec.replace(rootURL, ""); assert.ok(file.path, "Trying " + file.path);
let contents = readURISync(URI);
const URI = ios.newFileURI(file);
let leafName = URI.spec.replace(rootURL, "");
let contents = yield readURL(URI.spec);
if (!MPL2_LICENSE_TEST.test(contents)) { if (!MPL2_LICENSE_TEST.test(contents)) {
failures.push(leafName); failures.push(leafName);
} }
}); }
assert.equal(1, failures.length, "we expect one failure"); assert.equal(1, failures.length, "we expect one failure");
assert.ok(/test-mpl2-license-header\.js$/.test(failures[0]), "the only failure is this file"); assert.ok(/test-mpl2-license-header\.js$/.test(failures[0]), "the only failure is this file");

Просмотреть файл

@ -0,0 +1,66 @@
/* 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";
const { Cc, Ci, Cu } = require("chrome");
const { PageMod } = require("sdk/page-mod");
const { testPageMod, handleReadyState, openNewTab,
contentScriptWhenServer, createLoader } = require("./page-mod/helpers");
const { cleanUI, after } = require("sdk/test/utils");
const { open, getFrames, getMostRecentBrowserWindow, getInnerId } = require("sdk/window/utils");
const { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
const { require: devtoolsRequire } = devtools;
const contentGlobals = devtoolsRequire("devtools/server/content-globals");
// The following adds Debugger constructor to the global namespace.
const { addDebuggerToGlobal } = require('resource://gre/modules/jsdebugger.jsm');
addDebuggerToGlobal(this);
exports.testDebugMetadata = function(assert, done) {
let dbg = new Debugger;
let globalDebuggees = [];
dbg.onNewGlobalObject = function(global) {
globalDebuggees.push(global);
}
let mods = testPageMod(assert, done, "about:", [{
include: "about:",
contentScriptWhen: "start",
contentScript: "null;",
}], function(win, done) {
assert.ok(globalDebuggees.some(function(global) {
try {
let metadata = Cu.getSandboxMetadata(global.unsafeDereference());
return metadata && metadata.addonID && metadata.SDKContentScript &&
metadata['inner-window-id'] == getInnerId(win);
} catch(e) {
// Some of the globals might not be Sandbox instances and thus
// will cause getSandboxMetadata to fail.
return false;
}
}), "one of the globals is a content script");
done();
}
);
};
exports.testDevToolsExtensionsGetContentGlobals = function(assert, done) {
let mods = testPageMod(assert, done, "about:", [{
include: "about:",
contentScriptWhen: "start",
contentScript: "null;",
}], function(win, done) {
assert.equal(contentGlobals.getContentGlobals({ 'inner-window-id': getInnerId(win) }).length, 1);
done();
}
);
};
after(exports, function*(name, assert) {
assert.pass("cleaning ui.");
yield cleanUI();
});
require('sdk/test').run(exports);

Просмотреть файл

@ -3,118 +3,186 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict"; "use strict";
const { Cc, Ci, Cu } = require("chrome");
const { PageMod } = require("sdk/page-mod"); const { PageMod } = require("sdk/page-mod");
const { testPageMod, handleReadyState, openNewTab, const { testPageMod, handleReadyState, openNewTab,
contentScriptWhenServer, createLoader } = require("./pagemod-test-helpers"); contentScriptWhenServer, createLoader } = require("./page-mod/helpers");
const { Loader } = require('sdk/test/loader'); const { Loader } = require("sdk/test/loader");
const tabs = require("sdk/tabs"); const tabs = require("sdk/tabs");
const { setTimeout } = require("sdk/timers"); const { setTimeout } = require("sdk/timers");
const { Cc, Ci, Cu } = require("chrome");
const system = require("sdk/system/events"); const system = require("sdk/system/events");
const { open, getFrames, getMostRecentBrowserWindow, getInnerId } = require('sdk/window/utils'); const { open, getFrames, getMostRecentBrowserWindow, getInnerId } = require("sdk/window/utils");
const { getTabContentWindow, getActiveTab, setTabURL, openTab, closeTab, const { getTabContentWindow, getActiveTab, setTabURL, openTab, closeTab,
getBrowserForTab } = require('sdk/tabs/utils'); getBrowserForTab } = require("sdk/tabs/utils");
const xulApp = require("sdk/system/xul-app"); const xulApp = require("sdk/system/xul-app");
const { isPrivateBrowsingSupported } = require('sdk/self'); const { isPrivateBrowsingSupported } = require("sdk/self");
const { isPrivate } = require('sdk/private-browsing'); const { isPrivate } = require("sdk/private-browsing");
const { openWebpage } = require('./private-browsing/helper'); const { openWebpage } = require("./private-browsing/helper");
const { isTabPBSupported, isWindowPBSupported } = require('sdk/private-browsing/utils'); const { isTabPBSupported, isWindowPBSupported } = require("sdk/private-browsing/utils");
const promise = require("sdk/core/promise"); const promise = require("sdk/core/promise");
const { pb } = require('./private-browsing/helper'); const { pb } = require("./private-browsing/helper");
const { URL } = require("sdk/url"); const { URL } = require("sdk/url");
const { defer, all } = require('sdk/core/promise'); const { defer, all, resolve } = require("sdk/core/promise");
const { waitUntil } = require("sdk/test/utils"); const { waitUntil } = require("sdk/test/utils");
const data = require("./fixtures"); const data = require("./fixtures");
const { cleanUI, after } = require("sdk/test/utils");
const { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
const { require: devtoolsRequire } = devtools;
const contentGlobals = devtoolsRequire("devtools/server/content-globals");
const { cleanUI } = require("sdk/test/utils");
const testPageURI = data.url("test.html"); const testPageURI = data.url("test.html");
// The following adds Debugger constructor to the global namespace.
const { addDebuggerToGlobal } = require('resource://gre/modules/jsdebugger.jsm');
addDebuggerToGlobal(this);
function Isolate(worker) { function Isolate(worker) {
return "(" + worker + ")()"; return "(" + worker + ")()";
} }
/* Tests for the PageMod APIs */ /* Tests for the PageMod APIs */
exports.testPageMod1 = function(assert, done) { exports.testPageMod1 = function*(assert) {
let mods = testPageMod(assert, done, "about:", [{ let modAttached = defer();
include: /about:/, let mod = PageMod({
contentScriptWhen: 'end', include: /about:/,
contentScript: 'new ' + function WorkerScope() { contentScriptWhen: "end",
window.document.body.setAttribute("JEP-107", "worked"); contentScript: "new " + function WorkerScope() {
}, window.document.body.setAttribute("JEP-107", "worked");
onAttach: function() {
assert.equal(this, mods[0], "The 'this' object is the page mod."); self.port.once("done", () => {
} self.port.emit("results", window.document.body.getAttribute("JEP-107"))
}], });
function(win, done) {
assert.equal(
win.document.body.getAttribute("JEP-107"),
"worked",
"PageMod.onReady test"
);
done();
}, },
100 onAttach: function(worker) {
); assert.equal(this, mod, "The 'this' object is the page mod.");
mod.port.once("results", modAttached.resolve)
mod.port.emit("done");
}
});
let tab = yield new Promise(resolve => {
tabs.open({
url: "about:",
inBackground: true,
onReady: resolve
})
});
assert.pass("test tab was opened.");
let worked = yield modAttached.promise;
assert.pass("test mod was attached.");
mod.destroy();
assert.pass("test mod was destroyed.");
assert.equal(worked, "worked", "PageMod.onReady test");
}; };
exports.testPageMod2 = function(assert, done) { exports.testPageMod2 = function*(assert) {
testPageMod(assert, done, "about:", [{ let modAttached = defer();
include: "about:*", let mod = PageMod({
contentScript: [ include: testPageURI,
'new ' + function contentScript() { contentScriptWhen: "end",
window.AUQLUE = function() { return 42; } contentScript: [
try { 'new ' + function contentScript() {
window.AUQLUE() window.AUQLUE = function() { return 42; }
} try {
catch(e) { window.AUQLUE()
throw new Error("PageMod scripts executed in order");
}
document.documentElement.setAttribute("first", "true");
},
'new ' + function contentScript() {
document.documentElement.setAttribute("second", "true");
} }
] catch(e) {
}], function(win, done) { throw new Error("PageMod scripts executed in order");
assert.equal(win.document.documentElement.getAttribute("first"), }
"true", document.documentElement.setAttribute("first", "true");
"PageMod test #2: first script has run"); },
assert.equal(win.document.documentElement.getAttribute("second"), 'new ' + function contentScript() {
"true", document.documentElement.setAttribute("second", "true");
"PageMod test #2: second script has run");
assert.equal("AUQLUE" in win, false, self.port.once("done", () => {
"PageMod test #2: scripts get a wrapped window"); self.port.emit("results", {
done(); "first": window.document.documentElement.getAttribute("first"),
}, "second": window.document.documentElement.getAttribute("second"),
100 "AUQLUE": unsafeWindow.getAUQLUE()
); });
});
}
],
onAttach: modAttached.resolve
});
let tab = yield new Promise(resolve => {
tabs.open({
url: testPageURI,
inBackground: true,
onReady: resolve
})
});
assert.pass("test tab was opened.");
let worker = yield modAttached.promise;
assert.pass("test mod was attached.");
let results = yield new Promise(resolve => {
worker.port.once("results", resolve)
worker.port.emit("done");
});
mod.destroy();
assert.pass("test mod was destroyed.");
assert.equal(results["first"],
"true",
"PageMod test #2: first script has run");
assert.equal(results["second"],
"true",
"PageMod test #2: second script has run");
assert.equal(results["AUQLUE"], false,
"PageMod test #2: scripts get a wrapped window");
}; };
exports.testPageModIncludes = function(assert, done) { exports.testPageModIncludes = function*(assert) {
var asserts = []; var modsAttached = [];
var modNumber = 0;
var modAttached = defer();
let includes = [
"*",
"*.google.com",
"resource:*",
"resource:",
testPageURI
];
let expected = [
false,
false,
true,
false,
true
]
let mod = PageMod({
include: testPageURI,
contentScript: 'new ' + function() {
self.port.on("get-local-storage", () => {
let result = {};
self.options.forEach(include => {
result[include] = !!window.localStorage[include]
});
self.port.emit("got-local-storage", result);
window.localStorage.clear();
});
},
contentScriptOptions: includes,
onAttach: modAttached.resolve
});
function createPageModTest(include, expectedMatch) { function createPageModTest(include, expectedMatch) {
// Create an 'onload' test function... var modIndex = modNumber++;
asserts.push(function(test, win) {
var matches = include in win.localStorage; let attached = defer();
assert.ok(expectedMatch ? matches : !matches, modsAttached.push(expectedMatch ? attached.promise : resolve());
"'" + include + "' match test, expected: " + expectedMatch);
});
// ...and corresponding PageMod options // ...and corresponding PageMod options
return { return PageMod({
include: include, include: include,
contentScript: 'new ' + function() { contentScript: 'new ' + function() {
self.on("message", function(msg) { self.on("message", function(msg) {
window.localStorage[msg] = true; window.localStorage[msg] = true
self.port.emit('done');
}); });
}, },
// The testPageMod callback with test assertions is called on 'end', // The testPageMod callback with test assertions is called on 'end',
@ -122,27 +190,56 @@ exports.testPageModIncludes = function(assert, done) {
// so we attach it on 'start'. // so we attach it on 'start'.
contentScriptWhen: 'start', contentScriptWhen: 'start',
onAttach: function(worker) { onAttach: function(worker) {
assert.pass("mod " + modIndex + " was attached");
worker.port.once("done", () => {
assert.pass("mod " + modIndex + " is done");
attached.resolve(worker);
});
worker.postMessage(this.include[0]); worker.postMessage(this.include[0]);
} }
}; });
} }
testPageMod(assert, done, testPageURI, [ let mods = [
createPageModTest("*", false), createPageModTest("*", false),
createPageModTest("*.google.com", false), createPageModTest("*.google.com", false),
createPageModTest("resource:*", true), createPageModTest("resource:*", true),
createPageModTest("resource:", false), createPageModTest("resource:", false),
createPageModTest(testPageURI, true) createPageModTest(testPageURI, true)
], ];
function (win, done) {
waitUntil(() => win.localStorage[testPageURI], let tab = yield new Promise(resolve => {
testPageURI + " page-mod to be executed") tabs.open({
.then(() => { url: testPageURI,
asserts.forEach(fn => fn(assert, win)); inBackground: true,
win.localStorage.clear(); onReady: resolve
done();
});
}); });
});
assert.pass("tab was opened");
yield all(modsAttached);
assert.pass("all mods were attached.");
mods.forEach(mod => mod.destroy());
assert.pass("all mods were destroyed.");
yield modAttached.promise;
assert.pass("final test mod was attached.");
yield new Promise(resolve => {
mod.port.on("got-local-storage", (storage) => {
includes.forEach((include, i) => {
assert.equal(storage[include], expected[i], "localStorage is correct for " + include);
});
resolve();
});
mod.port.emit("get-local-storage");
});
assert.pass("final test of localStorage is complete.");
mod.destroy();
assert.pass("final test mod was destroyed.");
}; };
exports.testPageModExcludes = function(assert, done) { exports.testPageModExcludes = function(assert, done) {
@ -257,96 +354,116 @@ exports.testPageModValidationExclude = function(assert) {
}; };
/* Tests for internal functions. */ /* Tests for internal functions. */
exports.testCommunication1 = function(assert, done) { exports.testCommunication1 = function*(assert) {
let workerDone = false, let workerDone = defer();
callbackDone = null;
testPageMod(assert, done, "about:", [{ let mod = PageMod({
include: "about:*", include: "about:*",
contentScriptWhen: 'end', contentScriptWhen: "end",
contentScript: 'new ' + function WorkerScope() { contentScript: 'new ' + function WorkerScope() {
self.on('message', function(msg) { self.on('message', function(msg) {
document.body.setAttribute('JEP-107', 'worked'); document.body.setAttribute('JEP-107', 'worked');
self.postMessage(document.body.getAttribute('JEP-107')); self.postMessage(document.body.getAttribute('JEP-107'));
}) });
}, self.port.on('get-jep-107', () => {
onAttach: function(worker) { self.port.emit('got-jep-107', document.body.getAttribute('JEP-107'));
worker.on('error', function(e) { });
assert.fail('Errors where reported'); },
}); onAttach: function(worker) {
worker.on('message', function(value) { worker.on('error', function(e) {
assert.equal( assert.fail('Errors where reported');
"worked", });
value, worker.on('message', function(value) {
"test comunication" assert.equal(
); "worked",
workerDone = true; value,
if (callbackDone) "test comunication"
callbackDone(); );
}); workerDone.resolve();
worker.postMessage('do it!') });
} worker.postMessage("do it!")
}],
function(win, done) {
(callbackDone = function() {
if (workerDone) {
assert.equal(
'worked',
win.document.body.getAttribute('JEP-107'),
'attribute should be modified'
);
done();
}
})();
} }
); });
let tab = yield new Promise(resolve => {
tabs.open({
url: "about:",
onReady: resolve
});
});
assert.pass("opened tab");
yield workerDone.promise;
assert.pass("the worker has made a change");
let value = yield new Promise(resolve => {
mod.port.once("got-jep-107", resolve);
mod.port.emit("get-jep-107");
});
assert.equal("worked", value, "attribute should be modified");
mod.destroy();
assert.pass("the worker was destroyed");
}; };
exports.testCommunication2 = function(assert, done) { exports.testCommunication2 = function*(assert) {
let callbackDone = null, let workerDone = defer();
window; let url = data.url("test.html");
testPageMod(assert, done, "about:license", [{ let mod = PageMod({
include: "about:*", include: url,
contentScriptWhen: 'start', contentScriptWhen: 'start',
contentScript: 'new ' + function WorkerScope() { contentScript: 'new ' + function WorkerScope() {
document.documentElement.setAttribute('AUQLUE', 42); document.documentElement.setAttribute('AUQLUE', 42);
window.addEventListener('load', function listener() {
self.postMessage('onload'); window.addEventListener('load', function listener() {
}, false); self.postMessage({
self.on("message", function() { msg: 'onload',
self.postMessage(document.documentElement.getAttribute("test")) AUQLUE: document.documentElement.getAttribute('AUQLUE')
}); });
}, }, false);
onAttach: function(worker) {
worker.on('error', function(e) { self.on("message", function(msg) {
assert.fail('Errors where reported'); if (msg == "get window.test") {
unsafeWindow.changesInWindow();
}
self.postMessage({
msg: document.documentElement.getAttribute("test")
}); });
worker.on('message', function(msg) { });
if ('onload' == msg) { },
assert.equal( onAttach: function(worker) {
'42', worker.on('error', function(e) {
window.document.documentElement.getAttribute('AUQLUE'), assert.fail('Errors where reported');
'PageMod scripts executed in order' });
); worker.on('message', function({ msg, AUQLUE }) {
window.document.documentElement.setAttribute('test', 'changes in window'); if ('onload' == msg) {
worker.postMessage('get window.test') assert.equal('42', AUQLUE, 'PageMod scripts executed in order');
} else { worker.postMessage('get window.test');
assert.equal( }
'changes in window', else {
msg, assert.equal('changes in window', msg, 'PageMod test #2: second script has run');
'PageMod test #2: second script has run' workerDone.resolve();
) }
callbackDone(); });
}
});
}
}],
function(win, done) {
window = win;
callbackDone = done;
} }
); });
let tab = yield new Promise(resolve => {
tabs.open({
url: url,
inBackground: true,
onReady: resolve
});
});
assert.pass("opened tab");
yield workerDone.promise;
mod.destroy();
assert.pass("the worker was destroyed");
}; };
exports.testEventEmitter = function(assert, done) { exports.testEventEmitter = function(assert, done) {
@ -1074,55 +1191,83 @@ exports.testPageModCss = function(assert, done) {
); );
}; };
exports.testPageModCssList = function(assert, done) { exports.testPageModCssList = function*(assert) {
let [pageMod] = testPageMod(assert, done, const URL = 'data:text/html;charset=utf-8,<div style="width:320px; max-width: 480px!important">css test</div>';
'data:text/html;charset=utf-8,<div style="width:320px; max-width: 480px!important">css test</div>', [{ let modAttached = defer();
include: "data:*",
contentStyleFile: [
// Highlight evaluation order in this list
"data:text/css;charset=utf-8,div { border: 1px solid black; }",
"data:text/css;charset=utf-8,div { border: 10px solid black; }",
// Highlight evaluation order between contentStylesheet & contentStylesheetFile
"data:text/css;charset=utf-8s,div { height: 1000px; }",
// Highlight precedence between the author and user style sheet
"data:text/css;charset=utf-8,div { width: 200px; max-width: 640px!important}",
],
contentStyle: [
"div { height: 10px; }",
"div { height: 100px; }"
]
}],
function(win, done) {
let div = win.document.querySelector("div"),
style = win.getComputedStyle(div);
assert.equal( let pageMod = PageMod({
div.clientHeight, include: "data:*",
100, contentStyleFile: [
"PageMod contentStyle list works and is evaluated after contentStyleFile" // Highlight evaluation order in this list
); "data:text/css;charset=utf-8,div { border: 1px solid black; }",
"data:text/css;charset=utf-8,div { border: 10px solid black; }",
// Highlight evaluation order between contentStylesheet & contentStylesheetFile
"data:text/css;charset=utf-8s,div { height: 1000px; }",
// Highlight precedence between the author and user style sheet
"data:text/css;charset=utf-8,div { width: 200px; max-width: 640px!important}",
],
contentStyle: [
"div { height: 10px; }",
"div { height: 100px; }"
],
contentScript: 'new ' + function WorkerScope() {
self.port.on('get-results', () => {
let div = window.document.querySelector('div');
let style = window.getComputedStyle(div);
assert.equal( self.port.emit("results", {
div.offsetHeight, clientHeight: div.clientHeight,
120, offsetHeight: div.offsetHeight,
"PageMod contentStyleFile list works" width: style.width,
); maxWidth: style.maxWidth
});
})
},
onAttach: modAttached.resolve
});
assert.equal( let tab = yield new Promise(resolve => {
style.width, tabs.open({
"320px", url: URL,
"PageMod add-on author/page author style sheet precedence works" onReady: resolve
); });
});
assert.pass("the tab was opened");
assert.equal( yield modAttached.promise;
style.maxWidth, assert.pass("the mod has been attached");
"480px",
"PageMod add-on author/page author style sheet precedence with !important works"
);
done(); let results = yield new Promise(resolve => {
} pageMod.port.on("results", resolve);
pageMod.port.emit("get-results");
})
assert.equal(
results.clientHeight,
100,
"PageMod contentStyle list works and is evaluated after contentStyleFile"
); );
assert.equal(
results.offsetHeight,
120,
"PageMod contentStyleFile list works"
);
assert.equal(
results.width,
"320px",
"PageMod add-on author/page author style sheet precedence works"
);
assert.equal(
results.maxWidth,
"480px",
"PageMod add-on author/page author style sheet precedence with !important works"
);
pageMod.destroy();
assert.pass("the page mod was destroyed");
}; };
exports.testPageModCssDestroy = function(assert, done) { exports.testPageModCssDestroy = function(assert, done) {
@ -1417,30 +1562,49 @@ exports.testIFramePostMessage = function(assert, done) {
}); });
}; };
exports.testEvents = function(assert, done) { exports.testEvents = function*(assert) {
let modAttached = defer();
let content = "<script>\n new " + function DocumentScope() { let content = "<script>\n new " + function DocumentScope() {
window.addEventListener("ContentScriptEvent", function () { window.addEventListener("ContentScriptEvent", function () {
window.document.body.setAttribute("receivedEvent", true); window.document.body.setAttribute("receivedEvent", "ok");
}, false); }, false);
} + "\n</script>"; } + "\n</script>";
let url = "data:text/html;charset=utf-8," + encodeURIComponent(content); let url = "data:text/html;charset=utf-8," + encodeURIComponent(content);
testPageMod(assert, done, url, [{
include: "data:*", let mod = PageMod({
contentScript: 'new ' + function WorkerScope() { include: "data:*",
let evt = document.createEvent("Event"); contentScript: 'new ' + function WorkerScope() {
evt.initEvent("ContentScriptEvent", true, true); let evt = document.createEvent("Event");
document.body.dispatchEvent(evt); evt.initEvent("ContentScriptEvent", true, true);
} document.body.dispatchEvent(evt);
}],
function(win, done) { self.port.on("get-result", () => {
assert.ok( self.port.emit("result", {
win.document.body.getAttribute("receivedEvent"), receivedEvent: window.document.body.getAttribute("receivedEvent")
"Content script sent an event and document received it" });
); });
done();
}, },
100 onAttach: modAttached.resolve
); });
let tab = yield new Promise(resolve => {
tabs.open({
url: url,
onReady: resolve
});
});
assert.pass("the tab is ready");
yield modAttached.promise;
assert.pass("the mod was attached")
let result = yield new Promise(resolve => {
mod.port.once("result", resolve);
mod.port.emit("get-result");
});
assert.equal(result.receivedEvent, "ok",
"Content script sent an event and document received it");
}; };
exports["test page-mod on private tab"] = function (assert, done) { exports["test page-mod on private tab"] = function (assert, done) {
@ -1507,46 +1671,6 @@ exports.testWorkerTabClose = function(assert, done) {
); );
}; };
exports.testDebugMetadata = function(assert, done) {
let dbg = new Debugger;
let globalDebuggees = [];
dbg.onNewGlobalObject = function(global) {
globalDebuggees.push(global);
}
let mods = testPageMod(assert, done, "about:", [{
include: "about:",
contentScriptWhen: "start",
contentScript: "null;",
}], function(win, done) {
assert.ok(globalDebuggees.some(function(global) {
try {
let metadata = Cu.getSandboxMetadata(global.unsafeDereference());
return metadata && metadata.addonID && metadata.SDKContentScript &&
metadata['inner-window-id'] == getInnerId(win);
} catch(e) {
// Some of the globals might not be Sandbox instances and thus
// will cause getSandboxMetadata to fail.
return false;
}
}), "one of the globals is a content script");
done();
}
);
};
exports.testDevToolsExtensionsGetContentGlobals = function(assert, done) {
let mods = testPageMod(assert, done, "about:", [{
include: "about:",
contentScriptWhen: "start",
contentScript: "null;",
}], function(win, done) {
assert.equal(contentGlobals.getContentGlobals({ 'inner-window-id': getInnerId(win) }).length, 1);
done();
}
);
};
exports.testDetachOnDestroy = function(assert, done) { exports.testDetachOnDestroy = function(assert, done) {
let tab; let tab;
const TEST_URL = 'data:text/html;charset=utf-8,detach'; const TEST_URL = 'data:text/html;charset=utf-8,detach';
@ -2063,4 +2187,9 @@ exports.testDontInjectConsole = function(assert, done) {
let tab = openTab(getMostRecentBrowserWindow(), TEST_URL); let tab = openTab(getMostRecentBrowserWindow(), TEST_URL);
} }
after(exports, function*(name, assert) {
assert.pass("cleaning ui.");
yield cleanUI();
});
require('sdk/test').run(exports); require('sdk/test').run(exports);

Просмотреть файл

@ -22,6 +22,7 @@ const { getMostRecentBrowserWindow } = require('sdk/window/utils');
const { URL } = require('sdk/url'); const { URL } = require('sdk/url');
const { wait } = require('./event/helpers'); const { wait } = require('./event/helpers');
const packaging = require('@loader/options'); const packaging = require('@loader/options');
const { cleanUI, after } = require("sdk/test/utils");
const fixtures = require('./fixtures') const fixtures = require('./fixtures')
@ -335,65 +336,27 @@ exports["test Anchor And Arrow"] = function(assert, done) {
let { Panel } = loader.require('sdk/panel'); let { Panel } = loader.require('sdk/panel');
let count = 0; let count = 0;
let queue = []; let url = 'data:text/html;charset=utf-8,' +
let tab; '<html><head><title>foo</title></head><body>' +
'</body></html>';
function newPanel(anchor) { let panel = yield new Promise(resolve => {
let browserWindow = getMostRecentBrowserWindow();
let anchor = browserWindow.document.getElementById("identity-box");
let panel = Panel({ let panel = Panel({
contentURL: "data:text/html;charset=utf-8,<html><body style='padding: 0; margin: 0; " + contentURL: "data:text/html;charset=utf-8,<html><body style='padding: 0; margin: 0; " +
"background: gray; text-align: center;'>Anchor: " + "background: gray; text-align: center;'>Anchor: " +
anchor.id + "</body></html>", anchor.id + "</body></html>",
width: 200, width: 200,
height: 100, height: 100,
onShow: function () { onShow: () => resolve(panel)
panel.destroy();
next();
}
}); });
queue.push({ panel: panel, anchor: anchor });
}
function next () {
if (!queue.length) {
assert.pass("All anchored panel test displayed");
tab.close(function () {
done();
});
return;
}
let { panel, anchor } = queue.shift();
panel.show(null, anchor); panel.show(null, anchor);
}
let tabs= require("sdk/tabs");
let url = 'data:text/html;charset=utf-8,' +
'<html><head><title>foo</title></head><body>' +
'<style>div {background: gray; position: absolute; width: 300px; ' +
'border: 2px solid black;}</style>' +
'<div id="tl" style="top: 0px; left: 0px;">Top Left</div>' +
'<div id="tr" style="top: 0px; right: 0px;">Top Right</div>' +
'<div id="bl" style="bottom: 0px; left: 0px;">Bottom Left</div>' +
'<div id="br" style="bottom: 0px; right: 0px;">Bottom right</div>' +
'</body></html>';
tabs.open({
url: url,
onReady: function(_tab) {
tab = _tab;
let browserWindow = Cc["@mozilla.org/appshell/window-mediator;1"].
getService(Ci.nsIWindowMediator).
getMostRecentWindow("navigator:browser");
let window = browserWindow.content;
newPanel(window.document.getElementById('tl'));
newPanel(window.document.getElementById('tr'));
newPanel(window.document.getElementById('bl'));
newPanel(window.document.getElementById('br'));
let anchor = browserWindow.document.getElementById("identity-box");
newPanel(anchor);
next();
}
}); });
assert.pass("All anchored panel test displayed");
panel.destroy();
assert.pass("panel was destroyed.");
}; };
exports["test Panel Focus True"] = function(assert, done) { exports["test Panel Focus True"] = function(assert, done) {
@ -1352,6 +1315,11 @@ exports["test Panel without contentURL and contentScriptWhen=start should show"]
loader.unload(); loader.unload();
} }
after(exports, function*(name, assert) {
yield cleanUI();
assert.pass("ui was cleaned.");
});
if (packaging.isNative) { if (packaging.isNative) {
module.exports = { module.exports = {
"test skip on jpm": (assert) => assert.pass("skipping this file with jpm") "test skip on jpm": (assert) => assert.pass("skipping this file with jpm")

Просмотреть файл

@ -5,7 +5,6 @@
const tabs = require("sdk/tabs"); const tabs = require("sdk/tabs");
const windowUtils = require("sdk/deprecated/window-utils"); const windowUtils = require("sdk/deprecated/window-utils");
const { getTabForWindow } = require('sdk/tabs/helpers');
const windows = require("sdk/windows").browserWindows; const windows = require("sdk/windows").browserWindows;
const app = require("sdk/system/xul-app"); const app = require("sdk/system/xul-app");
const { viewFor } = require("sdk/view/core"); const { viewFor } = require("sdk/view/core");
@ -13,15 +12,6 @@ const { modelFor } = require("sdk/model/core");
const { getTabId, isTab } = require("sdk/tabs/utils"); const { getTabId, isTab } = require("sdk/tabs/utils");
const { defer } = require("sdk/lang/functional"); const { defer } = require("sdk/lang/functional");
// The primary test tab
var primaryTab;
// We have an auxiliary tab to test background tabs.
var auxTab;
// The window for the outer iframe in the primary test page
var iframeWin;
function tabExistenceInTabs(assert, found, tab, tabs) { function tabExistenceInTabs(assert, found, tab, tabs) {
let tabFound = false; let tabFound = false;
@ -43,99 +33,6 @@ function tabExistenceInTabs(assert, found, tab, tabs) {
assert.ok(!tabFound, 'the tab was not found as expected'); assert.ok(!tabFound, 'the tab was not found as expected');
} }
exports["test GetTabForWindow"] = function(assert, done) {
assert.equal(getTabForWindow(windowUtils.activeWindow), null,
"getTabForWindow return null on topwindow");
assert.equal(getTabForWindow(windowUtils.activeBrowserWindow), null,
"getTabForWindow return null on topwindow");
let subSubDocument = encodeURIComponent(
'Sub iframe<br/>'+
'<iframe id="sub-sub-iframe" src="data:text/html;charset=utf-8,SubSubIframe" />');
let subDocument = encodeURIComponent(
'Iframe<br/>'+
'<iframe id="sub-iframe" src="data:text/html;charset=utf-8,'+subSubDocument+'" />');
let url = 'data:text/html;charset=utf-8,' + encodeURIComponent(
'Content<br/><iframe id="iframe" src="data:text/html;charset=utf-8,'+subDocument+'" />');
// Open up a new tab in the background.
//
// This lets us test whether GetTabForWindow works even when the tab in
// question is not active.
tabs.open({
inBackground: true,
url: "about:mozilla",
onReady: function(tab) { auxTab = tab; step2(url, assert);},
onActivate: function(tab) { step3(assert, done); }
});
};
function step2(url, assert) {
tabs.open({
url: url,
onReady: function(tab) {
primaryTab = tab;
let window = windowUtils.activeBrowserWindow.content;
let matchedTab = getTabForWindow(window);
assert.equal(matchedTab, tab,
"We are able to find the tab with his content window object");
let timer = require("sdk/timers");
function waitForFrames() {
let iframe = window.document.getElementById("iframe");
if (!iframe) {
timer.setTimeout(waitForFrames, 100);
return;
}
iframeWin = iframe.contentWindow;
let subIframe = iframeWin.document.getElementById("sub-iframe");
if (!subIframe) {
timer.setTimeout(waitForFrames, 100);
return;
}
let subIframeWin = subIframe.contentWindow;
let subSubIframe = subIframeWin.document.getElementById("sub-sub-iframe");
if (!subSubIframe) {
timer.setTimeout(waitForFrames, 100);
return;
}
let subSubIframeWin = subSubIframe.contentWindow;
matchedTab = getTabForWindow(iframeWin);
assert.equal(matchedTab, tab,
"We are able to find the tab with an iframe window object");
matchedTab = getTabForWindow(subIframeWin);
assert.equal(matchedTab, tab,
"We are able to find the tab with a sub-iframe window object");
matchedTab = getTabForWindow(subSubIframeWin);
assert.equal(matchedTab, tab,
"We are able to find the tab with a sub-sub-iframe window object");
// Put our primary tab in the background and test again.
// The onActivate listener will take us to step3.
auxTab.activate();
}
waitForFrames();
}
});
}
function step3(assert, done) {
let matchedTab = getTabForWindow(iframeWin);
assert.equal(matchedTab, primaryTab,
"We get the correct tab even when it's in the background");
primaryTab.close(function () {
auxTab.close(function () { done();});
});
}
exports.testBehaviorOnCloseAfterReady = function(assert, done) { exports.testBehaviorOnCloseAfterReady = function(assert, done) {
tabs.open({ tabs.open({
url: "about:mozilla", url: "about:mozilla",

Просмотреть файл

@ -7,6 +7,8 @@
const { setTimeout } = require('sdk/timers'); const { setTimeout } = require('sdk/timers');
const { waitUntil, cleanUI } = require('sdk/test/utils'); const { waitUntil, cleanUI } = require('sdk/test/utils');
const tabs = require('sdk/tabs'); const tabs = require('sdk/tabs');
const fixtures = require("./fixtures");
const testURI = fixtures.url("test.html");
exports.testWaitUntil = function (assert, done) { exports.testWaitUntil = function (assert, done) {
let bool = false; let bool = false;
@ -44,29 +46,36 @@ exports.testWaitUntilInterval = function (assert, done) {
setTimeout(() => { bool = true; }, 10); setTimeout(() => { bool = true; }, 10);
}; };
exports.testCleanUIWithExtraTabAndWindow = function(assert, done) { exports.testCleanUIWithExtraTabAndWindow = function*(assert) {
tabs.open({ let tab = yield new Promise(resolve => {
url: "about:blank", tabs.open({
inNewWindow: true, url: testURI,
onOpen: () => { inNewWindow: true,
cleanUI().then(() => { onReady: resolve
assert.pass("the ui was cleaned"); });
assert.equal(tabs.length, 1, 'there is only one tab open');
}).then(done).catch(assert.fail);
}
}); });
assert.equal(tabs.length, 2, 'there are two tabs open');
yield cleanUI()
assert.pass("the ui was cleaned");
assert.equal(tabs.length, 1, 'there is only one tab open');
} }
exports.testCleanUIWithOnlyExtraTab = function(assert, done) { exports.testCleanUIWithOnlyExtraTab = function*(assert) {
tabs.open({ let tab = yield new Promise(resolve => {
url: "about:blank", tabs.open({
onOpen: () => { url: testURI,
cleanUI().then(() => { inBackground: true,
assert.pass("the ui was cleaned"); onReady: resolve
assert.equal(tabs.length, 1, 'there is only one tab open'); });
}).then(done).catch(assert.fail);
}
}); });
assert.equal(tabs.length, 2, 'there are two tabs open');
yield cleanUI();
assert.pass("the ui was cleaned.");
assert.equal(tabs.length, 1, 'there is only one tab open');
} }
require('sdk/test').run(exports); require('sdk/test').run(exports);

Просмотреть файл

@ -18,6 +18,7 @@ const { getMostRecentBrowserWindow } = require('sdk/window/utils');
const { partial } = require('sdk/lang/functional'); const { partial } = require('sdk/lang/functional');
const { wait } = require('./event/helpers'); const { wait } = require('./event/helpers');
const { gc } = require('sdk/test/memory'); const { gc } = require('sdk/test/memory');
const { emit, once } = require("sdk/event/core");
const openBrowserWindow = partial(open, null, {features: {toolbar: true}}); const openBrowserWindow = partial(open, null, {features: {toolbar: true}});
const openPrivateBrowserWindow = partial(open, null, const openPrivateBrowserWindow = partial(open, null,
@ -716,7 +717,11 @@ exports['test button tab state'] = function*(assert) {
'tab badgeColor inherited from global'); 'tab badgeColor inherited from global');
// check the node properties // check the node properties
yield wait(); yield new Promise(resolve => {
let target = {};
once(target, "ready", resolve);
emit(target, "ready");
});
assert.equal(node.getAttribute('label'), state.label, assert.equal(node.getAttribute('label'), state.label,
'node label is correct'); 'node label is correct');
@ -737,7 +742,11 @@ exports['test button tab state'] = function*(assert) {
// This is made in order to avoid to check the node before it // This is made in order to avoid to check the node before it
// is updated, need a better check // is updated, need a better check
yield wait(); yield new Promise(resolve => {
let target = {};
once(target, "ready", resolve);
emit(target, "ready");
});
state = button.state(mainTab); state = button.state(mainTab);

Просмотреть файл

@ -123,7 +123,6 @@ exports.testWaitUntilTimeoutInCallback = function(test) {
expected.push(["print", "TEST-START | wait4ever\n"]); expected.push(["print", "TEST-START | wait4ever\n"]);
expected.push(["error", "fail:", "Timed out (after: START)"]); expected.push(["error", "fail:", "Timed out (after: START)"]);
expected.push(["error", "test assertion never became true:\n", "assertion failed, value is false\n"]); expected.push(["error", "test assertion never became true:\n", "assertion failed, value is false\n"]);
expected.push(["print", "TEST-END | wait4ever\n"]);
} }
else { else {
expected.push(["info", "executing 'wait4ever'"]); expected.push(["info", "executing 'wait4ever'"]);
@ -132,17 +131,19 @@ exports.testWaitUntilTimeoutInCallback = function(test) {
} }
function checkExpected(name, args) { function checkExpected(name, args) {
if (expected.length == 0 || expected[0][0] != name) { var index = message;
test.fail("Saw an unexpected console." + name + "() call " + args); if (message++ >= expected.length) {
return; return;
} }
message++; let expectedArgs = expected[index].slice(1);
let expectedArgs = expected.shift().slice(1); for (let i = 0; i < expectedArgs.length; i++) {
for (let i = 0; i < expectedArgs.length; i++)
test.assertEqual(args[i], expectedArgs[i], "Should have seen the right message in argument " + i + " of message " + message); test.assertEqual(args[i], expectedArgs[i], "Should have seen the right message in argument " + i + " of message " + message);
if (expected.length == 0) }
if (message >= expected.length) {
test.done(); test.done();
}
} }
let runner = new (require("sdk/deprecated/unit-test").TestRunner)({ let runner = new (require("sdk/deprecated/unit-test").TestRunner)({

Просмотреть файл

@ -1,118 +1,81 @@
/* This Source Code Form is subject to the terms of the Mozilla Public /* 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 * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
'use strict'; "use strict";
const { Cu } = require('chrome'); const { Cu } = require("chrome");
const { Loader } = require('sdk/test/loader'); const memory = require("sdk/test/memory");
const { gc } = require("sdk/test/memory"); const { add, remove, has, clear, iterator } = require("sdk/lang/weak-set");
const { setInterval, clearInterval } = require("sdk/timers");
exports['test adding item'] = function*(assert) { function gc(assert) {
let loader = Loader(module); let wait = 1;
let { add, remove, has, clear, iterator } = loader.require('sdk/lang/weak-set'); let interval = setInterval(function() {
assert.pass("waited " + (wait++ * 0.250) + "secs for gc()..");
}, 250);
return memory.gc().then(() => {
assert.pass("gc completed!");
clearInterval(interval);
});
}
exports['test add/remove/iterate/clear item'] = function*(assert) {
let addItems = {};
let removeItems = {};
let iterateItems = {};
let clearItems = {};
let nonReferencedItems = {};
let items = {};
let item = {}; let item = {};
add(items, item);
yield gc();
assert.ok(has(items, item), 'the item is in the weak set');
loader.unload();
};
exports['test remove item'] = function*(assert) {
let loader = Loader(module);
let { add, remove, has, clear, iterator } = loader.require('sdk/lang/weak-set');
let items = {};
let item = {};
add(items, item);
remove(items, item);
yield gc();
assert.ok(!has(items, item), 'the item is not in weak set');
loader.unload();
};
exports['test iterate'] = function*(assert) {
let loader = Loader(module);
let { add, remove, has, clear, iterator } = loader.require('sdk/lang/weak-set');
let items = {};
let addedItems = [{}, {}]; let addedItems = [{}, {}];
add(items, addedItems[0]); assert.pass("adding things to items");
add(items, addedItems[1]); add(addItems, item);
add(items, addedItems[0]); // weak set shouldn't add this twice add(removeItems, item);
add(iterateItems, addedItems[0]);
add(iterateItems, addedItems[1]);
add(iterateItems, addedItems[0]); // weak set shouldn't add this twice
add(clearItems, addedItems[0]);
add(clearItems, addedItems[1]);
add(nonReferencedItems, {});
yield gc(); assert.pass("removing things from removeItems");
remove(removeItems, item);
assert.pass("clear things from clearItems");
clear(clearItems);
assert.pass("starting gc..");
yield gc(assert);
let count = 0; let count = 0;
for (let item of iterator(items)) { assert.equal(has(addItems, item), true, 'the addItems is in the weak set');
assert.equal(item, addedItems[count], assert.equal(has(removeItems, item), false, 'the removeItems is not in weak set');
'item in the expected order');
assert.pass("iterating iterateItems..");
for (let item of iterator(iterateItems)) {
assert.equal(item, addedItems[count], "item in the expected order");
count++; count++;
} }
assert.equal(count, 2, 'items in the expected number'); assert.equal(count, 2, 'items in the expected number');
loader.unload();
};
exports['test clear'] = function*(assert) { assert.pass("iterating clearItems..");
let loader = Loader(module); for (let item of iterator(clearItems)) {
let { add, remove, has, clear, iterator } = loader.require('sdk/lang/weak-set'); assert.fail("the loop should not be executed");
count++
let items = {};
let addedItems = [{}, {}];
add(items, addedItems[0]);
add(items, addedItems[1]);
clear(items)
yield gc();
let count = 0;
for (let item of iterator(items)) {
assert.fail('the loop should not be executed');
} }
assert.equal(count, 0, 'no items in the weak set'); for (let item of iterator(nonReferencedItems)) {
loader.unload(); assert.fail("the loop should not be executed");
}; count++
exports['test adding item without reference'] = function*(assert) {
let loader = Loader(module);
let { add, remove, has, clear, iterator } = loader.require('sdk/lang/weak-set');
let items = {};
add(items, {});
yield gc();
let count = 0;
for (let item of iterator(items)) {
assert.fail('the loop should not be executed');
} }
assert.equal(count, 0, 'no items in the weak set'); assert.equal(count, 2, 'items in the expected number');
loader.unload();
}; };
exports['test adding non object or null item'] = function(assert) { exports['test adding non object or null item'] = function(assert) {
let loader = Loader(module);
let { add, remove, has, clear, iterator } = loader.require('sdk/lang/weak-set');
let items = {}; let items = {};
assert.throws(() => { assert.throws(() => {
@ -147,9 +110,6 @@ exports['test adding non object or null item'] = function(assert) {
}; };
exports['test adding to non object or null item'] = function(assert) { exports['test adding to non object or null item'] = function(assert) {
let loader = Loader(module);
let { add, remove, has, clear, iterator } = loader.require('sdk/lang/weak-set');
let item = {}; let item = {};
assert.throws(() => { assert.throws(() => {
@ -183,4 +143,4 @@ exports['test adding to non object or null item'] = function(assert) {
'only non-null object are allowed'); 'only non-null object are allowed');
}; };
require('sdk/test').run(exports); require("sdk/test").run(exports);

Просмотреть файл

@ -10,6 +10,7 @@ const { viewFor } = require('sdk/view/core');
const { modelFor } = require('sdk/model/core'); const { modelFor } = require('sdk/model/core');
const { Ci } = require("chrome"); const { Ci } = require("chrome");
const { isBrowser, getWindowTitle } = require("sdk/window/utils"); const { isBrowser, getWindowTitle } = require("sdk/window/utils");
const { after, cleanUI } = require("sdk/test/utils");
// TEST: browserWindows Iterator // TEST: browserWindows Iterator
exports.testBrowserWindowsIterator = function(assert) { exports.testBrowserWindowsIterator = function(assert) {
@ -65,20 +66,18 @@ exports.testWindowActivateMethod_simple = function(assert) {
}; };
exports["test getView(window)"] = function(assert, done) { exports["test getView(window)"] = function*(assert) {
browserWindows.once("open", window => { let window = yield new Promise(resolve => {
const view = viewFor(window); browserWindows.once("open", resolve);
browserWindows.open({ url: "data:text/html;charset=utf-8,<title>yo</title>" });
assert.ok(view instanceof Ci.nsIDOMWindow, "view is a window");
assert.ok(isBrowser(view), "view is a browser window");
assert.equal(getWindowTitle(view), window.title,
"window has a right title");
window.close(done);
}); });
const view = viewFor(window);
browserWindows.open({ url: "data:text/html;charset=utf-8,<title>yo</title>" }); assert.ok(view instanceof Ci.nsIDOMWindow, "view is a window");
assert.ok(isBrowser(view), "view is a browser window");
assert.equal(getWindowTitle(view), window.title,
"window has a right title");
}; };
@ -97,4 +96,9 @@ exports["test modelFor(window)"] = function(assert, done) {
browserWindows.open({ url: "data:text/html;charset=utf-8,<title>yo</title>" }); browserWindows.open({ url: "data:text/html;charset=utf-8,<title>yo</title>" });
}; };
after(exports, function*(name, assert) {
assert.pass("cleaning the ui.");
yield cleanUI();
});
require('sdk/test').run(exports); require('sdk/test').run(exports);

Просмотреть файл

@ -1,10 +1,11 @@
/* This Source Code Form is subject to the terms of the Mozilla Public /* 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 * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
var xulApp = require("sdk/system/xul-app"); var xulApp = require("sdk/system/xul-app");
exports["test xulapp"] = function(assert) { exports["test xulapp"] = function (assert) {
assert.equal(typeof(xulApp.ID), "string", assert.equal(typeof(xulApp.ID), "string",
"ID is a string"); "ID is a string");
assert.equal(typeof(xulApp.name), "string", assert.equal(typeof(xulApp.name), "string",
@ -14,26 +15,26 @@ exports["test xulapp"] = function(assert) {
assert.equal(typeof(xulApp.platformVersion), "string", assert.equal(typeof(xulApp.platformVersion), "string",
"platformVersion is a string"); "platformVersion is a string");
assert.throws(function() { xulApp.is("blargy"); }, assert.throws(() => xulApp.is("blargy"),
/Unkown Mozilla Application: blargy/, /Unkown Mozilla Application: blargy/,
"is() throws error on bad app name"); "is() throws error on bad app name");
assert.throws(function() { xulApp.isOneOf(["blargy"]); },
/Unkown Mozilla Application: blargy/, assert.throws(() => xulApp.isOneOf(["blargy"]),
"isOneOf() throws error on bad app name"); /Unkown Mozilla Application: blargy/,
"isOneOf() throws error on bad app name");
function testSupport(name) { function testSupport(name) {
var item = xulApp.is(name); var item = xulApp.is(name);
assert.ok(item === true || item === false, assert.ok(item === true || item === false,
"is('" + name + "') is true or false."); "is('" + name + "') is true or false.");
} }
var apps = ["Firefox", "Mozilla", "SeaMonkey", "Fennec", "Thunderbird"]; var apps = ["Firefox", "Mozilla", "SeaMonkey", "Fennec", "Thunderbird"];
apps.forEach(testSupport); apps.forEach(testSupport);
assert.ok(xulApp.isOneOf(apps) == true || assert.ok(xulApp.isOneOf(apps) == true || xulApp.isOneOf(apps) == false,
xulApp.isOneOf(apps) == false, "isOneOf() returns true or false.");
"isOneOf() returns true or false.");
assert.equal(xulApp.versionInRange(xulApp.platformVersion, "1.9", "*"), assert.equal(xulApp.versionInRange(xulApp.platformVersion, "1.9", "*"),
true, "platformVersion in range [1.9, *)"); true, "platformVersion in range [1.9, *)");

Просмотреть файл

@ -327,7 +327,6 @@ exports.testTrackWindows = function(assert, done) {
// listen to global deactivate events // listen to global deactivate events
browserWindows.on("deactivate", windowsDeactivation); browserWindows.on("deactivate", windowsDeactivation);
function openWindow() { function openWindow() {
windows.push(browserWindows.open({ windows.push(browserWindows.open({
url: "data:text/html;charset=utf-8,<i>testTrackWindows</i>", url: "data:text/html;charset=utf-8,<i>testTrackWindows</i>",
@ -350,8 +349,10 @@ exports.testTrackWindows = function(assert, done) {
else { else {
(function closeWindows(windows) { (function closeWindows(windows) {
if (!windows.length) { if (!windows.length) {
assert.pass('the last window was closed');
browserWindows.removeListener("activate", windowsActivation); browserWindows.removeListener("activate", windowsActivation);
browserWindows.removeListener("deactivate", windowsDeactivation); browserWindows.removeListener("deactivate", windowsDeactivation);
assert.pass('removed listeners');
return done(); return done();
} }

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73"> <project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="b901c8b7be2119f4df42781aac1401ed12765460"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="4b7ad0dde990bdc44e166818c0bb09a35cd1207f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/> <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73"> <project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="b901c8b7be2119f4df42781aac1401ed12765460"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="4b7ad0dde990bdc44e166818c0bb09a35cd1207f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/> <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

Просмотреть файл

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="b901c8b7be2119f4df42781aac1401ed12765460"/> <project name="gaia.git" path="gaia" remote="mozillaorg" revision="4b7ad0dde990bdc44e166818c0bb09a35cd1207f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="87a2d8ab9248540910e56921654367b78a587095"/> <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="87a2d8ab9248540910e56921654367b78a587095"/>

Просмотреть файл

@ -17,7 +17,7 @@
</project> </project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="b901c8b7be2119f4df42781aac1401ed12765460"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="4b7ad0dde990bdc44e166818c0bb09a35cd1207f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/> <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="49192a4e48d080e44a0d66f059e6897f07cf67f8"/> <project name="apitrace" path="external/apitrace" remote="apitrace" revision="49192a4e48d080e44a0d66f059e6897f07cf67f8"/>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73"> <project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="b901c8b7be2119f4df42781aac1401ed12765460"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="4b7ad0dde990bdc44e166818c0bb09a35cd1207f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/> <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33"> <project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="b901c8b7be2119f4df42781aac1401ed12765460"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="4b7ad0dde990bdc44e166818c0bb09a35cd1207f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/> <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

Просмотреть файл

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="b901c8b7be2119f4df42781aac1401ed12765460"/> <project name="gaia.git" path="gaia" remote="mozillaorg" revision="4b7ad0dde990bdc44e166818c0bb09a35cd1207f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="87a2d8ab9248540910e56921654367b78a587095"/> <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="87a2d8ab9248540910e56921654367b78a587095"/>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73"> <project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="b901c8b7be2119f4df42781aac1401ed12765460"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="4b7ad0dde990bdc44e166818c0bb09a35cd1207f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/> <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

Просмотреть файл

@ -1,9 +1,9 @@
{ {
"git": { "git": {
"git_revision": "b901c8b7be2119f4df42781aac1401ed12765460", "git_revision": "4b7ad0dde990bdc44e166818c0bb09a35cd1207f",
"remote": "https://git.mozilla.org/releases/gaia.git", "remote": "https://git.mozilla.org/releases/gaia.git",
"branch": "" "branch": ""
}, },
"revision": "164aac2838e2a217a28f6366bd7ca48e17c956ac", "revision": "4dd94426a71c70db03184cb1e2d9c4c2ad065461",
"repo_path": "integration/gaia-central" "repo_path": "integration/gaia-central"
} }

Просмотреть файл

@ -17,7 +17,7 @@
</project> </project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="b901c8b7be2119f4df42781aac1401ed12765460"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="4b7ad0dde990bdc44e166818c0bb09a35cd1207f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/> <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="49192a4e48d080e44a0d66f059e6897f07cf67f8"/> <project name="apitrace" path="external/apitrace" remote="apitrace" revision="49192a4e48d080e44a0d66f059e6897f07cf67f8"/>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33"> <project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="b901c8b7be2119f4df42781aac1401ed12765460"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="4b7ad0dde990bdc44e166818c0bb09a35cd1207f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/> <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

Просмотреть файл

@ -10,7 +10,7 @@ MOZ_APP_UA_NAME=Firefox
MOZ_UA_OS_AGNOSTIC=1 MOZ_UA_OS_AGNOSTIC=1
MOZ_B2G_VERSION=3.0.0.0-prerelease MOZ_B2G_VERSION=2.5.0.0-prerelease
MOZ_B2G_OS_NAME=Boot2Gecko MOZ_B2G_OS_NAME=Boot2Gecko
MOZ_BRANDING_DIRECTORY=b2g/branding/unofficial MOZ_BRANDING_DIRECTORY=b2g/branding/unofficial

Просмотреть файл

@ -145,7 +145,12 @@
<panel type="autocomplete" id="PopupSearchAutoComplete" noautofocus="true" hidden="true"/> <panel type="autocomplete" id="PopupSearchAutoComplete" noautofocus="true" hidden="true"/>
<!-- for url bar autocomplete --> <!-- for url bar autocomplete -->
<panel type="autocomplete-richlistbox" id="PopupAutoCompleteRichResult" noautofocus="true" hidden="true"/> <panel type="autocomplete-richlistbox" id="PopupAutoCompleteRichResult" noautofocus="true" hidden="true">
<hbox id="urlbar-search-footer" flex="1" align="stretch" pack="end">
<button id="urlbar-search-settings" label="&changeSearchSettings.button;"
oncommand="BrowserUITelemetry.countSearchSettingsEvent('urlbar'); openPreferences('paneSearch')"/>
</hbox>
</panel>
<!-- for select dropdowns. The menupopup is what shows the list of options, <!-- for select dropdowns. The menupopup is what shows the list of options,
and the popuponly menulist makes things like the menuactive attributes and the popuponly menulist makes things like the menuactive attributes

Просмотреть файл

@ -445,6 +445,7 @@ skip-if = os == "linux" || e10s # Bug 1073339 - Investigate autocomplete test un
[browser_urlbarStop.js] [browser_urlbarStop.js]
[browser_urlbarTrimURLs.js] [browser_urlbarTrimURLs.js]
[browser_urlbar_search_healthreport.js] [browser_urlbar_search_healthreport.js]
[browser_urlbar_searchsettings.js]
[browser_utilityOverlay.js] [browser_utilityOverlay.js]
[browser_visibleFindSelection.js] [browser_visibleFindSelection.js]
[browser_visibleLabel.js] [browser_visibleLabel.js]

Просмотреть файл

@ -27,10 +27,20 @@ function hidden(sel) {
return display === "none"; return display === "none";
} }
function clickButton(sel) {
let win = gBrowser.ownerGlobal;
let el = win.document.querySelector(sel);
el.doCommand();
}
function testBenignPage() { function testBenignPage() {
info("Non-tracking content must not be blocked");
ok (!TrackingProtection.content.hasAttribute("block-disabled"), "blocking not disabled"); ok (!TrackingProtection.content.hasAttribute("block-disabled"), "blocking not disabled");
ok (!TrackingProtection.content.hasAttribute("block-active"), "blocking is not active"); ok (!TrackingProtection.content.hasAttribute("block-active"), "blocking is not active");
ok (hidden("#tracking-action-block"), "blockButton is hidden");
ok (hidden("#tracking-action-unblock"), "unblockButton is hidden");
// Make sure that the no tracking elements message appears // Make sure that the no tracking elements message appears
ok (!hidden("#tracking-not-detected"), "labelNoTracking is visible"); ok (!hidden("#tracking-not-detected"), "labelNoTracking is visible");
ok (hidden("#tracking-loaded"), "labelTrackingLoaded is hidden"); ok (hidden("#tracking-loaded"), "labelTrackingLoaded is hidden");
@ -38,9 +48,13 @@ function testBenignPage() {
} }
function testTrackingPage() { function testTrackingPage() {
info("Tracking content must be blocked");
ok (!TrackingProtection.content.hasAttribute("block-disabled"), "blocking not disabled"); ok (!TrackingProtection.content.hasAttribute("block-disabled"), "blocking not disabled");
ok (TrackingProtection.content.hasAttribute("block-active"), "blocking is active"); ok (TrackingProtection.content.hasAttribute("block-active"), "blocking is active");
ok (hidden("#tracking-action-block"), "blockButton is hidden");
ok (!hidden("#tracking-action-unblock"), "unblockButton is visible");
// Make sure that the blocked tracking elements message appears // Make sure that the blocked tracking elements message appears
ok (hidden("#tracking-not-detected"), "labelNoTracking is hidden"); ok (hidden("#tracking-not-detected"), "labelNoTracking is hidden");
ok (hidden("#tracking-loaded"), "labelTrackingLoaded is hidden"); ok (hidden("#tracking-loaded"), "labelTrackingLoaded is hidden");
@ -48,9 +62,13 @@ function testTrackingPage() {
} }
function testTrackingPageWhitelisted() { function testTrackingPageWhitelisted() {
info("Tracking content must be white-listed and not blocked");
ok (TrackingProtection.content.hasAttribute("block-disabled"), "blocking is disabled"); ok (TrackingProtection.content.hasAttribute("block-disabled"), "blocking is disabled");
ok (!TrackingProtection.content.hasAttribute("block-active"), "blocking is not active"); ok (!TrackingProtection.content.hasAttribute("block-active"), "blocking is not active");
ok (!hidden("#tracking-action-block"), "blockButton is visible");
ok (hidden("#tracking-action-unblock"), "unblockButton is hidden");
// Make sure that the blocked tracking elements message appears // Make sure that the blocked tracking elements message appears
ok (hidden("#tracking-not-detected"), "labelNoTracking is hidden"); ok (hidden("#tracking-not-detected"), "labelNoTracking is hidden");
ok (!hidden("#tracking-loaded"), "labelTrackingLoaded is visible"); ok (!hidden("#tracking-loaded"), "labelTrackingLoaded is visible");
@ -65,37 +83,30 @@ add_task(function* () {
TrackingProtection = gBrowser.ownerGlobal.TrackingProtection; TrackingProtection = gBrowser.ownerGlobal.TrackingProtection;
ok (TrackingProtection, "Functionality is attached to the browser window"); ok (TrackingProtection, "Functionality is attached to the browser window");
is (TrackingProtection.enabled, Services.prefs.getBoolPref(PREF), is (TrackingProtection.enabled, Services.prefs.getBoolPref(PREF),
"The initial enabled value is based on the default pref value"); "TP.enabled is based on the original pref value");
info("Enable Tracking Protection");
Services.prefs.setBoolPref(PREF, true); Services.prefs.setBoolPref(PREF, true);
ok (TrackingProtection.enabled, "Functionality is enabled after setting the pref"); ok (TrackingProtection.enabled, "TP is enabled after setting the pref");
info("Point tab to a test page NOT containing tracking elements"); info("Load a test page not containing tracking elements");
yield promiseTabLoadEvent(tab, BENIGN_PAGE); yield promiseTabLoadEvent(tab, BENIGN_PAGE);
testBenignPage(); testBenignPage();
info("Point tab to a test page containing tracking elements"); info("Load a test page containing tracking elements");
yield promiseTabLoadEvent(tab, TRACKING_PAGE); yield promiseTabLoadEvent(tab, TRACKING_PAGE);
info("Tracking content must be blocked");
testTrackingPage(); testTrackingPage();
info("Disable Tracking Content Protection for the page (which reloads the page)"); info("Disable TP for the page (which reloads the page)");
TrackingProtection.disableForCurrentPage(); clickButton("#tracking-action-unblock");
info("Wait for tab to reload following tracking-protection page white-listing"); info("Wait for tab to reload following TP white-listing");
yield promiseTabLoadEvent(tab); yield promiseTabLoadEvent(tab);
info("Tracking content must be white-listed (NOT blocked)");
testTrackingPageWhitelisted(); testTrackingPageWhitelisted();
info("Re-enable Tracking Content Protection for the page (which reloads the page)"); info("Re-enable TP for the page (which reloads the page)");
TrackingProtection.enableForCurrentPage(); clickButton("#tracking-action-block");
info("Wait for tab to reload following tracking-protection page white-listing"); info("Wait for tab to reload following TP black-listing");
yield promiseTabLoadEvent(tab); yield promiseTabLoadEvent(tab);
info("Tracking content must be blocked");
testTrackingPage(); testTrackingPage();
}); });

Просмотреть файл

@ -17,11 +17,11 @@ registerCleanupFunction(function() {
gBrowser.removeCurrentTab(); gBrowser.removeCurrentTab();
}); });
function testTrackingPageOFF() { function testTrackingPageOff() {
ok (TrackingProtection.container.hidden, "The container is hidden"); ok (TrackingProtection.container.hidden, "The container is hidden");
} }
function testBenignPageOFF() { function testBenignPageOff() {
ok (TrackingProtection.container.hidden, "The container is hidden"); ok (TrackingProtection.container.hidden, "The container is hidden");
} }
@ -31,19 +31,18 @@ add_task(function* () {
let tab = gBrowser.selectedTab = gBrowser.addTab(); let tab = gBrowser.selectedTab = gBrowser.addTab();
TrackingProtection = gBrowser.ownerGlobal.TrackingProtection; TrackingProtection = gBrowser.ownerGlobal.TrackingProtection;
ok (TrackingProtection, "Functionality is attached to the browser window"); ok (TrackingProtection, "TP is attached to the browser window");
is (TrackingProtection.enabled, Services.prefs.getBoolPref(PREF), is (TrackingProtection.enabled, Services.prefs.getBoolPref(PREF),
"The initial enabled value is based on the default pref value"); "TP.enabled is based on the original pref value");
info ("Disable Tracking Protection");
Services.prefs.setBoolPref(PREF, false); Services.prefs.setBoolPref(PREF, false);
ok (!TrackingProtection.enabled, "Functionality is disabled after setting the pref"); ok (!TrackingProtection.enabled, "TP is disabled after setting the pref");
info ("Point tab to a test page containing tracking elements"); info("Load a test page containing tracking elements");
yield promiseTabLoadEvent(tab, TRACKING_PAGE); yield promiseTabLoadEvent(tab, TRACKING_PAGE);
testTrackingPageOFF(); testTrackingPageOff();
info ("Point tab to a test page NOT containing tracking elements"); info("Load a test page not containing tracking elements");
yield promiseTabLoadEvent(tab, BENIGN_PAGE); yield promiseTabLoadEvent(tab, BENIGN_PAGE);
testBenignPageOFF(); testBenignPageOff();
}); });

Просмотреть файл

@ -0,0 +1,24 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
add_task(function*() {
yield BrowserTestUtils.withNewTab({ gBrowser, url: "about:blank" }, function* () {
let popupopened = BrowserTestUtils.waitForEvent(gURLBar.popup, "popupshown");
gURLBar.focus();
EventUtils.synthesizeKey("a", {});
yield popupopened;
// Since the current tab is blank the preferences pane will load there
let loaded = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
let popupclosed = BrowserTestUtils.waitForEvent(gURLBar.popup, "popuphidden");
EventUtils.synthesizeMouseAtCenter(document.getElementById("urlbar-search-settings"), {});
yield loaded;
yield popupclosed;
is(gBrowser.selectedBrowser.currentURI.spec, "about:preferences#search",
"Should have loaded the right page");
});
});

Просмотреть файл

@ -53,22 +53,16 @@
class="identity-popup-text" class="identity-popup-text"
crop="end">&trackingProtection.notDetected;</label> crop="end">&trackingProtection.notDetected;</label>
<button id="tracking-actions" <button id="tracking-action-unblock"
type="menu" label="&trackingContentBlocked.options;" label="&trackingProtection.unblock.label;"
sizetopopup="none"> class="identity-popup-button"
<menupopup> accesskey="&trackingProtection.unblock.accesskey;"
<menuitem oncommand="TrackingProtection.disableForCurrentPage();" />
id="tracking-action-unblock" <button id="tracking-action-block"
label="&trackingProtection.unblock.label;" label="&trackingProtection.block.label;"
accesskey="&trackingProtection.unblock.accesskey;" class="identity-popup-button"
oncommand="TrackingProtection.disableForCurrentPage();"/> accesskey="&trackingProtection.block.accesskey;"
<menuitem oncommand="TrackingProtection.enableForCurrentPage();" />
id="tracking-action-block"
label="&trackingProtection.block.label;"
accesskey="&trackingProtection.block.accesskey;"
oncommand="TrackingProtection.enableForCurrentPage();"/>
</menupopup>
</button>
</vbox> </vbox>
</hbox> </hbox>

Просмотреть файл

@ -10,7 +10,7 @@
const TEST_URL = "data:text/html;charset=utf8,<div></div>"; const TEST_URL = "data:text/html;charset=utf8,<div></div>";
add_task(function*() { add_task(function*() {
let {inspector, toolbox} = yield openInspectorForURL(TEST_URL); let {toolbox} = yield openInspectorForURL(TEST_URL);
info("Start the element picker"); info("Start the element picker");
yield toolbox.highlighterUtils.startPicker(); yield toolbox.highlighterUtils.startPicker();
@ -34,10 +34,12 @@ add_task(function*() {
info("Press escape again and wait for the split console to open"); info("Press escape again and wait for the split console to open");
let onSplitConsole = toolbox.once("split-console"); let onSplitConsole = toolbox.once("split-console");
let onConsoleReady = toolbox.once("webconsole-ready");
// The escape key is synthesized in the main process, which is where the focus // The escape key is synthesized in the main process, which is where the focus
// should be after the picker was stopped. // should be after the picker was stopped.
EventUtils.synthesizeKey("VK_ESCAPE", {}); EventUtils.synthesizeKey("VK_ESCAPE", {});
yield onSplitConsole; yield onSplitConsole;
yield onConsoleReady;
ok(toolbox.splitConsole, "The split console is shown."); ok(toolbox.splitConsole, "The split console is shown.");
// Hide the split console. // Hide the split console.

Просмотреть файл

@ -21,8 +21,13 @@ const PREF_EXPERIMENTS_ENABLED = "experiments.enabled";
const PREF_ACTIVE_EXPERIMENT = "experiments.activeExperiment"; // whether we have an active experiment const PREF_ACTIVE_EXPERIMENT = "experiments.activeExperiment"; // whether we have an active experiment
const PREF_HEALTHREPORT_ENABLED = "datareporting.healthreport.service.enabled"; const PREF_HEALTHREPORT_ENABLED = "datareporting.healthreport.service.enabled";
const PREF_TELEMETRY_ENABLED = "toolkit.telemetry.enabled"; const PREF_TELEMETRY_ENABLED = "toolkit.telemetry.enabled";
const PREF_TELEMETRY_UNIFIED = "toolkit.telemetry.unified";
const DELAY_INIT_MS = 30 * 1000; const DELAY_INIT_MS = 30 * 1000;
// Whether the FHR/Telemetry unification features are enabled.
// Changing this pref requires a restart.
const IS_UNIFIED_TELEMETRY = Preferences.get(PREF_TELEMETRY_UNIFIED, false);
XPCOMUtils.defineLazyGetter( XPCOMUtils.defineLazyGetter(
this, "gPrefs", () => { this, "gPrefs", () => {
return new Preferences(); return new Preferences();
@ -30,9 +35,11 @@ XPCOMUtils.defineLazyGetter(
XPCOMUtils.defineLazyGetter( XPCOMUtils.defineLazyGetter(
this, "gExperimentsEnabled", () => { this, "gExperimentsEnabled", () => {
// We can enable experiments if either unified Telemetry or FHR is on, and the user
// has opted into Telemetry.
return gPrefs.get(PREF_EXPERIMENTS_ENABLED, false) && return gPrefs.get(PREF_EXPERIMENTS_ENABLED, false) &&
gPrefs.get(PREF_TELEMETRY_ENABLED, false) && (gPrefs.get(PREF_HEALTHREPORT_ENABLED, false) || IS_UNIFIED_TELEMETRY) &&
gPrefs.get(PREF_HEALTHREPORT_ENABLED, false); gPrefs.get(PREF_TELEMETRY_ENABLED, false);
}); });
XPCOMUtils.defineLazyGetter( XPCOMUtils.defineLazyGetter(

Просмотреть файл

@ -916,6 +916,29 @@ toolbarbutton[constrain-size="true"][cui-areatype="toolbar"] > .toolbarbutton-ba
padding: 0 3px; padding: 0 3px;
} }
#urlbar-search-footer {
border-top: 1px solid hsla(210,4%,10%,.14);
background-color: hsla(210,4%,10%,.07);
}
#urlbar-search-settings {
-moz-appearance: none;
-moz-user-focus: ignore;
color: inherit;
margin: 0;
border: 0;
padding: 8px 20px;
background: transparent;
}
#urlbar-search-settings:hover {
background-color: hsla(210,4%,10%,.07);
}
#urlbar-search-settings:hover:active {
background-color: hsla(210,4%,10%,.12);
}
#urlbar-search-splitter { #urlbar-search-splitter {
-moz-appearance: none; -moz-appearance: none;
width: 8px; width: 8px;

Двоичные данные
browser/themes/linux/menuPanel@2x.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 39 KiB

После

Ширина:  |  Высота:  |  Размер: 46 KiB

Просмотреть файл

@ -1761,6 +1761,27 @@ toolbarbutton[constrain-size="true"][cui-areatype="toolbar"] > .toolbarbutton-ba
background-image: radial-gradient(circle closest-side, hsla(205,100%,70%,.3), transparent); background-image: radial-gradient(circle closest-side, hsla(205,100%,70%,.3), transparent);
} }
#urlbar-search-footer {
border-top: 1px solid hsla(210,4%,10%,.14);
background-color: hsla(210,4%,10%,.07);
}
#urlbar-search-settings {
-moz-appearance: none;
-moz-user-focus: ignore;
color: GrayText;
margin: 0;
padding: 8px 20px;
}
#urlbar-search-settings:hover {
background-color: hsla(210,4%,10%,.07);
}
#urlbar-search-settings:hover:active {
background-color: hsla(210,4%,10%,.12);
}
#urlbar-search-splitter { #urlbar-search-splitter {
min-width: 8px; min-width: 8px;
width: 8px; width: 8px;

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше