Merge latest green birch changeset and mozilla-central

This commit is contained in:
Ed Morley 2013-07-22 16:18:53 +01:00
commit a8fb8b7383
432 changed files with 13804 additions and 10183 deletions

View File

@ -17,5 +17,5 @@
#
# Modifying this file will now automatically clobber the buildbot machines \o/
#
Bug 889503 - Move Settings API to WebIDL.
Requires a clobber due to Bug 890744.
Bug 886886 - replace fixed-ratio capture resampler in webrtc with speex resampler
Requires a clobber due to modification of a .gypi file without a .gyp or configure.in change

View File

@ -9,9 +9,6 @@ ac_add_options --enable-signmar
# Nightlies only since this has a cost in performance
#ac_add_options --enable-js-diagnostics
# Avoid dependency on libstdc++ 4.5
ac_add_options --enable-stdcxx-compat
# This will overwrite the default of stripping everything and keep the symbol table.
# This is useful for profiling and debugging and only increases the package size
# by 2 MBs.

View File

@ -9,9 +9,6 @@ ac_add_options --enable-signmar
# Nightlies only since this has a cost in performance
#ac_add_options --enable-js-diagnostics
# Avoid dependency on libstdc++ 4.5
ac_add_options --enable-stdcxx-compat
# This will overwrite the default of stripping everything and keep the symbol table.
# This is useful for profiling and debugging and only increases the package size
# by 2 MBs.

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1373408730000">
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1374187152000">
<emItems>
<emItem blockID="i350" id="sqlmoz@facebook.com">
<versionRange minVersion="0" maxVersion="*" severity="3">
@ -1052,6 +1052,9 @@
</targetApplication>
</versionRange>
</pluginItem>
<pluginItem blockID="p428">
<match name="filename" exp="np[dD]eployJava1\.dll" /> <versionRange severity="0" vulnerabilitystatus="2"></versionRange>
</pluginItem>
</pluginItems>
<gfxItems>

View File

@ -16,20 +16,22 @@ function init(aEvent)
var distroId = Services.prefs.getCharPref("distribution.id");
if (distroId) {
var distroVersion = Services.prefs.getCharPref("distribution.version");
var distroAbout = Services.prefs.getComplexValue("distribution.about",
Components.interfaces.nsISupportsString);
var distroField = document.getElementById("distribution");
distroField.value = distroAbout;
distroField.style.display = "block";
var distroIdField = document.getElementById("distributionId");
distroIdField.value = distroId + " - " + distroVersion;
distroIdField.style.display = "block";
// This must be set last because it might not exist due to bug 895473.
var distroAbout = Services.prefs.getComplexValue("distribution.about",
Components.interfaces.nsISupportsString);
var distroField = document.getElementById("distribution");
distroField.value = distroAbout;
distroField.style.display = "block";
}
}
catch (e) {
// Pref is unset
Components.utils.reportError(e);
}
// Include the build ID and display warning if this is an "a#" (nightly or aurora) build

View File

@ -150,7 +150,7 @@ function onCheckboxClick(aPartId)
var command = document.getElementById("cmd_" + aPartId + "Toggle");
var checkbox = document.getElementById(aPartId + "Def");
if (checkbox.checked) {
SitePermissions.remove(gPermURI.host, aPartId);
SitePermissions.remove(gPermURI, aPartId);
command.setAttribute("disabled", "true");
var perm = SitePermissions.getDefault(aPartId);
setRadioState(aPartId, perm);

View File

@ -273,13 +273,18 @@ DistributionCustomizer.prototype = {
let partnerAbout = Cc["@mozilla.org/supports-string;1"].
createInstance(Ci.nsISupportsString);
if (globalPrefs["about." + this._locale]) {
partnerAbout.data = this._ini.getString("Global", "about." + this._locale);
} else {
partnerAbout.data = this._ini.getString("Global", "about");
try {
if (globalPrefs["about." + this._locale]) {
partnerAbout.data = this._ini.getString("Global", "about." + this._locale);
} else {
partnerAbout.data = this._ini.getString("Global", "about");
}
defaults.setComplexValue("distribution.about",
Ci.nsISupportsString, partnerAbout);
} catch (e) {
/* ignore bad prefs due to bug 895473 and move on */
Cu.reportError(e);
}
defaults.setComplexValue("distribution.about",
Ci.nsISupportsString, partnerAbout);
if (sections["Preferences"]) {
for (let key in enumerate(this._ini.getKeys("Preferences"))) {

View File

@ -6,9 +6,6 @@ ac_add_options --with-google-api-keyfile=/builds/gapi.data
. $topsrcdir/build/unix/mozconfig.linux32
# Avoid dependency on libstdc++ 4.5
ac_add_options --enable-stdcxx-compat
# Needed to enable breakpad in application.ini
export MOZILLA_OFFICIAL=1

View File

@ -4,9 +4,6 @@ ac_add_options --enable-signmar
. $topsrcdir/build/unix/mozconfig.linux32
# Avoid dependency on libstdc++ 4.5
ac_add_options --enable-stdcxx-compat
# Needed to enable breakpad in application.ini
export MOZILLA_OFFICIAL=1

View File

@ -8,9 +8,6 @@ ac_add_options --enable-valgrind
. $topsrcdir/build/unix/mozconfig.asan
# Avoid dependency on libstdc++ 4.5
ac_add_options --enable-stdcxx-compat
# Package js shell.
export MOZ_PACKAGE_JSSHELL=1

View File

@ -2,9 +2,6 @@ ac_add_options --with-l10n-base=../../l10n
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
ac_add_options --enable-update-packaging
# Avoid dependency on libstdc++ 4.5
ac_add_options --enable-stdcxx-compat
. $topsrcdir/build/unix/mozconfig.linux32
export MOZILLA_OFFICIAL=1

View File

@ -10,9 +10,6 @@ ac_add_options --enable-codesighs
. $topsrcdir/build/unix/mozconfig.asan
# Avoid dependency on libstdc++ 4.5
ac_add_options --enable-stdcxx-compat
# Package js shell.
export MOZ_PACKAGE_JSSHELL=1

View File

@ -6,9 +6,6 @@ ac_add_options --with-google-api-keyfile=/builds/gapi.data
. $topsrcdir/build/unix/mozconfig.linux
# Avoid dependency on libstdc++ 4.5
ac_add_options --enable-stdcxx-compat
# Needed to enable breakpad in application.ini
export MOZILLA_OFFICIAL=1

View File

@ -4,9 +4,6 @@ ac_add_options --enable-signmar
. $topsrcdir/build/unix/mozconfig.linux
# Avoid dependency on libstdc++ 4.5
ac_add_options --enable-stdcxx-compat
# Needed to enable breakpad in application.ini
export MOZILLA_OFFICIAL=1

View File

@ -8,9 +8,6 @@ ac_add_options --enable-valgrind
. $topsrcdir/build/unix/mozconfig.asan
# Avoid dependency on libstdc++ 4.5
ac_add_options --enable-stdcxx-compat
# Package js shell.
export MOZ_PACKAGE_JSSHELL=1

View File

@ -9,7 +9,4 @@ export CXX="$topsrcdir/clang/bin/clang++"
# Add the static checker
ac_add_options --enable-clang-plugin
# Avoid dependency on libstdc++ 4.5
ac_add_options --enable-stdcxx-compat
. "$topsrcdir/build/mozconfig.common.override"

View File

@ -2,9 +2,6 @@ ac_add_options --with-l10n-base=../../l10n
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
ac_add_options --enable-update-packaging
# Avoid dependency on libstdc++ 4.5
ac_add_options --enable-stdcxx-compat
. $topsrcdir/build/unix/mozconfig.linux
export MOZILLA_OFFICIAL=1

View File

@ -10,9 +10,6 @@ ac_add_options --enable-codesighs
. $topsrcdir/build/unix/mozconfig.asan
# Avoid dependency on libstdc++ 4.5
ac_add_options --enable-stdcxx-compat
# Package js shell.
export MOZ_PACKAGE_JSSHELL=1

View File

@ -600,6 +600,11 @@ XPCOMUtils.defineLazyModuleGetter(this, "AppCacheUtils",
return prefService.getBranch(null).QueryInterface(Ci.nsIPrefBranch2);
});
XPCOMUtils.defineLazyGetter(this, 'supportsString', function() {
return Cc["@mozilla.org/supports-string;1"]
.createInstance(Ci.nsISupportsString);
});
XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
"resource://gre/modules/NetUtil.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "console",
@ -719,7 +724,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "AppCacheUtils",
gcli.addCommand(commandSpec);
commands.push(commandSpec.name);
});
},
function onError(reason) {
console.error("OS.File.read(" + aFileEntry.path + ") failed.");
@ -733,7 +737,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "AppCacheUtils",
*/
gcli.addCommand({
name: "cmd",
get hidden() { return !prefBranch.prefHasUserValue(PREF_DIR); },
get hidden() {
return !prefBranch.prefHasUserValue(PREF_DIR);
},
description: gcli.lookup("cmdDesc")
});
@ -743,10 +749,49 @@ XPCOMUtils.defineLazyModuleGetter(this, "AppCacheUtils",
gcli.addCommand({
name: "cmd refresh",
description: gcli.lookup("cmdRefreshDesc"),
get hidden() { return !prefBranch.prefHasUserValue(PREF_DIR); },
exec: function Command_cmdRefresh(args, context) {
get hidden() {
return !prefBranch.prefHasUserValue(PREF_DIR);
},
exec: function(args, context) {
let chromeWindow = context.environment.chromeDocument.defaultView;
CmdCommands.refreshAutoCommands(chromeWindow);
let dirName = prefBranch.getComplexValue(PREF_DIR,
Ci.nsISupportsString).data.trim();
return gcli.lookupFormat("cmdStatus", [ commands.length, dirName ]);
}
});
/**
* 'cmd setdir' command
*/
gcli.addCommand({
name: "cmd setdir",
description: gcli.lookup("cmdSetdirDesc"),
params: [
{
name: "directory",
description: gcli.lookup("cmdSetdirDirectoryDesc"),
type: {
name: "file",
filetype: "directory",
existing: "yes"
},
defaultValue: null
}
],
returnType: "string",
get hidden() {
return true; // !prefBranch.prefHasUserValue(PREF_DIR);
},
exec: function(args, context) {
supportsString.data = args.directory;
prefBranch.setComplexValue(PREF_DIR, Ci.nsISupportsString, supportsString);
let chromeWindow = context.environment.chromeDocument.defaultView;
CmdCommands.refreshAutoCommands(chromeWindow);
return gcli.lookupFormat("cmdStatus", [ commands.length, args.directory ]);
}
});
}(this));
@ -1493,7 +1538,11 @@ XPCOMUtils.defineLazyModuleGetter(this, "AppCacheUtils",
params: [
{
name: "srcdir",
type: "string",
type: "string" /* {
name: "file",
filetype: "directory",
existing: "yes"
} */,
description: gcli.lookup("toolsSrcdirDir")
}
],

View File

@ -44,10 +44,14 @@ MOCHITEST_BROWSER_FILES = \
browser_cmd_screenshot.html \
browser_cmd_screenshot.js \
browser_cmd_settings.js \
browser_gcli_async.js \
browser_gcli_canon.js \
browser_gcli_cli.js \
browser_gcli_completion.js \
browser_gcli_date.js \
browser_gcli_exec.js \
browser_gcli_fail.js \
browser_gcli_file.js \
browser_gcli_focus.js \
browser_gcli_history.js \
browser_gcli_incomplete.js \

View File

@ -1,7 +1,17 @@
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
* Copyright 2012, Mozilla Foundation and contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// define(function(require, exports, module) {

View File

@ -217,10 +217,11 @@ exports.testAltCanon = function(options) {
var commandSpecs = altCanon.getCommandSpecs();
assert.is(JSON.stringify(commandSpecs),
'{"tss":{"name":"tss","params":[' +
'{"name":"str","type":"string"},' +
'{"name":"num","type":"number"},' +
'{"name":"opt","type":{"name":"selection","data":["1","2","3"]}}]}}',
'{"tss":{"name":"tss","description":"(No description)","params":[' +
'{"name":"str","type":"string","description":"(No description)"},' +
'{"name":"num","type":"number","description":"(No description)"},' +
'{"name":"opt","type":{"name":"selection","data":["1","2","3"]},"description":"(No description)"}'+
'],"isParent":false}}',
'JSON.stringify(commandSpecs)');
var remoter = function(args, context) {

View File

@ -37,26 +37,17 @@ function test() {
// var helpers = require('gclitest/helpers');
// var mockCommands = require('gclitest/mockCommands');
var cli = require('gcli/cli');
var origLogErrors = undefined;
exports.setup = function(options) {
mockCommands.setup();
origLogErrors = cli.logErrors;
cli.logErrors = false;
};
exports.shutdown = function(options) {
mockCommands.shutdown();
cli.logErrors = origLogErrors;
origLogErrors = undefined;
};
exports.testBaseline = function(options) {
helpers.audit(options, [
return helpers.audit(options, [
// These 3 establish a baseline for comparison when we have used the
// context command
{
@ -100,7 +91,7 @@ exports.testBaseline = function(options) {
};
exports.testContext = function(options) {
helpers.audit(options, [
return helpers.audit(options, [
// Use the 'tsn' context
{
setup: 'context tsn',

View File

@ -1,7 +1,17 @@
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
* Copyright 2012, Mozilla Foundation and contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// define(function(require, exports, module) {
@ -80,8 +90,10 @@ exports.testIncrement = function(options) {
};
exports.testInput = function(options) {
helpers.audit(options, [
return helpers.audit(options, [
{
// See bug 892901
skipRemainingIf: options.isFirefox,
setup: 'tsdate 2001-01-01 1980-01-03',
check: {
input: 'tsdate 2001-01-01 1980-01-03',
@ -132,8 +144,10 @@ exports.testInput = function(options) {
};
exports.testIncrDecr = function(options) {
helpers.audit(options, [
return helpers.audit(options, [
{
// See bug 892901
skipRemainingIf: options.isFirefox,
setup: 'tsdate 2001-01-01<UP>',
check: {
input: 'tsdate 2001-01-02',
@ -224,14 +238,14 @@ exports.testIncrDecr = function(options) {
message: ''
},
d2: {
value: function(d1) {
assert.is(d1.getFullYear(), 2000, 'd1 year');
assert.is(d1.getMonth(), 1, 'd1 month');
assert.is(d1.getDate(), 28, 'd1 date');
assert.is(d1.getHours(), 0, 'd1 hours');
assert.is(d1.getMinutes(), 0, 'd1 minutes');
assert.is(d1.getSeconds(), 0, 'd1 seconds');
assert.is(d1.getMilliseconds(), 0, 'd1 millis');
value: function(d2) {
assert.is(d2.getFullYear(), 2000, 'd2 year');
assert.is(d2.getMonth(), 1, 'd2 month');
assert.is(d2.getDate(), 28, 'd2 date');
assert.is(d2.getHours(), 0, 'd2 hours');
assert.is(d2.getMinutes(), 0, 'd2 minutes');
assert.is(d2.getSeconds(), 0, 'd2 seconds');
assert.is(d2.getMilliseconds(), 0, 'd2 millis');
},
arg: ' "2000-02-28"',
status: 'VALID',

View File

@ -1,7 +1,17 @@
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
* Copyright 2012, Mozilla Foundation and contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// define(function(require, exports, module) {
@ -27,22 +37,13 @@ function test() {
// var helpers = require('gclitest/helpers');
// var mockCommands = require('gclitest/mockCommands');
var cli = require('gcli/cli');
var origLogErrors = undefined;
exports.setup = function(options) {
mockCommands.setup();
origLogErrors = cli.logErrors;
cli.logErrors = false;
};
exports.shutdown = function(options) {
mockCommands.shutdown();
cli.logErrors = origLogErrors;
origLogErrors = undefined;
};
exports.testBasic = function(options) {

View File

@ -0,0 +1,848 @@
/*
* Copyright 2012, Mozilla Foundation and contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// define(function(require, exports, module) {
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
var exports = {};
const TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testFile.js</p>";
function test() {
helpers.addTabWithToolbar(TEST_URI, function(options) {
return helpers.runTests(options, exports);
}).then(finish);
}
// <INJECTED SOURCE:END>
'use strict';
// var helpers = require('gclitest/helpers');
// var mockCommands = require('gclitest/mockCommands');
exports.setup = function(options) {
mockCommands.setup();
};
exports.shutdown = function(options) {
mockCommands.shutdown();
};
var local = false;
exports.testBasic = function(options) {
var isPhantomjsFromFilesystem = (!options.isHttp && options.isPhantomjs);
return helpers.audit(options, [
{
// These tests require us to be using node directly or to be in
// phantomjs connected to an allowexec enabled node server or to be in
// firefox. In short they only don't work when in phantomjs reading
// from the filesystem, but they do work in Firefox
skipRemainingIf: isPhantomjsFromFilesystem || options.isFirefox,
setup: 'tsfile open /',
check: {
input: 'tsfile open /',
hints: '',
markup: 'VVVVVVVVVVVVI',
cursor: 13,
current: 'p1',
status: 'ERROR',
message: '\'/\' is not a file',
args: {
command: { name: 'tsfile open' },
p1: {
value: undefined,
arg: ' /',
status: 'INCOMPLETE',
message: '\'/\' is not a file'
}
}
}
},
{
setup: 'tsfile open /zxcv',
check: {
input: 'tsfile open /zxcv',
// hints: ' -> /etc/',
markup: 'VVVVVVVVVVVVIIIII',
cursor: 17,
current: 'p1',
status: 'ERROR',
message: '\'/zxcv\' doesn\'t exist',
args: {
command: { name: 'tsfile open' },
p1: {
value: undefined,
arg: ' /zxcv',
status: 'INCOMPLETE',
message: '\'/zxcv\' doesn\'t exist'
}
}
}
},
{
skipIf: !local,
setup: 'tsfile open /mach_kernel',
check: {
input: 'tsfile open /mach_kernel',
hints: '',
markup: 'VVVVVVVVVVVVVVVVVVVVVVVV',
cursor: 24,
current: 'p1',
status: 'VALID',
message: '',
args: {
command: { name: 'tsfile open' },
p1: {
value: '/mach_kernel',
arg: ' /mach_kernel',
status: 'VALID',
message: ''
}
}
}
},
{
setup: 'tsfile saveas /',
check: {
input: 'tsfile saveas /',
hints: '',
markup: 'VVVVVVVVVVVVVVI',
cursor: 15,
current: 'p1',
status: 'ERROR',
message: '\'/\' already exists',
args: {
command: { name: 'tsfile saveas' },
p1: {
value: undefined,
arg: ' /',
status: 'INCOMPLETE',
message: '\'/\' already exists'
}
}
}
},
{
setup: 'tsfile saveas /zxcv',
check: {
input: 'tsfile saveas /zxcv',
// hints: ' -> /etc/',
markup: 'VVVVVVVVVVVVVVVVVVV',
cursor: 19,
current: 'p1',
status: 'VALID',
message: '',
args: {
command: { name: 'tsfile saveas' },
p1: {
value: '/zxcv',
arg: ' /zxcv',
status: 'VALID',
message: ''
}
}
}
},
{
skipIf: !local,
setup: 'tsfile saveas /mach_kernel',
check: {
input: 'tsfile saveas /mach_kernel',
hints: '',
markup: 'VVVVVVVVVVVVVVIIIIIIIIIIII',
cursor: 26,
current: 'p1',
status: 'ERROR',
message: '\'/mach_kernel\' already exists',
args: {
command: { name: 'tsfile saveas' },
p1: {
value: undefined,
arg: ' /mach_kernel',
status: 'INCOMPLETE',
message: '\'/mach_kernel\' already exists'
}
}
}
},
{
setup: 'tsfile save /',
check: {
input: 'tsfile save /',
hints: '',
markup: 'VVVVVVVVVVVVI',
cursor: 13,
current: 'p1',
status: 'ERROR',
message: '\'/\' is not a file',
args: {
command: { name: 'tsfile save' },
p1: {
value: undefined,
arg: ' /',
status: 'INCOMPLETE',
message: '\'/\' is not a file'
}
}
}
},
{
setup: 'tsfile save /zxcv',
check: {
input: 'tsfile save /zxcv',
// hints: ' -> /etc/',
markup: 'VVVVVVVVVVVVVVVVV',
cursor: 17,
current: 'p1',
status: 'VALID',
message: '',
args: {
command: { name: 'tsfile save' },
p1: {
value: '/zxcv',
arg: ' /zxcv',
status: 'VALID',
message: ''
}
}
}
},
{
skipIf: !local,
setup: 'tsfile save /mach_kernel',
check: {
input: 'tsfile save /mach_kernel',
hints: '',
markup: 'VVVVVVVVVVVVVVVVVVVVVVVV',
cursor: 24,
current: 'p1',
status: 'VALID',
message: '',
args: {
command: { name: 'tsfile save' },
p1: {
value: '/mach_kernel',
arg: ' /mach_kernel',
status: 'VALID',
message: ''
}
}
}
},
{
setup: 'tsfile cd /',
check: {
input: 'tsfile cd /',
hints: '',
markup: 'VVVVVVVVVVV',
cursor: 11,
current: 'p1',
status: 'VALID',
message: '',
args: {
command: { name: 'tsfile cd' },
p1: {
value: '/',
arg: ' /',
status: 'VALID',
message: ''
}
}
}
},
{
setup: 'tsfile cd /zxcv',
check: {
input: 'tsfile cd /zxcv',
// hints: ' -> /dev/',
markup: 'VVVVVVVVVVIIIII',
cursor: 15,
current: 'p1',
status: 'ERROR',
message: '\'/zxcv\' doesn\'t exist',
args: {
command: { name: 'tsfile cd' },
p1: {
value: undefined,
arg: ' /zxcv',
status: 'INCOMPLETE',
message: '\'/zxcv\' doesn\'t exist'
}
}
}
},
{
skipIf: true || !local,
setup: 'tsfile cd /etc/passwd',
check: {
input: 'tsfile cd /etc/passwd',
hints: ' -> /etc/pam.d/',
markup: 'VVVVVVVVVVIIIIIIIIIII',
cursor: 21,
current: 'p1',
status: 'ERROR',
message: '\'/etc/passwd\' is not a directory',
args: {
command: { name: 'tsfile cd' },
p1: {
value: undefined,
arg: ' /etc/passwd',
status: 'INCOMPLETE',
message: '\'/etc/passwd\' is not a directory'
}
}
}
},
{
setup: 'tsfile mkdir /',
check: {
input: 'tsfile mkdir /',
hints: '',
markup: 'VVVVVVVVVVVVVI',
cursor: 14,
current: 'p1',
status: 'ERROR',
message: ''/' already exists',
args: {
command: { name: 'tsfile mkdir' },
p1: {
value: undefined,
arg: ' /',
status: 'INCOMPLETE',
message: '\'/\' already exists'
}
}
}
},
{
setup: 'tsfile mkdir /zxcv',
check: {
input: 'tsfile mkdir /zxcv',
// hints: ' -> /dev/',
markup: 'VVVVVVVVVVVVVVVVVV',
cursor: 18,
current: 'p1',
status: 'VALID',
message: '',
args: {
command: { name: 'tsfile mkdir' },
p1: {
value: '/zxcv',
arg: ' /zxcv',
status: 'VALID',
message: ''
}
}
}
},
{
skipIf: !local,
setup: 'tsfile mkdir /mach_kernel',
check: {
input: 'tsfile mkdir /mach_kernel',
hints: '',
markup: 'VVVVVVVVVVVVVIIIIIIIIIIII',
cursor: 25,
current: 'p1',
status: 'ERROR',
message: '\'/mach_kernel\' already exists',
args: {
command: { name: 'tsfile mkdir' },
p1: {
value: undefined,
arg: ' /mach_kernel',
status: 'INCOMPLETE',
message: '\'/mach_kernel\' already exists'
}
}
}
},
{
setup: 'tsfile rm /',
check: {
input: 'tsfile rm /',
hints: '',
markup: 'VVVVVVVVVVV',
cursor: 11,
current: 'p1',
status: 'VALID',
message: '',
args: {
command: { name: 'tsfile rm' },
p1: {
value: '/',
arg: ' /',
status: 'VALID',
message: ''
}
}
}
},
{
setup: 'tsfile rm /zxcv',
check: {
input: 'tsfile rm /zxcv',
// hints: ' -> /etc/',
markup: 'VVVVVVVVVVIIIII',
cursor: 15,
current: 'p1',
status: 'ERROR',
message: '\'/zxcv\' doesn\'t exist',
args: {
command: { name: 'tsfile rm' },
p1: {
value: undefined,
arg: ' /zxcv',
status: 'INCOMPLETE',
message: '\'/zxcv\' doesn\'t exist'
}
}
}
},
{
skipIf: !local,
setup: 'tsfile rm /mach_kernel',
check: {
input: 'tsfile rm /mach_kernel',
hints: '',
markup: 'VVVVVVVVVVVVVVVVVVVVVV',
cursor: 22,
current: 'p1',
status: 'VALID',
message: '',
args: {
command: { name: 'tsfile rm' },
p1: {
value: '/mach_kernel',
arg: ' /mach_kernel',
status: 'VALID',
message: ''
}
}
}
}
]);
};
exports.testFirefoxBasic = function(options) {
return helpers.audit(options, [
{
// These tests are just like the ones above tailored for running in
// Firefox
skipRemainingIf: true,
// skipRemainingIf: !options.isFirefox,
skipIf: true,
setup: 'tsfile open /',
check: {
input: 'tsfile open /',
hints: '',
markup: 'VVVVVVVVVVVVI',
cursor: 13,
current: 'p1',
status: 'ERROR',
message: '\'/\' is not a file',
args: {
command: { name: 'tsfile open' },
p1: {
value: undefined,
arg: ' /',
status: 'INCOMPLETE',
message: '\'/\' is not a file'
}
}
}
},
{
skipIf: true,
setup: 'tsfile open /zxcv',
check: {
input: 'tsfile open /zxcv',
// hints: ' -> /etc/',
markup: 'VVVVVVVVVVVVIIIII',
cursor: 17,
current: 'p1',
status: 'ERROR',
message: '\'/zxcv\' doesn\'t exist',
args: {
command: { name: 'tsfile open' },
p1: {
value: undefined,
arg: ' /zxcv',
status: 'INCOMPLETE',
message: '\'/zxcv\' doesn\'t exist'
}
}
}
},
{
skipIf: !local,
setup: 'tsfile open /mach_kernel',
check: {
input: 'tsfile open /mach_kernel',
hints: '',
markup: 'VVVVVVVVVVVVVVVVVVVVVVVV',
cursor: 24,
current: 'p1',
status: 'VALID',
message: '',
args: {
command: { name: 'tsfile open' },
p1: {
value: '/mach_kernel',
arg: ' /mach_kernel',
status: 'VALID',
message: ''
}
}
}
},
{
skipIf: true,
setup: 'tsfile saveas /',
check: {
input: 'tsfile saveas /',
hints: '',
markup: 'VVVVVVVVVVVVVVI',
cursor: 15,
current: 'p1',
status: 'ERROR',
message: '\'/\' already exists',
args: {
command: { name: 'tsfile saveas' },
p1: {
value: undefined,
arg: ' /',
status: 'INCOMPLETE',
message: '\'/\' already exists'
}
}
}
},
{
skipIf: true,
setup: 'tsfile saveas /zxcv',
check: {
input: 'tsfile saveas /zxcv',
// hints: ' -> /etc/',
markup: 'VVVVVVVVVVVVVVVVVVV',
cursor: 19,
current: 'p1',
status: 'VALID',
message: '',
args: {
command: { name: 'tsfile saveas' },
p1: {
value: '/zxcv',
arg: ' /zxcv',
status: 'VALID',
message: ''
}
}
}
},
{
skipIf: !local,
setup: 'tsfile saveas /mach_kernel',
check: {
input: 'tsfile saveas /mach_kernel',
hints: '',
markup: 'VVVVVVVVVVVVVVIIIIIIIIIIII',
cursor: 26,
current: 'p1',
status: 'ERROR',
message: '\'/mach_kernel\' already exists',
args: {
command: { name: 'tsfile saveas' },
p1: {
value: undefined,
arg: ' /mach_kernel',
status: 'INCOMPLETE',
message: '\'/mach_kernel\' already exists'
}
}
}
},
{
skipIf: true,
setup: 'tsfile save /',
check: {
input: 'tsfile save /',
hints: '',
markup: 'VVVVVVVVVVVVI',
cursor: 13,
current: 'p1',
status: 'ERROR',
message: '\'/\' is not a file',
args: {
command: { name: 'tsfile save' },
p1: {
value: undefined,
arg: ' /',
status: 'INCOMPLETE',
message: '\'/\' is not a file'
}
}
}
},
{
skipIf: true,
setup: 'tsfile save /zxcv',
check: {
input: 'tsfile save /zxcv',
// hints: ' -> /etc/',
markup: 'VVVVVVVVVVVVVVVVV',
cursor: 17,
current: 'p1',
status: 'VALID',
message: '',
args: {
command: { name: 'tsfile save' },
p1: {
value: '/zxcv',
arg: ' /zxcv',
status: 'VALID',
message: ''
}
}
}
},
{
skipIf: !local,
setup: 'tsfile save /mach_kernel',
check: {
input: 'tsfile save /mach_kernel',
hints: '',
markup: 'VVVVVVVVVVVVVVVVVVVVVVVV',
cursor: 24,
current: 'p1',
status: 'VALID',
message: '',
args: {
command: { name: 'tsfile save' },
p1: {
value: '/mach_kernel',
arg: ' /mach_kernel',
status: 'VALID',
message: ''
}
}
}
},
{
setup: 'tsfile cd /',
check: {
input: 'tsfile cd /',
hints: '',
markup: 'VVVVVVVVVVV',
cursor: 11,
current: 'p1',
status: 'VALID',
message: '',
args: {
command: { name: 'tsfile cd' },
p1: {
value: '/',
arg: ' /',
status: 'VALID',
message: ''
}
}
}
},
{
setup: 'tsfile cd /zxcv',
check: {
input: 'tsfile cd /zxcv',
// hints: ' -> /dev/',
// markup: 'VVVVVVVVVVIIIII',
cursor: 15,
current: 'p1',
// status: 'ERROR',
message: '\'/zxcv\' doesn\'t exist',
args: {
command: { name: 'tsfile cd' },
p1: {
value: undefined,
arg: ' /zxcv',
// status: 'INCOMPLETE',
message: '\'/zxcv\' doesn\'t exist'
}
}
}
},
{
skipIf: true || !local,
setup: 'tsfile cd /etc/passwd',
check: {
input: 'tsfile cd /etc/passwd',
hints: ' -> /etc/pam.d/',
markup: 'VVVVVVVVVVIIIIIIIIIII',
cursor: 21,
current: 'p1',
status: 'ERROR',
message: '\'/etc/passwd\' is not a directory',
args: {
command: { name: 'tsfile cd' },
p1: {
value: undefined,
arg: ' /etc/passwd',
status: 'INCOMPLETE',
message: '\'/etc/passwd\' is not a directory'
}
}
}
},
{
setup: 'tsfile mkdir /',
check: {
input: 'tsfile mkdir /',
hints: '',
markup: 'VVVVVVVVVVVVVI',
cursor: 14,
current: 'p1',
status: 'ERROR',
message: ''/' already exists',
args: {
command: { name: 'tsfile mkdir' },
p1: {
value: undefined,
arg: ' /',
status: 'INCOMPLETE',
message: '\'/\' already exists'
}
}
}
},
{
setup: 'tsfile mkdir /zxcv',
check: {
input: 'tsfile mkdir /zxcv',
// hints: ' -> /dev/',
markup: 'VVVVVVVVVVVVVVVVVV',
cursor: 18,
current: 'p1',
status: 'VALID',
message: '',
args: {
command: { name: 'tsfile mkdir' },
p1: {
value: '/zxcv',
arg: ' /zxcv',
status: 'VALID',
message: ''
}
}
}
},
{
skipIf: !local,
setup: 'tsfile mkdir /mach_kernel',
check: {
input: 'tsfile mkdir /mach_kernel',
hints: '',
markup: 'VVVVVVVVVVVVVIIIIIIIIIIII',
cursor: 25,
current: 'p1',
status: 'ERROR',
message: '\'/mach_kernel\' already exists',
args: {
command: { name: 'tsfile mkdir' },
p1: {
value: undefined,
arg: ' /mach_kernel',
status: 'INCOMPLETE',
message: '\'/mach_kernel\' already exists'
}
}
}
},
{
skipIf: true,
setup: 'tsfile rm /',
check: {
input: 'tsfile rm /',
hints: '',
markup: 'VVVVVVVVVVV',
cursor: 11,
current: 'p1',
status: 'VALID',
message: '',
args: {
command: { name: 'tsfile rm' },
p1: {
value: '/',
arg: ' /',
status: 'VALID',
message: ''
}
}
}
},
{
skipIf: true,
setup: 'tsfile rm /zxcv',
check: {
input: 'tsfile rm /zxcv',
// hints: ' -> /etc/',
markup: 'VVVVVVVVVVIIIII',
cursor: 15,
current: 'p1',
status: 'ERROR',
message: '\'/zxcv\' doesn\'t exist',
args: {
command: { name: 'tsfile rm' },
p1: {
value: undefined,
arg: ' /zxcv',
status: 'INCOMPLETE',
message: '\'/zxcv\' doesn\'t exist'
}
}
}
},
{
skipIf: !local,
setup: 'tsfile rm /mach_kernel',
check: {
input: 'tsfile rm /mach_kernel',
hints: '',
markup: 'VVVVVVVVVVVVVVVVVVVVVV',
cursor: 22,
current: 'p1',
status: 'VALID',
message: '',
args: {
command: { name: 'tsfile rm' },
p1: {
value: '/mach_kernel',
arg: ' /mach_kernel',
status: 'VALID',
message: ''
}
}
}
}
]);
};
// });

View File

@ -0,0 +1,57 @@
/*
* Copyright 2012, Mozilla Foundation and contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// define(function(require, exports, module) {
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
var exports = {};
const TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testFileparser.js</p>";
function test() {
helpers.addTabWithToolbar(TEST_URI, function(options) {
return helpers.runTests(options, exports);
}).then(finish);
}
// <INJECTED SOURCE:END>
'use strict';
// var assert = require('test/assert');
var fileparser = require('util/fileparser');
var local = false;
exports.testGetPredictor = function(options) {
if (!options.isNode || !local) {
return;
}
var options = { filetype: 'file', existing: 'yes' };
var predictor = fileparser.getPredictor('/usr/locl/bin/nmp', options);
return predictor().then(function(replies) {
assert.is(replies[0].name,
'/usr/local/bin/npm',
'predict npm');
});
};
// });

View File

@ -0,0 +1,78 @@
/*
* Copyright 2012, Mozilla Foundation and contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// define(function(require, exports, module) {
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
var exports = {};
const TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testFilesystem.js</p>";
function test() {
helpers.addTabWithToolbar(TEST_URI, function(options) {
return helpers.runTests(options, exports);
}).then(finish);
}
// <INJECTED SOURCE:END>
'use strict';
// var assert = require('test/assert');
// var helpers = require('gclitest/helpers');
var filesystem = require('util/filesystem');
exports.testSplit = function(options) {
if (!options.isNode) {
return;
}
helpers.arrayIs(filesystem.split('', '/'),
[ '.' ],
'split <blank>');
helpers.arrayIs(filesystem.split('a', '/'),
[ 'a' ],
'split a');
helpers.arrayIs(filesystem.split('a/b/c', '/'),
[ 'a', 'b', 'c' ],
'split a/b/c');
helpers.arrayIs(filesystem.split('/a/b/c/', '/'),
[ 'a', 'b', 'c' ],
'split a/b/c');
helpers.arrayIs(filesystem.split('/a/b///c/', '/'),
[ 'a', 'b', 'c' ],
'split a/b/c');
};
exports.testJoin = function(options) {
if (!options.isNode) {
return;
}
assert.is(filesystem.join('usr', 'local', 'bin'),
'usr/local/bin',
'join to usr/local/bin');
};
// });

View File

@ -1,7 +1,17 @@
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
* Copyright 2012, Mozilla Foundation and contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// define(function(require, exports, module) {

View File

@ -1,7 +1,17 @@
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
* Copyright 2012, Mozilla Foundation and contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// define(function(require, exports, module) {

View File

@ -1,7 +1,17 @@
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
* Copyright 2012, Mozilla Foundation and contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// define(function(require, exports, module) {

View File

@ -1,7 +1,17 @@
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
* Copyright 2012, Mozilla Foundation and contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// define(function(require, exports, module) {

View File

@ -48,6 +48,7 @@ exports.shutdown = function(options) {
};
exports.testRemote = function(options) {
var connected = false;
return helpers.audit(options, [
{
skipRemainingIf: !options.isHttp,
@ -65,6 +66,72 @@ exports.testRemote = function(options) {
unassigned: [ ],
}
},
{
setup: 'connect remote',
check: {
input: 'connect remote',
hints: ' [options]',
markup: 'VVVVVVVVVVVVVV',
cursor: 14,
current: 'prefix',
status: 'VALID',
options: [ ],
message: '',
predictions: [ ],
unassigned: [ ],
args: {
command: { name: 'connect' },
prefix: { value: 'remote', arg: ' remote', status: 'VALID', message: '' },
host: { value: undefined, arg: '', status: 'VALID', message: '' },
port: { value: undefined, arg: '', status: 'VALID', message: '' },
}
},
exec: {
completed: false,
error: false
},
post: function(output, data) {
connected = !output.error;
if (!connected) {
console.log('Failure from "connect remote". Run server with "node gcli server start --websocket --allowexec" to allow remote command testing');
}
}
},
{
// We do a connect-disconnect dance for 2 reasons, partly re-establishing
// a connection is a good test, and secondly it lets us have minimal
// testing on the first connection so we don't need to turn websockets
// on all the time
setup: 'disconnect remote --force',
skipRemainingIf: !connected,
check: {
input: 'disconnect remote --force',
hints: '',
markup: 'VVVVVVVVVVVVVVVVVVVVVVVVV',
cursor: 25,
current: 'force',
status: 'VALID',
message: '',
unassigned: [ ],
args: {
command: { name: 'disconnect' },
prefix: {
value: function(connection) {
assert.is(connection.prefix, 'remote', 'disconnecting remote');
},
arg: ' remote',
status: 'VALID',
message: ''
}
}
},
exec: {
output: /^Removed [0-9]* commands.$/,
completed: true,
type: 'string',
error: false
}
},
{
setup: 'connect remote',
check: {

View File

@ -35,7 +35,7 @@ function test() {
'use strict';
// var assert = require('test/assert');
var spell = require('gcli/types/spell');
var spell = require('util/spell');
exports.testSpellerSimple = function(options) {
var alternatives = Object.keys(options.window);
@ -54,5 +54,34 @@ exports.testSpellerSimple = function(options) {
assert.is(spell.correct('=========', alternatives), undefined);
};
exports.testRank = function(options) {
var distances = spell.rank('fred', [ 'banana', 'fred', 'ed', 'red', 'FRED' ]);
assert.is(distances.length, 5, 'rank length');
assert.is(distances[0].name, 'fred', 'fred name #0');
assert.is(distances[1].name, 'FRED', 'FRED name #1');
assert.is(distances[2].name, 'red', 'red name #2');
assert.is(distances[3].name, 'ed', 'ed name #3');
assert.is(distances[4].name, 'banana', 'banana name #4');
assert.is(distances[0].dist, 0, 'fred dist 0');
assert.is(distances[1].dist, 4, 'FRED dist 4');
assert.is(distances[2].dist, 10, 'red dist 10');
assert.is(distances[3].dist, 20, 'ed dist 20');
assert.is(distances[4].dist, 100, 'banana dist 100');
};
exports.testRank2 = function(options) {
var distances = spell.rank('caps', [ 'CAPS', 'false' ]);
assert.is(JSON.stringify(distances),
'[{"name":"CAPS","dist":4},{"name":"false","dist":50}]',
'spell.rank("caps", [ "CAPS", "false" ]');
};
exports.testDistancePrefix = function(options) {
assert.is(spell.distancePrefix('fred', 'freddy'), 0, 'distancePrefix fred');
assert.is(spell.distancePrefix('FRED', 'freddy'), 4, 'distancePrefix FRED');
};
// });

View File

@ -47,7 +47,7 @@ exports.shutdown = function(options) {
};
exports.testNewLine = function(options) {
helpers.audit(options, [
return helpers.audit(options, [
{
setup: 'echo a\\nb',
check: {
@ -72,7 +72,7 @@ exports.testNewLine = function(options) {
};
exports.testTab = function(options) {
helpers.audit(options, [
return helpers.audit(options, [
{
setup: 'echo a\\tb',
check: {
@ -97,7 +97,7 @@ exports.testTab = function(options) {
};
exports.testEscape = function(options) {
helpers.audit(options, [
return helpers.audit(options, [
{
// What's typed is actually:
// tsrsrsr a\\ b c
@ -143,7 +143,7 @@ exports.testEscape = function(options) {
};
exports.testBlank = function(options) {
helpers.audit(options, [
return helpers.audit(options, [
{
setup: 'tsrsrsr a "" c',
check: {
@ -213,7 +213,7 @@ exports.testBlank = function(options) {
};
exports.testBlankWithParam = function(options) {
helpers.audit(options, [
return helpers.audit(options, [
{
setup: 'tsrsrsr a --p3',
check: {

View File

@ -30,6 +30,7 @@ let promise = (Cu.import("resource://gre/modules/commonjs/sdk/core/promise.js",
let assert = { ok: ok, is: is, log: info };
var util = require('util/util');
var cli = require('gcli/cli');
var converters = require('gcli/converters');
@ -566,7 +567,7 @@ helpers._check = function(options, name, checks) {
if ('predictions' in checks) {
var predictionsCheck = function(actualPredictions) {
helpers._arrayIs(actualPredictions,
helpers.arrayIs(actualPredictions,
checks.predictions,
'predictions' + suffix);
};
@ -585,7 +586,7 @@ helpers._check = function(options, name, checks) {
}
if ('unassigned' in checks) {
helpers._arrayIs(helpers._actual.unassigned(options),
helpers.arrayIs(helpers._actual.unassigned(options),
checks.unassigned,
'unassigned' + suffix);
}
@ -613,7 +614,7 @@ helpers._check = function(options, name, checks) {
}
if ('options' in checks) {
helpers._arrayIs(helpers._actual.options(options),
helpers.arrayIs(helpers._actual.options(options),
checks.options,
'options' + suffix);
}
@ -718,6 +719,11 @@ helpers._exec = function(options, name, expected) {
return promise.resolve({});
}
var origLogErrors = cli.logErrors;
if (expected.error) {
cli.logErrors = false;
}
var output;
try {
output = options.display.requisition.exec({ hidden: true });
@ -726,6 +732,9 @@ helpers._exec = function(options, name, expected) {
assert.ok(false, 'Failure executing \'' + name + '\': ' + ex);
util.errorHandler(ex);
if (expected.error) {
cli.logErrors = origLogErrors;
}
return promise.resolve({});
}
@ -737,10 +746,17 @@ helpers._exec = function(options, name, expected) {
if (!options.window.document.createElement) {
assert.log('skipping output tests (missing doc.createElement) for ' + name);
if (expected.error) {
cli.logErrors = origLogErrors;
}
return promise.resolve({ output: output });
}
if (!('output' in expected)) {
if (expected.error) {
cli.logErrors = origLogErrors;
}
return promise.resolve({ output: output });
}
@ -788,6 +804,9 @@ helpers._exec = function(options, name, expected) {
doTest(expected.output, actualOutput);
}
if (expected.error) {
cli.logErrors = origLogErrors;
}
return { output: output, text: actualOutput };
});
};
@ -940,17 +959,6 @@ helpers.audit = function(options, audits) {
log('- START \'' + name + '\' in ' + assert.currentTest);
}
if (audit.skipIf) {
var skip = (typeof audit.skipIf === 'function') ?
audit.skipIf(options) :
!!audit.skipIf;
if (skip) {
var reason = audit.skipIf.name ? 'due to ' + audit.skipIf.name : '';
assert.log('Skipped ' + name + ' ' + reason);
return promise.resolve(undefined);
}
}
if (audit.skipRemainingIf) {
var skipRemainingIf = (typeof audit.skipRemainingIf === 'function') ?
audit.skipRemainingIf(options) :
@ -964,6 +972,17 @@ helpers.audit = function(options, audits) {
}
}
if (audit.skipIf) {
var skip = (typeof audit.skipIf === 'function') ?
audit.skipIf(options) :
!!audit.skipIf;
if (skip) {
var reason = audit.skipIf.name ? 'due to ' + audit.skipIf.name : '';
assert.log('Skipped ' + name + ' ' + reason);
return promise.resolve(undefined);
}
}
if (skipReason != null) {
assert.log('Skipped ' + name + ' ' + skipReason);
return promise.resolve(undefined);
@ -1008,7 +1027,7 @@ helpers.audit = function(options, audits) {
/**
* Compare 2 arrays.
*/
helpers._arrayIs = function(actual, expected, message) {
helpers.arrayIs = function(actual, expected, message) {
assert.ok(Array.isArray(actual), 'actual is not an array: ' + message);
assert.ok(Array.isArray(expected), 'expected is not an array: ' + message);

View File

@ -482,6 +482,116 @@ var tsfail = {
}
};
var tsfile = {
item: 'command',
name: 'tsfile',
description: 'test file params',
};
var tsfileOpen = {
item: 'command',
name: 'tsfile open',
description: 'a file param in open mode',
params: [
{
name: 'p1',
type: {
name: 'file',
filetype: 'file',
existing: 'yes'
}
}
],
exec: createExec('tsfile open')
};
var tsfileSaveas = {
item: 'command',
name: 'tsfile saveas',
description: 'a file param in saveas mode',
params: [
{
name: 'p1',
type: {
name: 'file',
filetype: 'file',
existing: 'no'
}
}
],
exec: createExec('tsfile saveas')
};
var tsfileSave = {
item: 'command',
name: 'tsfile save',
description: 'a file param in save mode',
params: [
{
name: 'p1',
type: {
name: 'file',
filetype: 'file',
existing: 'maybe'
}
}
],
exec: createExec('tsfile save')
};
var tsfileCd = {
item: 'command',
name: 'tsfile cd',
description: 'a file param in cd mode',
params: [
{
name: 'p1',
type: {
name: 'file',
filetype: 'directory',
existing: 'yes'
}
}
],
exec: createExec('tsfile cd')
};
var tsfileMkdir = {
item: 'command',
name: 'tsfile mkdir',
description: 'a file param in mkdir mode',
params: [
{
name: 'p1',
type: {
name: 'file',
filetype: 'directory',
existing: 'no'
}
}
],
exec: createExec('tsfile mkdir')
};
var tsfileRm = {
item: 'command',
name: 'tsfile rm',
description: 'a file param in rm mode',
params: [
{
name: 'p1',
type: {
name: 'file',
filetype: 'any',
existing: 'yes'
}
}
],
exec: createExec('tsfile rm')
};
mockCommands.commands = {};
/**
@ -533,6 +643,13 @@ mockCommands.setup = function(opts) {
mockCommands.commands.tslong = canon.addCommand(tslong);
mockCommands.commands.tsdate = canon.addCommand(tsdate);
mockCommands.commands.tsfail = canon.addCommand(tsfail);
mockCommands.commands.tsfile = canon.addCommand(tsfile);
mockCommands.commands.tsfileOpen = canon.addCommand(tsfileOpen);
mockCommands.commands.tsfileSaveas = canon.addCommand(tsfileSaveas);
mockCommands.commands.tsfileSave = canon.addCommand(tsfileSave);
mockCommands.commands.tsfileCd = canon.addCommand(tsfileCd);
mockCommands.commands.tsfileMkdir = canon.addCommand(tsfileMkdir);
mockCommands.commands.tsfileRm = canon.addCommand(tsfileRm);
};
mockCommands.shutdown = function(opts) {
@ -564,6 +681,13 @@ mockCommands.shutdown = function(opts) {
canon.removeCommand(tslong);
canon.removeCommand(tsdate);
canon.removeCommand(tsfail);
canon.removeCommand(tsfile);
canon.removeCommand(tsfileOpen);
canon.removeCommand(tsfileSaveas);
canon.removeCommand(tsfileSave);
canon.removeCommand(tsfileCd);
canon.removeCommand(tsfileMkdir);
canon.removeCommand(tsfileRm);
types.removeType(mockCommands.optionType);
types.removeType(mockCommands.optionValue);

View File

@ -707,6 +707,7 @@ FilterView.prototype = {
this._searchbox = document.getElementById("searchbox");
this._searchboxHelpPanel = document.getElementById("searchbox-help-panel");
this._filterLabel = document.getElementById("filter-label");
this._globalOperatorButton = document.getElementById("global-operator-button");
this._globalOperatorLabel = document.getElementById("global-operator-label");
this._functionOperatorButton = document.getElementById("function-operator-button");
@ -737,6 +738,8 @@ FilterView.prototype = {
this._lineOperatorButton.setAttribute("label", SEARCH_LINE_FLAG);
this._variableOperatorButton.setAttribute("label", SEARCH_VARIABLE_FLAG);
this._filterLabel.setAttribute("value",
L10N.getFormatStr("searchPanelFilter", this._fileSearchKey));
this._globalOperatorLabel.setAttribute("value",
L10N.getFormatStr("searchPanelGlobal", this._globalSearchKey));
this._functionOperatorLabel.setAttribute("value",
@ -780,7 +783,7 @@ FilterView.prototype = {
placeholder = L10N.getFormatStr("emptyChromeGlobalsFilterText", this._fileSearchKey);
break;
case DebuggerView.Sources:
placeholder = L10N.getFormatStr("emptyFilterText", this._fileSearchKey);
placeholder = L10N.getFormatStr("emptySearchText", this._fileSearchKey);
break;
}
this._searchbox.setAttribute("placeholder", placeholder);

View File

@ -310,8 +310,11 @@
noautofocus="true"
position="before_start">
<vbox>
<label id="searchbox-panel-description"
value="&debuggerUI.searchPanelTitle;"/>
<hbox>
<label id="filter-label"/>
</hbox>
<label id="searchbox-panel-operators"
value="&debuggerUI.searchPanelOperators;"/>
<hbox align="center">
<button id="global-operator-button"
class="searchbox-panel-operator-button"

View File

@ -106,6 +106,8 @@ MOCHITEST_BROWSER_TESTS = \
browser_dbg_source_maps-01.js \
browser_dbg_source_maps-02.js \
browser_dbg_step-out.js \
browser_dbg_event-listeners.js \
browser_dbg_break-on-dom-event.js \
head.js \
$(NULL)
@ -145,6 +147,7 @@ MOCHITEST_BROWSER_PAGES = \
test-location-changes-bp.html \
test-step-out.html \
test-pause-exceptions-reload.html \
test-event-listeners.html \
$(NULL)
# Bug 888811 & bug 891176:

View File

@ -0,0 +1,158 @@
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
// Tests that the break-on-dom-events request works.
var gClient = null;
var gTab = null;
var gThreadClient = null;
var gInput = null;
var gButton = null;
const DEBUGGER_TAB_URL = EXAMPLE_URL + "test-event-listeners.html";
function test()
{
let transport = DebuggerServer.connectPipe();
gClient = new DebuggerClient(transport);
gClient.connect(function(type, traits) {
gTab = addTab(DEBUGGER_TAB_URL, function() {
attach_thread_actor_for_url(gClient,
DEBUGGER_TAB_URL,
function(threadClient) {
gThreadClient = threadClient;
gInput = content.document.querySelector("input");
gButton = content.document.querySelector("button");
testBreakOnAll();
});
});
});
}
// Test pause on all events.
function testBreakOnAll()
{
gClient.addOneTimeListener("paused", function(event, packet) {
is(packet.why.type, "debuggerStatement", "debugger statement was hit.");
// Test calling pauseOnDOMEvents from a paused state.
gThreadClient.pauseOnDOMEvents("*", function(packet) {
is(packet, undefined, "The pause-on-any-event request completed successfully.");
gClient.addOneTimeListener("paused", function(event, packet) {
is(packet.why.type, "pauseOnDOMEvents", "A hidden breakpoint was hit.");
is(packet.frame.callee.name, "keyupHandler", "The keyupHandler is entered.");
gThreadClient.resume(function() {
gClient.addOneTimeListener("paused", function(event, packet) {
is(packet.why.type, "pauseOnDOMEvents", "A hidden breakpoint was hit.");
is(packet.frame.callee.name, "clickHandler", "The clickHandler is entered.");
gThreadClient.resume(function() {
gClient.addOneTimeListener("paused", function(event, packet) {
is(packet.why.type, "pauseOnDOMEvents", "A hidden breakpoint was hit.");
is(packet.frame.callee.name, "onchange", "The onchange handler is entered.");
gThreadClient.resume(testBreakOnDisabled);
});
gInput.focus();
gInput.value = "foo";
gInput.blur();
});
});
EventUtils.sendMouseEvent({ type: "click" }, gButton);
});
});
gThreadClient.resume(function() {
gInput.focus();
EventUtils.synthesizeKey("e", {}, content);
});
});
});
EventUtils.sendMouseEvent({ type: "click" }, gButton);
}
// Test that removing events from the array disables them.
function testBreakOnDisabled()
{
// Test calling pauseOnDOMEvents from a running state.
gThreadClient.pauseOnDOMEvents(["click"], function(packet) {
is(packet.error, undefined, "The pause-on-click-only request completed successfully.");
gClient.addListener("paused", unexpectedListener);
// This non-capturing event listener is guaranteed to run after the page's
// capturing one had a chance to execute and modify window.foobar.
gInput.addEventListener("keyup", function tempHandler() {
gInput.removeEventListener("keyup", tempHandler, false);
is(content.wrappedJSObject.foobar, "keyupHandler", "No hidden breakpoint was hit.");
gClient.removeListener("paused", unexpectedListener);
testBreakOnNone();
}, false);
gInput.focus();
EventUtils.synthesizeKey("e", {}, content);
});
}
// Test that specifying an empty event array clears all hidden breakpoints.
function testBreakOnNone()
{
// Test calling pauseOnDOMEvents from a running state.
gThreadClient.pauseOnDOMEvents([], function(packet) {
is(packet.error, undefined, "The pause-on-none request completed successfully.");
gClient.addListener("paused", unexpectedListener);
// This non-capturing event listener is guaranteed to run after the page's
// capturing one had a chance to execute and modify window.foobar.
gInput.addEventListener("keyup", function tempHandler() {
gInput.removeEventListener("keyup", tempHandler, false);
is(content.wrappedJSObject.foobar, "keyupHandler", "No hidden breakpoint was hit.");
gClient.removeListener("paused", unexpectedListener);
testBreakOnClick();
}, false);
gInput.focus();
EventUtils.synthesizeKey("g", {}, content);
});
}
function unexpectedListener(event, packet, callback) {
gClient.removeListener("paused", unexpectedListener);
ok(false, "An unexpected hidden breakpoint was hit.");
gThreadClient.resume(testBreakOnClick);
}
// Test pause on a single event.
function testBreakOnClick()
{
// Test calling pauseOnDOMEvents from a running state.
gThreadClient.pauseOnDOMEvents(["click"], function(packet) {
is(packet.error, undefined, "The pause-on-click request completed successfully.");
gClient.addOneTimeListener("paused", function(event, packet) {
is(packet.why.type, "pauseOnDOMEvents", "A hidden breakpoint was hit.");
is(packet.frame.callee.name, "clickHandler", "The clickHandler is entered.");
gThreadClient.resume(function() {
gClient.close(finish);
});
});
EventUtils.sendMouseEvent({ type: "click" }, gButton);
});
}
registerCleanupFunction(function() {
removeTab(gTab);
gTab = null;
gClient = null;
gThreadClient = null;
gInput = null;
gButton = null;
});

View File

@ -54,35 +54,33 @@ function test() {
cmd("dbg step out", function() {
is(output.value, "step out", "debugger stepped out");
cmd("dbg continue", function() {
cmd("dbg continue", function() {
is(output.value, "dbg continue", "debugger continued");
is(output.value, "dbg continue", "debugger continued");
function closeDebugger(cb) {
helpers.audit(options, [{
setup: "dbg close",
completed: false,
exec: { output: "" }
}]);
function closeDebugger(cb) {
helpers.audit(options, [{
setup: "dbg close",
completed: false,
exec: { output: "" }
}]);
let toolbox = gDevTools.getToolbox(options.target);
if (!toolbox) {
let toolbox = gDevTools.getToolbox(options.target);
if (!toolbox) {
ok(true, "Debugger was closed.");
cb();
} else {
toolbox.on("destroyed", function () {
ok(true, "Debugger was closed.");
cb();
} else {
toolbox.on("destroyed", function () {
ok(true, "Debugger was closed.");
cb();
});
}
});
}
}
// We're closing the debugger twice to make sure
// 'dbg close' doesn't error when toolbox is already
// closed. See bug 884638 for more info.
// We're closing the debugger twice to make sure
// 'dbg close' doesn't error when toolbox is already
// closed. See bug 884638 for more info.
closeDebugger(() => {
closeDebugger(() => deferred.resolve());
});
closeDebugger(() => {
closeDebugger(() => deferred.resolve());
});
});
});

View File

@ -0,0 +1,91 @@
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
// Tests that the eventListeners request works.
var gClient = null;
var gTab = null;
var gThreadClient = null;
const DEBUGGER_TAB_URL = EXAMPLE_URL + "test-event-listeners.html";
function test()
{
let transport = DebuggerServer.connectPipe();
gClient = new DebuggerClient(transport);
gClient.connect(function(aType, aTraits) {
gTab = addTab(DEBUGGER_TAB_URL, function() {
attach_thread_actor_for_url(gClient,
DEBUGGER_TAB_URL,
function(threadClient) {
gThreadClient = threadClient;
testEventListeners();
});
});
});
}
function testEventListeners()
{
gClient.addOneTimeListener("paused", function(aEvent, aPacket) {
is(aPacket.why.type, "debuggerStatement", "debugger statement was hit.");
gThreadClient.eventListeners(function(aPacket) {
is(aPacket.listeners.length, 4, "Found all event listeners.");
let types = [];
for (let l of aPacket.listeners) {
let node = l.node;
ok(node, "There is a node property.");
ok(node.object, "There is a node object property.");
ok(node.selector == "window" ||
content.document.querySelectorAll(node.selector).length == 1,
"The node property is a unique CSS selector");
ok(l.function, "There is a function property.");
is(l.function.type, "object", "The function form is of type 'object'.");
is(l.function.class, "Function", "The function form is of class 'Function'.");
is(l.function.url, DEBUGGER_TAB_URL, "The function url is correct.");
is(l.allowsUntrusted, true,
"allowsUntrusted property has the right value.");
is(l.inSystemEventGroup, false,
"inSystemEventGroup property has the right value.");
types.push(l.type);
if (l.type == "keyup") {
is(l.capturing, true, "Capturing property has the right value.");
is(l.isEventHandler, false,
"isEventHandler property has the right value.");
} else if (l.type == "load") {
is(l.capturing, false, "Capturing property has the right value.");
is(l.isEventHandler, false,
"isEventHandler property has the right value.");
} else {
is(l.capturing, false, "Capturing property has the right value.");
is(l.isEventHandler, true,
"isEventHandler property has the right value.");
}
}
ok(types.indexOf("click") != -1, "Found the click handler.");
ok(types.indexOf("change") != -1, "Found the change handler.");
ok(types.indexOf("keyup") != -1, "Found the keyup handler.");
finish_test();
});
});
EventUtils.sendMouseEvent({ type: "click" },
content.document.querySelector("button"));
}
function finish_test()
{
gThreadClient.resume(function() {
gClient.close(finish);
});
}
registerCleanupFunction(function() {
removeTab(gTab);
gTab = null;
gClient = null;
gThreadClient = null;
});

View File

@ -37,6 +37,13 @@ let gEnableLogging = Services.prefs.getBoolPref("devtools.debugger.log");
Services.prefs.setBoolPref("devtools.debugger.remote-enabled", true);
Services.prefs.setBoolPref("devtools.debugger.log", true);
// Redeclare dbg_assert with a fatal behavior.
function dbg_assert(cond, e) {
if (!cond) {
throw e;
}
}
registerCleanupFunction(function() {
Services.prefs.setBoolPref("devtools.debugger.remote-enabled", gEnableRemote);
Services.prefs.setBoolPref("devtools.debugger.log", gEnableLogging);
@ -143,11 +150,11 @@ function attach_tab_actor_for_url(aClient, aURL, aCallback) {
function attach_thread_actor_for_url(aClient, aURL, aCallback) {
attach_tab_actor_for_url(aClient, aURL, function(aTabActor, aResponse) {
aClient.attachThread(actor.threadActor, function(aResponse, aThreadClient) {
aClient.attachThread(aResponse.threadActor, function(aResponse, aThreadClient) {
// We don't care about the pause right now (use
// get_actor_for_url() if you do), so resume it.
aThreadClient.resume(function(aResponse) {
aCallback(actor);
aCallback(aThreadClient);
});
});
});

View File

@ -0,0 +1,37 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset='utf-8'/>
<title>Debugger Test for Event Listeners</title>
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<script type="text/javascript">
window.addEventListener("load", function() {
function initialSetup(event) {
debugger;
var button = document.querySelector("button");
button.onclick = clickHandler;
}
function clickHandler(event) {
window.foobar = "clickHandler";
}
function changeHandler(event) {
window.foobar = "changeHandler";
}
function keyupHandler(event) {
window.foobar = "keyupHandler";
}
var button = document.querySelector("button");
button.onclick = initialSetup;
var input = document.querySelector("input");
input.addEventListener("keyup", keyupHandler, true);
window.changeHandler = changeHandler;
});
</script>
</head>
<body>
<button>Click me!</button>
<input type="text" onchange="changeHandler()">
</body>
</html>

View File

@ -22,6 +22,7 @@ MOCHITEST_BROWSER_FILES = \
browser_toolbox_tool_ready.js \
browser_toolbox_sidebar.js \
browser_toolbox_window_shortcuts.js \
browser_toolbox_tabsswitch_shortcuts.js \
browser_toolbox_window_title_changes.js \
browser_toolbox_options.js \
browser_toolbox_options_disablejs.js \

View File

@ -0,0 +1,88 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
let Toolbox = devtools.Toolbox;
let toolbox, toolIDs, idIndex, secondTime = false,
reverse = false, nextKey = null, prevKey = null;
function test() {
waitForExplicitFinish();
addTab("about:blank", function() {
toolIDs = [tool.id for (tool of gDevTools.getToolDefinitionArray())];
let target = TargetFactory.forTab(gBrowser.selectedTab);
idIndex = 0;
gDevTools.showToolbox(target, toolIDs[0], Toolbox.HostType.BOTTOM)
.then(testShortcuts);
});
}
function testShortcuts(aToolbox, aIndex) {
if (aIndex == toolIDs.length) {
aIndex = 0;
if (secondTime) {
secondTime = false;
reverse = true;
aIndex = toolIDs.length - 2;
}
else {
secondTime = true;
}
}
else if (aIndex == -1) {
aIndex = toolIDs.length - 1;
if (secondTime) {
tidyUp();
return;
}
secondTime = true;
}
toolbox = aToolbox;
if (!nextKey) {
nextKey = toolbox.doc.getElementById("toolbox-next-tool-key")
.getAttribute("key");
prevKey = toolbox.doc.getElementById("toolbox-previous-tool-key")
.getAttribute("key");
}
info("Toolbox fired a `ready` event");
toolbox.once("select", onSelect);
if (aIndex != null) {
// This if block is to allow the call of onSelect without shortcut press for
// the first time. That happens because on opening of toolbox, one tool gets
// selected atleast.
let key = (reverse ? prevKey: nextKey);
let modifiers = {
accelKey: true
};
idIndex = aIndex;
info("Testing shortcut to switch to tool " + aIndex + ":" + toolIDs[aIndex] +
" using key " + key);
EventUtils.synthesizeKey(key, modifiers, toolbox.doc.defaultView);
}
}
function onSelect(event, id) {
info("toolbox-select event from " + id);
is(toolIDs.indexOf(id), idIndex,
"Correct tool is selected on pressing the shortcut for " + id);
// Execute soon to reset the stack trace.
executeSoon(() => {
testShortcuts(toolbox, idIndex + (reverse ? -1: 1));
});
}
function tidyUp() {
toolbox.destroy().then(function() {
gBrowser.removeCurrentTab();
toolbox = toolIDs = idIndex = Toolbox = secondTime = reverse = nextKey =
prevKey = null;
finish();
});
}

View File

@ -17,8 +17,7 @@ function test() {
addTab("about:blank", function() {
toolIDs = [];
for (let [id, definition] of gDevTools._tools) {
// Skipping Profiler due to bug 838069. Re-enable when bug 845752 is fixed
if (definition.key && id != "jsprofiler") {
if (definition.key) {
toolIDs.push(id);
}
}

View File

@ -207,6 +207,7 @@ Toolbox.prototype = {
this._buildTabs();
this._buildButtons();
this._addKeysToWindow();
this._addToolSwitchingKeys();
this._telemetry.toolOpened("toolbox");
@ -230,6 +231,13 @@ Toolbox.prototype = {
}.bind(this, "options"), true);
},
_addToolSwitchingKeys: function TBOX__addToolSwitchingKeys() {
let nextKey = this.doc.getElementById("toolbox-next-tool-key");
nextKey.addEventListener("command", this.selectNextTool.bind(this), true);
let prevKey = this.doc.getElementById("toolbox-previous-tool-key");
prevKey.addEventListener("command", this.selectPreviousTool.bind(this), true);
},
/**
* Adds the keys and commands to the Toolbox Window in window mode.
*/
@ -539,6 +547,26 @@ Toolbox.prototype = {
});
},
/**
* Loads the tool next to the currently selected tool.
*/
selectNextTool: function TBOX_selectNextTool() {
let selected = this.doc.querySelector(".devtools-tab[selected]");
let next = selected.nextSibling || selected.parentNode.firstChild;
let tool = next.getAttribute("toolid");
return this.selectTool(tool);
},
/**
* Loads the tool just left to the currently selected tool.
*/
selectPreviousTool: function TBOX_selectPreviousTool() {
let selected = this.doc.querySelector(".devtools-tab[selected]");
let previous = selected.previousSibling || selected.parentNode.lastChild;
let tool = previous.getAttribute("toolid");
return this.selectTool(tool);
},
/**
* Highlights the tool's tab if it is not the currently selected tool.
*
@ -744,7 +772,7 @@ Toolbox.prototype = {
gDevTools.off("tool-registered", this._toolRegistered);
gDevTools.off("tool-unregistered", this._toolUnregistered);
// Revert docShell.allowJavascript back to it's original value if it was
// Revert docShell.allowJavascript back to its original value if it was
// changed via the Disable JS option.
if (typeof this._origAllowJavascript != "undefined") {
let docShell = this._host.hostTab.linkedBrowser.docShell;
@ -755,7 +783,12 @@ Toolbox.prototype = {
let outstanding = [];
for (let [id, panel] of this._toolPanels) {
outstanding.push(panel.destroy());
try {
outstanding.push(panel.destroy());
} catch(e) {
// We don't want to stop here if any panel fail to close.
console.error(e);
}
}
let container = this.doc.getElementById("toolbox-buttons");

View File

@ -23,6 +23,14 @@
key="&toolboxOptionsButton.key;"
oncommand="void(0);"
modifiers="shift, accel"/>
<key id="toolbox-next-tool-key"
key="&toolboxNextTool.key;"
oncommand="void(0);"
modifiers="accel"/>
<key id="toolbox-previous-tool-key"
key="&toolboxPreviousTool.key;"
oncommand="void(0);"
modifiers="accel"/>
</keyset>
<notificationbox id="toolbox-notificationbox" flex="1">

View File

@ -229,6 +229,13 @@ Highlighter.prototype = {
*/
invalidateSize: function Highlighter_invalidateSize()
{
let canHiglightNode = this.selection.isNode() &&
this.selection.isConnected() &&
this.selection.isElementNode();
if (!canHiglightNode)
return;
// The highlighter runs locally while the selection runs remotely,
// so we can't quite trust the selection's isConnected to protect us
// here, do the check manually.
@ -238,13 +245,6 @@ Highlighter.prototype = {
return;
}
let canHiglightNode = this.selection.isNode() &&
this.selection.isConnected() &&
this.selection.isElementNode();
if (!canHiglightNode)
return;
let clientRect = this.selection.node.getBoundingClientRect();
let rect = LayoutHelpers.getDirtyRect(this.selection.node);
this.highlightRectangle(rect);

View File

@ -141,7 +141,7 @@ InspectorPanel.prototype = {
this.highlighter.unlock();
}
this.markup.expandNode(this.selection.node);
this.markup.expandNode(this.selection.nodeFront);
this.emit("ready");
deferred.resolve(this);
@ -157,14 +157,24 @@ InspectorPanel.prototype = {
* Return a promise that will resolve to the default node for selection.
*/
_getDefaultNodeForSelection : function() {
if (this._defaultNode) {
return this._defaultNode;
}
let walker = this.walker;
// if available set body node as default selected node
// else set documentElement
return this.walker.querySelector(this.walker.rootNode, "body").then(front => {
return walker.querySelector(this.walker.rootNode, "body").then(front => {
if (front) {
return front;
}
return this.walker.documentElement(this.walker.rootNode);
});
}).then(node => {
if (walker !== this.walker) {
promise.reject(null);
}
this._defaultNode = node;
return node;
})
},
/**
@ -214,18 +224,19 @@ InspectorPanel.prototype = {
} else if (this.target.window) {
searchDoc = this.target.window.document;
} else {
return;
searchDoc = null;
}
// Initiate the selectors search object.
let setNodeFunction = function(node) {
this.selection.setNode(node, "selectorsearch");
let setNodeFunction = function(eventName, node) {
this.selection.setNodeFront(node, "selectorsearch");
}.bind(this);
if (this.searchSuggestions) {
this.searchSuggestions.destroy();
this.searchSuggestions = null;
}
this.searchBox = this.panelDoc.getElementById("inspector-searchbox");
this.searchSuggestions = new SelectorSearch(searchDoc, this.searchBox, setNodeFunction);
this.searchSuggestions = new SelectorSearch(this, searchDoc, this.searchBox);
this.searchSuggestions.on("node-selected", setNodeFunction);
},
/**
@ -276,6 +287,7 @@ InspectorPanel.prototype = {
let newWindow = payload._navPayload || payload;
this.walker.release().then(null, console.error);
this.walker = null;
this._defaultNode = null;
this.selection.setNodeFront(null);
this.selection.setWalker(null);
this._destroyMarkup();
@ -297,7 +309,7 @@ InspectorPanel.prototype = {
this._initMarkup();
this.once("markuploaded", () => {
this.markup.expandNode(this.selection.node);
this.markup.expandNode(this.selection.nodeFront);
this.setupSearchBox();
});
});
@ -391,7 +403,7 @@ InspectorPanel.prototype = {
onDetached: function InspectorPanel_onDetached(event, parentNode) {
this.cancelLayoutChange();
this.breadcrumbs.cutAfter(this.breadcrumbs.indexOf(parentNode));
this.selection.setNodeFront(parentNode, "detached");
this.selection.setNodeFront(parentNode ? parentNode : this._defaultNode, "detached");
},
/**
@ -624,10 +636,7 @@ InspectorPanel.prototype = {
if (!this.selection.isNode()) {
return;
}
let toCopy = this.selection.node.innerHTML;
if (toCopy) {
clipboardHelper.copyString(toCopy);
}
this._copyLongStr(this.walker.innerHTML(this.selection.nodeFront));
},
/**
@ -638,10 +647,17 @@ InspectorPanel.prototype = {
if (!this.selection.isNode()) {
return;
}
let toCopy = this.selection.node.outerHTML;
if (toCopy) {
clipboardHelper.copyString(toCopy);
}
this._copyLongStr(this.walker.outerHTML(this.selection.nodeFront));
},
_copyLongStr: function(promise) {
return promise.then(longstr => {
return longstr.string().then(toCopy => {
longstr.release().then(null, console.error);
clipboardHelper.copyString(toCopy);
});
}).then(null, console.error);
},
/**
@ -668,17 +684,13 @@ InspectorPanel.prototype = {
return;
}
let toDelete = this.selection.node;
let parent = this.selection.node.parentNode;
// If the markup panel is active, use the markup panel to delete
// the node, making this an undoable action.
if (this.markup) {
this.markup.deleteNode(toDelete);
this.markup.deleteNode(this.selection.nodeFront);
} else {
// remove the node from content
parent.removeChild(toDelete);
this.walker.removeNode(this.selection.nodeFront);
}
},

View File

@ -5,6 +5,8 @@
"use strict";
const {Cu} = require("chrome");
const EventEmitter = require("devtools/shared/event-emitter");
const promise = require("sdk/core/promise");
loader.lazyGetter(this, "AutocompletePopup", () => {
return Cu.import("resource:///modules/devtools/AutocompletePopup.jsm", {}).AutocompletePopup;
@ -17,18 +19,19 @@ const MAX_SUGGESTIONS = 15;
* Converts any input box on a page to a CSS selector search and suggestion box.
*
* @constructor
* @param InspectorPanel aInspector
* The InspectorPanel whose `walker` attribute should be used for
* document traversal.
* @param nsIDOMDocument aContentDocument
* The content document which inspector is attached to.
* The content document which inspector is attached to, or null if
* a remote document.
* @param nsiInputElement aInputNode
* The input element to which the panel will be attached and from where
* search input will be taken.
* @param Function aCallback
* The method to callback when a search is available.
* This method is called with the matched node as the first argument.
*/
function SelectorSearch(aContentDocument, aInputNode, aCallback) {
function SelectorSearch(aInspector, aContentDocument, aInputNode) {
this.inspector = aInspector;
this.doc = aContentDocument;
this.callback = aCallback;
this.searchBox = aInputNode;
this.panelDoc = this.searchBox.ownerDocument;
@ -62,12 +65,20 @@ function SelectorSearch(aContentDocument, aInputNode, aCallback) {
// event listeners.
this.searchBox.addEventListener("command", this._onHTMLSearch, true);
this.searchBox.addEventListener("keypress", this._onSearchKeypress, true);
// For testing, we need to be able to wait for the most recent node request
// to finish. Tests can watch this promise for that.
this._lastQuery = promise.resolve(null);
EventEmitter.decorate(this);
}
exports.SelectorSearch = SelectorSearch;
SelectorSearch.prototype = {
get walker() this.inspector.walker,
// The possible states of the query.
States: {
CLASS: "class",
@ -168,7 +179,13 @@ SelectorSearch.prototype = {
this.panelDoc = null;
this._searchResults = null;
this._searchSuggestions = null;
this.callback = null;
EventEmitter.decorate(this);
},
_selectResult: function(index) {
return this._searchResults.item(index).then(node => {
this.emit("node-selected", node);
});
},
/**
@ -181,6 +198,7 @@ SelectorSearch.prototype = {
return;
}
this._lastSearched = query;
this._searchResults = null;
this._searchIndex = 0;
if (query.length == 0) {
@ -194,54 +212,68 @@ SelectorSearch.prototype = {
}
this.searchBox.setAttribute("filled", true);
try {
this._searchResults = this.doc.querySelectorAll(query);
}
catch (ex) {
this._searchResults = [];
}
if (this._searchResults.length > 0) {
this._lastValidSearch = query;
// Even though the selector matched atleast one node, there is still
// possibility of suggestions.
if (query.match(/[\s>+]$/)) {
// If the query has a space or '>' at the end, create a selector to match
// the children of the selector inside the search box by adding a '*'.
this._lastValidSearch += "*";
}
else if (query.match(/[\s>+][\.#a-zA-Z][\.#>\s+]*$/)) {
// If the query is a partial descendant selector which does not matches
// any node, remove the last incomplete part and add a '*' to match
// everything. For ex, convert 'foo > b' to 'foo > *' .
let lastPart = query.match(/[\s>+][\.#a-zA-Z][^>\s+]*$/)[0];
this._lastValidSearch = query.slice(0, -1 * lastPart.length + 1) + "*";
let queryList = null;
this._lastQuery = this.walker.querySelectorAll(this.walker.rootNode, query).then(list => {
return list;
}, (err) => {
// Failures are ok here, just use a null item list;
return null;
}).then(queryList => {
// Value has changed since we started this request, we're done.
if (query != this.searchBox.value) {
if (queryList) {
queryList.release();
}
return promise.reject(null);
}
if (!query.slice(-1).match(/[\.#\s>+]/)) {
// Hide the popup if we have some matching nodes and the query is not
// ending with [.# >] which means that the selector is not at the
// beginning of a new class, tag or id.
if (this.searchPopup.isOpen) {
this.searchPopup.hidePopup();
this._searchResults = queryList;
if (this._searchResults && this._searchResults.length > 0) {
this._lastValidSearch = query;
// Even though the selector matched atleast one node, there is still
// possibility of suggestions.
if (query.match(/[\s>+]$/)) {
// If the query has a space or '>' at the end, create a selector to match
// the children of the selector inside the search box by adding a '*'.
this._lastValidSearch += "*";
}
else if (query.match(/[\s>+][\.#a-zA-Z][\.#>\s+]*$/)) {
// If the query is a partial descendant selector which does not matches
// any node, remove the last incomplete part and add a '*' to match
// everything. For ex, convert 'foo > b' to 'foo > *' .
let lastPart = query.match(/[\s>+][\.#a-zA-Z][^>\s+]*$/)[0];
this._lastValidSearch = query.slice(0, -1 * lastPart.length + 1) + "*";
}
if (!query.slice(-1).match(/[\.#\s>+]/)) {
// Hide the popup if we have some matching nodes and the query is not
// ending with [.# >] which means that the selector is not at the
// beginning of a new class, tag or id.
if (this.searchPopup.isOpen) {
this.searchPopup.hidePopup();
}
}
else {
this.showSuggestions();
}
this.searchBox.classList.remove("devtools-no-search-result");
return this._selectResult(0);
}
else {
if (query.match(/[\s>+]$/)) {
this._lastValidSearch = query + "*";
}
else if (query.match(/[\s>+][\.#a-zA-Z][\.#>\s+]*$/)) {
let lastPart = query.match(/[\s+>][\.#a-zA-Z][^>\s+]*$/)[0];
this._lastValidSearch = query.slice(0, -1 * lastPart.length + 1) + "*";
}
this.searchBox.classList.add("devtools-no-search-result");
this.showSuggestions();
}
this.searchBox.classList.remove("devtools-no-search-result");
this.callback(this._searchResults[0]);
}
else {
if (query.match(/[\s>+]$/)) {
this._lastValidSearch = query + "*";
}
else if (query.match(/[\s>+][\.#a-zA-Z][\.#>\s+]*$/)) {
let lastPart = query.match(/[\s+>][\.#a-zA-Z][^>\s+]*$/)[0];
this._lastValidSearch = query.slice(0, -1 * lastPart.length + 1) + "*";
}
this.searchBox.classList.add("devtools-no-search-result");
this.showSuggestions();
}
return undefined;
});
},
/**
@ -252,7 +284,7 @@ SelectorSearch.prototype = {
switch(aEvent.keyCode) {
case aEvent.DOM_VK_ENTER:
case aEvent.DOM_VK_RETURN:
if (query == this._lastSearched) {
if (query == this._lastSearched && this._searchResults) {
this._searchIndex = (this._searchIndex + 1) % this._searchResults.length;
}
else {
@ -315,8 +347,8 @@ SelectorSearch.prototype = {
aEvent.preventDefault();
aEvent.stopPropagation();
if (this._searchResults.length > 0) {
this.callback(this._searchResults[this._searchIndex]);
if (this._searchResults && this._searchResults.length > 0) {
this._lastQuery = this._selectResult(this._searchIndex);
}
},
@ -442,6 +474,9 @@ SelectorSearch.prototype = {
* searchbox.
*/
showSuggestions: function SelectorSearch_showSuggestions() {
if (!this.walker.isLocal()) {
return;
}
let query = this.searchBox.value;
if (this._lastValidSearch != "" &&
this._lastToLastValidSearch != this._lastValidSearch) {

View File

@ -43,6 +43,7 @@ MOCHITEST_BROWSER_FILES := \
browser_inspector_bug_831693_search_suggestions.html \
browser_inspector_bug_835722_infobar_reappears.js \
browser_inspector_bug_840156_destroy_after_navigation.js \
browser_inspector_reload.js \
head.js \
$(NULL)

View File

@ -68,6 +68,7 @@ function test()
{
inspector = aInspector;
inspector.selection.setNode($("b1"));
searchBox =
inspector.panelWin.document.getElementById("inspector-searchbox");
@ -95,15 +96,18 @@ function test()
if (event.type == "keypress" && keypressStates.indexOf(state) == -1) {
return;
}
executeSoon(function() {
let [key, id, isValid] = keyStates[state];
info(inspector.selection.node.id + " is selected with text " +
inspector.searchBox.value);
is(inspector.selection.node, $(id),
"Correct node is selected for state " + state);
is(!searchBox.classList.contains("devtools-no-search-result"), isValid,
"Correct searchbox result state for state " + state);
checkStateAndMoveOn(state + 1);
inspector.searchSuggestions._lastQuery.then(() => {
executeSoon(() => {
let [key, id, isValid] = keyStates[state];
info(inspector.selection.node.id + " is selected with text " +
inspector.searchBox.value);
is(inspector.selection.node, $(id),
"Correct node is selected for state " + state);
is(!searchBox.classList.contains("devtools-no-search-result"), isValid,
"Correct searchbox result state for state " + state);
checkStateAndMoveOn(state + 1);
});
});
}

View File

@ -27,20 +27,21 @@ function test()
{
inspector = aInspector;
inspector.selection.setNode(node);
inspector.once("inspector-updated", () => {
let parentNode = node.parentNode;
parentNode.removeChild(node);
let parentNode = node.parentNode;
parentNode.removeChild(node);
let tmp = {};
Cu.import("resource:///modules/devtools/LayoutHelpers.jsm", tmp);
ok(!tmp.LayoutHelpers.isNodeConnected(node), "Node considered as disconnected.");
let tmp = {};
Cu.import("resource:///modules/devtools/LayoutHelpers.jsm", tmp);
ok(!tmp.LayoutHelpers.isNodeConnected(node), "Node considered as disconnected.");
// Wait for the selection to process the mutation
inspector.walker.on("mutations", () => {
is(inspector.selection.node, parentNode, "parent of selection got selected");
finishUp();
// Wait for the inspector to process the mutation
inspector.once("inspector-updated", () => {
is(inspector.selection.node, parentNode, "parent of selection got selected");
finishUp();
});
});
}
};
function finishUp() {
node = null;

View File

@ -60,6 +60,7 @@ function test()
function startTest(aInspector)
{
inspector = aInspector;
searchBox =
inspector.panelWin.document.getElementById("inspector-searchbox");
popup = inspector.searchSuggestions.searchPopup;
@ -85,7 +86,7 @@ function test()
}
function checkState(event) {
executeSoon(function() {
inspector.searchSuggestions._lastQuery.then(() => {
let [key, suggestions] = keyStates[state];
let actualSuggestions = popup.getItems();
is(popup._panel.state == "open" || popup._panel.state == "showing"

View File

@ -87,7 +87,7 @@ function test()
}
function checkState(event) {
executeSoon(function() {
inspector.searchSuggestions._lastQuery.then(() => {
let [key, suggestions] = keyStates[state];
let actualSuggestions = popup.getItems();
is(popup._panel.state == "open" || popup._panel.state == "showing"

View File

@ -72,10 +72,13 @@ function testHighlighter(node)
is(getHighlitNode(), node, "Right node is highlighted");
}
let callNo = 0;
function testMarkupView(node)
{
let i = getActiveInspector();
is(i.markup._selectedContainer.node, node, "Right node is selected in the markup view");
try {
is(i.markup._selectedContainer.node.rawNode(), node, "Right node is selected in the markup view");
} catch(ex) { console.error(ex); }
}
function testBreadcrumbs(node)
@ -91,7 +94,15 @@ function _clickOnInspectMenuItem(node) {
document.popupNode = node;
var contentAreaContextMenu = document.getElementById("contentAreaContextMenu");
var contextMenu = new nsContextMenu(contentAreaContextMenu);
return contextMenu.inspectNode();
var promise = devtools.require("sdk/core/promise");
var deferred = promise.defer();
contextMenu.inspectNode().then(() => {
let i = getActiveInspector();
i.once("inspector-updated", () => {
deferred.resolve(undefined);
});
});
return deferred.promise;
}
function runContextMenuTest()

View File

@ -53,21 +53,23 @@ function test() {
function checkElementMenuItems() {
info("Checking context menu entries for p tag");
inspector.selection.setNode(doc.querySelector("p"));
let tag = getMarkupTagNodeContaining("p");
inspector.once("inspector-updated", () => {
let tag = getMarkupTagNodeContaining("p");
// Right-click p tag
contextMenuClick(tag);
// Right-click p tag
contextMenuClick(tag);
checkEnabled("node-menu-copyinner");
checkEnabled("node-menu-copyouter");
checkEnabled("node-menu-copyuniqueselector");
checkEnabled("node-menu-delete");
checkEnabled("node-menu-copyinner");
checkEnabled("node-menu-copyouter");
checkEnabled("node-menu-copyuniqueselector");
checkEnabled("node-menu-delete");
for (let name of ["hover", "active", "focus"]) {
checkEnabled("node-menu-pseudo-" + name);
}
for (let name of ["hover", "active", "focus"]) {
checkEnabled("node-menu-pseudo-" + name);
}
testCopyInnerMenu();
testCopyInnerMenu();
});
}
function testCopyInnerMenu() {
@ -101,7 +103,7 @@ function test() {
let deleteNode = inspector.panelDoc.getElementById("node-menu-delete");
ok(deleteNode, "the popup menu has a delete menu item");
inspector.selection.once("detached", deleteTest);
inspector.once("markupmutation", deleteTest);
let commandEvent = document.createEvent("XULCommandEvent");
commandEvent.initCommandEvent("command", true, true, window, 0, false, false,

View File

@ -0,0 +1,51 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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/. */
function test() {
let inspector, toolbox;
waitForExplicitFinish();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function onload() {
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
waitForFocus(function() {
let target = TargetFactory.forTab(gBrowser.selectedTab);
gDevTools.showToolbox(target, "inspector").then(function(toolbox) {
startInspectorTests(toolbox);
}).then(null, console.error);
}, content);
}, true);
content.location = "data:text/html,<p>p</p>";
function startInspectorTests(aToolbox)
{
toolbox = aToolbox;
inspector = toolbox.getCurrentPanel();
info("Inspector started");
let p = content.document.querySelector("p");
inspector.selection.setNode(p);
inspector.once("inspector-updated", () => {
is(inspector.selection.node, p, "Node selected.");
inspector.once("markuploaded", onReload);
content.location.reload();
});
}
function onReload() {
info("Page reloaded");
let p = content.document.querySelector("p");
inspector.selection.setNode(p);
inspector.once("inspector-updated", () => {
is(inspector.selection.node, p, "Node re-selected.");
toolbox.destroy();
gBrowser.removeCurrentTab();
finish();
});
}
}

View File

@ -18,6 +18,15 @@ ul.children:not([expanded]) {
display: inline-block;
width: 1em;
height: 1ex;
margin-right: -1em;
}
.newattr:focus {
margin-right: 0;
}
.closing-bracket {
pointer-events: none;
}
.summary {
@ -28,10 +37,6 @@ ul.children:not([expanded]) {
display: none;
}
#root {
margin-right: 80px;
}
/* Preview */
#previewbar {

File diff suppressed because it is too large Load Diff

View File

@ -23,7 +23,7 @@
<li id="template-more-nodes" class="more-nodes devtools-class-comment" save="${elt}"><span>${showing}</span> <button href="#" onclick="${allButtonClick}">${showAll}</button></li>
</ul>
<span id="template-element" save="${elt}" class="editor"><span>&lt;</span><span save="${tag}" class="tagname theme-fg-color3"></span><span save="${attrList}"></span><span save="${newAttr}" class="newattr" tabindex="0"></span>&gt;</span>
<span id="template-element" save="${elt}" class="editor"><span>&lt;</span><span save="${tag}" class="tagname theme-fg-color3"></span><span save="${attrList}"></span><span save="${newAttr}" class="newattr" tabindex="0"></span><span class="closing-bracket">&gt;</span></span>
<span id="template-attribute" save="${attr}" data-attr="${attrName}" class="attreditor" style="display:none"> <span class="editable" save="${inner}" tabindex="0"><span save="${name}" class="attrname theme-fg-color2"></span>=&quot;<span save="${val}" class="attrvalue theme-fg-color6"></span>&quot;</span></span>

View File

@ -78,7 +78,7 @@ function test() {
},
execute: function(after) {
inspector.once("markupmutation", after);
let editor = markup.getContainer(doc.querySelector("#node1")).editor;
let editor = getContainerForRawNode(markup, doc.querySelector("#node1")).editor;
let attr = editor.attrs["class"].querySelector(".editable");
editField(attr, 'class="changednode1"');
},
@ -89,7 +89,6 @@ function test() {
});
}
},
{
desc: 'Try changing an attribute to a quote (") - this should result ' +
'in it being set to an empty string',
@ -100,10 +99,10 @@ function test() {
});
},
execute: function(after) {
let editor = markup.getContainer(doc.querySelector("#node22")).editor;
let editor = getContainerForRawNode(markup, doc.querySelector("#node22")).editor;
let attr = editor.attrs["class"].querySelector(".editable");
editField(attr, 'class="""');
executeSoon(after);
inspector.once("markupmutation", after);
},
after: function() {
assertAttributes(doc.querySelector("#node22"), {
@ -123,7 +122,7 @@ function test() {
},
execute: function(after) {
inspector.once("markupmutation", after);
let editor = markup.getContainer(doc.querySelector("#node4")).editor;
let editor = getContainerForRawNode(markup, doc.querySelector("#node4")).editor;
let attr = editor.attrs["class"].querySelector(".editable");
editField(attr, '');
},
@ -143,7 +142,7 @@ function test() {
},
execute: function(after) {
inspector.once("markupmutation", after);
let editor = markup.getContainer(doc.querySelector("#node14")).editor;
let editor = getContainerForRawNode(markup, doc.querySelector("#node14")).editor;
let attr = editor.newAttr;
editField(attr, 'class="newclass" style="color:green"');
},
@ -166,10 +165,10 @@ function test() {
});
},
execute: function(after) {
let editor = markup.getContainer(doc.querySelector("#node23")).editor;
let editor = getContainerForRawNode(markup, doc.querySelector("#node23")).editor;
let attr = editor.newAttr;
editField(attr, 'class="newclass" style="""');
executeSoon(after);
inspector.once("markupmutation", after);
},
after: function() {
assertAttributes(doc.querySelector("#node23"), {
@ -188,10 +187,10 @@ function test() {
});
},
execute: function(after) {
let editor = markup.getContainer(doc.querySelector("#node24")).editor;
let editor = getContainerForRawNode(markup, doc.querySelector("#node24")).editor;
let attr = editor.attrs["id"].querySelector(".editable");
editField(attr, attr.textContent + ' class="""');
executeSoon(after);
inspector.once("markupmutation", after);
},
after: function() {
assertAttributes(doc.querySelector("#node24"), {
@ -210,7 +209,7 @@ function test() {
execute: function(after) {
inspector.once("markupmutation", after);
let node = doc.querySelector('.node6').firstChild;
let editor = markup.getContainer(node).editor;
let editor = getContainerForRawNode(markup, node).editor;
let field = editor.elt.querySelector("pre");
editField(field, "New text");
},
@ -229,7 +228,7 @@ function test() {
},
execute: function(after) {
inspector.once("markupmutation", after);
let editor = markup.getContainer(doc.querySelector("#node25")).editor;
let editor = getContainerForRawNode(markup, doc.querySelector("#node25")).editor;
let attr = editor.newAttr;
editField(attr, 'src="somefile.html?param1=<a>&param2=&uuml;"bl\'ah"');
},
@ -260,40 +259,44 @@ function test() {
}
function startTests() {
let startNode = doc.documentElement.cloneNode();
markup = inspector.markup;
markup.expandAll();
markup.expandAll().then(() => {
let cursor = 0;
let cursor = 0;
function nextEditTest() {
executeSoon(function() {
if (cursor >= edits.length) {
addAttributes();
} else {
let step = edits[cursor++];
info("START " + step.desc);
if (step.setup) {
step.setup();
}
step.before();
info("before execute");
step.execute(function() {
info("after execute");
step.after();
ok(markup.undo.canUndo(), "Should be able to undo.");
markup.undo.undo();
function nextEditTest() {
executeSoon(function() {
if (cursor >= edits.length) {
addAttributes();
} else {
let step = edits[cursor++];
info("START " + step.desc);
if (step.setup) {
step.setup();
}
step.before();
ok(markup.undo.canRedo(), "Should be able to redo.");
markup.undo.redo();
step.after();
info("END " + step.desc);
nextEditTest();
});
}
});
}
nextEditTest();
info("before execute");
step.execute(function() {
info("after execute");
step.after();
ok(markup.undo.canUndo(), "Should be able to undo.");
markup.undo.undo();
inspector.once("markupmutation", () => {
step.before();
ok(markup.undo.canRedo(), "Should be able to redo.");
markup.undo.redo();
inspector.once("markupmutation", () => {
step.after();
info("END " + step.desc);
nextEditTest();
});
});
});
}
});
}
nextEditTest();
});
}
function addAttributes() {
@ -307,11 +310,8 @@ function test() {
id: "node18",
});
/**
* XXX: disabled until the remote markup view is enabled
* is(inspector.highlighter.nodeInfo.classesBox.textContent, "",
* "No classes in the infobar before edit.");
*/
is(inspector.highlighter.nodeInfo.classesBox.textContent, "",
"No classes in the infobar before edit.");
},
execute: function(after) {
inspector.once("markupmutation", function() {
@ -319,7 +319,7 @@ function test() {
// not just the markupview (which happens in this event loop)
executeSoon(after);
});
let editor = markup.getContainer(doc.querySelector("#node18")).editor;
let editor = getContainerForRawNode(markup, doc.querySelector("#node18")).editor;
let attr = editor.attrs["id"].querySelector(".editable");
editField(attr, attr.textContent + ' class="newclass" style="color:green"');
},
@ -330,11 +330,8 @@ function test() {
style: "color:green"
});
/**
* XXX: disabled until the remote markup view is enabled
*is(inspector.highlighter.nodeInfo.classesBox.textContent, ".newclass",
* "Correct classes in the infobar after edit.");
*/
is(inspector.highlighter.nodeInfo.classesBox.textContent, ".newclass",
"Correct classes in the infobar after edit.");
}
};
testAsyncSetup(test, editTagName);
@ -348,7 +345,7 @@ function test() {
},
before: function() {
let node = doc.querySelector("#retag-me");
let container = markup.getContainer(node);
let container = getContainerForRawNode(markup, node);
is(node.tagName, "DIV", "retag-me should be a div.");
ok(container.selected, "retag-me should be selected.");
@ -359,13 +356,13 @@ function test() {
execute: function(after) {
inspector.once("markupmutation", after);
let node = doc.querySelector("#retag-me");
let editor = markup.getContainer(node).editor;
let editor = getContainerForRawNode(markup, node).editor;
let field = editor.tag;
editField(field, "p");
},
after: function() {
let node = doc.querySelector("#retag-me");
let container = markup.getContainer(node);
let container = getContainerForRawNode(markup, node);
is(node.tagName, "P", "retag-me should be a p.");
ok(container.selected, "retag-me should be selected.");
ok(container.expanded, "retag-me should be expanded.");
@ -399,10 +396,12 @@ function test() {
info("START " + test.desc);
test.before();
inspector.selection.once("new-node", function BIMET_testAsyncExecNewNode() {
inspector.once("inspector-updated", function BIMET_testAsyncExecNewNode() {
test.executeCont();
test.after();
undoRedo(test, callback);
inspector.once("markupmutation", () => {
test.after();
undoRedo(test, callback);
});
});
executeSoon(function BIMET_setNode1() {
test.execute();
@ -412,7 +411,7 @@ function test() {
function testAsyncSetup(test, callback) {
info("START " + test.desc);
inspector.selection.once("new-node", function BIMET_testAsyncSetupNewNode() {
inspector.once("inspector-updated", function BIMET_testAsyncSetupNewNode() {
test.before();
test.execute(function() {
test.after();
@ -427,11 +426,11 @@ function test() {
function undoRedo(test, callback) {
ok(markup.undo.canUndo(), "Should be able to undo.");
markup.undo.undo();
executeSoon(function() {
inspector.once("markupmutation", () => {
test.before();
ok(markup.undo.canRedo(), "Should be able to redo.");
markup.undo.redo();
executeSoon(function() {
inspector.once("markupmutation", () => {
test.after();
info("END " + test.desc);
callback();

View File

@ -10,6 +10,10 @@ http://creativecommons.org/publicdomain/zero/1.0/ */
* - Compare it to the real dom with isEqualNode.
*/
function fail(err) {
ok(false, err)
}
function test() {
waitForExplicitFinish();
@ -45,10 +49,13 @@ function test() {
// Verify that the markup in the tool is the same as the markup in the document.
function checkMarkup()
{
markup.expandAll();
return markup.expandAll().then(checkMarkup2);
}
function checkMarkup2()
{
let contentNode = doc.querySelector("body");
let panelNode = markup._containers.get(contentNode).elt;
let panelNode = getContainerForRawNode(markup, contentNode).elt;
let parseNode = parseDoc.querySelector("body");
// Grab the text from the markup panel...
@ -154,8 +161,9 @@ function test() {
function startTests() {
markup = inspector.markup;
checkMarkup();
nextStep(0);
checkMarkup().then(() => {
nextStep(0);
}).then(null, fail);
}
function nextStep(cursor) {
@ -166,8 +174,9 @@ function test() {
mutations[cursor]();
inspector.once("markupmutation", function() {
executeSoon(function() {
checkMarkup();
nextStep(cursor + 1);
checkMarkup().then(() => {
nextStep(cursor + 1);
}).then(null, fail);
});
});
}

View File

@ -84,7 +84,7 @@ function test() {
var target = TargetFactory.forTab(gBrowser.selectedTab);
gDevTools.showToolbox(target, "inspector").then(function(toolbox) {
inspector = toolbox.getCurrentPanel();
startNavigation();
inspector.once("inspector-updated", startNavigation);
});
}
@ -126,7 +126,7 @@ function test() {
break;
}
executeSoon(function BIMNT_newNode() {
inspector.markup._waitForChildren().then(() => executeSoon(function BIMNT_newNode() {
let node = inspector.selection.node;
if (className == "*comment*") {
@ -140,7 +140,7 @@ function test() {
}
nextStep(cursor + 1);
});
}));
}
function finishUp() {

View File

@ -25,7 +25,7 @@ function test() {
function assertChildren(expected)
{
let container = markup.getContainer(doc.querySelector("body"));
let container = getContainerForRawNode(markup, doc.querySelector("body"));
let found = [];
for (let child of container.children.children) {
if (child.classList.contains("more-nodes")) {
@ -34,16 +34,24 @@ function test() {
found += child.container.node.getAttribute("id");
}
}
is(expected, found, "Got the expected children.");
is(found, expected, "Got the expected children.");
}
function forceReload()
{
let container = markup.getContainer(doc.querySelector("body"));
let container = getContainerForRawNode(markup, doc.querySelector("body"));
container.childrenDirty = true;
}
let selections = [
{
desc: "Select the last item",
selector: "#z",
before: function() {},
after: function() {
assertChildren("*more*vwxyz");
}
},
{
desc: "Select the first item",
selector: "#a",
@ -97,18 +105,9 @@ function test() {
function setupTest() {
var target = TargetFactory.forTab(gBrowser.selectedTab);
let toolbox = gDevTools.showToolbox(target, "inspector").then(function(toolbox) {
toolbox.once("inspector-selected", function SE_selected(id, aInspector) {
inspector = aInspector;
markup = inspector.markup;
runNextSelection();
});
});
}
function runTests() {
inspector.selection.once("new-node", startTests);
executeSoon(function() {
inspector.selection.setNode(doc.body);
inspector = toolbox.getCurrentPanel();
markup = inspector.markup;
inspector.once("inspector-updated", runNextSelection);
});
}
@ -121,7 +120,7 @@ function test() {
info(selection.desc);
selection.before();
inspector.selection.once("new-node", function() {
inspector.once("inspector-updated", function() {
selection.after();
runNextSelection();
});
@ -131,11 +130,13 @@ function test() {
function clickMore() {
info("Check that clicking more loads the whole thing.");
// Make sure that clicking the "more" button loads all the nodes.
let container = markup.getContainer(doc.querySelector("body"));
let container = getContainerForRawNode(markup, doc.querySelector("body"));
let button = container.elt.querySelector("button");
button.click();
assertChildren("abcdefghijklmnopqrstuvwxyz");
finishUp();
markup._waitForChildren().then(() => {
assertChildren("abcdefghijklmnopqrstuvwxyz");
finishUp();
});
}
function finishUp() {

View File

@ -16,3 +16,39 @@ function clearUserPrefs()
}
registerCleanupFunction(clearUserPrefs);
Services.prefs.setBoolPref("devtools.debugger.log", true);
SimpleTest.registerCleanupFunction(() => {
Services.prefs.clearUserPref("devtools.debugger.log");
});
function getContainerForRawNode(markupView, rawNode) {
let front = markupView.walker.frontForRawNode(rawNode);
let container = markupView.getContainer(front);
return container;
}
Services.prefs.setBoolPref("devtools.debugger.log", true);
SimpleTest.registerCleanupFunction(() => {
Services.prefs.clearUserPref("devtools.debugger.log");
});
function getContainerForRawNode(markupView, rawNode) {
let front = markupView.walker.frontForRawNode(rawNode);
let container = markupView.getContainer(front);
return container;
}
Services.prefs.setBoolPref("devtools.debugger.log", true);
SimpleTest.registerCleanupFunction(() => {
Services.prefs.clearUserPref("devtools.debugger.log");
});
function getContainerForRawNode(markupView, rawNode) {
let front = markupView.walker.frontForRawNode(rawNode);
let container = markupView.getContainer(front);
return container;
}

View File

@ -23,8 +23,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "NetworkHelper",
"resource://gre/modules/devtools/NetworkHelper.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "clipboardHelper",
"@mozilla.org/widget/clipboardhelper;1",
"nsIClipboardHelper");
"@mozilla.org/widget/clipboardhelper;1", "nsIClipboardHelper");
const NET_STRINGS_URI = "chrome://browser/locale/devtools/netmonitor.properties";
const LISTENERS = [ "NetworkActivity" ];

View File

@ -368,7 +368,7 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
copyUrl: function() {
let selected = this.selectedItem.attachment;
clipboardHelper.copyString(selected.url, this.document);
clipboardHelper.copyString(selected.url, document);
},
/**

View File

@ -12,21 +12,25 @@ function test() {
let { NetMonitorView } = aMonitor.panelWin;
let { RequestsMenu } = NetMonitorView;
RequestsMenu.lazyUpdate = false;
waitForNetworkEvents(aMonitor, 1).then(() => {
let imageRequest = RequestsMenu.getItemAtIndex(0);
RequestsMenu.selectedItem = imageRequest;
let requestItem = RequestsMenu.getItemAtIndex(0);
RequestsMenu.selectedItem = requestItem;
waitForClipboard(RequestsMenu.selectedItem.attachment.url, function(){ RequestsMenu.copyUrl() } , cleanUp, cleanUp);
waitForClipboard(requestItem.attachment.url, function setup() {
RequestsMenu.copyUrl();
}, function onSuccess() {
ok(true, "Clipboard contains the currently selected item's url.");
cleanUp();
}, function onFailure() {
ok(false, "Copying the currently selected item's url was unsuccessful.");
cleanUp();
});
});
aDebuggee.performRequests(1);
function cleanUp(){
teardown(aMonitor);
finish();
teardown(aMonitor).then(finish);
}
});
}

View File

@ -146,7 +146,7 @@ function ResponsiveUI(aWindow, aTab)
this.customPreset.width = bbox.width - 40; // horizontal padding of the container
this.customPreset.height = bbox.height - 80; // vertical padding + toolbar height
this.currentPresetKey = this.customPreset.key;
this.currentPresetKey = this.presets[1].key; // most common preset
}
this.container.setAttribute("responsivemode", "true");

View File

@ -137,7 +137,8 @@ function test() {
info("XXX BUG 851296: 'on' received.");
executeSoon(onUIOpen2);
});
synthesizeKeyFromKeyTag("key_responsiveUI");
//XXX BUG 851296: synthesizeKeyFromKeyTag("key_responsiveUI");
mgr.toggle(window, gBrowser.selectedTab);
info("XXX BUG 851296: restart() finished.");
}

View File

@ -51,9 +51,9 @@
<!ENTITY debuggerUI.showOriginalSource "Show original sources">
<!ENTITY debuggerUI.showOriginalSource.key "O">
<!-- LOCALIZATION NOTE (debuggerUI.searchPanelTitle): This is the text that
- appears in the filter panel popup as a description. -->
<!ENTITY debuggerUI.searchPanelTitle "Operators">
<!-- LOCALIZATION NOTE (debuggerUI.searchPanelOperators): This is the text that
- appears in the filter panel popup as a header for the operators part. -->
<!ENTITY debuggerUI.searchPanelOperators "Operators:">
<!-- LOCALIZATION NOTE (debuggerUI.searchFile): This is the text that appears
- in the source editor's context menu for the scripts search operation. -->

View File

@ -73,9 +73,9 @@ noMatchingSourcesText=No matching sources.
# global search results when there are no matching strings after filtering.
noMatchingStringsText=No matches found
# LOCALIZATION NOTE (emptyFilterText): This is the text that appears in the
# LOCALIZATION NOTE (emptySearchText): This is the text that appears in the
# filter text box when it is empty and the scripts container is selected.
emptyFilterText=Filter scripts (%S)
emptySearchText=Search scripts (%S)
# LOCALIZATION NOTE (emptyChromeGlobalsFilterText): This is the text that
# appears in the filter text box when it is empty and the chrome globals
@ -86,6 +86,10 @@ emptyChromeGlobalsFilterText=Filter chrome globals (%S)
# appears in the filter text box for the variables view container.
emptyVariablesFilterText=Filter variables
# LOCALIZATION NOTE (searchPanelFilter): This is the text that appears in the
# filter panel popup for the filter scripts operation.
searchPanelFilter=Filter scripts (%S)
# LOCALIZATION NOTE (searchPanelGlobal): This is the text that appears in the
# filter panel popup for the global search operation.
searchPanelGlobal=Search in all files (%S)

View File

@ -11,509 +11,320 @@
# A good criteria is the language in which you'd find the best
# documentation on web development on the web.
# LOCALIZATION NOTE (canonDescNone): Short string used to describe any command
# or command parameter when no description has been provided.
# For each command there are in general two strings. As an example consider
# the 'pref' command.
# commandDesc (e.g. prefDesc for the command 'pref'): this string contains a
# very short description of the command. It's designed to be shown in a menu
# alongside the command name, which is why it should be as short as possible.
# commandManual (e.g. prefManual for the command 'pref'): this string will
# contain a fuller description of the command. It's diplayed when the user
# asks for help about a specific command (e.g. 'help pref').
# LOCALIZATION NOTE: This message is used to describe any command or command
# parameter when no description has been provided.
canonDescNone=(No description)
# LOCALIZATION NOTE (canonDefaultGroupName): The default name for a group of
# parameters.
# LOCALIZATION NOTE: The default name for a group of parameters.
canonDefaultGroupName=Options
# LOCALIZATION NOTE (canonProxyDesc): A very short description of a set of
# remote commands. This string is designed to be shown in a menu alongside the
# command name, which is why it should be as short as possible. See
# canonProxyManual for a fuller description of what it does.
# LOCALIZATION NOTE (canonProxyDesc, canonProxyManual): These commands are
# used to execute commands on a remote system (using a proxy). Parameters: %S
# is the name of the remote system.
canonProxyDesc=Execute a command on %S
# LOCALIZATION NOTE (canonProxyManual): A fuller description of a set of
# remote commands. Displayed when the user asks for help on what it does.
canonProxyManual=A set of commands that are executed on a remote system. The remote system is reached via %S
# LOCALIZATION NOTE (canonProxyExists): An error message displayed when we try
# to add new command (via a proxy) where one already exists in that name.
# LOCALIZATION NOTE: This error message is displayed when we try to add a new
# command (using a proxy) where one already exists with the same name.
canonProxyExists=There is already a command called '%S'
# LOCALIZATION NOTE (cliEvalJavascript): The special '{' command allows entry
# of JavaScript like traditional developer tool command lines. This describes
# the '{' command.
# LOCALIZATION NOTE: This message describes the '{' command, which allows
# entry of JavaScript like traditional developer tool command lines.
cliEvalJavascript=Enter JavaScript directly
# LOCALIZATION NOTE (cliUnusedArg): When the command line has more arguments
# than the current command can understand this is the error message shown to
# the user.
# LOCALIZATION NOTE: This message is displayed when the command line has more
# arguments than the current command can understand.
cliUnusedArg=Too many arguments
# LOCALIZATION NOTE (cliOptions): The title of the dialog which displays the
# options that are available to the current command.
# LOCALIZATION NOTE: The title of the dialog which displays the options that
# are available to the current command.
cliOptions=Available Options
# LOCALIZATION NOTE (fieldSelectionSelect): When a command has a parameter
# that has a number of pre-defined options the user interface presents these
# in a drop-down menu, where the first 'option' is an indicator that a
# selection should be made. This string describes that first option.
# LOCALIZATION NOTE: Error message given when a file argument points to a file
# that does not exist, but should (e.g. for use with File->Open) %1$S is a
# filename
fileErrNotExists='%1$S' doesn't exist
# LOCALIZATION NOTE: Error message given when a file argument points to a file
# that exists, but should not (e.g. for use with File->Save As) %1$S is a
# filename
fileErrExists='%1$S' already exists
# LOCALIZATION NOTE: Error message given when a file argument points to a
# non-file, when a file is needed. %1$S is a filename
fileErrIsNotFile='%1$S' is not a file
# LOCALIZATION NOTE: Error message given when a file argument points to a
# non-directory, when a directory is needed (e.g. for use with 'cd') %1$S is a
# filename
fileErrIsNotDirectory='%1$S' is not a directory
# LOCALIZATION NOTE: Error message given when a file argument does not match
# the specified regular expression %1$S is a filename %2$S is a regular
# expression
fileErrDoesntMatch='%1$S' does not match '%2$S'
# LOCALIZATION NOTE: When a command has a parameter that has a number of
# pre-defined options the user interface presents these in a drop-down menu,
# where the first 'option' is an indicator that a selection should be made.
# This string describes that first option.
fieldSelectionSelect=Select a %S…
# LOCALIZATION NOTE (fieldArrayAdd): When a command has a parameter that can
# be repeated a number of times (e.g. like the 'cat a.txt b.txt' command) the
# user interface presents buttons to add and remove arguments. This string is
# used to add arguments.
# LOCALIZATION NOTE (fieldArrayAdd, fieldArrayDel): When a command has a
# parameter that can be repeated multiple times (e.g. like the 'cat a.txt
# b.txt' command) the user interface presents buttons to add and remove
# arguments. This string is used to add arguments.
fieldArrayAdd=Add
# LOCALIZATION NOTE (fieldArrayDel): When a command has a parameter that can
# be repeated a number of times (e.g. like the 'cat a.txt b.txt' command) the
# user interface presents buttons to add and remove arguments. This string is
# used to remove arguments.
fieldArrayDel=Delete
# LOCALIZATION NOTE (fieldMenuMore): When the menu has displayed all the
# matches that it should (i.e. about 10 items) then we display this to alert
# the user that more matches are available.
# LOCALIZATION NOTE: When the menu has displayed all the matches that it
# should (i.e. about 10 items) then we display this to alert the user that
# more matches are available.
fieldMenuMore=More matches, keep typing
# LOCALIZATION NOTE (jstypeParseScope): The command line provides completion
# for JavaScript commands, however there are times when the scope of what
# we're completing against can't be used. This error message is displayed when
# this happens.
# LOCALIZATION NOTE: The command line provides completion for JavaScript
# commands, however there are times when the scope of what we're completing
# against can't be used. This error message is displayed when this happens.
jstypeParseScope=Scope lost
# LOCALIZATION NOTE (jstypeParseMissing): When the command line is doing
# JavaScript completion, sometimes the property to be completed does not
# exist. This error message is displayed when this happens.
# LOCALIZATION NOTE (jstypeParseMissing, jstypeBeginSyntax,
# jstypeBeginUnterm): These error messages are displayed when the command line
# is doing JavaScript completion and encounters errors.
jstypeParseMissing=Can't find property '%S'
# LOCALIZATION NOTE (jstypeBeginSyntax): When the command line is doing
# JavaScript completion using invalid JavaScript, this error message is
# displayed.
jstypeBeginSyntax=Syntax error
# LOCALIZATION NOTE (jstypeBeginUnterm): When the command line is doing
# JavaScript completion using a string that is not properly terminated, this
# error message is displayed.
jstypeBeginUnterm=Unterminated string literal
# LOCALIZATION NOTE (jstypeParseError): If the system for providing JavaScript
# completions encounters and error it displays this.
# LOCALIZATION NOTE: This message is displayed if the system for providing
# JavaScript completions encounters and error it displays this.
jstypeParseError=Error
# LOCALIZATION NOTE (typesNumberNan): When the command line is passed a
# number, however the input string is not a valid number, this error message
# is displayed.
# LOCALIZATION NOTE (typesNumberNan, typesNumberNotInt2, typesDateNan): These
# error messages are displayed when the command line is passed a variable
# which has the wrong format and can't be converted. Parameters: %S is the
# passed variable.
typesNumberNan=Can't convert "%S" to a number.
# LOCALIZATION NOTE (typesNumberMax): When the command line is passed a
# number, but the number is bigger than the largest allowed number, this error
# message is displayed.
typesNumberMax=%1$S is greater than maximum allowed: %2$S.
# LOCALIZATION NOTE (typesNumberMin): When the command line is passed a
# number, but the number is lower than the smallest allowed number, this error
# message is displayed.
typesNumberMin=%1$S is smaller than minimum allowed: %2$S.
# LOCALIZATION NOTE (typesNumberNotInt2): When the command line is passed a
# number, but the number has a decimal part and floats are not allowed.
typesNumberNotInt2=Can't convert "%S" to an integer.
# LOCALIZATION NOTE (typesDateNan): When the command line is passed a date,
# however the input string is not a valid date, this error message is
# displayed.
typesDateNan=Can't convert "%S" to a date.
# LOCALIZATION NOTE (typesDateMax): When the command line is passed a date,
# but the number is later than the latest allowed date, this error message is
# displayed.
# LOCALIZATION NOTE (typesNumberMax, typesNumberMin, typesDateMax,
# typesDateMin): These error messages are displayed when the command line is
# passed a variable which has a value out of range (number or date).
# Parameters: %1$S is the passed variable, %2$S is the limit value.
typesNumberMax=%1$S is greater than maximum allowed: %2$S.
typesNumberMin=%1$S is smaller than minimum allowed: %2$S.
typesDateMax=%1$S is later than maximum allowed: %2$S.
# LOCALIZATION NOTE (typesDateMin): When the command line is passed a date,
# but the date is earlier than the earliest allowed number, this error message
# is displayed.
typesDateMin=%1$S is earlier than minimum allowed: %2$S.
# LOCALIZATION NOTE (typesSelectionNomatch): When the command line is passed
# an option with a limited number of correct values, but the passed value is
# not one of them, this error message is displayed.
# LOCALIZATION NOTE: This error message is displayed when the command line is
# passed an option with a limited number of correct values, but the passed
# value is not one of them.
typesSelectionNomatch=Can't use '%S'.
# LOCALIZATION NOTE (nodeParseSyntax): When the command line is expecting a
# CSS query string, however the passed string is not valid, this error message
# is displayed.
# LOCALIZATION NOTE: This error message is displayed when the command line is
# expecting a CSS query string, however the passed string is not valid.
nodeParseSyntax=Syntax error in CSS query
# LOCALIZATION NOTE (nodeParseMultiple): When the command line is expecting a
# CSS string that matches a single node, but more than one node matches, this
# error message is displayed.
# LOCALIZATION NOTE (nodeParseMultiple, nodeParseNone): These error messages
# are displayed when the command line is expecting a CSS string that matches a
# single node, but more nodes (or none) match.
nodeParseMultiple=Too many matches (%S)
# LOCALIZATION NOTE (nodeParseNone): When the command line is expecting a CSS
# string that matches a single node, but no nodes match, this error message is
# displayed.
nodeParseNone=No matches
# LOCALIZATION NOTE (helpDesc): A very short description of the 'help'
# command. This string is designed to be shown in a menu alongside the command
# name, which is why it should be as short as possible. See helpManual for a
# fuller description of what it does.
# LOCALIZATION NOTE (helpDesc, helpManual, helpSearchDesc, helpSearchManual3):
# These strings describe the "help" command, used to display a description of
# a command (e.g. "help pref"), and its parameter 'search'.
helpDesc=Get help on the available commands
# LOCALIZATION NOTE (helpManual): A fuller description of the 'help' command.
# Displayed when the user asks for help on what it does.
helpManual=Provide help either on a specific command (if a search string is provided and an exact match is found) or on the available commands (if a search string is not provided, or if no exact match is found).
# LOCALIZATION NOTE (helpSearchDesc): A very short description of the 'search'
# parameter to the 'help' command. See helpSearchManual3 for a fuller
# description of what it does. This string is designed to be shown in a dialog
# with restricted space, which is why it should be as short as possible.
helpSearchDesc=Search string
# LOCALIZATION NOTE (helpSearchManual3): A fuller description of the 'search'
# parameter to the 'help' command. Displayed when the user asks for help on
# what it does.
helpSearchManual3=search string to use in narrowing down the displayed commands. Regular expressions not supported.
# LOCALIZATION NOTE (helpManSynopsis): A heading shown at the top of a help
# page for a command in the console It labels a summary of the parameters to
# the command
# LOCALIZATION NOTE (helpManSynopsis, helpManDescription, helpManParameters):
# These strings are displayed in the help page for a command in the console.
helpManSynopsis=Synopsis
# LOCALIZATION NOTE (helpManDescription): A heading shown in a help page for a
# command in the console. This heading precedes the top level description.
helpManDescription=Description
# LOCALIZATION NOTE (helpManParameters): A heading shown above the parameters
# in a help page for a command in the console.
helpManParameters=Parameters
# LOCALIZATION NOTE (helpManNone): Some text shown under the parameters
# heading in a help page for a command which has no parameters.
# LOCALIZATION NOTE: This message is displayed in the help page if the command
# has no parameters.
helpManNone=None
# LOCALIZATION NOTE (helpListAll): The heading shown in response to the 'help'
# LOCALIZATION NOTE: This message is displayed in response to the 'help'
# command when used without a filter, just above the list of known commands.
helpListAll=Available Commands:
# LOCALIZATION NOTE (helpListPrefix): The heading shown in response to the
# 'help <search>' command (i.e. with a search string), just above the list of
# matching commands.
helpListPrefix=Commands starting with '%1$S':
# LOCALIZATION NOTE (helpListPrefix, helpListNone): These messages are
# displayed in response to the 'help <search>' command (i.e. with a search
# string), just above the list of matching commands. Parameters: %S is the
# search string.
helpListPrefix=Commands starting with '%S':
helpListNone=No commands starting with '%S'
# LOCALIZATION NOTE (helpListNone): The heading shown in response to the 'help
# <search>' command (i.e. with a search string), when there are no matching
# commands.
helpListNone=No commands starting with '%1$S'
# LOCALIZATION NOTE (helpManRequired): When the 'help x' command wants to show
# the manual for the 'x' command it needs to be able to describe the
# parameters as either required or optional, or if they have a default value.
# See also 'helpManOptional' and 'helpManDefault'.
# LOCALIZATION NOTE (helpManRequired, helpManOptional, helpManDefault): When
# the 'help x' command wants to show the manual for the 'x' command, it needs
# to be able to describe the parameters as either required or optional, or if
# they have a default value.
helpManRequired=required
# LOCALIZATION NOTE (helpManOptional): See description of 'helpManRequired'
helpManOptional=optional
helpManDefault=optional, default=%S
# LOCALIZATION NOTE (helpManDefault): See description of 'helpManRequired'. %1$
# S is the default value
helpManDefault=optional, default=%1$S
# LOCALIZATION NOTE (subCommands): Text shown as part of the output of the
# 'help' command when the command in question has sub-commands, before a list
# of the matching sub-commands
# LOCALIZATION NOTE: Text shown as part of the output of the 'help' command
# when the command in question has sub-commands, before a list of the matching
# sub-commands.
subCommands=Sub-Commands
# LOCALIZATION NOTE (subCommandsNone): Text shown as part of the output of the
# 'help' command when the command in question should have sub-commands but in
# fact has none
# LOCALIZATION NOTE: Text shown as part of the output of the 'help' command
# when the command in question should have sub-commands but in fact has none.
subCommandsNone=None
# LOCALIZATION NOTE (contextDesc): A very short description of the 'context'
# command. This string is designed to be shown in a menu alongside the command
# name, which is why it should be as short as possible. See contextManual for
# a fuller description of what it does.
# LOCALIZATION NOTE (contextDesc, contextManual, contextPrefixDesc): These
# strings are used to describe the 'context' command and its 'prefix'
# parameter. See localization comment for 'connect' for an explanation about
# 'prefix'.
contextDesc=Concentrate on a group of commands
# LOCALIZATION NOTE (contextManual): A fuller description of the 'context'
# command. Displayed when the user asks for help on what it does.
contextManual=Setup a default prefix to future commands. For example 'context git' would allow you to type 'commit' rather than 'git commit'.
# LOCALIZATION NOTE (contextPrefixDesc): A short description of the 'prefix'
# parameter to the 'context' command. This string is designed to be shown in a
# dialog with restricted space, which is why it should be as short as
# possible.
contextPrefixDesc=The command prefix
# LOCALIZATION NOTE (contextNotParentError): An error message displayed during
# the processing of the 'context' command, when the found command is not a
# parent command.
contextNotParentError=Can't use '%1$S' as a prefix because it is not a parent command.
# LOCALIZATION NOTE: This message message displayed during the processing of
# the 'context' command, when the found command is not a parent command.
contextNotParentError=Can't use '%S' as a prefix because it is not a parent command.
# LOCALIZATION NOTE (contextReply): A message displayed during the processing
# of the 'context' command, to indicate success.
contextReply=Using %1$S as a command prefix
# LOCALIZATION NOTE (contextEmptyReply): A message displayed during the
# processing of the 'context' command, to indicate that there is no command
# prefix
# LOCALIZATION NOTE (contextReply, contextEmptyReply): These messages are
# displayed during the processing of the 'context' command, to indicate
# success or that there is no command prefix.
contextReply=Using %S as a command prefix
contextEmptyReply=Command prefix is unset
# LOCALIZATION NOTE (connectDesc): A very short description of the 'connect'
# command. This string is designed to be shown in a menu alongside the command
# name, which is why it should be as short as possible. See connectManual for
# a fuller description of what it does.
# LOCALIZATION NOTE (connectDesc, connectManual, connectPrefixDesc,
# connectPortDesc, connectHostDesc, connectDupReply): These strings describe
# the 'connect' command and all its available parameters. A 'prefix' is an
# alias for the remote server (think of it as a "connection name"), and it
# allows to identify a specific server when connected to multiple remote
# servers.
connectDesc=Proxy commands to server
# LOCALIZATION NOTE (connectManual): A fuller description of the 'connect'
# command. Displayed when the user asks for help on what it does.
connectManual=Connect to the server, creating local versions of the commands on the server. Remote commands initially have a prefix to distinguish them from local commands (but see the context command to get past this)
# LOCALIZATION NOTE (connectPrefixDesc): A short description of the 'prefix'
# parameter to the 'connect' command. This string is designed to be shown in a
# dialog with restricted space, which is why it should be as short as
# possible.
connectPrefixDesc=Parent prefix for imported commands
# LOCALIZATION NOTE (connectPortDesc): A short description of the 'port'
# parameter to the 'connect' command. This string is designed to be shown in a
# dialog with restricted space, which is why it should be as short as
# possible.
connectPortDesc=The TCP port to listen on
# LOCALIZATION NOTE (connectHostDesc): A short description of the 'host'
# parameter to the 'connect' command. This string is designed to be shown in a
# dialog with restricted space, which is why it should be as short as
# possible.
connectHostDesc=The hostname to bind to
# LOCALIZATION NOTE (connectDupReply): An error condition from executing the
# 'connect' command
connectDupReply=Connection called %S already exists.
# LOCALIZATION NOTE (connectReply): The output of the 'connect' command,
# telling the user what it has done.
# LOCALIZATION NOTE: The output of the 'connect' command, telling the user
# what it has done. Parameters: %S is the prefix command. See localization
# comment for 'connect' for an explanation about 'prefix'.
connectReply=Added %S commands.
# LOCALIZATION NOTE (disconnectDesc): A very short description of the
# 'disconnect' command. This string is designed to be shown in a menu
# alongside the command name, which is why it should be as short as possible.
# See connectManual for a fuller description of what it does.
disconnectDesc=Proxy commands to server
# LOCALIZATION NOTE (disconnectManual): A fuller description of the
# 'disconnect' command. Displayed when the user asks for help on what it does.
disconnectManual=Connect to the server, creating local versions of the commands on the server. Remote commands initially have a prefix to distinguish them from local commands (but see the context command to get past this)
# LOCALIZATION NOTE (disconnectPrefixDesc): A short description of the
# 'prefix' parameter to the 'disconnect' command. This string is designed to
# be shown in a dialog with restricted space, which is why it should be as
# short as possible.
# LOCALIZATION NOTE (disconnectDesc2, disconnectManual2, disconnectPrefixDesc,
# disconnectForceDesc): These strings describe the 'disconnect' command and
# all its available parameters. See localization comment for 'connect' for an
# explanation about 'prefix'.
disconnectDesc2=Disconnect from server
disconnectManual2=Disconnect from a server currently connected for remote commands execution
disconnectPrefixDesc=Parent prefix for imported commands
# LOCALIZATION NOTE (disconnectForceDesc): A short description of the 'force'
# parameter to the 'disconnect' command. This string is designed to be shown
# in a dialog with restricted space, which is why it should be as short as
# possible.
disconnectForceDesc=Ignore outstanding requests
# LOCALIZATION NOTE (disconnectReply): The output of the 'disconnect' command,
# telling the user what it's done.
# LOCALIZATION NOTE: This is the output of the 'disconnect' command,
# explaining the user what has been done. Parameters: %S is the number of
# commands removed.
disconnectReply=Removed %S commands.
# LOCALIZATION NOTE (disconnectOutstanding): An error message displayed when
# the user attempts to disconnect before all requests have completed. %1$S is
# a list of commands which are incomplete
disconnectOutstanding=Outstanding requests (%1$S)
# LOCALIZATION NOTE: This error message is displayed when the user attempts to
# disconnect before all requests have completed. Parameters: %S is a list of
# incomplete requests.
disconnectOutstanding=Outstanding requests (%S)
# LOCALIZATION NOTE (prefDesc): A very short description of the 'pref'
# command. This string is designed to be shown in a menu alongside the command
# name, which is why it should be as short as possible. See prefManual for a
# fuller description of what it does.
# LOCALIZATION NOTE (prefDesc, prefManual, prefListDesc, prefListManual,
# prefListSearchDesc, prefListSearchManual, prefShowDesc, prefShowManual,
# prefShowSettingDesc, prefShowSettingManual): These strings describe the
# 'pref' command and all its available sub-commands and parameters.
prefDesc=Commands to control settings
# LOCALIZATION NOTE (prefManual): A fuller description of the 'pref' command.
# Displayed when the user asks for help on what it does.
prefManual=Commands to display and alter preferences both for GCLI and the surrounding environment
# LOCALIZATION NOTE (prefListDesc): A very short description of the 'pref
# list' command. This string is designed to be shown in a menu alongside the
# command name, which is why it should be as short as possible. See
# prefListManual for a fuller description of what it does.
prefListDesc=Display available settings
# LOCALIZATION NOTE (prefListManual): A fuller description of the 'pref list'
# command. Displayed when the user asks for help on what it does.
prefListManual=Display a list of preferences, optionally filtered when using the 'search' parameter
# LOCALIZATION NOTE (prefListSearchDesc): A short description of the 'search'
# parameter to the 'pref list' command. See prefListSearchManual for a fuller
# description of what it does. This string is designed to be shown in a dialog
# with restricted space, which is why it should be as short as possible.
prefListSearchDesc=Filter the list of settings displayed
# LOCALIZATION NOTE (prefListSearchManual): A fuller description of the
# 'search' parameter to the 'pref list' command. Displayed when the user asks
# for help on what it does.
prefListSearchManual=Search for the given string in the list of available preferences
# LOCALIZATION NOTE (prefShowDesc): A very short description of the 'pref
# show' command. This string is designed to be shown in a menu alongside the
# command name, which is why it should be as short as possible. See
# prefShowManual for a fuller description of what it does.
prefShowDesc=Display setting value
# LOCALIZATION NOTE (prefShowManual): A fuller description of the 'pref show'
# command. Displayed when the user asks for help on what it does.
prefShowManual=Display the value of a given preference
# LOCALIZATION NOTE (prefShowSettingDesc): A short description of the
# 'setting' parameter to the 'pref show' command. See prefShowSettingManual
# for a fuller description of what it does. This string is designed to be
# shown in a dialog with restricted space, which is why it should be as short
# as possible.
prefShowSettingDesc=Setting to display
# LOCALIZATION NOTE (prefShowSettingManual): A fuller description of the
# 'setting' parameter to the 'pref show' command. Displayed when the user asks
# for help on what it does.
prefShowSettingManual=The name of the setting to display
# LOCALIZATION NOTE (prefShowSettingValue): This is used to show the
# preference name and the associated preference value. %1$S is replaced with
# the preference name and %2$S is replaced with the preference value.
# LOCALIZATION NOTE: This message is used to show the preference name and the
# associated preference value. Parameters: %1$S is the preference name, %2$S
# is the preference value.
prefShowSettingValue=%1$S: %2$S
# LOCALIZATION NOTE (prefSetDesc): A very short description of the 'pref set'
# command. This string is designed to be shown in a menu alongside the command
# name, which is why it should be as short as possible. See prefSetManual for
# a fuller description of what it does.
# LOCALIZATION NOTE (prefSetDesc, prefSetManual, prefSetSettingDesc,
# prefSetSettingManual, prefSetValueDesc, prefSetValueManual): These strings
# describe the 'pref set' command and all its parameters.
prefSetDesc=Alter a setting
# LOCALIZATION NOTE (prefSetManual): A fuller description of the 'pref set'
# command. Displayed when the user asks for help on what it does.
prefSetManual=Alter preferences defined by the environment
# LOCALIZATION NOTE (prefSetSettingDesc): A short description of the 'setting'
# parameter to the 'pref set' command. See prefSetSettingManual for a fuller
# description of what it does. This string is designed to be shown in a dialog
# with restricted space, which is why it should be as short as possible.
prefSetSettingDesc=Setting to alter
# LOCALIZATION NOTE (prefSetSettingManual): A fuller description of the
# 'setting' parameter to the 'pref set' command. Displayed when the user asks
# for help on what it does.
prefSetSettingManual=The name of the setting to alter.
# LOCALIZATION NOTE (prefSetValueDesc): A short description of the 'value'
# parameter to the 'pref set' command. See prefSetValueManual for a fuller
# description of what it does. This string is designed to be shown in a dialog
# with restricted space, which is why it should be as short as possible.
prefSetValueDesc=New value for setting
# LOCALIZATION NOTE (prefSetValueManual): A fuller description of the 'value'
# parameter to the 'pref set' command. Displayed when the user asks for help
# on what it does.
prefSetValueManual=The new value for the specified setting
# LOCALIZATION NOTE (prefSetCheckHeading): Title displayed to the user the
# first time they try to alter a setting This is displayed directly above
# prefSetCheckBody and prefSetCheckGo.
# LOCALIZATION NOTE (prefSetCheckHeading, prefSetCheckBody, prefSetCheckGo):
# These strings are displayed to the user the first time they try to alter a
# setting.
prefSetCheckHeading=This might void your warranty!
# LOCALIZATION NOTE (prefSetCheckBody): The main text of the warning displayed
# to the user the first time they try to alter a setting. See also
# prefSetCheckHeading and prefSetCheckGo.
prefSetCheckBody=Changing these advanced settings can be harmful to the stability, security, and performance of this application. You should only continue if you are sure of what you are doing.
# LOCALIZATION NOTE (prefSetCheckGo): The text to enable preference editing.
# Displayed in a button directly under prefSetCheckHeading and
# prefSetCheckBody
prefSetCheckGo=I'll be careful, I promise!
# LOCALIZATION NOTE (prefResetDesc): A very short description of the 'pref
# reset' command. This string is designed to be shown in a menu alongside the
# command name, which is why it should be as short as possible. See
# prefResetManual for a fuller description of what it does.
# LOCALIZATION NOTE (prefResetDesc, prefResetManual, prefResetSettingDesc,
# prefResetSettingManual): These strings describe the 'pref reset' command and
# all its parameters.
prefResetDesc=Reset a setting
# LOCALIZATION NOTE (prefResetManual): A fuller description of the 'pref
# reset' command. Displayed when the user asks for help on what it does.
prefResetManual=Reset the value of a setting to the system defaults
# LOCALIZATION NOTE (prefResetSettingDesc): A short description of the
# 'setting' parameter to the 'pref reset' command. See prefResetSettingManual
# for a fuller description of what it does. This string is designed to be
# shown in a dialog with restricted space, which is why it should be as short
# as possible.
prefResetSettingDesc=Setting to reset
# LOCALIZATION NOTE (prefResetSettingManual): A fuller description of the
# 'setting' parameter to the 'pref reset' command. Displayed when the user
# asks for help on what it does.
prefResetSettingManual=The name of the setting to reset to the system default value
# LOCALIZATION NOTE (prefOutputFilter): Displayed in the output from the 'pref
# LOCALIZATION NOTE: This string is displayed in the output from the 'pref
# list' command as a label to an input element that allows the user to filter
# the results
# the results.
prefOutputFilter=Filter
# LOCALIZATION NOTE (prefOutputName): Displayed in the output from the 'pref
# list' command as a heading to a table. The column contains the names of the
# available preferences
# LOCALIZATION NOTE (prefOutputName, prefOutputValue): These strings are
# displayed in the output from the 'pref list' command as table headings.
prefOutputName=Name
# LOCALIZATION NOTE (prefOutputValue): Displayed in the output from the 'pref
# list' command as a heading to a table. The column contains the values of the
# available preferences
prefOutputValue=Value
# LOCALIZATION NOTE (introDesc): A very short description of the 'intro'
# command. This string is designed to be shown in a menu alongside the command
# name, which is why it should be as short as possible. See introManual for a
# fuller description of what it does.
# LOCALIZATION NOTE (introDesc, introManual): These strings describe the
# 'intro' command. The localization of 'Got it!' should be the same used in
# introTextGo.
introDesc=Show the opening message
# LOCALIZATION NOTE (introManual): A fuller description of the 'intro'
# command. Displayed when the user asks for help on what it does.
introManual=Redisplay the message that is shown to new users until they click the 'Got it!' button
# LOCALIZATION NOTE (introTextOpening2): The 'intro text' opens when the user
# LOCALIZATION NOTE (introTextOpening2, introTextCommands, introTextKeys2,
# introTextF1Escape, introTextGo): These strings are displayed when the user
# first opens the developer toolbar to explain the command line, and is shown
# each time it is opened until the user clicks the 'Got it!' button. This
# string is the opening paragraph of the intro text.
# each time it is opened until the user clicks the 'Got it!' button.
introTextOpening2=This command line is designed for developers. It focuses on speed of input over JavaScript syntax and a rich display over monospace output.
# LOCALIZATION NOTE (introTextCommands): For information about the 'intro
# text' see introTextOpening2. The second paragraph is in 2 sections, the
# first section points the user to the 'help' command.
introTextCommands=For a list of commands type
# LOCALIZATION NOTE (introTextKeys2): For information about the 'intro text'
# see introTextOpening2. The second section in the second paragraph points the
# user to the F1/Escape keys which show and hide hints.
introTextKeys2=, or to show/hide command hints press
# LOCALIZATION NOTE (introTextF1Escape): For information about the 'intro
# text' see introTextOpening2. This string is used with introTextKeys2, and
# contains the keys that are pressed to open and close hints.
introTextF1Escape=F1/Escape
# LOCALIZATION NOTE (introTextGo): For information about the 'intro text' see
# introTextOpening2. The text on the button that dismisses the intro text.
introTextGo=Got it!
# LOCALIZATION NOTE (hideIntroDesc): Short description of the 'hideIntro'
# setting. Displayed when the user asks for help on the settings.
# LOCALIZATION NOTE: This is a short description of the 'hideIntro' setting.
hideIntroDesc=Show the initial welcome message
# LOCALIZATION NOTE (eagerHelperDesc): Short description of the 'eagerHelper'
# setting. Displayed when the user asks for help on the settings. eagerHelper
# allows users to select between showing no tooltips, permanent tooltips, and
# only important tooltips
# LOCALIZATION NOTE: This is a description of the 'eagerHelper' setting. It's
# displayed when the user asks for help on the settings. eagerHelper allows
# users to select between showing no tooltips, permanent tooltips, and only
# important tooltips.
eagerHelperDesc=How eager are the tooltips
# LOCALIZATION NOTE (allowSetDesc): Short description of the 'allowSetDesc'
# setting. Displayed when the user asks for help on the settings.
# LOCALIZATION NOTE: This is a short description of the 'allowSetDesc'
# setting.
allowSetDesc=Has the user enabled the 'pref set' command?
# LOCALIZATION NOTE (introBody): The text displayed at the top of the output
# for the help command, just before the list of commands. This text is wrapped
# inside a link to a localized MDN article
# LOCALIZATION NOTE: This text is displayed at the top of the output for the
# help command, just before the list of commands. This text is wrapped inside
# a link to a localized MDN article.
introBody=For more information see MDN.

View File

@ -504,6 +504,21 @@ cmdDesc=Manipulate the commands
# name, which is why it should be as short as possible.
cmdRefreshDesc=Re-read mozcmd directory
# LOCALIZATION NOTE (cmdStatus) When the we load new commands from mozcmd
# directory, we report on how many we loaded. %1$S is a count of the number
# of loaded commands, and %2$S is the directory we loaded from.
cmdStatus=Read %1$S commands from '%2$S'
# LOCALIZATION NOTE (cmdSetdirDesc)
cmdSetdirDesc=Setup a mozcmd directory
# LOCALIZATION NOTE (cmdSetdirManual)
cmdSetdirManual=A 'mozcmd' directory is an easy way to create new custom commands for the Firefox command line. For more information see the <a href="https://developer.mozilla.org/en-US/docs/Tools/GCLI/Customization">MDN documentation</a>.
# LOCALIZATION NOTE (cmdSetdirDirectoryDesc) The description of the directory
# parameter to the 'cmd setdir' command.
cmdSetdirDirectoryDesc=Directory containing .mozcmd files
# LOCALIZATION NOTE (addonDesc) A very short description of the 'addon'
# command. This string is designed to be shown in a menu alongside the command
# name, which is why it should be as short as possible.

View File

@ -9,6 +9,8 @@
<!ENTITY toolboxCloseButton.tooltip "Close Developer Tools">
<!ENTITY toolboxOptionsButton.key "O">
<!ENTITY toolboxNextTool.key "]">
<!ENTITY toolboxPreviousTool.key "[">
<!-- LOCALIZATION NOTE (options.context.advancedSettings): This is the label for
- the heading of the advanced settings group in the options panel. -->

View File

@ -2,10 +2,6 @@
* 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/. */
// Fired when any context ui is displayed
const kContextUIShowEvent = "MozContextUIShow";
// Fired when any context ui is dismissed
const kContextUIDismissEvent = "MozContextUIDismiss";
// Fired when the tabtray is displayed
const kContextUITabsShowEvent = "MozContextUITabsShow";
// add more as needed...
@ -113,7 +109,6 @@ var ContextUI = {
if (shown) {
ContentAreaObserver.update(window.innerWidth, window.innerHeight);
this._fire(kContextUIShowEvent);
}
return shown;
@ -145,7 +140,6 @@ var ContextUI = {
if (dismissed) {
ContentAreaObserver.update(window.innerWidth, window.innerHeight);
this._fire(kContextUIDismissEvent);
}
return dismissed;

View File

@ -185,7 +185,7 @@ function TopSitesView(aGrid, aMaxSites, aUseThumbnails) {
}.bind(this));
}
TopSitesView.prototype = {
TopSitesView.prototype = Util.extend(Object.create(View.prototype), {
_set:null,
_topSitesMax: null,
// _lastSelectedSites used to temporarily store blocked/removed sites for undo/restore-ing
@ -307,23 +307,7 @@ TopSitesView.prototype = {
},
updateTile: function(aTileNode, aSite, aArrangeGrid) {
PlacesUtils.favicons.getFaviconURLForPage(Util.makeURI(aSite.url), function(iconURLfromSiteURL) {
if (!iconURLfromSiteURL) {
return;
}
aTileNode.iconSrc = iconURLfromSiteURL.spec;
let faviconURL = (PlacesUtils.favicons.getFaviconLinkForIcon(iconURLfromSiteURL)).spec;
let xpFaviconURI = Util.makeURI(faviconURL.replace("moz-anno:favicon:",""));
let successAction = function(foreground, background) {
aTileNode.style.color = foreground; //color text
aTileNode.setAttribute("customColor", background);
if (aTileNode.refresh) {
aTileNode.refresh();
}
};
let failureAction = function() {};
ColorUtils.getForegroundAndBackgroundIconColors(xpFaviconURI, successAction, failureAction);
});
this._updateFavicon(aTileNode, Util.makeURI(aSite.url));
if (this._useThumbs) {
Task.spawn(function() {
@ -437,7 +421,7 @@ TopSitesView.prototype = {
throw Cr.NS_ERROR_NO_INTERFACE;
}
};
});
let TopSitesStartView = {
_view: null,

View File

@ -93,7 +93,7 @@ function BookmarksView(aSet, aLimit, aRoot, aFilterUnpinned) {
this.root = aRoot;
}
BookmarksView.prototype = {
BookmarksView.prototype = Util.extend(Object.create(View.prototype), {
_limit: null,
_set: null,
_changes: null,
@ -216,7 +216,7 @@ BookmarksView.prototype = {
let item = this._set.insertItemAt(aPos || index, title, uri.spec, this._inBatch);
item.setAttribute("bookmarkId", aBookmarkId);
this._setContextActions(item);
this._updateFavicon(aBookmarkId, item, uri);
this._updateFavicon(item, uri);
},
_setContextActions: function bv__setContextActions(aItem) {
@ -225,26 +225,6 @@ BookmarksView.prototype = {
if (aItem.refresh) aItem.refresh();
},
_updateFavicon: function bv__updateFavicon(aBookmarkId, aItem, aUri) {
PlacesUtils.favicons.getFaviconURLForPage(aUri, this._gotIcon.bind(this, aBookmarkId, aItem));
},
_gotIcon: function bv__gotIcon(aBookmarkId, aItem, aIconUri) {
aItem.setAttribute("iconURI", aIconUri ? aIconUri.spec : "");
if (!aIconUri) {
return;
}
let successAction = function(foregroundColor, backgroundColor) {
aItem.style.color = foregroundColor; //color text
aItem.setAttribute("customColor", backgroundColor); //set background
if (aItem.refresh) {
aItem.refresh();
}
};
let failureAction = function() {};
ColorUtils.getForegroundAndBackgroundIconColors(aIconUri, successAction, failureAction);
},
_sendNeedsRefresh: function bv__sendNeedsRefresh(){
// Event sent when all view instances need to refresh.
let event = document.createEvent("Events");
@ -273,7 +253,7 @@ BookmarksView.prototype = {
item.setAttribute("value", uri.spec);
item.setAttribute("label", title);
this._updateFavicon(aBookmarkId, item, uri);
this._updateFavicon(item, uri);
},
removeBookmark: function bv_removeBookmark(aBookmarkId) {
@ -370,7 +350,7 @@ BookmarksView.prototype = {
break;
}
}
};
});
var BookmarksStartView = {
_view: null,

View File

@ -40,6 +40,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "CrossSlide",
XPCOMUtils.defineLazyGetter(this, "OS",
"resource://gre/modules/osfile.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "View",
"resource:///modules/View.jsm");
/*
* Services
*/

View File

@ -48,7 +48,7 @@ var FindHelperUI = {
this._cmdPrevious = document.getElementById(this.commands.previous);
this._cmdNext = document.getElementById(this.commands.next);
this._textbox.addEventListener('keydown', this);
this._textbox.addEventListener("keydown", this);
// Listen for find assistant messages from content
messageManager.addMessageListener("FindAssist:Show", this);
@ -57,7 +57,7 @@ var FindHelperUI = {
// Listen for events where form assistant should be closed
Elements.tabList.addEventListener("TabSelect", this, true);
Elements.browsers.addEventListener("URLChanged", this, true);
window.addEventListener("MozContextUIShow", this, true);
window.addEventListener("MozAppbarShowing", this);
},
receiveMessage: function findHelperReceiveMessage(aMessage) {
@ -79,7 +79,6 @@ var FindHelperUI = {
handleEvent: function findHelperHandleEvent(aEvent) {
switch (aEvent.type) {
case "MozContextUIShow":
case "TabSelect":
this.hide();
break;
@ -91,11 +90,16 @@ var FindHelperUI = {
case "keydown":
if (aEvent.keyCode == Ci.nsIDOMKeyEvent.DOM_VK_RETURN) {
if (aEvent.shiftKey) {
this.goToPrevious();
} else {
this.goToNext();
}
if (aEvent.shiftKey) {
this.goToPrevious();
} else {
this.goToNext();
}
}
case "MozAppbarShowing":
if (aEvent.target != this._container) {
this.hide();
}
}
},

View File

@ -1,7 +1,7 @@
// -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*-
/* 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';
function HistoryView(aSet, aLimit, aFilterUnpinned) {
@ -20,7 +20,7 @@ function HistoryView(aSet, aLimit, aFilterUnpinned) {
window.addEventListener('HistoryNeedsRefresh', this, false);
}
HistoryView.prototype = {
HistoryView.prototype = Util.extend(Object.create(View.prototype), {
_set: null,
_toRemove: null,
@ -97,8 +97,8 @@ HistoryView.prototype = {
addItemToSet: function addItemToSet(aURI, aTitle, aIcon, aPos) {
let item = this._set.insertItemAt(aPos || 0, aTitle, aURI, this._inBatch);
item.setAttribute("iconURI", aIcon);
this._setContextActions(item);
this._updateFavicon(item, aURI);
},
_setContextActions: function bv__setContextActions(aItem) {
@ -273,7 +273,7 @@ HistoryView.prototype = {
}
throw Cr.NS_ERROR_NO_INTERFACE;
}
};
});
let HistoryStartView = {
_view: null,

View File

@ -11,7 +11,7 @@ relativesrcdir = @relativesrcdir@
include $(DEPTH)/config/autoconf.mk
ifndef MOZ_DEBUG
PERF_TEST_FILES = \
MOCHITEST_METRO_FILES = \
../mochitest/head.js \
perfhelpers.js \
browser_miscgfx_01.js \
@ -22,20 +22,6 @@ PERF_TEST_FILES = \
browser_layers_01.js \
browser_firstx.js \
$(NULL)
PERF_RESOURCE_FILES = \
res/ripples.html \
res/scroll_test.html \
res/tidevideo.html \
res/tide.mp4 \
res/divs_test.html \
res/fx.png \
$(NULL)
PERF_TEST_DEST := $(DEPTH)/_tests/testing/mochitest/metro/$(relativesrcdir)
PERF_RESOURCE_DEST := $(DEPTH)/_tests/testing/mochitest/metro/$(relativesrcdir)/res
INSTALL_TARGETS += PERF_TEST PERF_RESOURCE
endif
include $(topsrcdir)/config/rules.mk

View File

@ -2,3 +2,5 @@
# 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/.
TEST_DIRS += ['res']

View File

@ -0,0 +1,24 @@
# 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/.
DEPTH = @DEPTH@
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
relativesrcdir = @relativesrcdir@
include $(DEPTH)/config/autoconf.mk
ifndef MOZ_DEBUG
MOCHITEST_METRO_FILES = \
ripples.html \
scroll_test.html \
tidevideo.html \
tide.mp4 \
divs_test.html \
fx.png \
$(NULL)
endif
include $(topsrcdir)/config/rules.mk

View File

@ -0,0 +1,4 @@
# vim: set filetype=python:
# 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/.

View File

@ -10,7 +10,7 @@ relativesrcdir = @relativesrcdir@
include $(DEPTH)/config/autoconf.mk
BROWSER_TESTS = \
MOCHITEST_METRO_FILES = \
head.js \
browser_urlbar.js \
browser_bookmarks.js \
@ -39,7 +39,7 @@ BROWSER_TESTS = \
$(NULL)
ifndef MOZ_DEBUG
BROWSER_TESTS += \
MOCHITEST_METRO_FILES += \
browser_selection_basic.js \
browser_selection_basic.html \
browser_selection_textarea.js \
@ -58,18 +58,4 @@ BROWSER_TESTS += \
$(NULL)
endif
BROWSER_TEST_RESOURCES = \
res/image01.png \
res/textblock01.html \
res/textinput01.html \
res/textarea01.html \
res/testEngine.xml \
$(NULL)
libs:: $(BROWSER_TESTS)
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/metro/$(relativesrcdir)
libs:: $(BROWSER_TEST_RESOURCES)
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/metro/$(relativesrcdir)/res
include $(topsrcdir)/config/rules.mk

View File

@ -34,6 +34,32 @@ gTests.push({
}
});
gTests.push({
desc: "Findbar/navbar interaction",
run: function() {
let tab = yield addTab(chromeRoot + "browser_findbar.html");
yield waitForCondition(() => BrowserUI.ready);
is(ContextUI.navbarVisible, false, "Navbar is hidden by default");
is(Elements.findbar.isShowing, false, "Find bar is hidden by default");
yield showNavBar();
is(ContextUI.navbarVisible, true, "Navbar is visible");
is(Elements.findbar.isShowing, false, "Find bar is still hidden");
EventUtils.synthesizeKey("f", { accelKey: true });
yield waitForEvent(Elements.navbar, "transitionend");
is(ContextUI.navbarVisible, false, "Navbar is hidden");
is(Elements.findbar.isShowing, true, "Findbar is visible");
yield showNavBar();
is(ContextUI.navbarVisible, true, "Navbar is visible again");
is(Elements.findbar.isShowing, false, "Find bar is hidden again");
Browser.closeTab(tab);
}
});
gTests.push({
desc: "Show and hide the find bar with mouse",
run: function() {

View File

@ -2,3 +2,5 @@
# 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/.
TEST_DIRS += ['res']

View 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/.
DEPTH = @DEPTH@
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
relativesrcdir = @relativesrcdir@
include $(DEPTH)/config/autoconf.mk
MOCHITEST_METRO_FILES = \
image01.png \
textblock01.html \
textinput01.html \
textarea01.html \
testEngine.xml \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@ -0,0 +1,4 @@
# vim: set filetype=python:
# 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/.

View File

@ -0,0 +1,63 @@
/* 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";
this.EXPORTED_SYMBOLS = ["View"];
Components.utils.import("resource://gre/modules/PlacesUtils.jsm");
Components.utils.import("resource:///modules/colorUtils.jsm");
Components.utils.import("resource://gre/modules/Services.jsm");
// --------------------------------
// module helpers
//
function makeURI(aURL, aOriginCharset, aBaseURI) {
return Services.io.newURI(aURL, aOriginCharset, aBaseURI);
}
// --------------------------------
// --------------------------------
// View prototype for shared functionality
function View() {
}
View.prototype = {
_updateFavicon: function pv__updateFavicon(aItem, aUri) {
if ("string" == typeof aUri) {
aUri = makeURI(aUri);
}
PlacesUtils.favicons.getFaviconURLForPage(aUri, this._gotIcon.bind(this, aItem));
},
_gotIcon: function pv__gotIcon(aItem, aIconUri) {
if (!aIconUri) {
aItem.removeAttribute("iconURI");
if (aItem.refresh) {
aItem.refresh();
}
return;
}
if ("string" == typeof aIconUri) {
aIconUri = makeURI(aIconUri);
}
aItem.iconSrc = aIconUri.spec;
let faviconURL = (PlacesUtils.favicons.getFaviconLinkForIcon(aIconUri)).spec;
let xpFaviconURI = makeURI(faviconURL.replace("moz-anno:favicon:",""));
let successAction = function(foreground, background) {
aItem.style.color = foreground; //color text
aItem.setAttribute("customColor", background);
if (aItem.refresh) {
aItem.refresh();
}
};
let failureAction = function() {};
ColorUtils.getForegroundAndBackgroundIconColors(xpFaviconURI, successAction, failureAction);
}
};

View File

@ -6,6 +6,7 @@
EXTRA_JS_MODULES += [
'CrossSlide.jsm',
'View.jsm',
'colorUtils.jsm',
]

View File

@ -204,18 +204,15 @@ documenttab[selected] .documenttab-selection {
}
#tabs-controls {
margin-top: @metro_spacing_small@;
-moz-box-align: start;
-moz-box-orient: vertical;
padding: 0 @metro_spacing_small@;
}
#tabs-controls toolbarbutton {
margin: @toolbar_vertical_spacing@ @toolbar_horizontal_spacing@;
}
#newtab-button {
list-style-image: url(chrome://browser/skin/images/newtab-default.png);
/* Add some extra padding for a larger target */
padding: 18px 25px 30px;
}
/* Selection overlay and monocles ----------------------------------------------- */

View File

@ -103,8 +103,12 @@
-moz-margin-start: 1px;
}
#searchbox-panel-description {
margin-top: 0;
#filter-label {
-moz-margin-start: 2px;
}
#searchbox-panel-operators {
margin-top: 5px;
margin-bottom: 8px;
-moz-margin-start: 2px;
}

View File

@ -105,8 +105,12 @@
-moz-margin-start: 1px;
}
#searchbox-panel-description {
margin-top: 0;
#filter-label {
-moz-margin-start: 2px;
}
#searchbox-panel-operators {
margin-top: 5px;
margin-bottom: 8px;
-moz-margin-start: 2px;
}

View File

@ -44,7 +44,7 @@
}
.theme-selected {
background: #26384E;
background: #26394D;
}
.theme-bg-darker {

Some files were not shown because too many files have changed in this diff Show More