Bug 1128988 - runAt support for commands/converters; r=bgrins

--HG--
rename : browser/devtools/main.js => browser/devtools/definitions.js
This commit is contained in:
Joe Walker 2015-04-23 10:24:49 +01:00
Родитель 57a6320951
Коммит 9cc5a4d6b3
147 изменённых файлов: 3474 добавлений и 4225 удалений

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

@ -1608,6 +1608,11 @@ pref("devtools.fontinspector.enabled", true);
// version for each user.
pref("devtools.telemetry.tools.opened.version", "{}");
// Set imgur upload client ID
pref("devtools.gcli.imgurClientID", '0df414e888d7240');
// Imgur's upload URL
pref("devtools.gcli.imgurUploadURL", "https://api.imgur.com/3/image");
// Whether the character encoding menu is under the main Firefox button. This
// preference is a string so that localizers can alter it.
pref("browser.menu.showCharacterEncoding", "chrome://browser/locale/browser.properties");

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

@ -4,9 +4,56 @@
"use strict";
const gcli = require("gcli/index");
const { createSystem, connectFront, disconnectFront } = require("gcli/system");
const { GcliFront } = require("devtools/server/actors/gcli");
const commandModules = [
/**
* This is the basic list of modules that should be loaded into each
* requisition instance whether server side or client side
*/
exports.baseModules = [
"gcli/types/delegate",
"gcli/types/selection",
"gcli/types/array",
"gcli/types/boolean",
"gcli/types/command",
"gcli/types/date",
"gcli/types/file",
"gcli/types/javascript",
"gcli/types/node",
"gcli/types/number",
"gcli/types/resource",
"gcli/types/setting",
"gcli/types/string",
"gcli/types/union",
"gcli/types/url",
"gcli/fields/fields",
"gcli/fields/delegate",
"gcli/fields/selection",
"gcli/ui/focus",
"gcli/ui/intro",
"gcli/converters/converters",
"gcli/converters/basic",
"gcli/converters/terminal",
"gcli/languages/command",
"gcli/languages/javascript",
"gcli/commands/clear",
"gcli/commands/context",
"gcli/commands/help",
"gcli/commands/pref",
];
/**
* Some commands belong to a tool (see getToolModules). This is a list of the
* modules that are *not* owned by a tool.
*/
exports.devtoolsModules = [
"devtools/tilt/tilt-commands",
"gcli/commands/addon",
"gcli/commands/appcache",
@ -28,15 +75,83 @@ const commandModules = [
"gcli/commands/tools",
];
gcli.addItemsByModule(commandModules, { delayedLoad: true });
/**
* Register commands from tools with 'command: [ "some/module" ]' definitions.
* The map/reduce incantation squashes the array of arrays to a single array.
*/
const defaultTools = require("definitions").defaultTools;
exports.devtoolsToolModules = defaultTools.map(def => def.commands || [])
.reduce((prev, curr) => prev.concat(curr), []);
const defaultTools = require("main").defaultTools;
for (let definition of defaultTools) {
if (definition.commands) {
gcli.addItemsByModule(definition.commands, { delayedLoad: true });
/**
* Add modules to a system for use in a content process (but don't call load)
*/
exports.addAllItemsByModule = function(system) {
system.addItemsByModule(exports.baseModules, { delayedLoad: true });
system.addItemsByModule(exports.devtoolsModules, { delayedLoad: true });
system.addItemsByModule(exports.devtoolsToolModules, { delayedLoad: true });
const { mozDirLoader } = require("gcli/commands/cmd");
system.addItemsByModule("mozcmd", { delayedLoad: true, loader: mozDirLoader });
};
/**
* This is WeakMap<Target, Links> where Links is an object that looks like
* { refs: number, promise: Promise<System>, front: GcliFront }
*/
var linksForTarget = new WeakMap();
/**
* The toolbox uses the following properties on a command to allow it to be
* added to the toolbox toolbar
*/
var customProperties = [ "buttonId", "buttonClass", "tooltipText" ];
/**
* Create a system which connects to a GCLI in a remote target
* @return Promise<System> for the given target
*/
exports.getSystem = function(target) {
const existingLinks = linksForTarget.get(target);
if (existingLinks != null) {
existingLinks.refs++;
return existingLinks.promise;
}
}
const { mozDirLoader } = require("gcli/commands/cmd");
const system = createSystem({ location: "client" });
gcli.addItemsByModule("mozcmd", { delayedLoad: true, loader: mozDirLoader });
exports.addAllItemsByModule(system);
// Load the client system
const links = {
refs: 1,
system,
promise: system.load().then(() => {
return GcliFront.create(target).then(front => {
links.front = front;
return connectFront(system, front, customProperties).then(() => system);
});
})
};
linksForTarget.set(target, links);
return links.promise;
};
/**
* Someone that called getSystem doesn't need it any more, so decrement the
* count of users of the system for that target, and destroy if needed
*/
exports.releaseSystem = function(target) {
const links = linksForTarget.get(target);
if (links == null) {
throw new Error("releaseSystem called for unknown target");
}
links.refs--;
if (links.refs === 0) {
disconnectFront(links.system, links.front);
links.system.destroy();
linksForTarget.delete(target);
}
};

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

@ -7,7 +7,7 @@ function test() {
return Task.spawn(spawnTest).then(finish, helpers.handleError);
}
function spawnTest() {
function* spawnTest() {
let options = yield helpers.openTab("about:blank");
yield helpers.openToolbar(options);

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

@ -11,7 +11,7 @@ function test() {
return Task.spawn(spawnTest).then(finish, helpers.handleError);
}
function spawnTest() {
function* spawnTest() {
let lines = [
'Manifest has a character encoding of ISO-8859-1. Manifests must have the ' +
'utf-8 character encoding.',

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

@ -10,7 +10,7 @@ function test() {
return Task.spawn(spawnTest).then(finish, helpers.handleError);
}
function spawnTest() {
function* spawnTest() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);

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

@ -8,7 +8,7 @@ const TEST_URI = "data:text/html;charset=utf-8,gcli-calllog";
let tests = {};
function test() {
return Task.spawn(function() {
return Task.spawn(function*() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);

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

@ -8,7 +8,7 @@ const TEST_URI = "data:text/html;charset=utf-8,cmd-calllog-chrome";
let tests = {};
function test() {
return Task.spawn(function() {
return Task.spawn(function*() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);

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

@ -9,7 +9,7 @@ function test() {
return Task.spawn(spawnTest).then(finish, helpers.handleError);
}
function spawnTest() {
function* spawnTest() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
@ -49,7 +49,7 @@ function spawnTest() {
yield helpers.audit(options, [
{
setup: "console close",
exec: { output: true }
exec: { output: "" }
}
]);

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

@ -33,18 +33,21 @@ add_task(function*() {
* Visit all the pages in the test
*/
function* navigate(usage, options) {
yield usage.start();
yield usage.start(options.chromeWindow, options.target);
ok(usage.isRunning(), "csscoverage is running");
let load1Promise = helpers.listenOnce(options.browser, "load", true);
yield helpers.navigate(PAGE_1, options);
// Wait for the test pages to auto-cycle
let ev = yield helpers.listenOnce(options.browser, "load", true);
is(ev.target.location.href, PAGE_1, "page 1 loaded");
yield load1Promise;
is(options.window.location.href, PAGE_1, "page 1 loaded");
ev = yield helpers.listenOnce(options.browser, "load", true);
is(ev.target.location.href, PAGE_3, "page 3 loaded");
// Page 2 is a frame in page 1. JS in the page navigates to page 3.
yield helpers.listenOnce(options.browser, "load", true);
is(options.window.location.href, PAGE_3, "page 3 loaded");
yield usage.stop();

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

@ -10,7 +10,7 @@ function test() {
return Task.spawn(testTask).then(finish, helpers.handleError);
}
function testTask() {
function* testTask() {
let options = yield helpers.openTab("about:blank");
yield helpers.openToolbar(options);
@ -29,7 +29,10 @@ function testTask() {
{
setup: 'jsb ' + TEST_URI,
// Should result in a new scratchpad window
exec: { }
exec: {
output: '',
error: false
}
}
]);

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

@ -74,7 +74,7 @@ let tests = {
};
function test() {
return Task.spawn(function() {
return Task.spawn(function*() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);

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

@ -10,7 +10,7 @@ function test() {
return Task.spawn(spawnTest).then(finish, helpers.handleError);
}
function spawnTest() {
function* spawnTest() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
@ -302,7 +302,8 @@ function spawnTest() {
args: {
searchAttributes: { value: undefined, status: 'INCOMPLETE' },
searchElements: { value: undefined, status: 'INCOMPLETE' },
root: { value: undefined },
// root: { value: undefined }, // 'root' is a node which is remote
// so we can't see the value in tests
ignoreCase: { value: false },
}
},
@ -317,7 +318,8 @@ function spawnTest() {
args: {
searchAttributes: { value: 'foo' },
searchElements: { value: 'bar' },
root: { value: undefined },
// root: { value: undefined }, // 'root' is a node which is remote
// so we can't see the value in tests
ignoreCase: { value: false },
}
},

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

@ -13,7 +13,7 @@ function test() {
return Task.spawn(spawnTest).then(finish, helpers.handleError);
}
function spawnTest() {
function* spawnTest() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);

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

@ -13,7 +13,7 @@ function test() {
return Task.spawn(spawnTest).then(finish, helpers.handleError);
}
function spawnTest() {
function* spawnTest() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);

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

@ -16,7 +16,7 @@ function test() {
return Task.spawn(spawnTest).then(finish, helpers.handleError);
}
function spawnTest() {
function* spawnTest() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);

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

@ -11,7 +11,7 @@ function test() {
return Task.spawn(spawnTest).then(finish, helpers.handleError);
}
function spawnTest() {
function* spawnTest() {
waitForExplicitFinish();
info("RUN TEST: non-private window");
@ -81,11 +81,6 @@ function addTabWithToolbarRunTests(win) {
input: 'screenshot --selector img#testImage',
markup: 'VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV',
status: 'VALID',
args: {
selector: {
value: options.window.document.getElementById("testImage")
},
}
},
},
]);

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

@ -16,14 +16,18 @@ function test() {
return Task.spawn(spawnTest).then(finish, helpers.handleError);
}
function spawnTest() {
function* spawnTest() {
// Setup
let options = yield helpers.openTab(TEST_URI);
require("devtools/commandline/commands-index");
let gcli = require("gcli/index");
yield gcli.load();
let settings = gcli.settings;
const { createSystem } = require("gcli/system");
const system = createSystem({ location: "server" });
const gcliInit = require("devtools/commandline/commands-index");
gcliInit.addAllItemsByModule(system);
yield system.load();
let settings = system.settings;
let hideIntroEnabled = settings.get("devtools.gcli.hideIntro");
let tabSize = settings.get("devtools.editor.tabsize");

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

@ -15,31 +15,16 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testAsync.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_async.js");
}
// <INJECTED SOURCE:END>
// var helpers = require('./helpers');
exports.testBasic = function(options) {
@ -74,7 +59,6 @@ exports.testBasic = function(options) {
args: {
command: { name: 'tsslow' },
hello: {
value: undefined,
arg: '',
status: 'INCOMPLETE'
},
@ -95,7 +79,6 @@ exports.testBasic = function(options) {
args: {
command: { name: 'tsslow' },
hello: {
value: undefined,
arg: ' S',
status: 'INCOMPLETE'
},
@ -116,7 +99,6 @@ exports.testBasic = function(options) {
args: {
command: { name: 'tsslow' },
hello: {
value: 'Shalom',
arg: ' Shalom ',
status: 'VALID',
message: ''

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

@ -15,31 +15,16 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testCanon.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_canon.js");
}
// <INJECTED SOURCE:END>
// var assert = require('../testharness/assert');
// var helpers = require('./helpers');
var Commands = require('gcli/commands/commands').Commands;
@ -219,6 +204,9 @@ exports.testAltCommands = function(options) {
{ name: 'num', type: 'number' },
{ name: 'opt', type: { name: 'selection', data: [ '1', '2', '3' ] } },
],
customProp1: 'localValue',
customProp2: true,
customProp3: 42,
exec: function(args, context) {
return context.commandName + ':' +
args.str + ':' + args.num + ':' + args.opt;
@ -235,6 +223,24 @@ exports.testAltCommands = function(options) {
'],"isParent":false}]',
'JSON.stringify(commandSpecs)');
var customProps = [ 'customProp1', 'customProp2', 'customProp3', ];
var commandSpecs2 = altCommands.getCommandSpecs(customProps);
assert.is(JSON.stringify(commandSpecs2),
'[{' +
'"item":"command",' +
'"name":"tss",' +
'"params":[' +
'{"name":"str","type":"string"},' +
'{"name":"num","type":"number"},' +
'{"name":"opt","type":{"name":"selection","data":["1","2","3"]}}' +
'],' +
'"isParent":false,' +
'"customProp1":"localValue",' +
'"customProp2":true,' +
'"customProp3":42' +
'}]',
'JSON.stringify(commandSpecs)');
var remoter = function(args, context) {
assert.is(context.commandName, 'tss', 'commandName is tss');

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

@ -15,31 +15,16 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testCli1.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_cli1.js");
}
// <INJECTED SOURCE:END>
// var assert = require('../testharness/assert');
// var helpers = require('./helpers');
@ -268,7 +253,6 @@ exports.testTsv = function(options) {
}
},
{
skipRemainingIf: options.isNoDom,
name: '|tsv option',
setup: function() {
return helpers.setInput(options, 'tsv option', 0);

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

@ -15,45 +15,18 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testCli2.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_cli2.js");
}
// <INJECTED SOURCE:END>
// var helpers = require('./helpers');
var nodetype = require('gcli/types/node');
exports.setup = function(options) {
if (options.window) {
nodetype.setDocument(options.window.document);
}
};
exports.shutdown = function(options) {
nodetype.unsetDocument();
};
exports.testSingleString = function(options) {
return helpers.audit(options, [
{
@ -376,7 +349,6 @@ exports.testSingleFloat = function(options) {
}
},
{
skipRemainingIf: options.isNoDom,
name: 'tsf x (cursor=4)',
setup: function() {
return helpers.setInput(options, 'tsf x', 4);
@ -406,21 +378,14 @@ exports.testSingleFloat = function(options) {
};
exports.testElementWeb = function(options) {
var inputElement = options.isNoDom ?
null :
options.window.document.getElementById('gcli-input');
return helpers.audit(options, [
{
skipIf: function gcliInputElementExists() {
return inputElement == null;
},
setup: 'tse #gcli-input',
setup: 'tse #gcli-root',
check: {
input: 'tse #gcli-input',
input: 'tse #gcli-root',
hints: ' [options]',
markup: 'VVVVVVVVVVVVVVV',
cursor: 15,
markup: 'VVVVVVVVVVVVVV',
cursor: 14,
current: 'node',
status: 'VALID',
predictions: [ ],
@ -428,8 +393,7 @@ exports.testElementWeb = function(options) {
args: {
command: { name: 'tse' },
node: {
value: inputElement,
arg: ' #gcli-input',
arg: ' #gcli-root',
status: 'VALID',
message: ''
},
@ -444,7 +408,6 @@ exports.testElementWeb = function(options) {
exports.testElement = function(options) {
return helpers.audit(options, [
{
skipRemainingIf: options.isNoDom,
setup: 'tse',
check: {
input: 'tse',
@ -457,7 +420,7 @@ exports.testElement = function(options) {
unassigned: [ ],
args: {
command: { name: 'tse' },
node: { value: undefined, arg: '', status: 'INCOMPLETE' },
node: { arg: '', status: 'INCOMPLETE' },
nodes: { arg: '', status: 'VALID', message: '' },
nodes2: { arg: '', status: 'VALID', message: '' },
}
@ -605,7 +568,7 @@ exports.testNestedCommand = function(options) {
}
},
{
skipIf: options.isPhantomjs,
skipIf: options.isPhantomjs, // PhantomJS gets predictions wrong
setup: 'tsn x',
check: {
input: 'tsn x',

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

@ -15,31 +15,16 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testCompletion1.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_completion1.js");
}
// <INJECTED SOURCE:END>
// var helpers = require('./helpers');
exports.testActivate = function(options) {
@ -183,7 +168,7 @@ exports.testActivate = function(options) {
}
},
{
skipIf: options.isPhantomjs,
skipIf: options.isPhantomjs, // PhantomJS gets predictions wrong
setup: 'tsg d',
check: {
hints: ' [options] -> ccc'

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

@ -15,31 +15,16 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testCompletion2.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_completion2.js");
}
// <INJECTED SOURCE:END>
// var helpers = require('./helpers');
exports.testLong = function(options) {
@ -170,7 +155,6 @@ exports.testNoTab = function(options) {
}
},
{
skipIf: options.isNoDom,
name: '<TAB>',
setup: function() {
// Doing it this way avoids clearing the input buffer

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

@ -15,31 +15,16 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testContext.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_context.js");
}
// <INJECTED SOURCE:END>
// var helpers = require('./helpers');
exports.testBaseline = function(options) {

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

@ -15,31 +15,16 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testDate.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_date.js");
}
// <INJECTED SOURCE:END>
// var assert = require('../testharness/assert');
// var helpers = require('./helpers');
@ -66,15 +51,15 @@ exports.testMaxMin = function(options) {
var date = types.createType({ name: 'date', max: max, min: min });
assert.is(date.getMax(), max, 'max setup');
var incremented = date.increment(min);
var incremented = date.nudge(min, 1);
assert.is(incremented, max, 'incremented');
};
exports.testIncrement = function(options) {
var date = options.requisition.system.types.createType('date');
return date.parseString('now').then(function(conversion) {
var plusOne = date.increment(conversion.value);
var minusOne = date.decrement(plusOne);
var plusOne = date.nudge(conversion.value, 1);
var minusOne = date.nudge(plusOne, -1);
// See comments in testParse
var gap = new Date().getTime() - minusOne.getTime();
@ -126,7 +111,7 @@ exports.testInput = function(options) {
},
exec: {
output: [ /^Exec: tsdate/, /2001/, /1980/ ],
type: 'string',
type: 'testCommandOutput',
error: false
}
},
@ -172,7 +157,7 @@ exports.testInput = function(options) {
},
exec: {
output: [ /^Exec: tsdate/, /2001/, /1980/ ],
type: 'string',
type: 'testCommandOutput',
error: false
}
},
@ -213,7 +198,7 @@ exports.testInput = function(options) {
},
exec: {
output: [ /^Exec: tsdate/, new Date().getFullYear() ],
type: 'string',
type: 'testCommandOutput',
error: false
}
},
@ -253,7 +238,7 @@ exports.testInput = function(options) {
},
exec: {
output: [ /^Exec: tsdate/, new Date().getFullYear() ],
type: 'string',
type: 'testCommandOutput',
error: false
}
}
@ -264,7 +249,7 @@ exports.testIncrDecr = function(options) {
return helpers.audit(options, [
{
// createRequisitionAutomator doesn't fake UP/DOWN well enough
skipRemainingIf: options.isNoDom,
skipRemainingIf: options.isNode,
setup: 'tsdate 2001-01-01<UP>',
check: {
input: 'tsdate 2001-01-02',

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

@ -15,54 +15,18 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testExec.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_exec.js");
}
// <INJECTED SOURCE:END>
// var assert = require('../testharness/assert');
// var helpers = require('./helpers');
var nodetype = require('gcli/types/node');
var mockBody = {
style: {}
};
var mockEmptyNodeList = {
length: 0,
item: function() { return null; }
};
var mockRootNodeList = {
length: 1,
item: function(i) { return mockBody; }
};
var mockDoc = {
querySelectorAll: function(css) {
return (css === ':root') ? mockRootNodeList : mockEmptyNodeList;
}
};
exports.testParamGroup = function(options) {
var tsg = options.requisition.system.commands.get('tsg');
@ -121,7 +85,7 @@ exports.testWithHelpers = function(options) {
}
},
exec: {
output: 'Exec: tsv optionType=string, optionValue=10'
output: 'Exec: tsv optionType=option1 optionValue=10'
}
},
{
@ -151,7 +115,7 @@ exports.testWithHelpers = function(options) {
}
},
exec: {
output: 'Exec: tsv optionType=number, optionValue=10'
output: 'Exec: tsv optionType=option2 optionValue=10'
}
},
// Delegated remote types can't transfer value types so we only test for
@ -163,7 +127,7 @@ exports.testWithHelpers = function(options) {
args: { optionValue: { value: '10' } }
},
exec: {
output: 'Exec: tsv optionType=string, optionValue=10'
output: 'Exec: tsv optionType=option1 optionValue=10'
}
},
{
@ -173,7 +137,7 @@ exports.testWithHelpers = function(options) {
args: { optionValue: { value: 10 } }
},
exec: {
output: 'Exec: tsv optionType=number, optionValue=10'
output: 'Exec: tsv optionType=option2 optionValue=10'
}
}
]);
@ -228,7 +192,7 @@ exports.testExecText = function(options) {
}
},
exec: {
output: 'Exec: tsr text=fred bloggs'
output: 'Exec: tsr text=fred\\ bloggs'
}
},
{
@ -253,7 +217,7 @@ exports.testExecText = function(options) {
}
},
exec: {
output: 'Exec: tsr text=fred bloggs'
output: 'Exec: tsr text=fred\\ bloggs'
}
},
{
@ -278,7 +242,7 @@ exports.testExecText = function(options) {
}
},
exec: {
output: 'Exec: tsr text=fred bloggs'
output: 'Exec: tsr text=fred\\ bloggs'
}
}
]);
@ -403,7 +367,6 @@ exports.testExecScript = function(options) {
args: {
command: { name: 'tsj' },
javascript: {
value: '1 + 1',
arg: ' { 1 + 1 }',
status: 'VALID',
message: ''
@ -418,12 +381,9 @@ exports.testExecScript = function(options) {
};
exports.testExecNode = function(options) {
var origDoc = nodetype.getDocument();
nodetype.setDocument(mockDoc);
return helpers.audit(options, [
{
skipIf: options.isNoDom,
skipIf: options.isRemote,
setup: 'tse :root',
check: {
input: 'tse :root',
@ -437,19 +397,16 @@ exports.testExecNode = function(options) {
args: {
command: { name: 'tse' },
node: {
value: mockBody,
arg: ' :root',
status: 'VALID',
message: ''
},
nodes: {
value: mockEmptyNodeList,
arg: '',
status: 'VALID',
message: ''
},
nodes2: {
value: mockEmptyNodeList,
arg: '',
status: 'VALID',
message: ''
@ -459,8 +416,10 @@ exports.testExecNode = function(options) {
exec: {
output: /^Exec: tse/
},
post: function() {
nodetype.setDocument(origDoc);
post: function(output) {
assert.is(output.data.args.node, ':root', 'node should be :root');
assert.is(output.data.args.nodes, 'Error', 'nodes should be Error');
assert.is(output.data.args.nodes2, 'Error', 'nodes2 should be Error');
}
}
]);
@ -552,7 +511,7 @@ exports.testExecArray = function(options) {
}
},
exec: {
output: 'Exec: tselarr num=1, arr='
output: 'Exec: tselarr num=1 arr='
}
},
{
@ -573,7 +532,7 @@ exports.testExecArray = function(options) {
}
},
exec: {
output: 'Exec: tselarr num=1, arr=a'
output: 'Exec: tselarr num=1 arr=a'
}
},
{
@ -594,7 +553,7 @@ exports.testExecArray = function(options) {
}
},
exec: {
output: 'Exec: tselarr num=1, arr=a,b'
output: 'Exec: tselarr num=1 arr=a b'
}
}
]);
@ -621,7 +580,7 @@ exports.testExecMultiple = function(options) {
}
},
exec: {
output: 'Exec: tsm abc=a, txt=10, num=10'
output: 'Exec: tsm abc=a txt=10 num=10'
}
}
]);
@ -651,9 +610,47 @@ exports.testExecDefaults = function(options) {
}
},
exec: {
output: 'Exec: tsg solo=aaa, txt1=null, bool=false, txt2=d, num=42'
output: 'Exec: tsg solo=aaa txt1= bool=false txt2=d num=42'
}
}
]);
};
exports.testNested = function(options) {
var commands = options.requisition.system.commands;
commands.add({
name: 'nestorama',
exec: function(args, context) {
return context.updateExec('tsb').then(function(tsbOutput) {
return context.updateExec('tsu 6').then(function(tsuOutput) {
return JSON.stringify({
tsb: tsbOutput.data,
tsu: tsuOutput.data
});
});
});
}
});
return helpers.audit(options, [
{
setup: 'nestorama',
exec: {
output:
'{' +
'"tsb":{' +
'"name":"tsb",' +
'"args":{"toggle":"false"}' +
'},' +
'"tsu":{' +
'"name":"tsu",' +
'"args":{"num":"6"}' +
'}' +
'}'
},
post: function() {
commands.remove('nestorama');
}
}
]);
};

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

@ -15,31 +15,16 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testFail.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_fail.js");
}
// <INJECTED SOURCE:END>
// var helpers = require('./helpers');
exports.testBasic = function(options) {

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

@ -15,31 +15,16 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testFile.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_file.js");
}
// <INJECTED SOURCE:END>
// var helpers = require('./helpers');
var local = false;
@ -47,10 +32,7 @@ var local = false;
exports.testBasic = function(options) {
return helpers.audit(options, [
{
// These tests require us to be using node directly or to be in
// PhantomJS connected to an execute enabled node server or to be in
// firefox.
skipRemainingIf: options.isPhantomjs || options.isFirefox,
skipRemainingIf: options.isFirefox, // No file implementation in Firefox
setup: 'tsfile open /',
check: {
input: 'tsfile open /',

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

@ -15,31 +15,16 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testFileparser.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_fileparser.js");
}
// <INJECTED SOURCE:END>
// var assert = require('../testharness/assert');
var fileparser = require('gcli/util/fileparser');

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

@ -15,31 +15,16 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testFilesystem.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_filesystem.js");
}
// <INJECTED SOURCE:END>
// var assert = require('../testharness/assert');
// var helpers = require('./helpers');
var filesystem = require('gcli/util/filesystem');

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

@ -15,31 +15,16 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testFocus.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_focus.js");
}
// <INJECTED SOURCE:END>
// var helpers = require('./helpers');
exports.testBasic = function(options) {

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

@ -15,31 +15,16 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testHistory.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_history.js");
}
// <INJECTED SOURCE:END>
// var assert = require('../testharness/assert');
var History = require('gcli/ui/history').History;

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

@ -15,31 +15,16 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testIncomplete.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_incomplete.js");
}
// <INJECTED SOURCE:END>
// var assert = require('../testharness/assert');
// var helpers = require('./helpers');

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

@ -15,31 +15,16 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testInputter.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_inputter.js");
}
// <INJECTED SOURCE:END>
// var assert = require('../testharness/assert');
var KeyEvent = require('gcli/util/util').KeyEvent;
@ -89,7 +74,7 @@ exports.testOutput = function(options) {
var ev1 = { keyCode: KeyEvent.DOM_VK_RETURN };
return terminal.handleKeyUp(ev1).then(function() {
assert.ok(latestEvent != null, 'events this test');
assert.is(latestData, 'Exec: tss ', 'last command is tss');
assert.is(latestData.name, 'tss', 'last command is tss');
assert.is(terminal.getInputState().typed,
'',

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

@ -15,31 +15,16 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testIntro.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_intro.js");
}
// <INJECTED SOURCE:END>
// var helpers = require('./helpers');
exports.testIntroStatus = function(options) {
@ -67,7 +52,6 @@ exports.testIntroStatus = function(options) {
},
{
setup: 'intro',
skipIf: options.isNoDom,
check: {
typed: 'intro',
markup: 'VVVVV',

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

@ -15,73 +15,55 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testJs.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_js.js");
}
// <INJECTED SOURCE:END>
// var assert = require('../testharness/assert');
// var helpers = require('./helpers');
var javascript = require('gcli/types/javascript');
var tempWindow;
exports.setup = function(options) {
if (options.isNoDom) {
if (jsTestDisallowed(options)) {
return;
}
tempWindow = javascript.getGlobalObject();
Object.defineProperty(options.window, 'donteval', {
// Check that we're not trespassing on 'donteval'
var win = options.requisition.environment.window;
Object.defineProperty(win, 'donteval', {
get: function() {
assert.ok(false, 'donteval should not be used');
console.trace();
return { cant: '', touch: '', 'this': '' };
},
enumerable: true,
configurable : true
configurable: true
});
javascript.setGlobalObject(options.window);
};
exports.shutdown = function(options) {
if (options.isNoDom) {
if (jsTestDisallowed(options)) {
return;
}
javascript.setGlobalObject(tempWindow);
tempWindow = undefined;
delete options.window.donteval;
delete options.requisition.environment.window.donteval;
};
function jsTestAllowed(options) {
return options.isRemote || options.isNoDom ||
function jsTestDisallowed(options) {
return options.isRemote || // Altering the environment (which isn't remoted)
options.isNode ||
options.requisition.system.commands.get('{') == null;
}
exports.testBasic = function(options) {
return helpers.audit(options, [
{
skipRemainingIf: jsTestAllowed,
skipRemainingIf: jsTestDisallowed,
setup: '{',
check: {
input: '{',
@ -236,7 +218,7 @@ exports.testBasic = function(options) {
exports.testDocument = function(options) {
return helpers.audit(options, [
{
skipRemainingIf: jsTestAllowed,
skipRemainingIf: jsTestDisallowed,
setup: '{ docu',
check: {
input: '{ docu',
@ -315,7 +297,8 @@ exports.testDocument = function(options) {
command: { name: '{' },
javascript: {
value: 'document.title',
arg: '{ document.title ',
// arg: '{ document.title ',
// Node/JSDom gets this wrong and omits the trailing space. Why?
status: 'VALID',
message: ''
}
@ -348,14 +331,9 @@ exports.testDocument = function(options) {
};
exports.testDonteval = function(options) {
if (!options.isNoDom) {
// nodom causes an eval here, maybe that's node/v8?
assert.ok('donteval' in options.window, 'donteval exists');
}
return helpers.audit(options, [
{
skipRemainingIf: jsTestAllowed,
skipRemainingIf: true, // Commented out until we fix non-enumerable props
setup: '{ don',
check: {
input: '{ don',
@ -476,7 +454,7 @@ exports.testDonteval = function(options) {
exports.testExec = function(options) {
return helpers.audit(options, [
{
skipRemainingIf: jsTestAllowed,
skipRemainingIf: jsTestDisallowed,
setup: '{ 1+1',
check: {
input: '{ 1+1',

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

@ -15,46 +15,19 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testKeyboard1.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_keyboard1.js");
}
// <INJECTED SOURCE:END>
var javascript = require('gcli/types/javascript');
// var helpers = require('./helpers');
var tempWindow;
exports.setup = function(options) {
tempWindow = javascript.getGlobalObject();
javascript.setGlobalObject(options.window);
};
exports.shutdown = function(options) {
javascript.setGlobalObject(tempWindow);
tempWindow = undefined;
};
exports.testSimple = function(options) {
return helpers.audit(options, [
{
@ -75,16 +48,12 @@ exports.testSimple = function(options) {
exports.testScript = function(options) {
return helpers.audit(options, [
{
skipIf: function commandJsMissing() {
return options.requisition.system.commands.get('{') == null;
},
skipRemainingIf: options.isRemote ||
options.requisition.system.commands.get('{') == null,
setup: '{ wind<TAB>',
check: { input: '{ window' }
},
{
skipIf: function commandJsMissing() {
return options.requisition.system.commands.get('{') == null;
},
setup: '{ window.docum<TAB>',
check: { input: '{ window.document' }
}
@ -94,9 +63,8 @@ exports.testScript = function(options) {
exports.testJsdom = function(options) {
return helpers.audit(options, [
{
skipIf: function jsDomOrCommandJsMissing() {
return options.requisition.system.commands.get('{') == null;
},
skipIf: options.isRemote ||
options.requisition.system.commands.get('{') == null,
setup: '{ window.document.titl<TAB>',
check: { input: '{ window.document.title ' }
}

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

@ -15,31 +15,16 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testKeyboard2.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_keyboard2.js");
}
// <INJECTED SOURCE:END>
// var helpers = require('./helpers');
exports.testIncr = function(options) {

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

@ -15,31 +15,16 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testKeyboard3.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_keyboard3.js");
}
// <INJECTED SOURCE:END>
// var helpers = require('./helpers');
exports.testDecr = function(options) {

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

@ -15,31 +15,16 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testKeyboard4.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_keyboard4.js");
}
// <INJECTED SOURCE:END>
// var helpers = require('./helpers');
exports.testIncrFloat = function(options) {

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

@ -15,31 +15,16 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testKeyboard5.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_keyboard5.js");
}
// <INJECTED SOURCE:END>
// var helpers = require('./helpers');
exports.testCompleteDown = function(options) {

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

@ -15,31 +15,16 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testKeyboard6.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_keyboard6.js");
}
// <INJECTED SOURCE:END>
// var helpers = require('./helpers');
exports.testCompleteUp = function(options) {

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

@ -15,31 +15,16 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testMenu.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_menu.js");
}
// <INJECTED SOURCE:END>
// var helpers = require('./helpers');
exports.testOptions = function(options) {

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

@ -15,49 +15,22 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testNode.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_node.js");
}
// <INJECTED SOURCE:END>
// var assert = require('../testharness/assert');
// var helpers = require('./helpers');
var nodetype = require('gcli/types/node');
exports.setup = function(options) {
if (options.window) {
nodetype.setDocument(options.window.document);
}
};
exports.shutdown = function(options) {
nodetype.unsetDocument();
};
exports.testNode = function(options) {
return helpers.audit(options, [
{
skipRemainingIf: options.isNoDom,
setup: 'tse ',
check: {
input: 'tse ',
@ -165,11 +138,8 @@ exports.testNode = function(options) {
};
exports.testNodeDom = function(options) {
var requisition = options.requisition;
return helpers.audit(options, [
{
skipRemainingIf: options.isNoDom,
setup: 'tse :root',
check: {
input: 'tse :root',
@ -202,10 +172,12 @@ exports.testNodeDom = function(options) {
nodes2: { status: 'VALID' }
}
},
post: function() {
assert.is(requisition.getAssignment('node').value.tagName,
'HTML',
'root id');
exec: {
},
post: function(output) {
if (!options.isRemote) {
assert.is(output.args.node.tagName, 'HTML', ':root tagName');
}
}
},
{
@ -234,11 +206,8 @@ exports.testNodeDom = function(options) {
};
exports.testNodes = function(options) {
var requisition = options.requisition;
return helpers.audit(options, [
{
skipRemainingIf: options.isNoDom,
setup: 'tse :root --nodes *',
check: {
input: 'tse :root --nodes *',
@ -253,10 +222,18 @@ exports.testNodes = function(options) {
nodes2: { status: 'VALID' }
}
},
post: function() {
assert.is(requisition.getAssignment('node').value.tagName,
'HTML',
'#gcli-input id');
exec: {
},
post: function(output) {
if (!options.isRemote) {
assert.is(output.args.node.tagName, 'HTML', ':root tagName');
assert.ok(output.args.nodes.length > 3, 'nodes length');
assert.is(output.args.nodes2.length, 0, 'nodes2 length');
}
assert.is(output.data.args.node, ':root', 'node data');
assert.is(output.data.args.nodes, '*', 'nodes data');
assert.is(output.data.args.nodes2, 'Error', 'nodes2 data');
}
},
{
@ -275,10 +252,18 @@ exports.testNodes = function(options) {
nodes2: { arg: ' --nodes2 div', status: 'VALID' }
}
},
post: function() {
assert.is(requisition.getAssignment('node').value.tagName,
'HTML',
'root id');
exec: {
},
post: function(output) {
if (!options.isRemote) {
assert.is(output.args.node.tagName, 'HTML', ':root tagName');
assert.is(output.args.nodes.length, 0, 'nodes length');
assert.is(output.args.nodes2.item(0).tagName, 'DIV', 'div tagName');
}
assert.is(output.data.args.node, ':root', 'node data');
assert.is(output.data.args.nodes, 'Error', 'nodes data');
assert.is(output.data.args.nodes2, 'div', 'nodes2 data');
}
},
{
@ -305,13 +290,6 @@ exports.testNodes = function(options) {
},
nodes2: { arg: '', status: 'VALID', message: '' }
}
},
post: function() {
/*
assert.is(requisition.getAssignment('nodes2').value.constructor.name,
'NodeList',
'#gcli-input id');
*/
}
},
{
@ -333,16 +311,6 @@ exports.testNodes = function(options) {
nodes: { arg: '', status: 'VALID', message: '' },
nodes2: { arg: ' --nodes2 ffff', status: 'VALID', message: '' }
}
},
post: function() {
/*
assert.is(requisition.getAssignment('nodes').value.constructor.name,
'NodeList',
'#gcli-input id');
assert.is(requisition.getAssignment('nodes2').value.constructor.name,
'NodeList',
'#gcli-input id');
*/
}
},
]);

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

@ -15,31 +15,16 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testPref1.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_pref1.js");
}
// <INJECTED SOURCE:END>
// var helpers = require('./helpers');
exports.testPrefShowStatus = function(options) {
@ -67,7 +52,7 @@ exports.testPrefShowStatus = function(options) {
setup: 'pref show ',
check: {
typed: 'pref show ',
hints: 'allowSet',
hints: 'eagerHelper',
markup: 'VVVVVVVVVV',
status: 'ERROR'
}
@ -144,7 +129,7 @@ exports.testPrefSetStatus = function(options) {
setup: 'pref set ',
check: {
typed: 'pref set ',
hints: 'allowSet <value>',
hints: 'eagerHelper <value>',
markup: 'VVVVVVVVV',
status: 'ERROR'
}
@ -159,6 +144,7 @@ exports.testPrefSetStatus = function(options) {
}
},
{
skipIf: options.isRemote,
setup: 'pref set tempTBool 4',
check: {
typed: 'pref set tempTBool 4',

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

@ -15,31 +15,16 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testPref2.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_pref2.js");
}
// <INJECTED SOURCE:END>
// var assert = require('../testharness/assert');
// var helpers = require('./helpers');
var mockSettings = require('./mockSettings');
@ -55,10 +40,6 @@ exports.testPrefExec = function(options) {
return;
}
var allowSet = settings.getSetting('allowSet');
var initialAllowSet = allowSet.value;
allowSet.value = false;
assert.is(mockSettings.tempNumber.value, 42, 'set to 42');
return helpers.audit(options, [
@ -73,7 +54,6 @@ exports.testPrefExec = function(options) {
}
},
{
skipRemainingIf: options.isNoDom,
setup: 'pref set tempNumber 4',
check: {
input: 'pref set tempNumber 4',
@ -98,16 +78,6 @@ exports.testPrefExec = function(options) {
}
}
},
exec: {
output: [ /void your warranty/, /I promise/ ]
},
post: function() {
assert.is(mockSettings.tempNumber.value, 42, 'still set to 42');
allowSet.value = true;
}
},
{
setup: 'pref set tempNumber 4',
exec: {
output: ''
},
@ -128,8 +98,6 @@ exports.testPrefExec = function(options) {
},
post: function() {
assert.is(mockSettings.tempNumber.value, 42, 'reset to 42');
allowSet.value = initialAllowSet;
}
},
{

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

@ -15,31 +15,16 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testRemoteWs.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_remotews.js");
}
// <INJECTED SOURCE:END>
// var assert = require('../testharness/assert');
// var helpers = require('./helpers');
@ -83,8 +68,8 @@ exports.testRemoteWebsocket = function(options) {
check: {
args: {
prefix: {
value: function(connection) {
assert.is(connection.prefix, 'remote', 'disconnecting remote');
value: function(front) {
assert.is(front.prefix, 'remote', 'disconnecting remote');
}
}
}
@ -112,8 +97,8 @@ exports.testRemoteWebsocket = function(options) {
check: {
args: {
prefix: {
value: function(connection) {
assert.is(connection.prefix, 'remote', 'disconnecting remote');
value: function(front) {
assert.is(front.prefix, 'remote', 'disconnecting remote');
}
}
}
@ -466,8 +451,8 @@ exports.testRemoteWebsocket = function(options) {
unassigned: [ ],
args: {
prefix: {
value: function(connection) {
assert.is(connection.prefix, 'remote', 'disconnecting remote');
value: function(front) {
assert.is(front.prefix, 'remote', 'disconnecting remote');
},
arg: ' remote',
status: 'VALID',

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

@ -15,31 +15,16 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testRemoteXhr.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_remotexhr.js");
}
// <INJECTED SOURCE:END>
// var assert = require('../testharness/assert');
// var helpers = require('./helpers');
@ -83,8 +68,8 @@ exports.testRemoteXhr = function(options) {
check: {
args: {
prefix: {
value: function(connection) {
assert.is(connection.prefix, 'remote', 'disconnecting remote');
value: function(front) {
assert.is(front.prefix, 'remote', 'disconnecting remote');
}
}
}
@ -112,8 +97,8 @@ exports.testRemoteXhr = function(options) {
check: {
args: {
prefix: {
value: function(connection) {
assert.is(connection.prefix, 'remote', 'disconnecting remote');
value: function(front) {
assert.is(front.prefix, 'remote', 'disconnecting remote');
}
}
}
@ -466,8 +451,8 @@ exports.testRemoteXhr = function(options) {
unassigned: [ ],
args: {
prefix: {
value: function(connection) {
assert.is(connection.prefix, 'remote', 'disconnecting remote');
value: function(front) {
assert.is(front.prefix, 'remote', 'disconnecting remote');
},
arg: ' remote',
status: 'VALID',

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

@ -15,31 +15,17 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testResource.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_resource.js");
}
// <INJECTED SOURCE:END>
// var helpers = require('./helpers');
// var assert = require('../testharness/assert');
var Promise = require('gcli/util/promise').Promise;
@ -47,84 +33,85 @@ var util = require('gcli/util/util');
var resource = require('gcli/types/resource');
var Status = require('gcli/types/types').Status;
var tempDocument;
exports.setup = function(options) {
tempDocument = resource.getDocument();
if (options.window) {
resource.setDocument(options.window.document);
}
};
exports.shutdown = function(options) {
resource.setDocument(tempDocument);
tempDocument = undefined;
exports.testCommand = function(options) {
return helpers.audit(options, [
{
setup: 'tsres ',
check: {
predictionsContains: [ 'inline-css' ],
}
}
]);
};
exports.testAllPredictions1 = function(options) {
if (options.isFirefox || options.isNoDom) {
assert.log('Skipping checks due to firefox document.stylsheets support.');
if (options.isRemote) {
assert.log('Can\'t directly test remote types locally.');
return;
}
var context = options.requisition.conversionContext;
var resource = options.requisition.system.types.createType('resource');
return resource.getLookup().then(function(opts) {
return resource.getLookup(context).then(function(opts) {
assert.ok(opts.length > 1, 'have all resources');
return util.promiseEach(opts, function(prediction) {
return checkPrediction(resource, prediction);
return checkPrediction(resource, prediction, context);
});
});
};
exports.testScriptPredictions = function(options) {
if (options.isFirefox || options.isNoDom) {
assert.log('Skipping checks due to firefox document.stylsheets support.');
if (options.isRemote || options.isNode) {
assert.log('Can\'t directly test remote types locally.');
return;
}
var context = options.requisition.conversionContext;
var types = options.requisition.system.types;
var resource = types.createType({ name: 'resource', include: 'text/javascript' });
return resource.getLookup().then(function(opts) {
return resource.getLookup(context).then(function(opts) {
assert.ok(opts.length > 1, 'have js resources');
return util.promiseEach(opts, function(prediction) {
return checkPrediction(resource, prediction);
return checkPrediction(resource, prediction, context);
});
});
};
exports.testStylePredictions = function(options) {
if (options.isFirefox || options.isNoDom) {
assert.log('Skipping checks due to firefox document.stylsheets support.');
if (options.isRemote) {
assert.log('Can\'t directly test remote types locally.');
return;
}
var context = options.requisition.conversionContext;
var types = options.requisition.system.types;
var resource = types.createType({ name: 'resource', include: 'text/css' });
return resource.getLookup().then(function(opts) {
return resource.getLookup(context).then(function(opts) {
assert.ok(opts.length >= 1, 'have css resources');
return util.promiseEach(opts, function(prediction) {
return checkPrediction(resource, prediction);
return checkPrediction(resource, prediction, context);
});
});
};
exports.testAllPredictions2 = function(options) {
if (options.isNoDom) {
assert.log('Skipping checks due to nodom document.stylsheets support.');
if (options.isRemote) {
assert.log('Can\'t directly test remote types locally.');
return;
}
var context = options.requisition.conversionContext;
var types = options.requisition.system.types;
var scriptRes = types.createType({ name: 'resource', include: 'text/javascript' });
return scriptRes.getLookup().then(function(scriptOptions) {
return scriptRes.getLookup(context).then(function(scriptOptions) {
var styleRes = types.createType({ name: 'resource', include: 'text/css' });
return styleRes.getLookup().then(function(styleOptions) {
return styleRes.getLookup(context).then(function(styleOptions) {
var allRes = types.createType({ name: 'resource' });
return allRes.getLookup().then(function(allOptions) {
return allRes.getLookup(context).then(function(allOptions) {
assert.is(scriptOptions.length + styleOptions.length,
allOptions.length,
'split');
@ -134,27 +121,26 @@ exports.testAllPredictions2 = function(options) {
};
exports.testAllPredictions3 = function(options) {
if (options.isNoDom) {
assert.log('Skipping checks due to nodom document.stylsheets support.');
if (options.isRemote) {
assert.log('Can\'t directly test remote types locally.');
return;
}
var context = options.requisition.conversionContext;
var types = options.requisition.system.types;
var res1 = types.createType({ name: 'resource' });
return res1.getLookup().then(function(options1) {
return res1.getLookup(context).then(function(options1) {
var res2 = types.createType('resource');
return res2.getLookup().then(function(options2) {
return res2.getLookup(context).then(function(options2) {
assert.is(options1.length, options2.length, 'type spec');
});
});
};
function checkPrediction(res, prediction) {
function checkPrediction(res, prediction, context) {
var name = prediction.name;
var value = prediction.value;
// resources don't need context so cheat and pass in null
var context = null;
return res.parseString(name, context).then(function(conversion) {
assert.is(conversion.getStatus(), Status.VALID, 'status VALID for ' + name);
assert.is(conversion.value, value, 'value for ' + name);

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

@ -15,31 +15,16 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testShort.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_short.js");
}
// <INJECTED SOURCE:END>
// var helpers = require('./helpers');
exports.testBasic = function(options) {

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

@ -14,31 +14,16 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testSpell.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_spell.js");
}
// <INJECTED SOURCE:END>
// var assert = require('../testharness/assert');
var spell = require('gcli/util/spell');

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

@ -15,31 +15,16 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testSplit.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_split.js");
}
// <INJECTED SOURCE:END>
// var assert = require('../testharness/assert');
var cli = require('gcli/cli');

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

@ -15,31 +15,16 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testString.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_string.js");
}
// <INJECTED SOURCE:END>
// var helpers = require('./helpers');
exports.testNewLine = function(options) {

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

@ -15,31 +15,16 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testTokenize.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_tokenize.js");
}
// <INJECTED SOURCE:END>
// var assert = require('../testharness/assert');
var cli = require('gcli/cli');

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

@ -15,40 +15,20 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testTooltip.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_tooltip.js");
}
// <INJECTED SOURCE:END>
// var assert = require('../testharness/assert');
// var helpers = require('./helpers');
exports.testActivate = function(options) {
if (!options.display) {
assert.log('No display. Skipping activate tests');
return;
}
return helpers.audit(options, [
{
setup: ' ',

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

@ -15,49 +15,25 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testTypes.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_types.js");
}
// <INJECTED SOURCE:END>
// var assert = require('../testharness/assert');
var util = require('gcli/util/util');
var Promise = require('gcli/util/promise').Promise;
var nodetype = require('gcli/types/node');
exports.setup = function(options) {
if (options.window) {
nodetype.setDocument(options.window.document);
}
};
exports.shutdown = function(options) {
nodetype.unsetDocument();
};
function forEachType(options, typeSpec, callback) {
function forEachType(options, templateTypeSpec, callback) {
var types = options.requisition.system.types;
return util.promiseEach(types.getTypeNames(), function(name) {
var typeSpec = {};
util.copyProperties(templateTypeSpec, typeSpec);
typeSpec.name = name;
typeSpec.requisition = options.requisition;
@ -79,29 +55,19 @@ function forEachType(options, typeSpec, callback) {
else if (name === 'union') {
typeSpec.alternatives = [{ name: 'string' }];
}
else if (options.isRemote) {
if (name === 'node' || name === 'nodelist') {
return;
}
}
var type = types.createType(typeSpec);
var reply = callback(type);
return Promise.resolve(reply).then(function(value) {
// Clean up
delete typeSpec.name;
delete typeSpec.requisition;
delete typeSpec.data;
delete typeSpec.delegateType;
delete typeSpec.subtype;
delete typeSpec.alternatives;
return value;
});
return Promise.resolve(reply);
});
}
exports.testDefault = function(options) {
if (options.isNoDom) {
assert.log('Skipping tests due to issues with resource type.');
return;
}
return forEachType(options, {}, function(type) {
var context = options.requisition.executionContext;
var blank = type.getBlank(context).value;

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

@ -15,31 +15,16 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testUnion.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_union.js");
}
// <INJECTED SOURCE:END>
// var assert = require('../testharness/assert');
// var helpers = require('./helpers');
@ -126,7 +111,7 @@ exports.testDefault = function(options) {
}
},
{
skipIf: options.isPhantomjs, // Phantom goes weird with predictions
skipIf: options.isPhantomjs, // PhantomJS gets predictions wrong
setup: 'unionc1 5',
check: {
input: 'unionc1 5',
@ -160,7 +145,7 @@ exports.testDefault = function(options) {
}
},
{
skipRemainingIf: options.isPhantomjs,
skipIf: options.isPhantomjs, // PhantomJS URL type is broken
setup: 'unionc2 on',
check: {
input: 'unionc2 on',

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

@ -15,38 +15,23 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var exports = {};
var TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testUrl.js</p>";
const exports = {};
function test() {
return Task.spawn(function() {
let options = yield helpers.openTab(TEST_URI);
yield helpers.openToolbar(options);
gcli.addItems(mockCommands.items);
yield helpers.runTests(options, exports);
gcli.removeItems(mockCommands.items);
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
helpers.runTestModule(exports, "browser_gcli_url.js");
}
// <INJECTED SOURCE:END>
// var assert = require('../testharness/assert');
// var helpers = require('./helpers');
exports.testDefault = function(options) {
return helpers.audit(options, [
{
skipRemainingIf: options.isPhantomjs,
skipRemainingIf: options.isPhantomjs, // PhantomJS URL type is broken
setup: 'urlc',
check: {
input: 'urlc',

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

@ -18,7 +18,7 @@
// A copy of this code exists in firefox mochitests. They should be kept
// in sync. Hence the exports synonym for non AMD contexts.
var { helpers, gcli, assert } = (function() {
var { helpers, assert } = (function() {
var helpers = {};
@ -30,23 +30,24 @@ var util = require('gcli/util/util');
var Promise = require('gcli/util/promise').Promise;
var cli = require('gcli/cli');
var KeyEvent = require('gcli/util/util').KeyEvent;
var gcli = require('gcli/index');
const { GcliFront } = require("devtools/server/actors/gcli");
/**
* See notes in helpers.checkOptions()
*/
var createFFDisplayAutomator = function(display) {
var createDeveloperToolbarAutomator = function(toolbar) {
var automator = {
setInput: function(typed) {
return display.inputter.setInput(typed);
return toolbar.inputter.setInput(typed);
},
setCursor: function(cursor) {
return display.inputter.setCursor(cursor);
return toolbar.inputter.setCursor(cursor);
},
focus: function() {
return display.inputter.focus();
return toolbar.inputter.focus();
},
fakeKey: function(keyCode) {
@ -56,36 +57,36 @@ var createFFDisplayAutomator = function(display) {
timeStamp: new Date().getTime()
};
display.inputter.onKeyDown(fakeEvent);
toolbar.inputter.onKeyDown(fakeEvent);
if (keyCode === KeyEvent.DOM_VK_BACK_SPACE) {
var input = display.inputter.element;
var input = toolbar.inputter.element;
input.value = input.value.slice(0, -1);
}
return display.inputter.handleKeyUp(fakeEvent);
return toolbar.inputter.handleKeyUp(fakeEvent);
},
getInputState: function() {
return display.inputter.getInputState();
return toolbar.inputter.getInputState();
},
getCompleterTemplateData: function() {
return display.completer._getCompleterTemplateData();
return toolbar.completer._getCompleterTemplateData();
},
getErrorMessage: function() {
return display.tooltip.errorEle.textContent;
return toolbar.tooltip.errorEle.textContent;
}
};
Object.defineProperty(automator, 'focusManager', {
get: function() { return display.focusManager; },
get: function() { return toolbar.focusManager; },
enumerable: true
});
Object.defineProperty(automator, 'field', {
get: function() { return display.tooltip.field; },
get: function() { return toolbar.tooltip.field; },
enumerable: true
});
@ -223,9 +224,9 @@ helpers.openToolbar = function(options) {
options.chromeWindow = options.chromeWindow || window;
return options.chromeWindow.DeveloperToolbar.show(true).then(function() {
var display = options.chromeWindow.DeveloperToolbar.display;
options.automator = createFFDisplayAutomator(display);
options.requisition = display.requisition;
var toolbar = options.chromeWindow.DeveloperToolbar;
options.automator = createDeveloperToolbarAutomator(toolbar);
options.requisition = toolbar.requisition;
return options;
});
};
@ -331,17 +332,17 @@ helpers.promiseify = function(functionWithLastParamCallback, scope) {
* Warning: For use with Firefox Mochitests only.
*
* As addTab, but that also opens the developer toolbar. In addition a new
* 'automator' property is added to the options object with the display from GCLI
* in the developer toolbar
* 'automator' property is added to the options object which uses the
* developer toolbar
*/
helpers.addTabWithToolbar = function(url, callback, options) {
return helpers.addTab(url, function(innerOptions) {
var win = innerOptions.chromeWindow;
return win.DeveloperToolbar.show(true).then(function() {
var display = win.DeveloperToolbar.display;
innerOptions.automator = createFFDisplayAutomator(display);
innerOptions.requisition = display.requisition;
var toolbar = win.DeveloperToolbar;
innerOptions.automator = createDeveloperToolbarAutomator(toolbar);
innerOptions.requisition = toolbar.requisition;
var reply = callback.call(null, innerOptions);
@ -376,7 +377,7 @@ helpers.runTests = function(options, tests) {
var recover = function(error) {
ok(false, error);
console.error(error);
console.error(error, error.stack);
};
info("SETUP");
@ -410,6 +411,87 @@ helpers.runTests = function(options, tests) {
}, recover);
};
const MOCK_COMMANDS_URI = "chrome://mochitests/content/browser/browser/devtools/commandline/test/mockCommands.js";
const defer = function() {
const deferred = { };
deferred.promise = new Promise(function(resolve, reject) {
deferred.resolve = resolve;
deferred.reject = reject;
});
return deferred;
};
/**
* This does several actions associated with running a GCLI test in mochitest
* 1. Create a new tab containing basic markup for GCLI tests
* 2. Open the developer toolbar
* 3. Register the mock commands with the server process
* 4. Wait for the proxy commands to be auto-regitstered with the client
* 5. Register the mock converters with the client process
* 6. Run all the tests
* 7. Tear down all the setup
*/
helpers.runTestModule = function(exports, name) {
return Task.spawn(function*() {
const uri = "data:text/html;charset=utf-8," +
"<style>div{color:red;}</style>" +
"<div id='gcli-root'>" + name + "</div>";
const options = yield helpers.openTab(uri);
options.isRemote = true;
yield helpers.openToolbar(options);
const system = options.requisition.system;
// Register a one time listener with the local set of commands
const addedDeferred = defer();
const removedDeferred = defer();
let state = 'preAdd'; // Then 'postAdd' then 'postRemove'
system.commands.onCommandsChange.add(function(ev) {
if (system.commands.get('tsslow') != null) {
if (state === 'preAdd') {
addedDeferred.resolve();
state = 'postAdd';
}
}
else {
if (state === 'postAdd') {
removedDeferred.resolve();
state = 'postRemove';
}
}
});
// Send a message to add the commands to the content process
const front = yield GcliFront.create(options.target);
yield front._testOnly_addItemsByModule(MOCK_COMMANDS_URI);
// This will cause the local set of commands to be updated with the
// command proxies, wait for that to complete.
yield addedDeferred.promise;
// Now we need to add the converters to the local GCLI
const converters = mockCommands.items.filter(item => item.item === 'converter');
system.addItems(converters);
// Next run the tests
yield helpers.runTests(options, exports);
// Finally undo the mock commands and converters
system.removeItems(converters);
const removePromise = system.commands.onCommandsChange.once();
yield front._testOnly_removeItemsByModule(MOCK_COMMANDS_URI);
yield removedDeferred.promise;
// And close everything down
yield helpers.closeToolbar(options);
yield helpers.closeTab(options);
}).then(finish, helpers.handleError);
};
///////////////////////////////////////////////////////////////////////////////
/**
@ -759,15 +841,15 @@ helpers._check = function(options, name, checks) {
var outstanding = [];
var suffix = name ? ' (for \'' + name + '\')' : '';
if (!options.isNoDom && 'input' in checks) {
if (!options.isNode && 'input' in checks) {
assert.is(helpers._actual.input(options), checks.input, 'input' + suffix);
}
if (!options.isNoDom && 'cursor' in checks) {
if (!options.isNode && 'cursor' in checks) {
assert.is(helpers._actual.cursor(options), checks.cursor, 'cursor' + suffix);
}
if (!options.isNoDom && 'current' in checks) {
if (!options.isNode && 'current' in checks) {
assert.is(helpers._actual.current(options), checks.current, 'current' + suffix);
}
@ -775,18 +857,18 @@ helpers._check = function(options, name, checks) {
assert.is(helpers._actual.status(options), checks.status, 'status' + suffix);
}
if (!options.isNoDom && 'markup' in checks) {
if (!options.isNode && 'markup' in checks) {
assert.is(helpers._actual.markup(options), checks.markup, 'markup' + suffix);
}
if (!options.isNoDom && 'hints' in checks) {
if (!options.isNode && 'hints' in checks) {
var hintCheck = function(actualHints) {
assert.is(actualHints, checks.hints, 'hints' + suffix);
};
outstanding.push(helpers._actual.hints(options).then(hintCheck));
}
if (!options.isNoDom && 'predictions' in checks) {
if (!options.isNode && 'predictions' in checks) {
var predictionsCheck = function(actualPredictions) {
helpers.arrayIs(actualPredictions,
checks.predictions,
@ -795,12 +877,16 @@ helpers._check = function(options, name, checks) {
outstanding.push(helpers._actual.predictions(options).then(predictionsCheck));
}
if (!options.isNoDom && 'predictionsContains' in checks) {
if (!options.isNode && 'predictionsContains' in checks) {
var containsCheck = function(actualPredictions) {
checks.predictionsContains.forEach(function(prediction) {
var index = actualPredictions.indexOf(prediction);
assert.ok(index !== -1,
'predictionsContains:' + prediction + suffix);
if (index === -1) {
log('Actual predictions (' + actualPredictions.length + '): ' +
actualPredictions.join(', '));
}
});
};
outstanding.push(helpers._actual.predictions(options).then(containsCheck));
@ -813,26 +899,26 @@ helpers._check = function(options, name, checks) {
}
/* TODO: Fix this
if (!options.isNoDom && 'tooltipState' in checks) {
if (!options.isNode && 'tooltipState' in checks) {
assert.is(helpers._actual.tooltipState(options),
checks.tooltipState,
'tooltipState' + suffix);
}
*/
if (!options.isNoDom && 'outputState' in checks) {
if (!options.isNode && 'outputState' in checks) {
assert.is(helpers._actual.outputState(options),
checks.outputState,
'outputState' + suffix);
}
if (!options.isNoDom && 'options' in checks) {
if (!options.isNode && 'options' in checks) {
helpers.arrayIs(helpers._actual.options(options),
checks.options,
'options' + suffix);
}
if (!options.isNoDom && 'error' in checks) {
if (!options.isNode && 'error' in checks) {
assert.is(helpers._actual.message(options), checks.error, 'error' + suffix);
}
@ -894,7 +980,7 @@ helpers._check = function(options, name, checks) {
'arg.' + paramName + '.status' + suffix);
}
if (!options.isNoDom && 'message' in check) {
if (!options.isNode && 'message' in check) {
if (typeof check.message.test === 'function') {
assert.ok(check.message.test(assignment.message),
'arg.' + paramName + '.message' + suffix);
@ -952,12 +1038,12 @@ helpers._exec = function(options, name, expected) {
var context = requisition.conversionContext;
var convertPromise;
if (options.isNoDom) {
if (options.isNode) {
convertPromise = output.convert('string', context);
}
else {
convertPromise = output.convert('dom', context).then(function(node) {
return node.textContent.trim();
return (node == null) ? '' : node.textContent.trim();
});
}
@ -1171,9 +1257,8 @@ helpers.audit = function(options, audits) {
'';
assert.log('Skipped ' + name + ' ' + skipReason);
// Tests need at least one pass, fail or todo. Let's create a dummy pass
// in case there are none.
ok(true, "Each test requires at least one pass, fail or todo so here is a pass.");
// Tests need at least one pass, fail or todo. Create a dummy pass
assert.ok(true, 'Each test requires at least one pass, fail or todo');
return Promise.resolve(undefined);
}
@ -1270,5 +1355,5 @@ function log(message) {
}
}
return { helpers: helpers, gcli: gcli, assert: assert };
return { helpers: helpers, assert: assert };
})();

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

@ -15,16 +15,21 @@
*/
'use strict';
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
// <INJECTED SOURCE:END>
// PLEASE TALK TO SOMEONE IN DEVELOPER TOOLS BEFORE EDITING IT
var Promise = require('gcli/util/promise').Promise;
var mockCommands = {};
var mockCommands;
if (typeof exports !== 'undefined') {
// If we're being loaded via require();
mockCommands = exports;
}
else {
// If we're being loaded via loadScript in mochitest
mockCommands = {};
}
// We use an alias for exports here because this module is used in Firefox
// mochitests where we don't have define/require
@ -41,32 +46,70 @@ mockCommands.shutdown = function(requisition) {
};
function createExec(name) {
return function(args, executionContext) {
var argsOut = Object.keys(args).map(function(key) {
return key + '=' + args[key];
}).join(', ');
return 'Exec: ' + name + ' ' + argsOut;
return function(args, context) {
var promises = [];
Object.keys(args).map(function(argName) {
var value = args[argName];
var type = this.getParameterByName(argName).type;
var promise = Promise.resolve(type.stringify(value, context));
promises.push(promise.then(function(str) {
return { name: argName, value: str };
}.bind(this)));
}.bind(this));
return Promise.all(promises).then(function(data) {
var argValues = {};
data.forEach(function(entry) { argValues[entry.name] = entry.value; });
return context.typedData('testCommandOutput', {
name: name,
args: argValues
});
}.bind(this));
};
}
mockCommands.items = [
{
item: 'converter',
from: 'json',
to: 'string',
exec: function(json, context) {
return JSON.stringify(json, null, ' ');
from: 'testCommandOutput',
to: 'dom',
exec: function(testCommandOutput, context) {
var view = context.createView({
data: testCommandOutput,
html: '' +
'<table>' +
'<thead>' +
'<tr>' +
'<th colspan="3">Exec: ${name}</th>' +
'</tr>' +
'</thead>' +
'<tbody>' +
'<tr foreach="key in ${args}">' +
'<td> ${key}</td>' +
'<td>=</td>' +
'<td>${args[key]}</td>' +
'</tr>' +
'</tbody>' +
'</table>',
options: {
allowEval: true
}
});
return view.toDom(context.document);
}
},
{
item: 'converter',
from: 'json',
to: 'view',
exec: function(json, context) {
var html = JSON.stringify(json, null, '&#160;').replace(/\n/g, '<br/>');
return {
html: '<pre>' + html + '</pre>'
};
from: 'testCommandOutput',
to: 'string',
exec: function(testCommandOutput, context) {
var argsOut = Object.keys(testCommandOutput.args).map(function(key) {
return key + '=' + testCommandOutput.args[key];
}).join(' ');
return 'Exec: ' + testCommandOutput.name + ' ' + argsOut;
}
},
{
@ -508,7 +551,7 @@ mockCommands.items = [
exec: function(args, context) {
if (args.method === 'reject') {
return new Promise(function(resolve, reject) {
setTimeout(function() {
context.environment.window.setTimeout(function() {
reject('rejected promise');
}, 10);
});
@ -516,7 +559,7 @@ mockCommands.items = [
if (args.method === 'rejecttyped') {
return new Promise(function(resolve, reject) {
setTimeout(function() {
context.environment.window.setTimeout(function() {
reject(context.typedData('number', 54));
}, 10);
});
@ -524,7 +567,7 @@ mockCommands.items = [
if (args.method === 'throwinpromise') {
return new Promise(function(resolve, reject) {
setTimeout(function() {
context.environment.window.setTimeout(function() {
resolve('should be lost');
}, 10);
}).then(function() {
@ -655,7 +698,7 @@ mockCommands.items = [
name: 'selection',
data: function(context) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
context.environment.window.setTimeout(function() {
resolve([
'Shalom', 'Namasté', 'Hallo', 'Dydd-da',
'Chào', 'Hej', 'Saluton', 'Sawubona'
@ -738,5 +781,16 @@ mockCommands.items = [
exec: function(args, context) {
return args;
}
},
{
item: 'command',
name: 'tsres',
params: [
{
name: 'resource',
type: 'resource'
}
],
exec: createExec('tsres'),
}
];

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

@ -5,7 +5,7 @@
"use strict";
const { Cc, Ci, Cu } = require("chrome");
const gcli = require("gcli/index");
const l10n = require("gcli/l10n");
loader.lazyImporter(this, "gDevTools", "resource:///modules/devtools/gDevTools.jsm");
@ -67,8 +67,8 @@ function getAllSources(dbg) {
*/
exports.items.push({
name: "break",
description: gcli.lookup("breakDesc"),
manual: gcli.lookup("breakManual")
description: l10n.lookup("breakDesc"),
manual: l10n.lookup("breakManual")
});
/**
@ -76,7 +76,9 @@ exports.items.push({
*/
exports.items.push({
name: "break list",
description: gcli.lookup("breaklistDesc"),
item: "command",
runAt: "client",
description: l10n.lookup("breaklistDesc"),
returnType: "breakpoints",
exec: function(args, context) {
let dbg = getPanel(context, "jsdebugger", { ensureOpened: true });
@ -102,7 +104,7 @@ exports.items.push({
} else {
return context.createView({
html: "<p>${message}</p>",
data: { message: gcli.lookup("breaklistNone") }
data: { message: l10n.lookup("breaklistNone") }
});
}
}
@ -126,7 +128,7 @@ var breakListHtml = "" +
" data-command='break del ${breakpoint.label}'" +
" onclick='${onclick}'" +
" ondblclick='${ondblclick}'>" +
" " + gcli.lookup("breaklistOutRemove") + "</span>" +
" " + l10n.lookup("breaklistOutRemove") + "</span>" +
" </td>" +
" </tr>" +
" </tbody>" +
@ -141,16 +143,18 @@ var MAX_LABEL_LENGTH = 20;
*/
exports.items.push({
name: "break add",
description: gcli.lookup("breakaddDesc"),
manual: gcli.lookup("breakaddManual")
description: l10n.lookup("breakaddDesc"),
manual: l10n.lookup("breakaddManual")
});
/**
* 'break add line' command
*/
exports.items.push({
item: "command",
runAt: "client",
name: "break add line",
description: gcli.lookup("breakaddlineDesc"),
description: l10n.lookup("breakaddlineDesc"),
params: [
{
name: "file",
@ -160,19 +164,19 @@ exports.items.push({
return getAllSources(getPanel(context, "jsdebugger"));
}
},
description: gcli.lookup("breakaddlineFileDesc")
description: l10n.lookup("breakaddlineFileDesc")
},
{
name: "line",
type: { name: "number", min: 1, step: 10 },
description: gcli.lookup("breakaddlineLineDesc")
description: l10n.lookup("breakaddlineLineDesc")
}
],
returnType: "string",
exec: function(args, context) {
let dbg = getPanel(context, "jsdebugger");
if (!dbg) {
return gcli.lookup("debuggerStopped");
return l10n.lookup("debuggerStopped");
}
let deferred = context.defer();
@ -182,9 +186,9 @@ exports.items.push({
let position = { actor: item.value, line: args.line };
dbg.addBreakpoint(position).then(() => {
deferred.resolve(gcli.lookup("breakaddAdded"));
deferred.resolve(l10n.lookup("breakaddAdded"));
}, aError => {
deferred.resolve(gcli.lookupFormat("breakaddFailed", [aError]));
deferred.resolve(l10n.lookupFormat("breakaddFailed", [aError]));
});
return deferred.promise;
@ -195,8 +199,10 @@ exports.items.push({
* 'break del' command
*/
exports.items.push({
item: "command",
runAt: "client",
name: "break del",
description: gcli.lookup("breakdelDesc"),
description: l10n.lookup("breakdelDesc"),
params: [
{
name: "breakpoint",
@ -214,14 +220,14 @@ exports.items.push({
}));
}
},
description: gcli.lookup("breakdelBreakidDesc")
description: l10n.lookup("breakdelBreakidDesc")
}
],
returnType: "string",
exec: function(args, context) {
let dbg = getPanel(context, "jsdebugger");
if (!dbg) {
return gcli.lookup("debuggerStopped");
return l10n.lookup("debuggerStopped");
}
let source = dbg._view.Sources.getItemForAttachment(a => {
@ -233,9 +239,9 @@ exports.items.push({
line: args.breakpoint.lineNumber };
dbg.removeBreakpoint(position).then(() => {
deferred.resolve(gcli.lookup("breakdelRemoved"));
deferred.resolve(l10n.lookup("breakdelRemoved"));
}, () => {
deferred.resolve(gcli.lookup("breakNotFound"));
deferred.resolve(l10n.lookup("breakNotFound"));
});
return deferred.promise;
@ -247,16 +253,18 @@ exports.items.push({
*/
exports.items.push({
name: "dbg",
description: gcli.lookup("dbgDesc"),
manual: gcli.lookup("dbgManual")
description: l10n.lookup("dbgDesc"),
manual: l10n.lookup("dbgManual")
});
/**
* 'dbg open' command
*/
exports.items.push({
item: "command",
runAt: "client",
name: "dbg open",
description: gcli.lookup("dbgOpen"),
description: l10n.lookup("dbgOpen"),
params: [],
exec: function(args, context) {
let target = context.environment.target;
@ -268,8 +276,10 @@ exports.items.push({
* 'dbg close' command
*/
exports.items.push({
item: "command",
runAt: "client",
name: "dbg close",
description: gcli.lookup("dbgClose"),
description: l10n.lookup("dbgClose"),
params: [],
exec: function(args, context) {
if (!getPanel(context, "jsdebugger")) {
@ -284,13 +294,15 @@ exports.items.push({
* 'dbg interrupt' command
*/
exports.items.push({
item: "command",
runAt: "client",
name: "dbg interrupt",
description: gcli.lookup("dbgInterrupt"),
description: l10n.lookup("dbgInterrupt"),
params: [],
exec: function(args, context) {
let dbg = getPanel(context, "jsdebugger");
if (!dbg) {
return gcli.lookup("debuggerStopped");
return l10n.lookup("debuggerStopped");
}
let controller = dbg._controller;
@ -305,13 +317,15 @@ exports.items.push({
* 'dbg continue' command
*/
exports.items.push({
item: "command",
runAt: "client",
name: "dbg continue",
description: gcli.lookup("dbgContinue"),
description: l10n.lookup("dbgContinue"),
params: [],
exec: function(args, context) {
let dbg = getPanel(context, "jsdebugger");
if (!dbg) {
return gcli.lookup("debuggerStopped");
return l10n.lookup("debuggerStopped");
}
let controller = dbg._controller;
@ -326,22 +340,26 @@ exports.items.push({
* 'dbg step' command
*/
exports.items.push({
item: "command",
runAt: "client",
name: "dbg step",
description: gcli.lookup("dbgStepDesc"),
manual: gcli.lookup("dbgStepManual")
description: l10n.lookup("dbgStepDesc"),
manual: l10n.lookup("dbgStepManual")
});
/**
* 'dbg step over' command
*/
exports.items.push({
item: "command",
runAt: "client",
name: "dbg step over",
description: gcli.lookup("dbgStepOverDesc"),
description: l10n.lookup("dbgStepOverDesc"),
params: [],
exec: function(args, context) {
let dbg = getPanel(context, "jsdebugger");
if (!dbg) {
return gcli.lookup("debuggerStopped");
return l10n.lookup("debuggerStopped");
}
let controller = dbg._controller;
@ -356,13 +374,15 @@ exports.items.push({
* 'dbg step in' command
*/
exports.items.push({
item: "command",
runAt: "client",
name: 'dbg step in',
description: gcli.lookup("dbgStepInDesc"),
description: l10n.lookup("dbgStepInDesc"),
params: [],
exec: function(args, context) {
let dbg = getPanel(context, "jsdebugger");
if (!dbg) {
return gcli.lookup("debuggerStopped");
return l10n.lookup("debuggerStopped");
}
let controller = dbg._controller;
@ -377,13 +397,15 @@ exports.items.push({
* 'dbg step over' command
*/
exports.items.push({
item: "command",
runAt: "client",
name: 'dbg step out',
description: gcli.lookup("dbgStepOutDesc"),
description: l10n.lookup("dbgStepOutDesc"),
params: [],
exec: function(args, context) {
let dbg = getPanel(context, "jsdebugger");
if (!dbg) {
return gcli.lookup("debuggerStopped");
return l10n.lookup("debuggerStopped");
}
let controller = dbg._controller;
@ -398,14 +420,16 @@ exports.items.push({
* 'dbg list' command
*/
exports.items.push({
item: "command",
runAt: "client",
name: "dbg list",
description: gcli.lookup("dbgListSourcesDesc"),
description: l10n.lookup("dbgListSourcesDesc"),
params: [],
returnType: "dom",
exec: function(args, context) {
let dbg = getPanel(context, "jsdebugger");
if (!dbg) {
return gcli.lookup("debuggerClosed");
return l10n.lookup("debuggerClosed");
}
let sources = getAllSources(dbg);
@ -440,10 +464,12 @@ exports.items.push({
}
].forEach(function(cmd) {
const lookup = function(id) {
return gcli.lookup(cmd.l10nPrefix + id);
return l10n.lookup(cmd.l10nPrefix + id);
};
exports.items.push({
item: "command",
runAt: "client",
name: "dbg " + cmd.name,
description: lookup("Desc"),
params: [
@ -475,7 +501,7 @@ exports.items.push({
const dbg = getPanel(context, "jsdebugger");
const doc = context.environment.chromeDocument;
if (!dbg) {
throw new Error(gcli.lookup("debuggerClosed"));
throw new Error(l10n.lookup("debuggerClosed"));
}
const { promise, resolve, reject } = context.defer();

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

@ -0,0 +1,409 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const {Cc, Ci, Cu} = require("chrome");
const { Services } = require("resource://gre/modules/Services.jsm");
loader.lazyGetter(this, "osString", () => Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).OS);
// Panels
loader.lazyGetter(this, "OptionsPanel", () => require("devtools/framework/toolbox-options").OptionsPanel);
loader.lazyGetter(this, "InspectorPanel", () => require("devtools/inspector/inspector-panel").InspectorPanel);
loader.lazyGetter(this, "WebConsolePanel", () => require("devtools/webconsole/panel").WebConsolePanel);
loader.lazyGetter(this, "DebuggerPanel", () => require("devtools/debugger/panel").DebuggerPanel);
loader.lazyGetter(this, "StyleEditorPanel", () => require("devtools/styleeditor/styleeditor-panel").StyleEditorPanel);
loader.lazyGetter(this, "ShaderEditorPanel", () => require("devtools/shadereditor/panel").ShaderEditorPanel);
loader.lazyGetter(this, "CanvasDebuggerPanel", () => require("devtools/canvasdebugger/panel").CanvasDebuggerPanel);
loader.lazyGetter(this, "WebAudioEditorPanel", () => require("devtools/webaudioeditor/panel").WebAudioEditorPanel);
loader.lazyGetter(this, "PerformancePanel", () => require("devtools/performance/panel").PerformancePanel);
loader.lazyGetter(this, "NetMonitorPanel", () => require("devtools/netmonitor/panel").NetMonitorPanel);
loader.lazyGetter(this, "StoragePanel", () => require("devtools/storage/panel").StoragePanel);
loader.lazyGetter(this, "ScratchpadPanel", () => require("devtools/scratchpad/scratchpad-panel").ScratchpadPanel);
// Strings
const toolboxProps = "chrome://browser/locale/devtools/toolbox.properties";
const inspectorProps = "chrome://browser/locale/devtools/inspector.properties";
const webConsoleProps = "chrome://browser/locale/devtools/webconsole.properties";
const debuggerProps = "chrome://browser/locale/devtools/debugger.properties";
const styleEditorProps = "chrome://browser/locale/devtools/styleeditor.properties";
const shaderEditorProps = "chrome://browser/locale/devtools/shadereditor.properties";
const canvasDebuggerProps = "chrome://browser/locale/devtools/canvasdebugger.properties";
const webAudioEditorProps = "chrome://browser/locale/devtools/webaudioeditor.properties";
const profilerProps = "chrome://browser/locale/devtools/profiler.properties";
const netMonitorProps = "chrome://browser/locale/devtools/netmonitor.properties";
const storageProps = "chrome://browser/locale/devtools/storage.properties";
const scratchpadProps = "chrome://browser/locale/devtools/scratchpad.properties";
loader.lazyGetter(this, "toolboxStrings", () => Services.strings.createBundle(toolboxProps));
loader.lazyGetter(this, "profilerStrings",() => Services.strings.createBundle(profilerProps));
loader.lazyGetter(this, "webConsoleStrings", () => Services.strings.createBundle(webConsoleProps));
loader.lazyGetter(this, "debuggerStrings", () => Services.strings.createBundle(debuggerProps));
loader.lazyGetter(this, "styleEditorStrings", () => Services.strings.createBundle(styleEditorProps));
loader.lazyGetter(this, "shaderEditorStrings", () => Services.strings.createBundle(shaderEditorProps));
loader.lazyGetter(this, "canvasDebuggerStrings", () => Services.strings.createBundle(canvasDebuggerProps));
loader.lazyGetter(this, "webAudioEditorStrings", () => Services.strings.createBundle(webAudioEditorProps));
loader.lazyGetter(this, "inspectorStrings", () => Services.strings.createBundle(inspectorProps));
loader.lazyGetter(this, "netMonitorStrings", () => Services.strings.createBundle(netMonitorProps));
loader.lazyGetter(this, "storageStrings", () => Services.strings.createBundle(storageProps));
loader.lazyGetter(this, "scratchpadStrings", () => Services.strings.createBundle(scratchpadProps));
let Tools = {};
exports.Tools = Tools;
// Definitions
Tools.options = {
id: "options",
ordinal: 0,
url: "chrome://browser/content/devtools/framework/toolbox-options.xul",
icon: "chrome://browser/skin/devtools/tool-options.svg",
invertIconForLightTheme: true,
bgTheme: "theme-body",
label: l10n("options.label", toolboxStrings),
iconOnly: true,
panelLabel: l10n("options.panelLabel", toolboxStrings),
tooltip: l10n("optionsButton.tooltip", toolboxStrings),
inMenu: false,
isTargetSupported: function(target) {
return true;
},
build: function(iframeWindow, toolbox) {
return new OptionsPanel(iframeWindow, toolbox);
}
}
Tools.inspector = {
id: "inspector",
accesskey: l10n("inspector.accesskey", inspectorStrings),
key: l10n("inspector.commandkey", inspectorStrings),
ordinal: 1,
modifiers: osString == "Darwin" ? "accel,alt" : "accel,shift",
icon: "chrome://browser/skin/devtools/tool-inspector.svg",
invertIconForLightTheme: true,
url: "chrome://browser/content/devtools/inspector/inspector.xul",
label: l10n("inspector.label", inspectorStrings),
panelLabel: l10n("inspector.panelLabel", inspectorStrings),
tooltip: l10n("inspector.tooltip", inspectorStrings),
inMenu: true,
commands: [
"devtools/resize-commands",
"devtools/inspector/inspector-commands",
"devtools/eyedropper/commands.js"
],
preventClosingOnKey: true,
onkey: function(panel) {
panel.toolbox.highlighterUtils.togglePicker();
},
isTargetSupported: function(target) {
return target.hasActor("inspector");
},
build: function(iframeWindow, toolbox) {
return new InspectorPanel(iframeWindow, toolbox);
}
};
Tools.webConsole = {
id: "webconsole",
key: l10n("cmd.commandkey", webConsoleStrings),
accesskey: l10n("webConsoleCmd.accesskey", webConsoleStrings),
modifiers: Services.appinfo.OS == "Darwin" ? "accel,alt" : "accel,shift",
ordinal: 2,
icon: "chrome://browser/skin/devtools/tool-webconsole.svg",
invertIconForLightTheme: true,
url: "chrome://browser/content/devtools/webconsole.xul",
label: l10n("ToolboxTabWebconsole.label", webConsoleStrings),
menuLabel: l10n("MenuWebconsole.label", webConsoleStrings),
panelLabel: l10n("ToolboxWebConsole.panelLabel", webConsoleStrings),
tooltip: l10n("ToolboxWebconsole.tooltip", webConsoleStrings),
inMenu: true,
commands: "devtools/webconsole/console-commands",
preventClosingOnKey: true,
onkey: function(panel, toolbox) {
if (toolbox.splitConsole)
return toolbox.focusConsoleInput();
panel.focusInput();
},
isTargetSupported: function(target) {
return true;
},
build: function(iframeWindow, toolbox) {
return new WebConsolePanel(iframeWindow, toolbox);
}
};
Tools.jsdebugger = {
id: "jsdebugger",
key: l10n("debuggerMenu.commandkey", debuggerStrings),
accesskey: l10n("debuggerMenu.accesskey", debuggerStrings),
modifiers: osString == "Darwin" ? "accel,alt" : "accel,shift",
ordinal: 3,
icon: "chrome://browser/skin/devtools/tool-debugger.svg",
invertIconForLightTheme: true,
highlightedicon: "chrome://browser/skin/devtools/tool-debugger-paused.svg",
url: "chrome://browser/content/devtools/debugger.xul",
label: l10n("ToolboxDebugger.label", debuggerStrings),
panelLabel: l10n("ToolboxDebugger.panelLabel", debuggerStrings),
tooltip: l10n("ToolboxDebugger.tooltip", debuggerStrings),
inMenu: true,
commands: "devtools/debugger/debugger-commands",
isTargetSupported: function(target) {
return true;
},
build: function(iframeWindow, toolbox) {
return new DebuggerPanel(iframeWindow, toolbox);
}
};
Tools.styleEditor = {
id: "styleeditor",
key: l10n("open.commandkey", styleEditorStrings),
ordinal: 4,
accesskey: l10n("open.accesskey", styleEditorStrings),
modifiers: "shift",
icon: "chrome://browser/skin/devtools/tool-styleeditor.svg",
invertIconForLightTheme: true,
url: "chrome://browser/content/devtools/styleeditor.xul",
label: l10n("ToolboxStyleEditor.label", styleEditorStrings),
panelLabel: l10n("ToolboxStyleEditor.panelLabel", styleEditorStrings),
tooltip: l10n("ToolboxStyleEditor.tooltip2", styleEditorStrings),
inMenu: true,
commands: "devtools/styleeditor/styleeditor-commands",
isTargetSupported: function(target) {
return target.hasActor("styleEditor") || target.hasActor("styleSheets");
},
build: function(iframeWindow, toolbox) {
return new StyleEditorPanel(iframeWindow, toolbox);
}
};
Tools.shaderEditor = {
id: "shadereditor",
ordinal: 5,
visibilityswitch: "devtools.shadereditor.enabled",
icon: "chrome://browser/skin/devtools/tool-styleeditor.svg",
invertIconForLightTheme: true,
url: "chrome://browser/content/devtools/shadereditor.xul",
label: l10n("ToolboxShaderEditor.label", shaderEditorStrings),
panelLabel: l10n("ToolboxShaderEditor.panelLabel", shaderEditorStrings),
tooltip: l10n("ToolboxShaderEditor.tooltip", shaderEditorStrings),
isTargetSupported: function(target) {
return target.hasActor("webgl") && !target.chrome;
},
build: function(iframeWindow, toolbox) {
return new ShaderEditorPanel(iframeWindow, toolbox);
}
};
Tools.canvasDebugger = {
id: "canvasdebugger",
ordinal: 6,
visibilityswitch: "devtools.canvasdebugger.enabled",
icon: "chrome://browser/skin/devtools/tool-styleeditor.svg",
invertIconForLightTheme: true,
url: "chrome://browser/content/devtools/canvasdebugger.xul",
label: l10n("ToolboxCanvasDebugger.label", canvasDebuggerStrings),
panelLabel: l10n("ToolboxCanvasDebugger.panelLabel", canvasDebuggerStrings),
tooltip: l10n("ToolboxCanvasDebugger.tooltip", canvasDebuggerStrings),
// Hide the Canvas Debugger in the Add-on Debugger and Browser Toolbox
// (bug 1047520).
isTargetSupported: function(target) {
return target.hasActor("canvas") && !target.chrome;
},
build: function (iframeWindow, toolbox) {
return new CanvasDebuggerPanel(iframeWindow, toolbox);
}
};
Tools.performance = {
id: "performance",
ordinal: 7,
icon: "chrome://browser/skin/devtools/tool-profiler.svg",
invertIconForLightTheme: true,
url: "chrome://browser/content/devtools/performance.xul",
visibilityswitch: "devtools.performance.enabled",
label: l10n("profiler.label2", profilerStrings),
panelLabel: l10n("profiler.panelLabel2", profilerStrings),
tooltip: l10n("profiler.tooltip2", profilerStrings),
accesskey: l10n("profiler.accesskey", profilerStrings),
key: l10n("profiler.commandkey2", profilerStrings),
modifiers: "shift",
inMenu: true,
isTargetSupported: function (target) {
return target.hasActor("profiler");
},
build: function (frame, target) {
return new PerformancePanel(frame, target);
}
};
Tools.netMonitor = {
id: "netmonitor",
accesskey: l10n("netmonitor.accesskey", netMonitorStrings),
key: l10n("netmonitor.commandkey", netMonitorStrings),
ordinal: 9,
modifiers: osString == "Darwin" ? "accel,alt" : "accel,shift",
visibilityswitch: "devtools.netmonitor.enabled",
icon: "chrome://browser/skin/devtools/tool-network.svg",
invertIconForLightTheme: true,
url: "chrome://browser/content/devtools/netmonitor.xul",
label: l10n("netmonitor.label", netMonitorStrings),
panelLabel: l10n("netmonitor.panelLabel", netMonitorStrings),
tooltip: l10n("netmonitor.tooltip", netMonitorStrings),
inMenu: true,
isTargetSupported: function(target) {
return target.getTrait("networkMonitor");
},
build: function(iframeWindow, toolbox) {
return new NetMonitorPanel(iframeWindow, toolbox);
}
};
Tools.storage = {
id: "storage",
key: l10n("storage.commandkey", storageStrings),
ordinal: 10,
accesskey: l10n("storage.accesskey", storageStrings),
modifiers: "shift",
visibilityswitch: "devtools.storage.enabled",
icon: "chrome://browser/skin/devtools/tool-storage.svg",
invertIconForLightTheme: true,
url: "chrome://browser/content/devtools/storage.xul",
label: l10n("storage.label", storageStrings),
menuLabel: l10n("storage.menuLabel", storageStrings),
panelLabel: l10n("storage.panelLabel", storageStrings),
tooltip: l10n("storage.tooltip2", storageStrings),
inMenu: true,
isTargetSupported: function(target) {
return target.isLocalTab ||
( target.hasActor("storage") &&
target.getTrait("storageInspector") );
},
build: function(iframeWindow, toolbox) {
return new StoragePanel(iframeWindow, toolbox);
}
};
Tools.webAudioEditor = {
id: "webaudioeditor",
ordinal: 11,
visibilityswitch: "devtools.webaudioeditor.enabled",
icon: "chrome://browser/skin/devtools/tool-webaudio.svg",
invertIconForLightTheme: true,
url: "chrome://browser/content/devtools/webaudioeditor.xul",
label: l10n("ToolboxWebAudioEditor1.label", webAudioEditorStrings),
panelLabel: l10n("ToolboxWebAudioEditor1.panelLabel", webAudioEditorStrings),
tooltip: l10n("ToolboxWebAudioEditor1.tooltip", webAudioEditorStrings),
isTargetSupported: function(target) {
return !target.chrome && target.hasActor("webaudio");
},
build: function(iframeWindow, toolbox) {
return new WebAudioEditorPanel(iframeWindow, toolbox);
}
};
Tools.scratchpad = {
id: "scratchpad",
ordinal: 12,
visibilityswitch: "devtools.scratchpad.enabled",
icon: "chrome://browser/skin/devtools/tool-scratchpad.svg",
invertIconForLightTheme: true,
url: "chrome://browser/content/devtools/scratchpad.xul",
label: l10n("scratchpad.label", scratchpadStrings),
panelLabel: l10n("scratchpad.panelLabel", scratchpadStrings),
tooltip: l10n("scratchpad.tooltip", scratchpadStrings),
inMenu: false,
commands: "devtools/scratchpad/scratchpad-commands",
isTargetSupported: function(target) {
return target.isRemote;
},
build: function(iframeWindow, toolbox) {
return new ScratchpadPanel(iframeWindow, toolbox);
}
};
let defaultTools = [
Tools.options,
Tools.webConsole,
Tools.inspector,
Tools.jsdebugger,
Tools.styleEditor,
Tools.shaderEditor,
Tools.canvasDebugger,
Tools.webAudioEditor,
Tools.performance,
Tools.netMonitor,
Tools.storage,
Tools.scratchpad
];
exports.defaultTools = defaultTools;
Tools.darkTheme = {
id: "dark",
label: l10n("options.darkTheme.label", toolboxStrings),
ordinal: 1,
stylesheets: ["chrome://browser/skin/devtools/dark-theme.css"],
classList: ["theme-dark"],
};
Tools.lightTheme = {
id: "light",
label: l10n("options.lightTheme.label", toolboxStrings),
ordinal: 2,
stylesheets: ["chrome://browser/skin/devtools/light-theme.css"],
classList: ["theme-light"],
};
exports.defaultThemes = [
Tools.darkTheme,
Tools.lightTheme,
];
/**
* Lookup l10n string from a string bundle.
*
* @param {string} name
* The key to lookup.
* @param {StringBundle} bundle
* The key to lookup.
* @returns A localized version of the given key.
*/
function l10n(name, bundle)
{
try {
return bundle.GetStringFromName(name);
} catch (ex) {
Services.console.logStringMessage("Error reading '" + name + "'");
throw new Error("l10n error with " + name);
}
}

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

@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
const gcli = require("gcli/index");
const l10n = require("gcli/l10n");
const EventEmitter = require("devtools/toolkit/event-emitter");
const eventEmitter = new EventEmitter();
@ -12,14 +12,19 @@ let { Eyedropper, EyedropperManager } = require("devtools/eyedropper/eyedropper"
* 'eyedropper' command
*/
exports.items = [{
item: "command",
runAt: "client",
name: "eyedropper",
description: gcli.lookup("eyedropperDesc"),
manual: gcli.lookup("eyedropperManual"),
description: l10n.lookup("eyedropperDesc"),
manual: l10n.lookup("eyedropperManual"),
buttonId: "command-button-eyedropper",
buttonClass: "command-button command-button-invertable",
tooltipText: gcli.lookup("eyedropperTooltip"),
tooltipText: l10n.lookup("eyedropperTooltip"),
state: {
isChecked: function(target) {
if (!target.tab) {
return false;
}
let chromeWindow = target.tab.ownerDocument.defaultView;
let dropper = EyedropperManager.getInstance(chromeWindow);
if (dropper) {

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

@ -118,6 +118,10 @@ function test() {
todo(false, "Front for " + actor + " still held in pool!");
continue;
}
// gcliActor is for the commandline which is separate to the toolbox
if (actor.contains("gcliActor")) {
continue;
}
ok(false, "Front for " + actor + " still held in pool!");
}
}

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

@ -713,10 +713,13 @@ Toolbox.prototype = {
this._buildPickerButton();
}
let spec = CommandUtils.getCommandbarSpec("devtools.toolbox.toolbarSpec");
let environment = CommandUtils.createEnvironment(this, '_target');
return CommandUtils.createRequisition(environment).then(requisition => {
const options = {
environment: CommandUtils.createEnvironment(this, '_target')
};
return CommandUtils.createRequisition(this.target, options).then(requisition => {
this._requisition = requisition;
const spec = CommandUtils.getCommandbarSpec("devtools.toolbox.toolbarSpec");
return CommandUtils.createButtons(spec, this.target, this.doc,
requisition).then(buttons => {
let container = this.doc.getElementById("toolbox-buttons");
@ -1752,7 +1755,7 @@ Toolbox.prototype = {
let win = this.frame.ownerGlobal;
if (this._requisition) {
this._requisition.destroy();
CommandUtils.destroyRequisition(this._requisition, this.target);
}
this._telemetry.toolClosed("toolbox");
this._telemetry.destroy();

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

@ -4,18 +4,20 @@
"use strict";
const gcli = require("gcli/index");
const l10n = require("gcli/l10n");
exports.items = [{
item: "command",
runAt: "server",
name: "inspect",
description: gcli.lookup("inspectDesc"),
manual: gcli.lookup("inspectManual"),
description: l10n.lookup("inspectDesc"),
manual: l10n.lookup("inspectManual"),
params: [
{
name: "selector",
type: "node",
description: gcli.lookup("inspectNodeDesc"),
manual: gcli.lookup("inspectNodeManual")
description: l10n.lookup("inspectNodeDesc"),
manual: l10n.lookup("inspectNodeManual")
}
],
exec: function(args, context) {

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

@ -4,11 +4,20 @@
"use strict";
const {Cc, Ci, Cu} = require("chrome");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
const { Cu } = require("chrome");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource:///modules/devtools/gDevTools.jsm");
const { gDevTools } = require("resource:///modules/devtools/gDevTools.jsm");
const { defaultTools, defaultThemes } = require("definitions");
defaultTools.forEach(definition => gDevTools.registerTool(definition));
defaultThemes.forEach(definition => gDevTools.registerTheme(definition));
// Re-export for backwards compatibility, but we should probably the
// definitions from require("definitions") in the future
exports.defaultTools = require("definitions").defaultTools;
exports.defaultThemes = require("definitions").defaultThemes;
exports.Tools = require("definitions").Tools;
Object.defineProperty(exports, "Toolbox", {
get: () => require("devtools/framework/toolbox").Toolbox
@ -17,398 +26,7 @@ Object.defineProperty(exports, "TargetFactory", {
get: () => require("devtools/framework/target").TargetFactory
});
loader.lazyGetter(this, "osString", () => Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).OS);
let events = require("sdk/system/events");
// Panels
loader.lazyGetter(this, "OptionsPanel", () => require("devtools/framework/toolbox-options").OptionsPanel);
loader.lazyGetter(this, "InspectorPanel", () => require("devtools/inspector/inspector-panel").InspectorPanel);
loader.lazyGetter(this, "WebConsolePanel", () => require("devtools/webconsole/panel").WebConsolePanel);
loader.lazyGetter(this, "DebuggerPanel", () => require("devtools/debugger/panel").DebuggerPanel);
loader.lazyGetter(this, "StyleEditorPanel", () => require("devtools/styleeditor/styleeditor-panel").StyleEditorPanel);
loader.lazyGetter(this, "ShaderEditorPanel", () => require("devtools/shadereditor/panel").ShaderEditorPanel);
loader.lazyGetter(this, "CanvasDebuggerPanel", () => require("devtools/canvasdebugger/panel").CanvasDebuggerPanel);
loader.lazyGetter(this, "WebAudioEditorPanel", () => require("devtools/webaudioeditor/panel").WebAudioEditorPanel);
loader.lazyGetter(this, "PerformancePanel", () => require("devtools/performance/panel").PerformancePanel);
loader.lazyGetter(this, "NetMonitorPanel", () => require("devtools/netmonitor/panel").NetMonitorPanel);
loader.lazyGetter(this, "StoragePanel", () => require("devtools/storage/panel").StoragePanel);
loader.lazyGetter(this, "ScratchpadPanel", () => require("devtools/scratchpad/scratchpad-panel").ScratchpadPanel);
// Strings
const toolboxProps = "chrome://browser/locale/devtools/toolbox.properties";
const inspectorProps = "chrome://browser/locale/devtools/inspector.properties";
const webConsoleProps = "chrome://browser/locale/devtools/webconsole.properties";
const debuggerProps = "chrome://browser/locale/devtools/debugger.properties";
const styleEditorProps = "chrome://browser/locale/devtools/styleeditor.properties";
const shaderEditorProps = "chrome://browser/locale/devtools/shadereditor.properties";
const canvasDebuggerProps = "chrome://browser/locale/devtools/canvasdebugger.properties";
const webAudioEditorProps = "chrome://browser/locale/devtools/webaudioeditor.properties";
const profilerProps = "chrome://browser/locale/devtools/profiler.properties";
const netMonitorProps = "chrome://browser/locale/devtools/netmonitor.properties";
const storageProps = "chrome://browser/locale/devtools/storage.properties";
const scratchpadProps = "chrome://browser/locale/devtools/scratchpad.properties";
loader.lazyGetter(this, "toolboxStrings", () => Services.strings.createBundle(toolboxProps));
loader.lazyGetter(this, "profilerStrings",() => Services.strings.createBundle(profilerProps));
loader.lazyGetter(this, "webConsoleStrings", () => Services.strings.createBundle(webConsoleProps));
loader.lazyGetter(this, "debuggerStrings", () => Services.strings.createBundle(debuggerProps));
loader.lazyGetter(this, "styleEditorStrings", () => Services.strings.createBundle(styleEditorProps));
loader.lazyGetter(this, "shaderEditorStrings", () => Services.strings.createBundle(shaderEditorProps));
loader.lazyGetter(this, "canvasDebuggerStrings", () => Services.strings.createBundle(canvasDebuggerProps));
loader.lazyGetter(this, "webAudioEditorStrings", () => Services.strings.createBundle(webAudioEditorProps));
loader.lazyGetter(this, "inspectorStrings", () => Services.strings.createBundle(inspectorProps));
loader.lazyGetter(this, "netMonitorStrings", () => Services.strings.createBundle(netMonitorProps));
loader.lazyGetter(this, "storageStrings", () => Services.strings.createBundle(storageProps));
loader.lazyGetter(this, "scratchpadStrings", () => Services.strings.createBundle(scratchpadProps));
let Tools = {};
exports.Tools = Tools;
// Definitions
Tools.options = {
id: "options",
ordinal: 0,
url: "chrome://browser/content/devtools/framework/toolbox-options.xul",
icon: "chrome://browser/skin/devtools/tool-options.svg",
invertIconForLightTheme: true,
bgTheme: "theme-body",
label: l10n("options.label", toolboxStrings),
iconOnly: true,
panelLabel: l10n("options.panelLabel", toolboxStrings),
tooltip: l10n("optionsButton.tooltip", toolboxStrings),
inMenu: false,
isTargetSupported: function(target) {
return true;
},
build: function(iframeWindow, toolbox) {
return new OptionsPanel(iframeWindow, toolbox);
}
}
Tools.inspector = {
id: "inspector",
accesskey: l10n("inspector.accesskey", inspectorStrings),
key: l10n("inspector.commandkey", inspectorStrings),
ordinal: 1,
modifiers: osString == "Darwin" ? "accel,alt" : "accel,shift",
icon: "chrome://browser/skin/devtools/tool-inspector.svg",
invertIconForLightTheme: true,
url: "chrome://browser/content/devtools/inspector/inspector.xul",
label: l10n("inspector.label", inspectorStrings),
panelLabel: l10n("inspector.panelLabel", inspectorStrings),
tooltip: l10n("inspector.tooltip", inspectorStrings),
inMenu: true,
commands: [
"devtools/resize-commands",
"devtools/inspector/inspector-commands",
"devtools/eyedropper/commands.js"
],
preventClosingOnKey: true,
onkey: function(panel) {
panel.toolbox.highlighterUtils.togglePicker();
},
isTargetSupported: function(target) {
return target.hasActor("inspector");
},
build: function(iframeWindow, toolbox) {
return new InspectorPanel(iframeWindow, toolbox);
}
};
Tools.webConsole = {
id: "webconsole",
key: l10n("cmd.commandkey", webConsoleStrings),
accesskey: l10n("webConsoleCmd.accesskey", webConsoleStrings),
modifiers: Services.appinfo.OS == "Darwin" ? "accel,alt" : "accel,shift",
ordinal: 2,
icon: "chrome://browser/skin/devtools/tool-webconsole.svg",
invertIconForLightTheme: true,
url: "chrome://browser/content/devtools/webconsole.xul",
label: l10n("ToolboxTabWebconsole.label", webConsoleStrings),
menuLabel: l10n("MenuWebconsole.label", webConsoleStrings),
panelLabel: l10n("ToolboxWebConsole.panelLabel", webConsoleStrings),
tooltip: l10n("ToolboxWebconsole.tooltip", webConsoleStrings),
inMenu: true,
commands: "devtools/webconsole/console-commands",
preventClosingOnKey: true,
onkey: function(panel, toolbox) {
if (toolbox.splitConsole)
return toolbox.focusConsoleInput();
panel.focusInput();
},
isTargetSupported: function(target) {
return true;
},
build: function(iframeWindow, toolbox) {
return new WebConsolePanel(iframeWindow, toolbox);
}
};
Tools.jsdebugger = {
id: "jsdebugger",
key: l10n("debuggerMenu.commandkey", debuggerStrings),
accesskey: l10n("debuggerMenu.accesskey", debuggerStrings),
modifiers: osString == "Darwin" ? "accel,alt" : "accel,shift",
ordinal: 3,
icon: "chrome://browser/skin/devtools/tool-debugger.svg",
invertIconForLightTheme: true,
highlightedicon: "chrome://browser/skin/devtools/tool-debugger-paused.svg",
url: "chrome://browser/content/devtools/debugger.xul",
label: l10n("ToolboxDebugger.label", debuggerStrings),
panelLabel: l10n("ToolboxDebugger.panelLabel", debuggerStrings),
tooltip: l10n("ToolboxDebugger.tooltip", debuggerStrings),
inMenu: true,
commands: "devtools/debugger/debugger-commands",
isTargetSupported: function(target) {
return true;
},
build: function(iframeWindow, toolbox) {
return new DebuggerPanel(iframeWindow, toolbox);
}
};
Tools.styleEditor = {
id: "styleeditor",
key: l10n("open.commandkey", styleEditorStrings),
ordinal: 4,
accesskey: l10n("open.accesskey", styleEditorStrings),
modifiers: "shift",
icon: "chrome://browser/skin/devtools/tool-styleeditor.svg",
invertIconForLightTheme: true,
url: "chrome://browser/content/devtools/styleeditor.xul",
label: l10n("ToolboxStyleEditor.label", styleEditorStrings),
panelLabel: l10n("ToolboxStyleEditor.panelLabel", styleEditorStrings),
tooltip: l10n("ToolboxStyleEditor.tooltip2", styleEditorStrings),
inMenu: true,
commands: "devtools/styleeditor/styleeditor-commands",
isTargetSupported: function(target) {
return target.hasActor("styleEditor") || target.hasActor("styleSheets");
},
build: function(iframeWindow, toolbox) {
return new StyleEditorPanel(iframeWindow, toolbox);
}
};
Tools.shaderEditor = {
id: "shadereditor",
ordinal: 5,
visibilityswitch: "devtools.shadereditor.enabled",
icon: "chrome://browser/skin/devtools/tool-styleeditor.svg",
invertIconForLightTheme: true,
url: "chrome://browser/content/devtools/shadereditor.xul",
label: l10n("ToolboxShaderEditor.label", shaderEditorStrings),
panelLabel: l10n("ToolboxShaderEditor.panelLabel", shaderEditorStrings),
tooltip: l10n("ToolboxShaderEditor.tooltip", shaderEditorStrings),
isTargetSupported: function(target) {
return target.hasActor("webgl") && !target.chrome;
},
build: function(iframeWindow, toolbox) {
return new ShaderEditorPanel(iframeWindow, toolbox);
}
};
Tools.canvasDebugger = {
id: "canvasdebugger",
ordinal: 6,
visibilityswitch: "devtools.canvasdebugger.enabled",
icon: "chrome://browser/skin/devtools/tool-styleeditor.svg",
invertIconForLightTheme: true,
url: "chrome://browser/content/devtools/canvasdebugger.xul",
label: l10n("ToolboxCanvasDebugger.label", canvasDebuggerStrings),
panelLabel: l10n("ToolboxCanvasDebugger.panelLabel", canvasDebuggerStrings),
tooltip: l10n("ToolboxCanvasDebugger.tooltip", canvasDebuggerStrings),
// Hide the Canvas Debugger in the Add-on Debugger and Browser Toolbox
// (bug 1047520).
isTargetSupported: function(target) {
return target.hasActor("canvas") && !target.chrome;
},
build: function (iframeWindow, toolbox) {
return new CanvasDebuggerPanel(iframeWindow, toolbox);
}
};
Tools.performance = {
id: "performance",
ordinal: 7,
icon: "chrome://browser/skin/devtools/tool-profiler.svg",
invertIconForLightTheme: true,
url: "chrome://browser/content/devtools/performance.xul",
visibilityswitch: "devtools.performance.enabled",
label: l10n("profiler.label2", profilerStrings),
panelLabel: l10n("profiler.panelLabel2", profilerStrings),
tooltip: l10n("profiler.tooltip2", profilerStrings),
accesskey: l10n("profiler.accesskey", profilerStrings),
key: l10n("profiler.commandkey2", profilerStrings),
modifiers: "shift",
inMenu: true,
isTargetSupported: function (target) {
return target.hasActor("profiler");
},
build: function (frame, target) {
return new PerformancePanel(frame, target);
}
};
Tools.netMonitor = {
id: "netmonitor",
accesskey: l10n("netmonitor.accesskey", netMonitorStrings),
key: l10n("netmonitor.commandkey", netMonitorStrings),
ordinal: 9,
modifiers: osString == "Darwin" ? "accel,alt" : "accel,shift",
visibilityswitch: "devtools.netmonitor.enabled",
icon: "chrome://browser/skin/devtools/tool-network.svg",
invertIconForLightTheme: true,
url: "chrome://browser/content/devtools/netmonitor.xul",
label: l10n("netmonitor.label", netMonitorStrings),
panelLabel: l10n("netmonitor.panelLabel", netMonitorStrings),
tooltip: l10n("netmonitor.tooltip", netMonitorStrings),
inMenu: true,
isTargetSupported: function(target) {
return target.getTrait("networkMonitor");
},
build: function(iframeWindow, toolbox) {
return new NetMonitorPanel(iframeWindow, toolbox);
}
};
Tools.storage = {
id: "storage",
key: l10n("storage.commandkey", storageStrings),
ordinal: 10,
accesskey: l10n("storage.accesskey", storageStrings),
modifiers: "shift",
visibilityswitch: "devtools.storage.enabled",
icon: "chrome://browser/skin/devtools/tool-storage.svg",
invertIconForLightTheme: true,
url: "chrome://browser/content/devtools/storage.xul",
label: l10n("storage.label", storageStrings),
menuLabel: l10n("storage.menuLabel", storageStrings),
panelLabel: l10n("storage.panelLabel", storageStrings),
tooltip: l10n("storage.tooltip2", storageStrings),
inMenu: true,
isTargetSupported: function(target) {
return target.isLocalTab ||
( target.hasActor("storage") &&
target.getTrait("storageInspector") );
},
build: function(iframeWindow, toolbox) {
return new StoragePanel(iframeWindow, toolbox);
}
};
Tools.webAudioEditor = {
id: "webaudioeditor",
ordinal: 11,
visibilityswitch: "devtools.webaudioeditor.enabled",
icon: "chrome://browser/skin/devtools/tool-webaudio.svg",
invertIconForLightTheme: true,
url: "chrome://browser/content/devtools/webaudioeditor.xul",
label: l10n("ToolboxWebAudioEditor1.label", webAudioEditorStrings),
panelLabel: l10n("ToolboxWebAudioEditor1.panelLabel", webAudioEditorStrings),
tooltip: l10n("ToolboxWebAudioEditor1.tooltip", webAudioEditorStrings),
isTargetSupported: function(target) {
return !target.chrome && target.hasActor("webaudio");
},
build: function(iframeWindow, toolbox) {
return new WebAudioEditorPanel(iframeWindow, toolbox);
}
};
Tools.scratchpad = {
id: "scratchpad",
ordinal: 12,
visibilityswitch: "devtools.scratchpad.enabled",
icon: "chrome://browser/skin/devtools/tool-scratchpad.svg",
invertIconForLightTheme: true,
url: "chrome://browser/content/devtools/scratchpad.xul",
label: l10n("scratchpad.label", scratchpadStrings),
panelLabel: l10n("scratchpad.panelLabel", scratchpadStrings),
tooltip: l10n("scratchpad.tooltip", scratchpadStrings),
inMenu: false,
commands: "devtools/scratchpad/scratchpad-commands",
isTargetSupported: function(target) {
return target.isRemote;
},
build: function(iframeWindow, toolbox) {
return new ScratchpadPanel(iframeWindow, toolbox);
}
};
let defaultTools = [
Tools.options,
Tools.webConsole,
Tools.inspector,
Tools.jsdebugger,
Tools.styleEditor,
Tools.shaderEditor,
Tools.canvasDebugger,
Tools.webAudioEditor,
Tools.performance,
Tools.netMonitor,
Tools.storage,
Tools.scratchpad
];
exports.defaultTools = defaultTools;
for (let definition of defaultTools) {
gDevTools.registerTool(definition);
}
Tools.darkTheme = {
id: "dark",
label: l10n("options.darkTheme.label", toolboxStrings),
ordinal: 1,
stylesheets: ["chrome://browser/skin/devtools/dark-theme.css"],
classList: ["theme-dark"],
};
Tools.lightTheme = {
id: "light",
label: l10n("options.lightTheme.label", toolboxStrings),
ordinal: 2,
stylesheets: ["chrome://browser/skin/devtools/light-theme.css"],
classList: ["theme-light"],
};
let defaultThemes = [
Tools.darkTheme,
Tools.lightTheme,
];
for (let definition of defaultThemes) {
gDevTools.registerTheme(definition);
}
var unloadObserver = {
const unloadObserver = {
observe: function(subject, topic, data) {
if (subject.wrappedJSObject === require("@loader/unload")) {
Services.obs.removeObserver(unloadObserver, "sdk:loader:destroy");
@ -423,23 +41,5 @@ var unloadObserver = {
};
Services.obs.addObserver(unloadObserver, "sdk:loader:destroy", false);
const events = require("sdk/system/events");
events.emit("devtools-loaded", {});
/**
* Lookup l10n string from a string bundle.
*
* @param {string} name
* The key to lookup.
* @param {StringBundle} bundle
* The key to lookup.
* @returns A localized version of the given key.
*/
function l10n(name, bundle)
{
try {
return bundle.GetStringFromName(name);
} catch (ex) {
Services.console.logStringMessage("Error reading '" + name + "'");
throw new Error("l10n error with " + name);
}
}

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

@ -41,5 +41,6 @@ EXTRA_COMPONENTS += [
JAR_MANIFESTS += ['jar.mn']
EXTRA_JS_MODULES.devtools += [
'definitions.js',
'main.js',
]

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

@ -11,43 +11,54 @@ const BRAND_SHORT_NAME = Cc["@mozilla.org/intl/stringbundle;1"].
createBundle("chrome://branding/locale/brand.properties").
GetStringFromName("brandShortName");
const gcli = require("gcli/index");
const l10n = require("gcli/l10n");
exports.items = [
{
name: 'resize',
description: gcli.lookup('resizeModeDesc')
description: l10n.lookup('resizeModeDesc')
},
{
item: "command",
runAt: "client",
name: 'resize on',
description: gcli.lookup('resizeModeOnDesc'),
manual: gcli.lookupFormat('resizeModeManual2', [BRAND_SHORT_NAME]),
description: l10n.lookup('resizeModeOnDesc'),
manual: l10n.lookupFormat('resizeModeManual2', [BRAND_SHORT_NAME]),
exec: gcli_cmd_resize
},
{
item: "command",
runAt: "client",
name: 'resize off',
description: gcli.lookup('resizeModeOffDesc'),
manual: gcli.lookupFormat('resizeModeManual2', [BRAND_SHORT_NAME]),
description: l10n.lookup('resizeModeOffDesc'),
manual: l10n.lookupFormat('resizeModeManual2', [BRAND_SHORT_NAME]),
exec: gcli_cmd_resize
},
{
item: "command",
runAt: "client",
name: 'resize toggle',
buttonId: "command-button-responsive",
buttonClass: "command-button command-button-invertable",
tooltipText: gcli.lookup("resizeModeToggleTooltip"),
description: gcli.lookup('resizeModeToggleDesc'),
manual: gcli.lookupFormat('resizeModeManual2', [BRAND_SHORT_NAME]),
tooltipText: l10n.lookup("resizeModeToggleTooltip"),
description: l10n.lookup('resizeModeToggleDesc'),
manual: l10n.lookupFormat('resizeModeManual2', [BRAND_SHORT_NAME]),
state: {
isChecked: function(aTarget) {
if (!aTarget.tab) {
return false;
}
let browserWindow = aTarget.tab.ownerDocument.defaultView;
let mgr = browserWindow.ResponsiveUI.ResponsiveUIManager;
return mgr.isActiveForTab(aTarget.tab);
},
onChange: function(aTarget, aChangeHandler) {
let browserWindow = aTarget.tab.ownerDocument.defaultView;
let mgr = browserWindow.ResponsiveUI.ResponsiveUIManager;
mgr.on("on", aChangeHandler);
mgr.on("off", aChangeHandler);
if (aTarget.tab) {
let browserWindow = aTarget.tab.ownerDocument.defaultView;
let mgr = browserWindow.ResponsiveUI.ResponsiveUIManager;
mgr.on("on", aChangeHandler);
mgr.on("off", aChangeHandler);
}
},
offChange: function(aTarget, aChangeHandler) {
if (aTarget.tab) {
@ -61,18 +72,20 @@ exports.items = [
exec: gcli_cmd_resize
},
{
item: "command",
runAt: "client",
name: 'resize to',
description: gcli.lookup('resizeModeToDesc'),
description: l10n.lookup('resizeModeToDesc'),
params: [
{
name: 'width',
type: 'number',
description: gcli.lookup("resizePageArgWidthDesc"),
description: l10n.lookup("resizePageArgWidthDesc"),
},
{
name: 'height',
type: 'number',
description: gcli.lookup("resizePageArgHeightDesc"),
description: l10n.lookup("resizePageArgHeightDesc"),
},
],
exec: gcli_cmd_resize

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

@ -4,13 +4,15 @@
"use strict";
const gcli = require("gcli/index");
const l10n = require("gcli/l10n");
exports.items = [{
item: "command",
runAt: "client",
name: "scratchpad",
buttonId: "command-button-scratchpad",
buttonClass: "command-button command-button-invertable",
tooltipText: gcli.lookup("scratchpadOpenTooltip"),
tooltipText: l10n.lookup("scratchpadOpenTooltip"),
hidden: true,
exec: function(args, context) {
let Scratchpad = context.environment.chromeWindow.Scratchpad;

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

@ -39,14 +39,12 @@ XPCOMUtils.defineLazyGetter(this, "toolboxStrings", function () {
const Telemetry = require("devtools/shared/telemetry");
// This lazy getter is needed to prevent a require loop
XPCOMUtils.defineLazyGetter(this, "gcli", () => {
XPCOMUtils.defineLazyGetter(this, "gcliInit", function() {
try {
require("devtools/commandline/commands-index");
return require("gcli/index");
return require("devtools/commandline/commands-index");
}
catch (ex) {
console.error(ex);
console.log(ex);
}
});
@ -62,7 +60,7 @@ Object.defineProperty(this, "ConsoleServiceListener", {
enumerable: true
});
const promise = Cu.import('resource://gre/modules/Promise.jsm', {}).Promise;
const promise = Cu.import("resource://gre/modules/Promise.jsm", {}).Promise;
/**
* A collection of utilities to help working with commands
@ -71,12 +69,21 @@ let CommandUtils = {
/**
* Utility to ensure that things are loaded in the correct order
*/
createRequisition: function(environment) {
return gcli.load().then(() => {
return gcli.createRequisition({ environment: environment });
createRequisition: function(target, options) {
return gcliInit.getSystem(target).then(system => {
var Requisition = require("gcli/cli").Requisition;
return new Requisition(system, options);
});
},
/**
* Destroy the remote side of the requisition as well as the local side
*/
destroyRequisition: function(requisition, target) {
requisition.destroy();
gcliInit.releaseSystem(target);
},
/**
* Read a toolbarSpec from preferences
* @param pref The name of the preference to read
@ -105,12 +112,6 @@ let CommandUtils = {
throw new Error("No command '" + typed + "'");
}
// Do not build a button for a non-remote safe command in a non-local target.
if (!target.isLocalTab && !command.isRemoteSafe) {
requisition.clear();
return;
}
if (command.buttonId != null) {
button.id = command.buttonId;
if (command.buttonClass != null) {
@ -192,17 +193,17 @@ let CommandUtils = {
* @param targetContainer An object containing a 'target' property which
* reflects the current debug target
*/
createEnvironment: function(container, targetProperty='target') {
createEnvironment: function(container, targetProperty="target") {
if (!container[targetProperty].toString ||
!/TabTarget/.test(container[targetProperty].toString())) {
throw new Error('Missing target');
throw new Error("Missing target");
}
return {
get target() {
if (!container[targetProperty].toString ||
!/TabTarget/.test(container[targetProperty].toString())) {
throw new Error('Removed target');
throw new Error("Removed target");
}
return container[targetProperty];
@ -213,15 +214,17 @@ let CommandUtils = {
},
get chromeDocument() {
return this.chromeWindow.document;
return this.target.tab.ownerDocument.defaultView.document;
},
get window() {
return this.chromeWindow.gBrowser.selectedBrowser.contentWindow;
// throw new Error("environment.window is not available in runAt:client commands");
return this.chromeWindow.gBrowser.contentWindowAsCPOW;
},
get document() {
return this.window.document;
// throw new Error("environment.document is not available in runAt:client commands");
return this.chromeWindow.gBrowser.contentDocumentAsCPOW;
}
};
},
@ -255,6 +258,8 @@ this.DeveloperToolbar = function DeveloperToolbar(aChromeWindow, aToolbarElement
{
this._chromeWindow = aChromeWindow;
this.target = null; // Will be setup when show() is called
this._element = aToolbarElement;
this._element.hidden = true;
this._doc = this._element.ownerDocument;
@ -291,21 +296,11 @@ const NOTIFICATIONS = {
*/
DeveloperToolbar.prototype.NOTIFICATIONS = NOTIFICATIONS;
/**
* target is dynamic because the selectedTab changes
*/
Object.defineProperty(DeveloperToolbar.prototype, "target", {
get: function() {
return TargetFactory.forTab(this._chromeWindow.gBrowser.selectedTab);
},
enumerable: true
});
/**
* Is the toolbar open?
*/
Object.defineProperty(DeveloperToolbar.prototype, 'visible', {
get: function DT_visible() {
Object.defineProperty(DeveloperToolbar.prototype, "visible", {
get: function() {
return !this._element.hidden;
},
enumerable: true
@ -316,8 +311,8 @@ let _gSequenceId = 0;
/**
* Getter for a unique ID.
*/
Object.defineProperty(DeveloperToolbar.prototype, 'sequenceId', {
get: function DT_visible() {
Object.defineProperty(DeveloperToolbar.prototype, "sequenceId", {
get: function() {
return _gSequenceId++;
},
enumerable: true
@ -408,57 +403,84 @@ DeveloperToolbar.prototype.show = function(focus) {
this._doc.getElementById("Tools:DevToolbar").setAttribute("checked", "true");
return gcli.load().then(() => {
this.display = gcli.createDisplay({
contentDocument: this._chromeWindow.gBrowser.contentDocumentAsCPOW,
chromeDocument: this._doc,
chromeWindow: this._chromeWindow,
hintElement: this.tooltipPanel.hintElement,
inputElement: this._input,
completeElement: this._doc.querySelector(".gclitoolbar-complete-node"),
backgroundElement: this._doc.querySelector(".gclitoolbar-stack-node"),
outputDocument: this.outputPanel.document,
environment: CommandUtils.createEnvironment(this, "target"),
tooltipClass: "gcliterm-tooltip",
eval: null,
scratchpad: null
this.target = TargetFactory.forTab(this._chromeWindow.gBrowser.selectedTab);
const options = {
environment: CommandUtils.createEnvironment(this, "target"),
document: this.outputPanel.document,
};
return CommandUtils.createRequisition(this.target, options).then(requisition => {
this.requisition = requisition;
return this.requisition.update(this._input.value).then(() => {
const Inputter = require('gcli/mozui/inputter').Inputter;
const Completer = require('gcli/mozui/completer').Completer;
const Tooltip = require('gcli/mozui/tooltip').Tooltip;
const FocusManager = require('gcli/ui/focus').FocusManager;
this.onOutput = this.requisition.commandOutputManager.onOutput;
this.focusManager = new FocusManager(this._doc, requisition.system.settings);
this.inputter = new Inputter({
requisition: this.requisition,
focusManager: this.focusManager,
element: this._input,
});
this.completer = new Completer({
requisition: this.requisition,
inputter: this.inputter,
backgroundElement: this._doc.querySelector(".gclitoolbar-stack-node"),
element: this._doc.querySelector(".gclitoolbar-complete-node"),
});
this.tooltip = new Tooltip({
requisition: this.requisition,
focusManager: this.focusManager,
inputter: this.inputter,
element: this.tooltipPanel.hintElement,
});
this.inputter.tooltip = this.tooltip;
this.focusManager.addMonitoredElement(this.outputPanel._frame);
this.focusManager.addMonitoredElement(this._element);
this.focusManager.onVisibilityChange.add(this.outputPanel._visibilityChanged,
this.outputPanel);
this.focusManager.onVisibilityChange.add(this.tooltipPanel._visibilityChanged,
this.tooltipPanel);
this.onOutput.add(this.outputPanel._outputChanged, this.outputPanel);
let tabbrowser = this._chromeWindow.gBrowser;
tabbrowser.tabContainer.addEventListener("TabSelect", this, false);
tabbrowser.tabContainer.addEventListener("TabClose", this, false);
tabbrowser.addEventListener("load", this, true);
tabbrowser.addEventListener("beforeunload", this, true);
this._initErrorsCount(tabbrowser.selectedTab);
this._devtoolsUnloaded = this._devtoolsUnloaded.bind(this);
this._devtoolsLoaded = this._devtoolsLoaded.bind(this);
Services.obs.addObserver(this._devtoolsUnloaded, "devtools-unloaded", false);
Services.obs.addObserver(this._devtoolsLoaded, "devtools-loaded", false);
this._element.hidden = false;
if (focus) {
this._input.focus();
}
this._notify(NOTIFICATIONS.SHOW);
if (!DeveloperToolbar.introShownThisSession) {
let intro = require("gcli/ui/intro");
intro.maybeShowIntro(this.requisition.commandOutputManager,
this.requisition.conversionContext);
DeveloperToolbar.introShownThisSession = true;
}
this._showPromise = null;
});
this.display.focusManager.addMonitoredElement(this.outputPanel._frame);
this.display.focusManager.addMonitoredElement(this._element);
this.display.onVisibilityChange.add(this.outputPanel._visibilityChanged,
this.outputPanel);
this.display.onVisibilityChange.add(this.tooltipPanel._visibilityChanged,
this.tooltipPanel);
this.display.onOutput.add(this.outputPanel._outputChanged, this.outputPanel);
let tabbrowser = this._chromeWindow.gBrowser;
tabbrowser.tabContainer.addEventListener("TabSelect", this, false);
tabbrowser.tabContainer.addEventListener("TabClose", this, false);
tabbrowser.addEventListener("load", this, true);
tabbrowser.addEventListener("beforeunload", this, true);
this._initErrorsCount(tabbrowser.selectedTab);
this._devtoolsUnloaded = this._devtoolsUnloaded.bind(this);
this._devtoolsLoaded = this._devtoolsLoaded.bind(this);
Services.obs.addObserver(this._devtoolsUnloaded, "devtools-unloaded", false);
Services.obs.addObserver(this._devtoolsLoaded, "devtools-loaded", false);
this._element.hidden = false;
if (focus) {
this._input.focus();
}
this._notify(NOTIFICATIONS.SHOW);
if (!DeveloperToolbar.introShownThisSession) {
this.display.maybeShowIntro();
DeveloperToolbar.introShownThisSession = true;
}
this._showPromise = null;
});
});
});
@ -585,26 +607,26 @@ DeveloperToolbar.prototype.destroy = function() {
Services.obs.removeObserver(this._devtoolsLoaded, "devtools-loaded");
Array.prototype.forEach.call(tabbrowser.tabs, this._stopErrorsCount, this);
this.display.focusManager.removeMonitoredElement(this.outputPanel._frame);
this.display.focusManager.removeMonitoredElement(this._element);
this.focusManager.removeMonitoredElement(this.outputPanel._frame);
this.focusManager.removeMonitoredElement(this._element);
this.focusManager.onVisibilityChange.remove(this.outputPanel._visibilityChanged,
this.outputPanel);
this.focusManager.onVisibilityChange.remove(this.tooltipPanel._visibilityChanged,
this.tooltipPanel);
this.onOutput.remove(this.outputPanel._outputChanged, this.outputPanel);
this.tooltip.destroy();
this.completer.destroy();
this.inputter.destroy();
this.focusManager.destroy();
this.display.onVisibilityChange.remove(this.outputPanel._visibilityChanged, this.outputPanel);
this.display.onVisibilityChange.remove(this.tooltipPanel._visibilityChanged, this.tooltipPanel);
this.display.onOutput.remove(this.outputPanel._outputChanged, this.outputPanel);
this.display.destroy();
this.outputPanel.destroy();
this.tooltipPanel.destroy();
delete this._input;
// We could "delete this.display" etc if we have hard-to-track-down memory
// leaks as a belt-and-braces approach, however this prevents our DOM node
// hunter from looking in all the nooks and crannies, so it's better if we
// can be leak-free without
/*
delete this.display;
delete this.outputPanel;
delete this.tooltipPanel;
*/
CommandUtils.destroyRequisition(this.requisition, this.target);
this.target = undefined;
};
/**
@ -623,8 +645,9 @@ DeveloperToolbar.prototype._notify = function(topic) {
DeveloperToolbar.prototype.handleEvent = function(ev) {
if (ev.type == "TabSelect" || ev.type == "load") {
if (this.visible) {
this.display.reattach({
contentDocument: this._chromeWindow.gBrowser.contentDocumentAsCPOW
this.target = TargetFactory.forTab(this._chromeWindow.gBrowser.selectedTab);
gcliInit.getSystem(this.target).then(system => {
this.requisition.system = system;
});
if (ev.type == "TabSelect") {
@ -751,7 +774,7 @@ DeveloperToolbar.prototype.resetErrorsCount = function(tab) {
* Creating a OutputPanel is asynchronous
*/
function OutputPanel() {
throw new Error('Use OutputPanel.create()');
throw new Error("Use OutputPanel.create()");
}
/**
@ -838,8 +861,8 @@ OutputPanel.prototype._init = function(devtoolbar) {
this._copyTheme();
this._div = this.document.getElementById("gcli-output-root");
this._div.classList.add('gcli-row-out');
this._div.setAttribute('aria-live', 'assertive');
this._div.classList.add("gcli-row-out");
this._div.setAttribute("aria-live", "assertive");
let styles = this._toolbar.ownerDocument.defaultView
.getComputedStyle(this._toolbar);
@ -992,8 +1015,8 @@ OutputPanel.prototype._update = function() {
}
if (this.displayedOutput.data != null) {
let context = this._devtoolbar.display.requisition.conversionContext;
this.displayedOutput.convert('dom', context).then(node => {
let context = this._devtoolbar.requisition.conversionContext;
this.displayedOutput.convert("dom", context).then(node => {
if (node == null) {
return;
}
@ -1002,9 +1025,9 @@ OutputPanel.prototype._update = function() {
this._div.removeChild(this._div.firstChild);
}
var links = node.querySelectorAll('*[href]');
var links = node.querySelectorAll("*[href]");
for (var i = 0; i < links.length; i++) {
links[i].setAttribute('target', '_blank');
links[i].setAttribute("target", "_blank");
}
this._div.appendChild(node);
@ -1071,7 +1094,7 @@ OutputPanel.prototype._visibilityChanged = function(ev) {
* Creating a TooltipPanel is asynchronous
*/
function TooltipPanel() {
throw new Error('Use TooltipPanel.create()');
throw new Error("Use TooltipPanel.create()");
}
/**

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

@ -15,20 +15,24 @@ add_task(function*() {
info("inspector opened");
info("testing the eyedropper button");
testButton(toolbox, Telemetry);
yield testButton(toolbox, Telemetry);
stopRecordingTelemetryLogs(Telemetry);
yield gDevTools.closeToolbox(target);
gBrowser.removeCurrentTab();
});
function testButton(toolbox, Telemetry) {
function* testButton(toolbox, Telemetry) {
let button = toolbox.doc.querySelector("#command-button-eyedropper");
ok(button, "Captain, we have the eyedropper button");
let clicked = toolbox._requisition.commandOutputManager.onOutput.once();
info("clicking the button to open the eyedropper");
button.click();
yield clicked;
checkResults("_EYEDROPPER_", Telemetry);
}

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

@ -33,25 +33,25 @@ add_task(function* showToolbar() {
add_task(function* testDimensions() {
let tooltipPanel = DeveloperToolbar.tooltipPanel;
DeveloperToolbar.display.focusManager.helpRequest();
yield DeveloperToolbar.display.inputter.setInput('help help');
DeveloperToolbar.focusManager.helpRequest();
yield DeveloperToolbar.inputter.setInput('help help');
DeveloperToolbar.display.inputter.setCursor({ start: 'help help'.length });
DeveloperToolbar.inputter.setCursor({ start: 'help help'.length });
is(tooltipPanel._dimensions.start, 'help '.length,
'search param start, when cursor at end');
ok(getLeftMargin() > 30, 'tooltip offset, when cursor at end')
DeveloperToolbar.display.inputter.setCursor({ start: 'help'.length });
DeveloperToolbar.inputter.setCursor({ start: 'help'.length });
is(tooltipPanel._dimensions.start, 0,
'search param start, when cursor at end of command');
ok(getLeftMargin() > 9, 'tooltip offset, when cursor at end of command')
DeveloperToolbar.display.inputter.setCursor({ start: 'help help'.length - 1 });
DeveloperToolbar.inputter.setCursor({ start: 'help help'.length - 1 });
is(tooltipPanel._dimensions.start, 'help '.length,
'search param start, when cursor at penultimate position');
ok(getLeftMargin() > 30, 'tooltip offset, when cursor at penultimate position')
DeveloperToolbar.display.inputter.setCursor({ start: 0 });
DeveloperToolbar.inputter.setCursor({ start: 0 });
is(tooltipPanel._dimensions.start, 0,
'search param start, when cursor at start');
ok(getLeftMargin() > 9, 'tooltip offset, when cursor at start')
@ -63,19 +63,36 @@ add_task(function* testThemes() {
Services.prefs.setCharPref(PREF_DEVTOOLS_THEME, "dark");
yield DeveloperToolbar.display.inputter.setInput("");
yield DeveloperToolbar.display.inputter.setInput("help help");
yield DeveloperToolbar.inputter.setInput("");
yield DeveloperToolbar.inputter.setInput("help help");
is(tooltipPanel.document.documentElement.getAttribute("devtoolstheme"),
"dark", "Tooltip panel has correct theme");
Services.prefs.setCharPref(PREF_DEVTOOLS_THEME, "light");
yield DeveloperToolbar.display.inputter.setInput("");
yield DeveloperToolbar.display.inputter.setInput("help help");
yield DeveloperToolbar.inputter.setInput("");
yield DeveloperToolbar.inputter.setInput("help help");
is(tooltipPanel.document.documentElement.getAttribute("devtoolstheme"),
"light", "Tooltip panel has correct theme");
});
add_task(function* hideToolbar() {
info("Ending browser_toolbar_tooltip.js");
yield DeveloperToolbar.inputter.setInput('');
ok(DeveloperToolbar.visible, "DeveloperToolbar is visible in hideToolbar");
info("Hide toolbar");
let hidePromise = observeOnce(DeveloperToolbar.NOTIFICATIONS.HIDE);
document.getElementById("Tools:DevToolbar").doCommand();
yield hidePromise;
ok(!DeveloperToolbar.visible, "DeveloperToolbar is not visible in hideToolbar");
info("Done test");
});
function getLeftMargin() {
let style = DeveloperToolbar.tooltipPanel._panel.style.marginLeft;
return parseInt(style.slice(0, -2), 10);

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

@ -4,12 +4,30 @@
"use strict";
const gcli = require("gcli/index");
const l10n = require("gcli/l10n");
/**
* The `edit` command opens the toolbox to the style editor, with a given
* stylesheet open.
*
* This command is tricky. The 'edit' command uses the toolbox, so it's
* clearly runAt:client, but it uses the 'resource' type which accesses the
* DOM, so it must also be runAt:server.
*
* Our solution is to have the command technically be runAt:server, but to not
* actually do anything other than basically `return args;`, and have the
* converter (all converters are runAt:client) do the actual work of opening
* a toolbox.
*
* For alternative solutions that we considered, see the comment on commit
* 2645af7.
*/
exports.items = [{
item: "command",
runAt: "server",
name: "edit",
description: gcli.lookup("editDesc"),
manual: gcli.lookup("editManual2"),
description: l10n.lookup("editDesc"),
manual: l10n.lookup("editManual2"),
params: [
{
name: 'resource',
@ -17,7 +35,7 @@ exports.items = [{
name: 'resource',
include: 'text/css'
},
description: gcli.lookup("editResourceDesc")
description: l10n.lookup("editResourceDesc")
},
{
name: "line",
@ -27,15 +45,23 @@ exports.items = [{
min: 1,
step: 10
},
description: gcli.lookup("editLineToJumpToDesc")
description: l10n.lookup("editLineToJumpToDesc")
}
],
returnType: "editArgs",
exec: args => {
return { href: args.resource.name, line: args.line };
}
}, {
item: "converter",
from: "editArgs",
to: "dom",
exec: function(args, context) {
let target = context.environment.target;
let gDevTools = require("resource:///modules/devtools/gDevTools.jsm").gDevTools;
return gDevTools.showToolbox(target, "styleeditor").then(function(toolbox) {
let styleEditor = toolbox.getCurrentPanel();
styleEditor.selectStyleSheet(args.resource.element, args.line);
styleEditor.selectStyleSheet(args.href, args.line);
return null;
});
}

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

@ -176,14 +176,6 @@ add_task(function* () {
setup: "edit css#style2",
check: {
input: "edit css#style2",
args: {
resource: {
value: function(resource) {
let style2 = options.window.document.getElementById("style2");
return resource.element.ownerNode == style2;
}
}
}
},
exec: { output: "" }
},

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

@ -4,7 +4,7 @@
"use strict";
const gcli = require("gcli/index");
const l10n = require("gcli/l10n");
// Fetch TiltManager using the current loader, but don't save a
// reference to it, because it might change with a tool reload.
@ -19,18 +19,18 @@ Object.defineProperty(this, "TiltManager", {
exports.items = [
{
name: 'tilt',
description: gcli.lookup("tiltDesc"),
manual: gcli.lookup("tiltManual"),
description: l10n.lookup("tiltDesc"),
manual: l10n.lookup("tiltManual"),
hidden: true
},
{
name: 'tilt open',
description: gcli.lookup("tiltOpenDesc"),
manual: gcli.lookup("tiltOpenManual"),
description: l10n.lookup("tiltOpenDesc"),
manual: l10n.lookup("tiltOpenManual"),
hidden: true,
exec: function(args, context) {
if (isMultiProcess(context)) {
return gcli.lookupFormat("notAvailableInE10S", [this.name]);
return l10n.lookupFormat("notAvailableInE10S", [this.name]);
}
let chromeWindow = context.environment.chromeDocument.defaultView;
@ -44,7 +44,7 @@ exports.items = [
name: "tilt toggle",
buttonId: "command-button-tilt",
buttonClass: "command-button command-button-invertable",
tooltipText: gcli.lookup("tiltToggleTooltip"),
tooltipText: l10n.lookup("tiltToggleTooltip"),
hidden: true,
state: {
isChecked: function(aTarget) {
@ -66,7 +66,7 @@ exports.items = [
},
exec: function(args, context) {
if (isMultiProcess(context)) {
return gcli.lookupFormat("notAvailableInE10S", [this.name]);
return l10n.lookupFormat("notAvailableInE10S", [this.name]);
}
let chromeWindow = context.environment.chromeDocument.defaultView;
@ -76,28 +76,28 @@ exports.items = [
},
{
name: 'tilt translate',
description: gcli.lookup("tiltTranslateDesc"),
manual: gcli.lookup("tiltTranslateManual"),
description: l10n.lookup("tiltTranslateDesc"),
manual: l10n.lookup("tiltTranslateManual"),
hidden: true,
params: [
{
name: "x",
type: "number",
defaultValue: 0,
description: gcli.lookup("tiltTranslateXDesc"),
manual: gcli.lookup("tiltTranslateXManual")
description: l10n.lookup("tiltTranslateXDesc"),
manual: l10n.lookup("tiltTranslateXManual")
},
{
name: "y",
type: "number",
defaultValue: 0,
description: gcli.lookup("tiltTranslateYDesc"),
manual: gcli.lookup("tiltTranslateYManual")
description: l10n.lookup("tiltTranslateYDesc"),
manual: l10n.lookup("tiltTranslateYManual")
}
],
exec: function(args, context) {
if (isMultiProcess(context)) {
return gcli.lookupFormat("notAvailableInE10S", [this.name]);
return l10n.lookupFormat("notAvailableInE10S", [this.name]);
}
let chromeWindow = context.environment.chromeDocument.defaultView;
@ -109,35 +109,35 @@ exports.items = [
},
{
name: 'tilt rotate',
description: gcli.lookup("tiltRotateDesc"),
manual: gcli.lookup("tiltRotateManual"),
description: l10n.lookup("tiltRotateDesc"),
manual: l10n.lookup("tiltRotateManual"),
hidden: true,
params: [
{
name: "x",
type: { name: 'number', min: -360, max: 360, step: 10 },
defaultValue: 0,
description: gcli.lookup("tiltRotateXDesc"),
manual: gcli.lookup("tiltRotateXManual")
description: l10n.lookup("tiltRotateXDesc"),
manual: l10n.lookup("tiltRotateXManual")
},
{
name: "y",
type: { name: 'number', min: -360, max: 360, step: 10 },
defaultValue: 0,
description: gcli.lookup("tiltRotateYDesc"),
manual: gcli.lookup("tiltRotateYManual")
description: l10n.lookup("tiltRotateYDesc"),
manual: l10n.lookup("tiltRotateYManual")
},
{
name: "z",
type: { name: 'number', min: -360, max: 360, step: 10 },
defaultValue: 0,
description: gcli.lookup("tiltRotateZDesc"),
manual: gcli.lookup("tiltRotateZManual")
description: l10n.lookup("tiltRotateZDesc"),
manual: l10n.lookup("tiltRotateZManual")
}
],
exec: function(args, context) {
if (isMultiProcess(context)) {
return gcli.lookupFormat("notAvailableInE10S", [this.name]);
return l10n.lookupFormat("notAvailableInE10S", [this.name]);
}
let chromeWindow = context.environment.chromeDocument.defaultView;
@ -149,20 +149,20 @@ exports.items = [
},
{
name: 'tilt zoom',
description: gcli.lookup("tiltZoomDesc"),
manual: gcli.lookup("tiltZoomManual"),
description: l10n.lookup("tiltZoomDesc"),
manual: l10n.lookup("tiltZoomManual"),
hidden: true,
params: [
{
name: "zoom",
type: { name: 'number' },
description: gcli.lookup("tiltZoomAmountDesc"),
manual: gcli.lookup("tiltZoomAmountManual")
description: l10n.lookup("tiltZoomAmountDesc"),
manual: l10n.lookup("tiltZoomAmountManual")
}
],
exec: function(args, context) {
if (isMultiProcess(context)) {
return gcli.lookupFormat("notAvailableInE10S", [this.name]);
return l10n.lookupFormat("notAvailableInE10S", [this.name]);
}
let chromeWindow = context.environment.chromeDocument.defaultView;
@ -175,12 +175,12 @@ exports.items = [
},
{
name: 'tilt reset',
description: gcli.lookup("tiltResetDesc"),
manual: gcli.lookup("tiltResetManual"),
description: l10n.lookup("tiltResetDesc"),
manual: l10n.lookup("tiltResetManual"),
hidden: true,
exec: function(args, context) {
if (isMultiProcess(context)) {
return gcli.lookupFormat("notAvailableInE10S", [this.name]);
return l10n.lookupFormat("notAvailableInE10S", [this.name]);
}
let chromeWindow = context.environment.chromeDocument.defaultView;
@ -193,12 +193,12 @@ exports.items = [
},
{
name: 'tilt close',
description: gcli.lookup("tiltCloseDesc"),
manual: gcli.lookup("tiltCloseManual"),
description: l10n.lookup("tiltCloseDesc"),
manual: l10n.lookup("tiltCloseManual"),
hidden: true,
exec: function(args, context) {
if (isMultiProcess(context)) {
return gcli.lookupFormat("notAvailableInE10S", [this.name]);
return l10n.lookupFormat("notAvailableInE10S", [this.name]);
}
let chromeWindow = context.environment.chromeDocument.defaultView;

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

@ -4,16 +4,18 @@
"use strict";
const gcli = require("gcli/index");
const { gDevTools } = require("resource:///modules/devtools/gDevTools.jsm");
const l10n = require("gcli/l10n");
loader.lazyGetter(this, "gDevTools", () => require("resource:///modules/devtools/gDevTools.jsm").gDevTools);
exports.items = [
{
item: "command",
runAt: "client",
name: 'splitconsole',
hidden: true,
buttonId: "command-button-splitconsole",
buttonClass: "command-button command-button-invertable",
tooltipText: gcli.lookup("splitconsoleTooltip"),
tooltipText: l10n.lookup("splitconsoleTooltip"),
isRemoteSafe: true,
state: {
isChecked: function(target) {
@ -51,12 +53,14 @@ exports.items = [
},
{
name: "console",
description: gcli.lookup("consoleDesc"),
manual: gcli.lookup("consoleManual")
description: l10n.lookup("consoleDesc"),
manual: l10n.lookup("consoleManual")
},
{
item: "command",
runAt: "client",
name: "console clear",
description: gcli.lookup("consoleclearDesc"),
description: l10n.lookup("consoleclearDesc"),
exec: function(args, context) {
let toolbox = gDevTools.getToolbox(context.environment.target);
if (toolbox == null) {
@ -72,17 +76,24 @@ exports.items = [
}
},
{
item: "command",
runAt: "client",
name: "console close",
description: gcli.lookup("consolecloseDesc"),
description: l10n.lookup("consolecloseDesc"),
exec: function(args, context) {
return gDevTools.closeToolbox(context.environment.target);
return gDevTools.closeToolbox(context.environment.target)
.then(() => {}); // Don't return a value to GCLI
}
},
{
item: "command",
runAt: "client",
name: "console open",
description: gcli.lookup("consoleopenDesc"),
description: l10n.lookup("consoleopenDesc"),
exec: function(args, context) {
return gDevTools.showToolbox(context.environment.target, "webconsole");
const target = context.environment.target;
return gDevTools.showToolbox(target, "webconsole")
.then(() => {}); // Don't return a value to GCLI
}
}
];

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

@ -7,6 +7,8 @@
const {Cc, Ci, Cu} = require("chrome");
const { Services } = require("resource://gre/modules/Services.jsm");
loader.lazyImporter(this, "VariablesView", "resource:///modules/devtools/VariablesView.jsm");
loader.lazyImporter(this, "escapeHTML", "resource:///modules/devtools/VariablesView.jsm");
loader.lazyImporter(this, "gDevTools", "resource:///modules/devtools/gDevTools.jsm");

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

@ -51,7 +51,7 @@ cliOptions=Available Options
# LOCALIZATION NOTE: The error message when the user types a command that
# isn't registered
cliUnknownCommand=Invalid Command
cliUnknownCommand2=Invalid Command: '%1$S'.
# LOCALIZATION NOTE: A parameter should have a value, but doesn't
cliIncompleteParam=Value required for '%1$S'.

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

@ -82,6 +82,10 @@ screenshotChromeManual2=True if you want to take the screenshot of the %1$S wind
# the screenshot command.
screenshotGroupOptions=Options
# LOCALIZATION NOTE (screenshotGroupOptions) A label for the advanced options of
# the screenshot command.
screenshotAdvancedOptions=Advanced Options
# LOCALIZATION NOTE (screenshotDelayDesc) A very short string to describe
# the 'delay' parameter to the 'screenshot' command, which is displayed in
# a dialog when the user is using this command.
@ -132,6 +136,25 @@ screenshotCopied=Copied to clipboard.
# LOCALIZATION NOTE (screenshotTooltip) Text displayed as tooltip for screenshot button in devtools ToolBox.
screenshotTooltip=Take a fullpage screenshot
# LOCALIZATION NOTE (screenshotImgurDesc) A very short string to describe
# the 'imgur' parameter to the 'screenshot' command, which is displayed in
# a dialog when the user is using this command.
screenshotImgurDesc=Upload to imgur.com
# LOCALIZATION NOTE (screenshotImgurManual) A fuller description of the
# 'imgur' parameter to the 'screenshot' command, displayed when the user
# asks for help on what it does.
screenshotImgurManual=Use if you want to upload to imgur.com instead of saving to disk
# LOCALIZATION NOTE (screenshotImgurError) Text displayed to user upon
# encountering error while uploading the screenshot to imgur.com.
screenshotImgurError=Could not reach imgur API
# LOCALIZATION NOTE (screenshotImgurUploading) Text displayed to user when the
# screenshot is successfully sent to Imgur but the program is waiting on a response.
# The argument (%1$S) is a new image URL at Imgur.
screenshotImgurUploaded=Uploaded to %1$S
# LOCALIZATION NOTE (highlightDesc) A very short description of the
# 'highlight' command. See highlightManual for a fuller description of what
# it does. This string is designed to be shown in a menu alongside the

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

@ -79,6 +79,7 @@ BuiltinProvider.prototype = {
// corresponding addition to the SrcdirProvider mapping below as well.
"": "resource://gre/modules/commonjs/",
"main": "resource:///modules/devtools/main.js",
"definitions": "resource:///modules/devtools/definitions.js",
"devtools": "resource:///modules/devtools",
"devtools/toolkit": "resource://gre/modules/devtools",
"devtools/server": "resource://gre/modules/devtools/server",
@ -135,6 +136,7 @@ SrcdirProvider.prototype = {
let devtoolsDir = OS.Path.join(srcdir, "browser", "devtools");
let toolkitDir = OS.Path.join(srcdir, "toolkit", "devtools");
let mainURI = this.fileURI(OS.Path.join(devtoolsDir, "main.js"));
let definitionsURI = this.fileURI(OS.Path.join(devtoolsDir, "definitions.js"));
let devtoolsURI = this.fileURI(devtoolsDir);
let toolkitURI = this.fileURI(toolkitDir);
let serverURI = this.fileURI(OS.Path.join(toolkitDir, "server"));
@ -161,6 +163,7 @@ SrcdirProvider.prototype = {
paths: {
"": "resource://gre/modules/commonjs/",
"main": mainURI,
"definitions": definitionsURI,
"devtools": devtoolsURI,
"devtools/toolkit": toolkitURI,
"devtools/server": serverURI,

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

@ -19,11 +19,7 @@ Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "console",
"resource://gre/modules/devtools/Console.jsm");
'do not use strict';
// WARNING: do not 'use strict' without reading the notes in envEval();
// Also don't remove the 'do not use strict' marker. The orion build uses these
// markers to know where to insert AMD headers.
'use strict';
/**
* For full documentation, see:
@ -69,9 +65,9 @@ var template = function(node, data, options) {
processNode(state, node, data);
};
//
//
//
if (typeof exports !== 'undefined') {
exports.template = template;
}
/**
* Helper for the places where we need to act asynchronously and keep track of
@ -182,6 +178,7 @@ function processNode(state, node, data) {
replacement = envEval(state, value.slice(2, -1), data, value);
if (replacement && typeof replacement.then === 'function') {
node.setAttribute(name, '');
/* jshint loopfunc:true */
replacement.then(function(newValue) {
node.setAttribute(name, newValue);
}).then(null, console.error);
@ -361,15 +358,16 @@ function processForEachMember(state, member, templNode, siblingNode, data, param
});
newData[paramName] = reply;
if (node.parentNode != null) {
var clone;
if (templNode.nodeName.toLowerCase() === 'loop') {
for (var i = 0; i < templNode.childNodes.length; i++) {
var clone = templNode.childNodes[i].cloneNode(true);
clone = templNode.childNodes[i].cloneNode(true);
node.parentNode.insertBefore(clone, node);
processNode(cState, clone, newData);
}
}
else {
var clone = templNode.cloneNode(true);
clone = templNode.cloneNode(true);
clone.removeAttribute('foreach');
node.parentNode.insertBefore(clone, node);
processNode(cState, clone, newData);
@ -543,10 +541,6 @@ function property(state, path, data, newValue) {
/**
* Like eval, but that creates a context of the variables in <tt>env</tt> in
* which the script is evaluated.
* WARNING: This script uses 'with' which is generally regarded to be evil.
* The alternative is to create a Function at runtime that takes X parameters
* according to the X keys in the env object, and then call that function using
* the values in the env object. This is likely to be slow, but workable.
* @param script The string to be evaluated.
* @param data The environment in which to eval the script.
* @param frame Optional debugging string in case of failure.
@ -566,9 +560,26 @@ function envEval(state, script, data, frame) {
' can not be resolved using a simple property path.');
return '${' + script + '}';
}
with (data) {
return eval(script);
}
// What we're looking to do is basically:
// with(data) { return eval(script); }
// except in strict mode where 'with' is banned.
// So we create a function which has a parameter list the same as the
// keys in 'data' and with 'script' as its function body.
// We then call this function with the values in 'data'
var keys = allKeys(data);
var func = Function.apply(null, keys.concat("return " + script));
var values = keys.map(function(key) { return data[key]; });
return func.apply(null, values);
// TODO: The 'with' method is different from the code above in the value
// of 'this' when calling functions. For example:
// envEval(state, 'foo()', { foo: function() { return this; } }, ...);
// The global for 'foo' when using 'with' is the data object. However the
// code above, the global is null. (Using 'func.apply(data, values)'
// changes 'this' in the 'foo()' frame, but not in the inside the body
// of 'foo', so that wouldn't help)
}
}
catch (ex) {
@ -580,6 +591,15 @@ function envEval(state, script, data, frame) {
}
}
/**
* Object.keys() that respects the prototype chain
*/
function allKeys(data) {
var keys = [];
for (var key in data) { keys.push(key); }
return keys;
}
/**
* A generic way of reporting errors, for easy overloading in different
* environments.
@ -599,5 +619,5 @@ function handleError(state, message, ex) {
* @param message the error message to report.
*/
function logError(message) {
console.log(message);
console.error(message);
}

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

@ -4,9 +4,33 @@
"use strict";
/**
* You can't require the AddonManager in a child process, but GCLI wants to
* check for 'items' in all processes, so we return empty array if the
* AddonManager is not available
*/
function getAddonManager() {
try {
return {
AddonManager: require("resource://gre/modules/AddonManager.jsm").AddonManager,
addonManagerActive: true
};
}
catch (ex) {
// Fake up an AddonManager just enough to let the file load
return {
AddonManager: {
getAllAddons() {},
getAddonsByTypes() {}
},
addonManagerActive: false
};
}
}
const { Cc, Ci, Cu } = require("chrome");
const { AddonManager } = Cu.import("resource://gre/modules/AddonManager.jsm", {});
const gcli = require("gcli/index");
const { AddonManager, addonManagerActive } = getAddonManager();
const l10n = require("gcli/l10n");
const { Promise: promise } = require("resource://gre/modules/Promise.jsm");
const BRAND_SHORT_NAME = Cc["@mozilla.org/intl/stringbundle;1"]
@ -49,7 +73,7 @@ function pendingOperations(addon) {
}, []);
}
exports.items = [
var items = [
{
item: "type",
name: "addon",
@ -76,11 +100,11 @@ exports.items = [
},
{
name: "addon",
description: gcli.lookup("addonDesc")
description: l10n.lookup("addonDesc")
},
{
name: "addon list",
description: gcli.lookup("addonListDesc"),
description: l10n.lookup("addonListDesc"),
returnType: "addonsInfo",
params: [{
name: "type",
@ -89,7 +113,7 @@ exports.items = [
data: [ "dictionary", "extension", "locale", "plugin", "theme", "all" ]
},
defaultValue: "all",
description: gcli.lookup("addonListTypeDesc")
description: l10n.lookup("addonListTypeDesc")
}],
exec: function(args, context) {
let types = (args.type === "all") ? null : [ args.type ];
@ -114,7 +138,7 @@ exports.items = [
if (!addonsInfo.addons.length) {
return context.createView({
html: "<p>${message}</p>",
data: { message: gcli.lookup("addonNoneOfType") }
data: { message: l10n.lookup("addonNoneOfType") }
});
}
@ -126,7 +150,7 @@ exports.items = [
"theme": "addonListThemeHeading",
"all": "addonListAllHeading"
};
let header = gcli.lookup(headerLookups[addonsInfo.type] ||
let header = l10n.lookup(headerLookups[addonsInfo.type] ||
"addonListUnknownHeading");
let operationLookups = {
@ -138,7 +162,7 @@ exports.items = [
};
function lookupOperation(opName) {
let lookupName = operationLookups[opName];
return lookupName ? gcli.lookup(lookupName) : opName;
return lookupName ? l10n.lookup(lookupName) : opName;
}
function arrangeAddons(addons) {
@ -193,14 +217,14 @@ exports.items = [
status: addon.isActive ? "enabled" : "disabled",
version: addon.version,
pendingOperations: addon.pendingOperations.length ?
(" (" + gcli.lookup("addonPending") + ": "
(" (" + l10n.lookup("addonPending") + ": "
+ addon.pendingOperations.map(lookupOperation).join(", ")
+ ")") :
"",
toggleActionName: isActiveForToggle(addon) ? "disable": "enable",
toggleActionMessage: isActiveForToggle(addon) ?
gcli.lookup("addonListOutDisable") :
gcli.lookup("addonListOutEnable")
l10n.lookup("addonListOutDisable") :
l10n.lookup("addonListOutEnable")
};
}),
onclick: context.update,
@ -210,33 +234,37 @@ exports.items = [
}
},
{
item: "command",
runAt: "client",
name: "addon enable",
description: gcli.lookup("addonEnableDesc"),
description: l10n.lookup("addonEnableDesc"),
params: [
{
name: "addon",
type: "addon",
description: gcli.lookup("addonNameDesc")
description: l10n.lookup("addonNameDesc")
}
],
exec: function(args, context) {
let name = (args.addon.name + " " + args.addon.version).trim();
if (args.addon.userDisabled) {
args.addon.userDisabled = false;
return gcli.lookupFormat("addonEnabled", [ name ]);
return l10n.lookupFormat("addonEnabled", [ name ]);
}
return gcli.lookupFormat("addonAlreadyEnabled", [ name ]);
return l10n.lookupFormat("addonAlreadyEnabled", [ name ]);
}
},
{
item: "command",
runAt: "client",
name: "addon disable",
description: gcli.lookup("addonDisableDesc"),
description: l10n.lookup("addonDisableDesc"),
params: [
{
name: "addon",
type: "addon",
description: gcli.lookup("addonNameDesc")
description: l10n.lookup("addonNameDesc")
}
],
exec: function(args, context) {
@ -247,10 +275,12 @@ exports.items = [
if (!args.addon.userDisabled ||
args.addon.userDisabled === AddonManager.STATE_ASK_TO_ACTIVATE) {
args.addon.userDisabled = true;
return gcli.lookupFormat("addonDisabled", [ name ]);
return l10n.lookupFormat("addonDisabled", [ name ]);
}
return gcli.lookupFormat("addonAlreadyDisabled", [ name ]);
return l10n.lookupFormat("addonAlreadyDisabled", [ name ]);
}
}
];
exports.items = addonManagerActive ? items : [];

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

@ -4,19 +4,22 @@
"use strict";
const gcli = require("gcli/index");
const l10n = require("gcli/l10n");
loader.lazyImporter(this, "AppCacheUtils", "resource:///modules/devtools/AppCacheUtils.jsm");
exports.items = [
{
item: "command",
name: "appcache",
description: gcli.lookup("appCacheDesc")
description: l10n.lookup("appCacheDesc")
},
{
item: "command",
runAt: "server",
name: "appcache validate",
description: gcli.lookup("appCacheValidateDesc"),
manual: gcli.lookup("appCacheValidateManual"),
description: l10n.lookup("appCacheValidateDesc"),
manual: l10n.lookup("appCacheValidateManual"),
returnType: "appcacheerrors",
params: [{
group: "options",
@ -24,7 +27,7 @@ exports.items = [
{
type: "string",
name: "uri",
description: gcli.lookup("appCacheValidateUriDesc"),
description: l10n.lookup("appCacheValidateUriDesc"),
defaultValue: null,
}
]
@ -53,7 +56,7 @@ exports.items = [
exec: function([errors, manifestURI], context) {
if (errors.length == 0) {
return context.createView({
html: "<span>" + gcli.lookup("appCacheValidatedSuccessfully") + "</span>"
html: "<span>" + l10n.lookup("appCacheValidatedSuccessfully") + "</span>"
});
}
@ -73,20 +76,24 @@ exports.items = [
}
},
{
item: "command",
runAt: "server",
name: "appcache clear",
description: gcli.lookup("appCacheClearDesc"),
manual: gcli.lookup("appCacheClearManual"),
description: l10n.lookup("appCacheClearDesc"),
manual: l10n.lookup("appCacheClearManual"),
exec: function(args, context) {
let utils = new AppCacheUtils(args.uri);
utils.clearAll();
return gcli.lookup("appCacheClearCleared");
return l10n.lookup("appCacheClearCleared");
}
},
{
item: "command",
runAt: "server",
name: "appcache list",
description: gcli.lookup("appCacheListDesc"),
manual: gcli.lookup("appCacheListManual"),
description: l10n.lookup("appCacheListDesc"),
manual: l10n.lookup("appCacheListManual"),
returnType: "appcacheentries",
params: [{
group: "options",
@ -94,7 +101,7 @@ exports.items = [
{
type: "string",
name: "search",
description: gcli.lookup("appCacheListSearchDesc"),
description: l10n.lookup("appCacheListSearchDesc"),
defaultValue: null,
},
]
@ -115,35 +122,35 @@ exports.items = [
" <li foreach='entry in ${entries}'>" +
" <table class='gcli-appcache-detail'>" +
" <tr>" +
" <td>" + gcli.lookup("appCacheListKey") + "</td>" +
" <td>" + l10n.lookup("appCacheListKey") + "</td>" +
" <td>${entry.key}</td>" +
" </tr>" +
" <tr>" +
" <td>" + gcli.lookup("appCacheListFetchCount") + "</td>" +
" <td>" + l10n.lookup("appCacheListFetchCount") + "</td>" +
" <td>${entry.fetchCount}</td>" +
" </tr>" +
" <tr>" +
" <td>" + gcli.lookup("appCacheListLastFetched") + "</td>" +
" <td>" + l10n.lookup("appCacheListLastFetched") + "</td>" +
" <td>${entry.lastFetched}</td>" +
" </tr>" +
" <tr>" +
" <td>" + gcli.lookup("appCacheListLastModified") + "</td>" +
" <td>" + l10n.lookup("appCacheListLastModified") + "</td>" +
" <td>${entry.lastModified}</td>" +
" </tr>" +
" <tr>" +
" <td>" + gcli.lookup("appCacheListExpirationTime") + "</td>" +
" <td>" + l10n.lookup("appCacheListExpirationTime") + "</td>" +
" <td>${entry.expirationTime}</td>" +
" </tr>" +
" <tr>" +
" <td>" + gcli.lookup("appCacheListDataSize") + "</td>" +
" <td>" + l10n.lookup("appCacheListDataSize") + "</td>" +
" <td>${entry.dataSize}</td>" +
" </tr>" +
" <tr>" +
" <td>" + gcli.lookup("appCacheListDeviceID") + "</td>" +
" <td>" + l10n.lookup("appCacheListDeviceID") + "</td>" +
" <td>${entry.deviceID} <span class='gcli-out-shortcut' " +
"onclick='${onclick}' ondblclick='${ondblclick}' " +
"data-command='appcache viewentry ${entry.key}'" +
">" + gcli.lookup("appCacheListViewEntry") + "</span>" +
">" + l10n.lookup("appCacheListViewEntry") + "</span>" +
" </td>" +
" </tr>" +
" </table>" +
@ -158,14 +165,16 @@ exports.items = [
}
},
{
item: "command",
runAt: "server",
name: "appcache viewentry",
description: gcli.lookup("appCacheViewEntryDesc"),
manual: gcli.lookup("appCacheViewEntryManual"),
description: l10n.lookup("appCacheViewEntryDesc"),
manual: l10n.lookup("appCacheViewEntryManual"),
params: [
{
type: "string",
name: "key",
description: gcli.lookup("appCacheViewEntryKey"),
description: l10n.lookup("appCacheViewEntryKey"),
defaultValue: null,
}
],

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

@ -6,6 +6,7 @@
const { Cc, Ci, Cu } = require("chrome");
const TargetFactory = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools.TargetFactory;
const l10n = require("gcli/l10n");
const gcli = require("gcli/index");
loader.lazyImporter(this, "gDevTools", "resource:///modules/devtools/gDevTools.jsm");
@ -24,11 +25,13 @@ let sandboxes = [];
exports.items = [
{
name: "calllog",
description: gcli.lookup("calllogDesc")
description: l10n.lookup("calllogDesc")
},
{
item: "command",
runAt: "client",
name: "calllog start",
description: gcli.lookup("calllogStartDesc"),
description: l10n.lookup("calllogStartDesc"),
exec: function(args, context) {
let contentWindow = context.environment.window;
@ -45,7 +48,7 @@ exports.items = [
let target = TargetFactory.forTab(gBrowser.selectedTab);
gDevTools.showToolbox(target, "webconsole");
return gcli.lookup("calllogStartReply");
return l10n.lookup("calllogStartReply");
},
callDescription: function(frame) {
@ -72,13 +75,15 @@ exports.items = [
}
},
{
item: "command",
runAt: "client",
name: "calllog stop",
description: gcli.lookup("calllogStopDesc"),
description: l10n.lookup("calllogStopDesc"),
exec: function(args, context) {
let numDebuggers = debuggers.length;
if (numDebuggers == 0) {
return gcli.lookup("calllogStopNoLogging");
return l10n.lookup("calllogStopNoLogging");
}
for (let dbg of debuggers) {
@ -86,12 +91,14 @@ exports.items = [
}
debuggers = [];
return gcli.lookupFormat("calllogStopReply", [ numDebuggers ]);
return l10n.lookupFormat("calllogStopReply", [ numDebuggers ]);
}
},
{
item: "command",
runAt: "client",
name: "calllog chromestart",
description: gcli.lookup("calllogChromeStartDesc"),
description: l10n.lookup("calllogChromeStartDesc"),
get hidden() gcli.hiddenByChromePref(),
params: [
{
@ -104,8 +111,8 @@ exports.items = [
{
name: "source",
type: "string",
description: gcli.lookup("calllogChromeSourceTypeDesc"),
manual: gcli.lookup("calllogChromeSourceTypeManual"),
description: l10n.lookup("calllogChromeSourceTypeDesc"),
manual: l10n.lookup("calllogChromeSourceTypeManual"),
}
],
exec: function(args, context) {
@ -117,20 +124,20 @@ exports.items = [
globalObj = Cu.import(args.source);
}
catch (e) {
return gcli.lookup("callLogChromeInvalidJSM");
return l10n.lookup("callLogChromeInvalidJSM");
}
} else if (args.sourceType == "content-variable") {
if (args.source in contentWindow) {
globalObj = Cu.getGlobalForObject(contentWindow[args.source]);
} else {
throw new Error(gcli.lookup("callLogChromeVarNotFoundContent"));
throw new Error(l10n.lookup("callLogChromeVarNotFoundContent"));
}
} else if (args.sourceType == "chrome-variable") {
let chromeWin = context.environment.chromeDocument.defaultView;
if (args.source in chromeWin) {
globalObj = Cu.getGlobalForObject(chromeWin[args.source]);
} else {
return gcli.lookup("callLogChromeVarNotFoundChrome");
return l10n.lookup("callLogChromeVarNotFoundChrome");
}
} else {
let chromeWin = context.environment.chromeDocument.defaultView;
@ -147,13 +154,13 @@ exports.items = [
} catch(e) {
// We need to save the message before cleaning up else e contains a dead
// object.
let msg = gcli.lookup("callLogChromeEvalException") + ": " + e;
let msg = l10n.lookup("callLogChromeEvalException") + ": " + e;
Cu.nukeSandbox(sandbox);
return msg;
}
if (typeof returnVal == "undefined") {
return gcli.lookup("callLogChromeEvalNeedsObject");
return l10n.lookup("callLogChromeEvalNeedsObject");
}
globalObj = Cu.getGlobalForObject(returnVal);
@ -164,7 +171,7 @@ exports.items = [
dbg.onEnterFrame = function(frame) {
// BUG 773652 - Make the output from the GCLI calllog command nicer
contentWindow.console.log(gcli.lookup("callLogChromeMethodCall") +
contentWindow.console.log(l10n.lookup("callLogChromeMethodCall") +
": " + this.callDescription(frame));
}.bind(this);
@ -172,7 +179,7 @@ exports.items = [
let target = TargetFactory.forTab(gBrowser.selectedTab);
gDevTools.showToolbox(target, "webconsole");
return gcli.lookup("calllogChromeStartReply");
return l10n.lookup("calllogChromeStartReply");
},
valueToString: function(value) {
@ -182,19 +189,21 @@ exports.items = [
},
callDescription: function(frame) {
let name = frame.callee.name || gcli.lookup("callLogChromeAnonFunction");
let name = frame.callee.name || l10n.lookup("callLogChromeAnonFunction");
let args = frame.arguments.map(this.valueToString).join(", ");
return name + "(" + args + ")";
}
},
{
item: "command",
runAt: "client",
name: "calllog chromestop",
description: gcli.lookup("calllogChromeStopDesc"),
description: l10n.lookup("calllogChromeStopDesc"),
get hidden() gcli.hiddenByChromePref(),
exec: function(args, context) {
let numDebuggers = chromeDebuggers.length;
if (numDebuggers == 0) {
return gcli.lookup("calllogChromeStopNoLogging");
return l10n.lookup("calllogChromeStopNoLogging");
}
for (let dbg of chromeDebuggers) {
@ -207,7 +216,7 @@ exports.items = [
chromeDebuggers = [];
sandboxes = [];
return gcli.lookupFormat("calllogChromeStopReply", [ numDebuggers ]);
return l10n.lookupFormat("calllogChromeStopReply", [ numDebuggers ]);
}
}
];

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

@ -11,6 +11,7 @@ const { Promise: promise } = require("resource://gre/modules/Promise.jsm");
const { OS } = Cu.import("resource://gre/modules/osfile.jsm", {});
const { TextEncoder, TextDecoder } = Cu.import('resource://gre/modules/commonjs/toolkit/loader.js', {});
const gcli = require("gcli/index");
const l10n = require("gcli/l10n");
loader.lazyGetter(this, "prefBranch", function() {
let prefService = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefService);
@ -127,11 +128,13 @@ exports.items = [
get hidden() {
return !prefBranch.prefHasUserValue(PREF_DIR);
},
description: gcli.lookup("cmdDesc")
description: l10n.lookup("cmdDesc")
},
{
item: "command",
runAt: "client",
name: "cmd refresh",
description: gcli.lookup("cmdRefreshDesc"),
description: l10n.lookup("cmdRefreshDesc"),
get hidden() {
return !prefBranch.prefHasUserValue(PREF_DIR);
},
@ -140,17 +143,19 @@ exports.items = [
let dirName = prefBranch.getComplexValue(PREF_DIR,
Ci.nsISupportsString).data.trim();
return gcli.lookupFormat("cmdStatus3", [ dirName ]);
return l10n.lookupFormat("cmdStatus3", [ dirName ]);
}
},
{
item: "command",
runAt: "client",
name: "cmd setdir",
description: gcli.lookup("cmdSetdirDesc"),
manual: gcli.lookup("cmdSetdirManual2"),
description: l10n.lookup("cmdSetdirDesc"),
manual: l10n.lookup("cmdSetdirManual2"),
params: [
{
name: "directory",
description: gcli.lookup("cmdSetdirDirectoryDesc"),
description: l10n.lookup("cmdSetdirDirectoryDesc"),
type: {
name: "file",
filetype: "directory",
@ -169,7 +174,7 @@ exports.items = [
gcli.load();
return gcli.lookupFormat("cmdStatus3", [ args.directory ]);
return l10n.lookupFormat("cmdStatus3", [ args.directory ]);
}
}
];

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

@ -4,9 +4,14 @@
"use strict";
const { Cc, Ci, Cu } = require("chrome");
const gcli = require("gcli/index");
const cookieMgr = Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager2);
const { Ci, Cc } = require("chrome");
const l10n = require("gcli/l10n");
const URL = require("sdk/url").URL;
XPCOMUtils.defineLazyGetter(this, "cookieMgr", function() {
const { Cc, Ci } = require("chrome");
return Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager2);
});
/**
* Check host value and remove port part as it is not used
@ -26,7 +31,7 @@ function sanitizeHost(host) {
*/
function translateExpires(expires) {
if (expires == 0) {
return gcli.lookup("cookieListOutSession");
return l10n.lookup("cookieListOutSession");
}
return new Date(expires).toLocaleString();
}
@ -49,13 +54,15 @@ function isCookieAtHost(cookie, host) {
exports.items = [
{
name: "cookie",
description: gcli.lookup("cookieDesc"),
manual: gcli.lookup("cookieManual")
description: l10n.lookup("cookieDesc"),
manual: l10n.lookup("cookieManual")
},
{
item: "command",
runAt: "server",
name: "cookie list",
description: gcli.lookup("cookieListDesc"),
manual: gcli.lookup("cookieListManual"),
description: l10n.lookup("cookieListDesc"),
manual: l10n.lookup("cookieListManual"),
returnType: "cookies",
exec: function(args, context) {
let host = sanitizeHost(context.environment.document.location.host);
@ -83,14 +90,16 @@ exports.items = [
}
},
{
item: "command",
runAt: "server",
name: "cookie remove",
description: gcli.lookup("cookieRemoveDesc"),
manual: gcli.lookup("cookieRemoveManual"),
description: l10n.lookup("cookieRemoveDesc"),
manual: l10n.lookup("cookieRemoveManual"),
params: [
{
name: "name",
type: "string",
description: gcli.lookup("cookieRemoveKeyDesc"),
description: l10n.lookup("cookieRemoveKeyDesc"),
}
],
exec: function(args, context) {
@ -114,8 +123,9 @@ exports.items = [
to: "view",
exec: function(cookies, context) {
if (cookies.length == 0) {
let host = sanitizeHost(context.environment.document.location.host);
let msg = gcli.lookupFormat("cookieListOutNoneHost", [ host ]);
let host = new URL(context.environment.target.url).host;
host = sanitizeHost(host);
let msg = l10n.lookupFormat("cookieListOutNoneHost", [ host ]);
return context.createView({ html: "<span>" + msg + "</span>" });
}
@ -126,7 +136,7 @@ exports.items = [
cookie.attrs = (cookie.secure ? "secure" : " ") +
(cookie.httpOnly ? "httpOnly" : " ") +
(cookie.sameDomain ? "sameDomain" : " ") +
(noAttrs ? gcli.lookup("cookieListOutNone") : " ");
(noAttrs ? l10n.lookup("cookieListOutNone") : " ");
}
return context.createView({
@ -136,29 +146,29 @@ exports.items = [
" <div>${cookie.name}=${cookie.value}</div>" +
" <table class='gcli-cookielist-detail'>" +
" <tr>" +
" <td>" + gcli.lookup("cookieListOutHost") + "</td>" +
" <td>" + l10n.lookup("cookieListOutHost") + "</td>" +
" <td>${cookie.host}</td>" +
" </tr>" +
" <tr>" +
" <td>" + gcli.lookup("cookieListOutPath") + "</td>" +
" <td>" + l10n.lookup("cookieListOutPath") + "</td>" +
" <td>${cookie.path}</td>" +
" </tr>" +
" <tr>" +
" <td>" + gcli.lookup("cookieListOutExpires") + "</td>" +
" <td>" + l10n.lookup("cookieListOutExpires") + "</td>" +
" <td>${cookie.expires}</td>" +
" </tr>" +
" <tr>" +
" <td>" + gcli.lookup("cookieListOutAttributes") + "</td>" +
" <td>" + l10n.lookup("cookieListOutAttributes") + "</td>" +
" <td>${cookie.attrs}</td>" +
" </tr>" +
" <tr><td colspan='2'>" +
" <span class='gcli-out-shortcut' onclick='${onclick}'" +
" data-command='cookie set ${cookie.name} '" +
" >" + gcli.lookup("cookieListOutEdit") + "</span>" +
" >" + l10n.lookup("cookieListOutEdit") + "</span>" +
" <span class='gcli-out-shortcut'" +
" onclick='${onclick}' ondblclick='${ondblclick}'" +
" data-command='cookie remove ${cookie.name}'" +
" >" + gcli.lookup("cookieListOutRemove") + "</span>" +
" >" + l10n.lookup("cookieListOutRemove") + "</span>" +
" </td></tr>" +
" </table>" +
" </li>" +
@ -173,55 +183,57 @@ exports.items = [
}
},
{
item: "command",
runAt: "server",
name: "cookie set",
description: gcli.lookup("cookieSetDesc"),
manual: gcli.lookup("cookieSetManual"),
description: l10n.lookup("cookieSetDesc"),
manual: l10n.lookup("cookieSetManual"),
params: [
{
name: "name",
type: "string",
description: gcli.lookup("cookieSetKeyDesc")
description: l10n.lookup("cookieSetKeyDesc")
},
{
name: "value",
type: "string",
description: gcli.lookup("cookieSetValueDesc")
description: l10n.lookup("cookieSetValueDesc")
},
{
group: gcli.lookup("cookieSetOptionsDesc"),
group: l10n.lookup("cookieSetOptionsDesc"),
params: [
{
name: "path",
type: { name: "string", allowBlank: true },
defaultValue: "/",
description: gcli.lookup("cookieSetPathDesc")
description: l10n.lookup("cookieSetPathDesc")
},
{
name: "domain",
type: "string",
defaultValue: null,
description: gcli.lookup("cookieSetDomainDesc")
description: l10n.lookup("cookieSetDomainDesc")
},
{
name: "secure",
type: "boolean",
description: gcli.lookup("cookieSetSecureDesc")
description: l10n.lookup("cookieSetSecureDesc")
},
{
name: "httpOnly",
type: "boolean",
description: gcli.lookup("cookieSetHttpOnlyDesc")
description: l10n.lookup("cookieSetHttpOnlyDesc")
},
{
name: "session",
type: "boolean",
description: gcli.lookup("cookieSetSessionDesc")
description: l10n.lookup("cookieSetSessionDesc")
},
{
name: "expires",
type: "string",
defaultValue: "Jan 17, 2038",
description: gcli.lookup("cookieSetExpiresDesc")
description: l10n.lookup("cookieSetExpiresDesc")
},
]
}

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

@ -6,7 +6,8 @@
const { Cc, Ci } = require("chrome");
const { gDevTools } = require("resource:///modules/devtools/gDevTools.jsm");
loader.lazyGetter(this, "gDevTools", () => require("resource:///modules/devtools/gDevTools.jsm").gDevTools);
const promise = require("resource://gre/modules/Promise.jsm").Promise;
const domtemplate = require("gcli/util/domtemplate");
@ -27,6 +28,8 @@ exports.items = [
description: l10n.lookup("csscoverageDesc"),
},
{
item: "command",
runAt: "client",
name: "csscoverage start",
hidden: true,
description: l10n.lookup("csscoverageStartDesc2"),
@ -48,6 +51,8 @@ exports.items = [
}
},
{
item: "command",
runAt: "client",
name: "csscoverage stop",
hidden: true,
description: l10n.lookup("csscoverageStopDesc2"),
@ -62,6 +67,8 @@ exports.items = [
}
},
{
item: "command",
runAt: "client",
name: "csscoverage oneshot",
hidden: true,
description: l10n.lookup("csscoverageOneShotDesc2"),
@ -76,6 +83,8 @@ exports.items = [
}
},
{
item: "command",
runAt: "client",
name: "csscoverage toggle",
hidden: true,
description: l10n.lookup("csscoverageToggleDesc2"),
@ -110,6 +119,8 @@ exports.items = [
}
},
{
item: "command",
runAt: "client",
name: "csscoverage report",
hidden: true,
description: l10n.lookup("csscoverageReportDesc2"),

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

@ -6,7 +6,7 @@
const { Cc, Ci, Cu, CC } = require("chrome");
const { Services } = require("resource://gre/modules/Services.jsm");
const gcli = require("gcli/index");
const l10n = require("gcli/l10n");
const dirService = Cc["@mozilla.org/file/directory_service;1"]
.getService(Ci.nsIProperties);
@ -19,29 +19,31 @@ function showFolder(aPath) {
if (file.exists()) {
file.reveal();
return gcli.lookupFormat("folderOpenDirResult", [aPath]);
return l10n.lookupFormat("folderOpenDirResult", [aPath]);
} else {
return gcli.lookup("folderInvalidPath");
return l10n.lookup("folderInvalidPath");
}
} catch (e) {
return gcli.lookup("folderInvalidPath");
return l10n.lookup("folderInvalidPath");
}
}
exports.items = [
{
name: "folder",
description: gcli.lookup("folderDesc")
description: l10n.lookup("folderDesc")
},
{
item: "command",
runAt: "client",
name: "folder open",
description: gcli.lookup("folderOpenDesc"),
description: l10n.lookup("folderOpenDesc"),
params: [
{
name: "path",
type: { name: "string", allowBlank: true },
defaultValue: "~",
description: gcli.lookup("folderOpenDir")
description: l10n.lookup("folderOpenDir")
}
],
returnType: "string",
@ -60,8 +62,10 @@ exports.items = [
}
},
{
item: "command",
runAt: "client",
name: "folder openprofile",
description: gcli.lookup("folderOpenProfileDesc"),
description: l10n.lookup("folderOpenProfileDesc"),
returnType: "string",
exec: function(args, context) {
// Get the profile directory.

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

@ -5,7 +5,7 @@
"use strict";
const {Cc, Ci, Cu} = require("chrome");
const gcli = require("gcli/index");
const l10n = require("gcli/l10n");
require("devtools/server/actors/inspector");
const {BoxModelHighlighter} = require("devtools/server/actors/highlighter");
@ -13,6 +13,7 @@ XPCOMUtils.defineLazyGetter(this, "nodesSelected", function() {
return Services.strings.createBundle("chrome://browser/locale/devtools/gclicommands.properties");
});
XPCOMUtils.defineLazyModuleGetter(this, "PluralForm","resource://gre/modules/PluralForm.jsm");
const events = require("sdk/event/core");
// How many maximum nodes can be highlighted in parallel
const MAX_HIGHLIGHTED_ELEMENTS = 100;
@ -34,36 +35,38 @@ function unhighlightAll() {
exports.items = [
{
item: "command",
runAt: "server",
name: "highlight",
description: gcli.lookup("highlightDesc"),
manual: gcli.lookup("highlightManual"),
description: l10n.lookup("highlightDesc"),
manual: l10n.lookup("highlightManual"),
params: [
{
name: "selector",
type: "nodelist",
description: gcli.lookup("highlightSelectorDesc"),
manual: gcli.lookup("highlightSelectorManual")
description: l10n.lookup("highlightSelectorDesc"),
manual: l10n.lookup("highlightSelectorManual")
},
{
group: gcli.lookup("highlightOptionsDesc"),
group: l10n.lookup("highlightOptionsDesc"),
params: [
{
name: "hideguides",
type: "boolean",
description: gcli.lookup("highlightHideGuidesDesc"),
manual: gcli.lookup("highlightHideGuidesManual")
description: l10n.lookup("highlightHideGuidesDesc"),
manual: l10n.lookup("highlightHideGuidesManual")
},
{
name: "showinfobar",
type: "boolean",
description: gcli.lookup("highlightShowInfoBarDesc"),
manual: gcli.lookup("highlightShowInfoBarManual")
description: l10n.lookup("highlightShowInfoBarDesc"),
manual: l10n.lookup("highlightShowInfoBarManual")
},
{
name: "showall",
type: "boolean",
description: gcli.lookup("highlightShowAllDesc"),
manual: gcli.lookup("highlightShowAllManual")
description: l10n.lookup("highlightShowAllDesc"),
manual: l10n.lookup("highlightShowAllManual")
},
{
name: "region",
@ -71,22 +74,22 @@ exports.items = [
name: "selection",
data: ["content", "padding", "border", "margin"]
},
description: gcli.lookup("highlightRegionDesc"),
manual: gcli.lookup("highlightRegionManual"),
description: l10n.lookup("highlightRegionDesc"),
manual: l10n.lookup("highlightRegionManual"),
defaultValue: "border"
},
{
name: "fill",
type: "string",
description: gcli.lookup("highlightFillDesc"),
manual: gcli.lookup("highlightFillManual"),
description: l10n.lookup("highlightFillDesc"),
manual: l10n.lookup("highlightFillManual"),
defaultValue: null
},
{
name: "keep",
type: "boolean",
description: gcli.lookup("highlightKeepDesc"),
manual: gcli.lookup("highlightKeepManual"),
description: l10n.lookup("highlightKeepDesc"),
manual: l10n.lookup("highlightKeepManual"),
}
]
}
@ -100,14 +103,7 @@ exports.items = [
let env = context.environment;
// Unhighlight on navigate
env.target.once("navigate", unhighlightAll);
// Build a tab context for the highlighter (which normally takes a
// TabActor as parameter to its constructor)
let tabContext = {
browser: env.chromeWindow.gBrowser.getBrowserForDocument(env.document),
window: env.window
};
events.on(env.__deprecatedTabActor, "will-navigate", unhighlightAll);
let i = 0;
for (let node of args.selector) {
@ -115,7 +111,7 @@ exports.items = [
break;
}
let highlighter = new BoxModelHighlighter(tabContext);
let highlighter = new BoxModelHighlighter(env.__deprecatedTabActor);
if (args.fill) {
highlighter.regionFill[args.region] = args.fill;
}
@ -133,7 +129,7 @@ exports.items = [
let output = PluralForm.get(args.selector.length, highlightText)
.replace("%1$S", args.selector.length);
if (args.selector.length > i) {
output = gcli.lookupFormat("highlightOutputMaxReached",
output = l10n.lookupFormat("highlightOutputMaxReached",
["" + args.selector.length, "" + i]);
}
@ -141,9 +137,11 @@ exports.items = [
}
},
{
item: "command",
runAt: "server",
name: "unhighlight",
description: gcli.lookup("unhighlightDesc"),
manual: gcli.lookup("unhighlightManual"),
description: l10n.lookup("unhighlightDesc"),
manual: l10n.lookup("unhighlightManual"),
exec: unhighlightAll
}
];

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

@ -6,13 +6,15 @@
const { Services } = require("resource://gre/modules/Services.jsm");
const { listenOnce } = require("devtools/async-utils");
const gcli = require("gcli/index");
const l10n = require("gcli/l10n");
exports.items = [
{
item: "command",
runAt: "server",
name: "inject",
description: gcli.lookup("injectDesc"),
manual: gcli.lookup("injectManual2"),
description: l10n.lookup("injectDesc"),
manual: l10n.lookup("injectManual2"),
params: [{
name: "library",
type: {
@ -49,7 +51,7 @@ exports.items = [
}
]
},
description: gcli.lookup("injectLibraryDesc")
description: l10n.lookup("injectLibraryDesc")
}],
exec: function*(args, context) {
let document = context.environment.document;
@ -67,7 +69,7 @@ exports.items = [
// Check if URI is valid
Services.io.newURI(src, null, null);
} catch(e) {
return gcli.lookupFormat("injectFailed", [name]);
return l10n.lookupFormat("injectFailed", [name]);
}
let newSource = document.createElement("script");
@ -78,7 +80,7 @@ exports.items = [
yield loadPromise;
return gcli.lookupFormat("injectLoaded", [name]);
return l10n.lookupFormat("injectLoaded", [name]);
}
}
];

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

@ -5,7 +5,7 @@
"use strict";
const { Cc, Ci, Cu } = require("chrome");
const gcli = require("gcli/index");
const l10n = require("gcli/l10n");
const XMLHttpRequest = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"];
const { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
@ -15,23 +15,25 @@ devtools.lazyRequireGetter(this, "beautify", "devtools/jsbeautify");
exports.items = [
{
item: "command",
runAt: "client",
name: "jsb",
description: gcli.lookup("jsbDesc"),
description: l10n.lookup("jsbDesc"),
returnValue:"string",
params: [
{
name: "url",
type: "string",
description: gcli.lookup("jsbUrlDesc")
description: l10n.lookup("jsbUrlDesc")
},
{
group: gcli.lookup("jsbOptionsDesc"),
group: l10n.lookup("jsbOptionsDesc"),
params: [
{
name: "indentSize",
type: "number",
description: gcli.lookup("jsbIndentSizeDesc"),
manual: gcli.lookup("jsbIndentSizeManual"),
description: l10n.lookup("jsbIndentSizeDesc"),
manual: l10n.lookup("jsbIndentSizeManual"),
defaultValue: Preferences.get("devtools.editor.tabsize", 2),
},
{
@ -43,27 +45,27 @@ exports.items = [
{ name: "tab", value: "\t" }
]
},
description: gcli.lookup("jsbIndentCharDesc"),
manual: gcli.lookup("jsbIndentCharManual"),
description: l10n.lookup("jsbIndentCharDesc"),
manual: l10n.lookup("jsbIndentCharManual"),
defaultValue: " ",
},
{
name: "doNotPreserveNewlines",
type: "boolean",
description: gcli.lookup("jsbDoNotPreserveNewlinesDesc")
description: l10n.lookup("jsbDoNotPreserveNewlinesDesc")
},
{
name: "preserveMaxNewlines",
type: "number",
description: gcli.lookup("jsbPreserveMaxNewlinesDesc"),
manual: gcli.lookup("jsbPreserveMaxNewlinesManual"),
description: l10n.lookup("jsbPreserveMaxNewlinesDesc"),
manual: l10n.lookup("jsbPreserveMaxNewlinesManual"),
defaultValue: -1
},
{
name: "jslintHappy",
type: "boolean",
description: gcli.lookup("jsbJslintHappyDesc"),
manual: gcli.lookup("jsbJslintHappyManual")
description: l10n.lookup("jsbJslintHappyDesc"),
manual: l10n.lookup("jsbJslintHappyManual")
},
{
name: "braceStyle",
@ -71,20 +73,20 @@ exports.items = [
name: "selection",
data: ["collapse", "expand", "end-expand", "expand-strict"]
},
description: gcli.lookup("jsbBraceStyleDesc2"),
manual: gcli.lookup("jsbBraceStyleManual2"),
description: l10n.lookup("jsbBraceStyleDesc2"),
manual: l10n.lookup("jsbBraceStyleManual2"),
defaultValue: "collapse"
},
{
name: "noSpaceBeforeConditional",
type: "boolean",
description: gcli.lookup("jsbNoSpaceBeforeConditionalDesc")
description: l10n.lookup("jsbNoSpaceBeforeConditionalDesc")
},
{
name: "unescapeStrings",
type: "boolean",
description: gcli.lookup("jsbUnescapeStringsDesc"),
manual: gcli.lookup("jsbUnescapeStringsManual")
description: l10n.lookup("jsbUnescapeStringsDesc"),
manual: l10n.lookup("jsbUnescapeStringsManual")
}
]
}
@ -107,12 +109,12 @@ exports.items = [
try {
xhr.open("GET", args.url, true);
} catch(e) {
return gcli.lookup("jsbInvalidURL");
return l10n.lookup("jsbInvalidURL");
}
let deferred = context.defer();
xhr.onreadystatechange = function(aEvt) {
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if (xhr.status == 200 || xhr.status == 0) {
let browserDoc = context.environment.chromeDocument;
@ -124,8 +126,8 @@ exports.items = [
deferred.resolve();
} else {
deferred.resolve("Unable to load page to beautify: " + args.url + " " +
xhr.status + " " + xhr.statusText);
deferred.reject("Unable to load page to beautify: " + args.url + " " +
xhr.status + " " + xhr.statusText);
}
};
}

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

@ -6,7 +6,7 @@
const { Cc, Ci, Cu } = require("chrome");
const Services = require("Services");
const gcli = require("gcli/index");
const l10n = require("gcli/l10n");
const { XPCOMUtils } = require("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "DevToolsLoader",
"resource://gre/modules/devtools/Loader.jsm");
@ -34,9 +34,11 @@ XPCOMUtils.defineLazyGetter(this, "debuggerServer", () => {
exports.items = [
{
item: "command",
runAt: "client",
name: "listen",
description: gcli.lookup("listenDesc"),
manual: gcli.lookupFormat("listenManual2", [ BRAND_SHORT_NAME ]),
description: l10n.lookup("listenDesc"),
manual: l10n.lookupFormat("listenManual2", [ BRAND_SHORT_NAME ]),
params: [
{
name: "port",
@ -44,23 +46,23 @@ exports.items = [
get defaultValue() {
return Services.prefs.getIntPref("devtools.debugger.chrome-debugging-port");
},
description: gcli.lookup("listenPortDesc"),
description: l10n.lookup("listenPortDesc"),
}
],
exec: function(args, context) {
var listener = debuggerServer.createListener();
if (!listener) {
throw new Error(gcli.lookup("listenDisabledOutput"));
throw new Error(l10n.lookup("listenDisabledOutput"));
}
listener.portOrPath = args.port;
listener.open();
if (debuggerServer.initialized) {
return gcli.lookupFormat("listenInitOutput", [ "" + args.port ]);
return l10n.lookupFormat("listenInitOutput", [ "" + args.port ]);
}
return gcli.lookup("listenNoInitOutput");
return l10n.lookup("listenNoInitOutput");
},
}
];

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

@ -4,21 +4,23 @@
"use strict";
const gcli = require("gcli/index");
const l10n = require("gcli/l10n");
exports.items = [
{
name: "media",
description: gcli.lookup("mediaDesc")
description: l10n.lookup("mediaDesc")
},
{
item: "command",
runAt: "client",
name: "media emulate",
description: gcli.lookup("mediaEmulateDesc"),
manual: gcli.lookup("mediaEmulateManual"),
description: l10n.lookup("mediaEmulateDesc"),
manual: l10n.lookup("mediaEmulateManual"),
params: [
{
name: "type",
description: gcli.lookup("mediaEmulateType"),
description: l10n.lookup("mediaEmulateType"),
type: {
name: "selection",
data: [
@ -35,8 +37,10 @@ exports.items = [
}
},
{
item: "command",
runAt: "client",
name: "media reset",
description: gcli.lookup("mediaResetDesc"),
description: l10n.lookup("mediaResetDesc"),
exec: function(args, context) {
let markupDocumentViewer = context.environment.chromeWindow
.gBrowser.markupDocumentViewer;

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

@ -5,58 +5,60 @@
"use strict";
const { Cc, Ci, Cu } = require("chrome");
const gcli = require("gcli/index");
const l10n = require("gcli/l10n");
exports.items = [
{
name: "pagemod",
description: gcli.lookup("pagemodDesc"),
description: l10n.lookup("pagemodDesc"),
},
{
item: "command",
runAt: "server",
name: "pagemod replace",
description: gcli.lookup("pagemodReplaceDesc"),
description: l10n.lookup("pagemodReplaceDesc"),
params: [
{
name: "search",
type: "string",
description: gcli.lookup("pagemodReplaceSearchDesc"),
description: l10n.lookup("pagemodReplaceSearchDesc"),
},
{
name: "replace",
type: "string",
description: gcli.lookup("pagemodReplaceReplaceDesc"),
description: l10n.lookup("pagemodReplaceReplaceDesc"),
},
{
name: "ignoreCase",
type: "boolean",
description: gcli.lookup("pagemodReplaceIgnoreCaseDesc"),
description: l10n.lookup("pagemodReplaceIgnoreCaseDesc"),
},
{
name: "selector",
type: "string",
description: gcli.lookup("pagemodReplaceSelectorDesc"),
description: l10n.lookup("pagemodReplaceSelectorDesc"),
defaultValue: "*:not(script):not(style):not(embed):not(object):not(frame):not(iframe):not(frameset)",
},
{
name: "root",
type: "node",
description: gcli.lookup("pagemodReplaceRootDesc"),
description: l10n.lookup("pagemodReplaceRootDesc"),
defaultValue: null,
},
{
name: "attrOnly",
type: "boolean",
description: gcli.lookup("pagemodReplaceAttrOnlyDesc"),
description: l10n.lookup("pagemodReplaceAttrOnlyDesc"),
},
{
name: "contentOnly",
type: "boolean",
description: gcli.lookup("pagemodReplaceContentOnlyDesc"),
description: l10n.lookup("pagemodReplaceContentOnlyDesc"),
},
{
name: "attributes",
type: "string",
description: gcli.lookup("pagemodReplaceAttributesDesc"),
description: l10n.lookup("pagemodReplaceAttributesDesc"),
defaultValue: null,
},
],
@ -114,39 +116,41 @@ exports.items = [
}
}
return gcli.lookupFormat("pagemodReplaceResult",
return l10n.lookupFormat("pagemodReplaceResult",
[elements.length, replacedTextNodes,
replacedAttributes]);
}
},
{
name: "pagemod remove",
description: gcli.lookup("pagemodRemoveDesc"),
description: l10n.lookup("pagemodRemoveDesc"),
},
{
item: "command",
runAt: "server",
name: "pagemod remove element",
description: gcli.lookup("pagemodRemoveElementDesc"),
description: l10n.lookup("pagemodRemoveElementDesc"),
params: [
{
name: "search",
type: "string",
description: gcli.lookup("pagemodRemoveElementSearchDesc"),
description: l10n.lookup("pagemodRemoveElementSearchDesc"),
},
{
name: "root",
type: "node",
description: gcli.lookup("pagemodRemoveElementRootDesc"),
description: l10n.lookup("pagemodRemoveElementRootDesc"),
defaultValue: null,
},
{
name: "stripOnly",
type: "boolean",
description: gcli.lookup("pagemodRemoveElementStripOnlyDesc"),
description: l10n.lookup("pagemodRemoveElementStripOnlyDesc"),
},
{
name: "ifEmptyOnly",
type: "boolean",
description: gcli.lookup("pagemodRemoveElementIfEmptyOnlyDesc"),
description: l10n.lookup("pagemodRemoveElementIfEmptyOnlyDesc"),
},
],
exec: function(args, context) {
@ -171,34 +175,36 @@ exports.items = [
}
}
return gcli.lookupFormat("pagemodRemoveElementResultMatchedAndRemovedElements",
return l10n.lookupFormat("pagemodRemoveElementResultMatchedAndRemovedElements",
[elements.length, removed]);
}
},
{
item: "command",
runAt: "server",
name: "pagemod remove attribute",
description: gcli.lookup("pagemodRemoveAttributeDesc"),
description: l10n.lookup("pagemodRemoveAttributeDesc"),
params: [
{
name: "searchAttributes",
type: "string",
description: gcli.lookup("pagemodRemoveAttributeSearchAttributesDesc"),
description: l10n.lookup("pagemodRemoveAttributeSearchAttributesDesc"),
},
{
name: "searchElements",
type: "string",
description: gcli.lookup("pagemodRemoveAttributeSearchElementsDesc"),
description: l10n.lookup("pagemodRemoveAttributeSearchElementsDesc"),
},
{
name: "root",
type: "node",
description: gcli.lookup("pagemodRemoveAttributeRootDesc"),
description: l10n.lookup("pagemodRemoveAttributeRootDesc"),
defaultValue: null,
},
{
name: "ignoreCase",
type: "boolean",
description: gcli.lookup("pagemodRemoveAttributeIgnoreCaseDesc"),
description: l10n.lookup("pagemodRemoveAttributeIgnoreCaseDesc"),
},
],
exec: function(args, context) {
@ -225,18 +231,20 @@ exports.items = [
}
}
return gcli.lookupFormat("pagemodRemoveAttributeResult",
return l10n.lookupFormat("pagemodRemoveAttributeResult",
[elements.length, removed]);
}
},
// This command allows the user to export the page to HTML after DOM changes
{
name: "export",
description: gcli.lookup("exportDesc"),
description: l10n.lookup("exportDesc"),
},
{
item: "command",
runAt: "server",
name: "export html",
description: gcli.lookup("exportHtmlDesc"),
description: l10n.lookup("exportHtmlDesc"),
params: [
{
name: "destination",

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

@ -14,11 +14,19 @@ const EventEmitter = require("devtools/toolkit/event-emitter");
const eventEmitter = new EventEmitter();
const gcli = require("gcli/index");
const l10n = require("gcli/l10n");
function onPaintFlashingChanged(context) {
let tab = context.environment.chromeWindow.gBrowser.selectedTab;
let target = TargetFactory.forTab(tab);
/**
* Keep a store of the paintFlashing state here. This is a nasty hack but
* the only other way to know is to ask the server, which is async and we need
* the answer synchronously in "paintflashing toggle".state()
*/
let isContentPaintFlashing = false;
/**
* Fire events and telemetry when paintFlashing happens
*/
function onPaintFlashingChanged(target, value) {
eventEmitter.emit("changed", { target: target });
function fireChange() {
eventEmitter.emit("changed", { target: target });
@ -27,25 +35,60 @@ function onPaintFlashingChanged(context) {
target.off("navigate", fireChange);
target.once("navigate", fireChange);
let window = context.environment.window;
let wUtils = window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
if (wUtils.paintFlashing) {
if (value) {
telemetry.toolOpened("paintflashing");
} else {
telemetry.toolClosed("paintflashing");
}
}
/**
* Alter the paintFlashing state of a window and report on the new value.
* This works with chrome or content windows.
*
* This is a bizarre method that you could argue should be broken up into
* separate getter and setter functions, however keeping it as one helps
* to simplify the commands below.
*
* @param state {string} One of:
* - "on" which does window.paintFlashing = true
* - "off" which does window.paintFlashing = false
* - "toggle" which does window.paintFlashing = !window.paintFlashing
* - "query" which does nothing
* @return The new value of the window.paintFlashing flag
*/
function setPaintFlashing(window, state) {
const winUtils = window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils)
if (["on", "off", "toggle", "query"].indexOf(state) === -1) {
throw new Error("Unsupported state: " + state);
}
if (state === "on") {
winUtils.paintFlashing = true;
}
else if (state === "off") {
winUtils.paintFlashing = false;
}
else if (state === "toggle") {
winUtils.paintFlashing = !winUtils.paintFlashing;
}
return winUtils.paintFlashing;
}
exports.items = [
{
name: "paintflashing",
description: gcli.lookup("paintflashingDesc")
description: l10n.lookup("paintflashingDesc")
},
{
item: "command",
runAt: "client",
name: "paintflashing on",
description: gcli.lookup("paintflashingOnDesc"),
manual: gcli.lookup("paintflashingManual"),
description: l10n.lookup("paintflashingOnDesc"),
manual: l10n.lookup("paintflashingManual"),
params: [{
group: "options",
params: [
@ -53,25 +96,27 @@ exports.items = [
type: "boolean",
name: "chrome",
get hidden() gcli.hiddenByChromePref(),
description: gcli.lookup("paintflashingChromeDesc"),
description: l10n.lookup("paintflashingChromeDesc"),
}
]
}],
exec: function(args, context) {
let window = args.chrome ?
context.environment.chromeWindow :
context.environment.window;
window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils)
.paintFlashing = true;
onPaintFlashingChanged(context);
exec: function*(args, context) {
if (!args.chrome) {
const value = yield context.updateExec("paintflashing_server --state on");
isContentPaintFlashing = value;
onPaintFlashingChanged(context.environment.target, value);
}
else {
setPaintFlashing(context.environment.chromeWindow, "on");
}
}
},
{
item: "command",
runAt: "client",
name: "paintflashing off",
description: gcli.lookup("paintflashingOffDesc"),
manual: gcli.lookup("paintflashingManual"),
description: l10n.lookup("paintflashingOffDesc"),
manual: l10n.lookup("paintflashingManual"),
params: [{
group: "options",
params: [
@ -79,57 +124,59 @@ exports.items = [
type: "boolean",
name: "chrome",
get hidden() gcli.hiddenByChromePref(),
description: gcli.lookup("paintflashingChromeDesc"),
description: l10n.lookup("paintflashingChromeDesc"),
}
]
}],
exec: function(args, context) {
let window = args.chrome ?
context.environment.chromeWindow :
context.environment.window;
window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils)
.paintFlashing = false;
onPaintFlashingChanged(context);
if (!args.chrome) {
const value = yield context.updateExec("paintflashing_server --state off");
isContentPaintFlashing = value;
onPaintFlashingChanged(context.environment.target, value);
}
else {
setPaintFlashing(context.environment.chromeWindow, "off");
}
}
},
{
item: "command",
runAt: "client",
name: "paintflashing toggle",
hidden: true,
buttonId: "command-button-paintflashing",
buttonClass: "command-button command-button-invertable",
state: {
isChecked: function(aTarget) {
if (aTarget.isLocalTab) {
let isChecked = false;
let window = aTarget.tab.linkedBrowser.contentWindow;
if (window) {
let wUtils = window.QueryInterface(Ci.nsIInterfaceRequestor).
getInterface(Ci.nsIDOMWindowUtils);
isChecked = wUtils.paintFlashing;
}
return isChecked;
} else {
throw new Error("Unsupported target");
isChecked: () => isContentPaintFlashing,
onChange: (_, handler) => eventEmitter.on("changed", handler),
offChange: (_, handler) => eventEmitter.off("changed", handler),
},
tooltipText: l10n.lookup("paintflashingTooltip"),
description: l10n.lookup("paintflashingToggleDesc"),
manual: l10n.lookup("paintflashingManual"),
exec: function(args, context) {
const value = yield context.updateExec("paintflashing_server --state toggle");
isContentPaintFlashing = value;
onPaintFlashingChanged(context.environment.target, value);
}
},
{
item: "command",
runAt: "server",
name: "paintflashing_server",
hidden: true,
params: [
{
name: "state",
type: {
name: "selection",
data: [ "on", "off", "toggle", "query" ]
}
},
onChange: function(aTarget, aChangeHandler) {
eventEmitter.on("changed", aChangeHandler);
},
offChange: function(aTarget, aChangeHandler) {
eventEmitter.off("changed", aChangeHandler);
},
},
tooltipText: gcli.lookup("paintflashingTooltip"),
description: gcli.lookup("paintflashingToggleDesc"),
manual: gcli.lookup("paintflashingManual"),
],
returnType: "boolean",
exec: function(args, context) {
let window = context.environment.window;
let wUtils = window.QueryInterface(Ci.nsIInterfaceRequestor).
getInterface(Ci.nsIDOMWindowUtils);
wUtils.paintFlashing = !wUtils.paintFlashing;
onPaintFlashingChanged(context);
return setPaintFlashing(context.environment.window, args.state);
}
}
];

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

@ -5,7 +5,7 @@
"use strict";
const { Cc, Ci, Cu } = require("chrome");
const gcli = require("gcli/index");
const l10n = require("gcli/l10n");
const Services = require("Services");
const BRAND_SHORT_NAME = Cc["@mozilla.org/intl/stringbundle;1"]
@ -27,13 +27,15 @@ const BRAND_SHORT_NAME = Cc["@mozilla.org/intl/stringbundle;1"]
*/
exports.items = [
{
item: "command",
runAt: "client",
name: "restart",
description: gcli.lookupFormat("restartBrowserDesc", [ BRAND_SHORT_NAME ]),
description: l10n.lookupFormat("restartBrowserDesc", [ BRAND_SHORT_NAME ]),
params: [
{
name: "nocache",
type: "boolean",
description: gcli.lookup("restartBrowserNocacheDesc")
description: l10n.lookup("restartBrowserNocacheDesc")
}
],
returnType: "string",
@ -42,7 +44,7 @@ exports.items = [
.createInstance(Ci.nsISupportsPRBool);
Services.obs.notifyObservers(canceled, "quit-application-requested", "restart");
if (canceled.data) {
return gcli.lookup("restartBrowserRequestCancelled");
return l10n.lookup("restartBrowserRequestCancelled");
}
// disable loading content from cache.
@ -54,7 +56,7 @@ exports.items = [
Cc["@mozilla.org/toolkit/app-startup;1"]
.getService(Ci.nsIAppStartup)
.quit(Ci.nsIAppStartup.eAttemptQuit | Ci.nsIAppStartup.eRestart);
return gcli.lookupFormat("restartBrowserRestarting", [ BRAND_SHORT_NAME ]);
return l10n.lookupFormat("restartBrowserRestarting", [ BRAND_SHORT_NAME ]);
}
}
];

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

@ -9,6 +9,7 @@ const eventEmitter = new EventEmitter();
const events = require("sdk/event/core");
const gcli = require("gcli/index");
const l10n = require("gcli/l10n");
require("devtools/server/actors/inspector");
const { RulersHighlighter } = require("devtools/server/actors/highlighter");
@ -17,11 +18,11 @@ const highlighters = new WeakMap();
exports.items = [
{
name: "rulers",
description: gcli.lookup("rulersDesc"),
manual: gcli.lookup("rulersManual"),
description: l10n.lookup("rulersDesc"),
manual: l10n.lookup("rulersManual"),
buttonId: "command-button-rulers",
buttonClass: "command-button command-button-invertable",
tooltipText: gcli.lookup("rulersTooltip"),
tooltipText: l10n.lookup("rulersTooltip"),
state: {
isChecked: function(aTarget) {
if (aTarget.isLocalTab) {

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

@ -5,7 +5,8 @@
"use strict";
const { Cc, Ci, Cu } = require("chrome");
const gcli = require("gcli/index");
const l10n = require("gcli/l10n");
const { Services } = require("resource://gre/modules/Services.jsm");
loader.lazyImporter(this, "Downloads", "resource://gre/modules/Downloads.jsm");
loader.lazyImporter(this, "LayoutHelpers", "resource://gre/modules/devtools/LayoutHelpers.jsm");
@ -21,241 +22,443 @@ const BRAND_SHORT_NAME = Cc["@mozilla.org/intl/stringbundle;1"]
// format: "Screen Shot yyyy-mm-dd at HH.MM.SS.png"
const FILENAME_DEFAULT_VALUE = " ";
/*
* There are 2 commands and 1 converter here. The 2 commands are nearly
* identical except that one runs on the client and one in the server.
*
* The server command is hidden, and is designed to be called from the client
* command when the --chrome flag is *not* used.
*/
/**
* Both commands have the same initial filename parameter
*/
const filenameParam = {
name: "filename",
type: "string",
defaultValue: FILENAME_DEFAULT_VALUE,
description: l10n.lookup("screenshotFilenameDesc"),
manual: l10n.lookup("screenshotFilenameManual")
};
/**
* Both commands have the same set of standard optional parameters
*/
const standardParams = {
group: l10n.lookup("screenshotGroupOptions"),
params: [
{
name: "clipboard",
type: "boolean",
description: l10n.lookup("screenshotClipboardDesc"),
manual: l10n.lookup("screenshotClipboardManual")
},
{
name: "imgur",
hidden: true, // Hidden because it fails with "Could not reach imgur API"
type: "boolean",
description: l10n.lookup("screenshotImgurDesc"),
manual: l10n.lookup("screenshotImgurManual")
},
{
name: "delay",
type: { name: "number", min: 0 },
defaultValue: 0,
description: l10n.lookup("screenshotDelayDesc"),
manual: l10n.lookup("screenshotDelayManual")
},
{
name: "fullpage",
type: "boolean",
description: l10n.lookup("screenshotFullPageDesc"),
manual: l10n.lookup("screenshotFullPageManual")
},
{
name: "selector",
type: "node",
defaultValue: null,
description: l10n.lookup("inspectNodeDesc"),
manual: l10n.lookup("inspectNodeManual")
}
]
};
exports.items = [
{
/**
* Format an 'imageSummary' (as output by the screenshot command).
* An 'imageSummary' is a simple JSON object that looks like this:
*
* {
* destinations: [ "..." ], // Required array of descriptions of the
* // locations of the result image (the command
* // can have multiple outputs)
* data: "...", // Optional Base64 encoded image data
* width:1024, height:768, // Dimensions of the image data, required
* // if data != null
* filename: "...", // If set, clicking the image will open the
* // folder containing the given file
* href: "...", // If set, clicking the image will open the
* // link in a new tab
* }
*/
item: "converter",
from: "imageSummary",
to: "dom",
exec: function(imageSummary, context) {
const document = context.document;
const root = document.createElement("div");
// Add a line to the result for each destination
imageSummary.destinations.forEach(destination => {
const title = document.createElement("div");
title.textContent = destination;
root.appendChild(title);
});
// Add the thumbnail image
if (imageSummary.data != null) {
const image = context.document.createElement("div");
const previewHeight = parseInt(256 * imageSummary.height / imageSummary.width);
const style = "" +
"width: 256px;" +
"height: " + previewHeight + "px;" +
"max-height: 256px;" +
"background-image: url('" + imageSummary.data + "');" +
"background-size: 256px " + previewHeight + "px;" +
"margin: 4px;" +
"display: block;";
image.setAttribute("style", style);
root.appendChild(image);
}
// Click handler
if (imageSummary.filename) {
root.style.cursor = "pointer";
root.addEventListener("click", () => {
if (imageSummary.filename) {
const file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
file.initWithPath(imageSummary.filename);
file.reveal();
}
});
}
return root;
}
},
{
item: "command",
runAt: "client",
name: "screenshot",
description: gcli.lookup("screenshotDesc"),
manual: gcli.lookup("screenshotManual"),
returnType: "dom",
description: l10n.lookup("screenshotDesc"),
manual: l10n.lookup("screenshotManual"),
returnType: "imageSummary",
buttonId: "command-button-screenshot",
buttonClass: "command-button command-button-invertable",
tooltipText: gcli.lookup("screenshotTooltip"),
tooltipText: l10n.lookup("screenshotTooltip"),
params: [
filenameParam,
standardParams,
{
name: "filename",
type: "string",
defaultValue: FILENAME_DEFAULT_VALUE,
description: gcli.lookup("screenshotFilenameDesc"),
manual: gcli.lookup("screenshotFilenameManual")
},
{
group: gcli.lookup("screenshotGroupOptions"),
group: l10n.lookup("screenshotAdvancedOptions"),
params: [
{
name: "clipboard",
type: "boolean",
description: gcli.lookup("screenshotClipboardDesc"),
manual: gcli.lookup("screenshotClipboardManual")
},
{
name: "chrome",
type: "boolean",
description: gcli.lookupFormat("screenshotChromeDesc2", [BRAND_SHORT_NAME]),
manual: gcli.lookupFormat("screenshotChromeManual2", [BRAND_SHORT_NAME])
description: l10n.lookupFormat("screenshotChromeDesc2", [BRAND_SHORT_NAME]),
manual: l10n.lookupFormat("screenshotChromeManual2", [BRAND_SHORT_NAME])
},
{
name: "delay",
type: { name: "number", min: 0 },
defaultValue: 0,
description: gcli.lookup("screenshotDelayDesc"),
manual: gcli.lookup("screenshotDelayManual")
},
{
name: "fullpage",
type: "boolean",
description: gcli.lookup("screenshotFullPageDesc"),
manual: gcli.lookup("screenshotFullPageManual")
},
{
name: "selector",
type: "node",
defaultValue: null,
description: gcli.lookup("inspectNodeDesc"),
manual: gcli.lookup("inspectNodeManual")
}
]
}
},
],
exec: function(args, context) {
if (args.chrome && args.selector) {
// Node screenshot with chrome option does not work as intended
// Refer https://bugzilla.mozilla.org/show_bug.cgi?id=659268#c7
// throwing for now.
throw new Error(gcli.lookup("screenshotSelectorChromeConflict"));
}
var document = args.chrome? context.environment.chromeDocument
: context.environment.document;
if (args.delay > 0) {
var deferred = context.defer();
document.defaultView.setTimeout(() => {
this.grabScreen(document, args.filename, args.clipboard,
args.fullpage).then(deferred.resolve, deferred.reject);
}, args.delay * 1000);
return deferred.promise;
throw new Error(l10n.lookup("screenshotSelectorChromeConflict"));
}
return this.grabScreen(document, args.filename, args.clipboard,
args.fullpage, args.selector);
},
grabScreen: function(document, filename, clipboard, fullpage, node) {
return Task.spawn(function() {
let window = document.defaultView;
let canvas = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
let left = 0;
let top = 0;
let width;
let height;
let div = document.createElementNS("http://www.w3.org/1999/xhtml", "div");
let currentX = window.scrollX;
let currentY = window.scrollY;
if (fullpage) {
// Bug 961832: GCLI screenshot shows fixed position element in wrong
// position if we don't scroll to top
window.scrollTo(0,0);
width = window.innerWidth + window.scrollMaxX;
height = window.innerHeight + window.scrollMaxY;
} else if (node) {
let lh = new LayoutHelpers(window);
let rect = lh.getRect(node, window);
top = rect.top;
left = rect.left;
width = rect.width;
height = rect.height;
} else {
left = window.scrollX;
top = window.scrollY;
width = window.innerWidth;
height = window.innerHeight;
}
let winUtils = window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
let scrollbarHeight = {};
let scrollbarWidth = {};
winUtils.getScrollbarSize(false, scrollbarWidth, scrollbarHeight);
width -= scrollbarWidth.value;
height -= scrollbarHeight.value;
canvas.width = width;
canvas.height = height;
let ctx = canvas.getContext("2d");
ctx.drawWindow(window, left, top, width, height, "#fff");
let data = canvas.toDataURL("image/png", "");
if(fullpage) {
window.scrollTo(currentX, currentY);
}
let loadContext = document.defaultView
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsILoadContext);
if (clipboard) {
try {
let io = Cc["@mozilla.org/network/io-service;1"]
.getService(Ci.nsIIOService);
let channel = io.newChannel2(data,
null,
null,
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_IMAGE);
let input = channel.open();
let imgTools = Cc["@mozilla.org/image/tools;1"]
.getService(Ci.imgITools);
let container = {};
imgTools.decodeImageData(input, channel.contentType, container);
let wrapped = Cc["@mozilla.org/supports-interface-pointer;1"]
.createInstance(Ci.nsISupportsInterfacePointer);
wrapped.data = container.value;
let trans = Cc["@mozilla.org/widget/transferable;1"]
.createInstance(Ci.nsITransferable);
trans.init(loadContext);
trans.addDataFlavor(channel.contentType);
trans.setTransferData(channel.contentType, wrapped, -1);
let clipid = Ci.nsIClipboard;
let clip = Cc["@mozilla.org/widget/clipboard;1"].getService(clipid);
clip.setData(trans, null, clipid.kGlobalClipboard);
div.textContent = gcli.lookup("screenshotCopied");
}
catch (ex) {
div.textContent = gcli.lookup("screenshotErrorCopying");
}
throw new Task.Result(div);
}
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
// Create a name for the file if not present
if (filename == FILENAME_DEFAULT_VALUE) {
let date = new Date();
let dateString = date.getFullYear() + "-" + (date.getMonth() + 1) +
"-" + date.getDate();
dateString = dateString.split("-").map(function(part) {
if (part.length == 1) {
part = "0" + part;
}
return part;
}).join("-");
let timeString = date.toTimeString().replace(/:/g, ".").split(" ")[0];
filename = gcli.lookupFormat("screenshotGeneratedFilename",
[dateString, timeString]) + ".png";
}
// Check there is a .png extension to filename
else if (!filename.match(/.png$/i)) {
filename += ".png";
}
// If the filename is relative, tack it onto the download directory
if (!filename.match(/[\\\/]/)) {
let preferredDir = yield Downloads.getPreferredDownloadsDirectory();
filename = OS.Path.join(preferredDir, filename);
}
try {
file.initWithPath(filename);
} catch (ex) {
div.textContent = gcli.lookup("screenshotErrorSavingToFile") + " " + filename;
throw new Task.Result(div);
}
let ioService = Cc["@mozilla.org/network/io-service;1"]
.getService(Ci.nsIIOService);
let Persist = Ci.nsIWebBrowserPersist;
let persist = Cc["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
.createInstance(Persist);
persist.persistFlags = Persist.PERSIST_FLAGS_REPLACE_EXISTING_FILES |
Persist.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION;
let source = ioService.newURI(data, "UTF8", null);
persist.saveURI(source, null, null, 0, null, null, file, loadContext);
div.textContent = gcli.lookup("screenshotSavedToFile") + " \"" + filename +
"\"";
div.addEventListener("click", function openFile() {
div.removeEventListener("click", openFile);
file.reveal();
if (!args.chrome) {
// Re-execute the command on the server
const command = context.typed.replace(/^screenshot/, "screenshot_server");
return context.updateExec(command).then(output => {
return output.error ? Promise.reject(output.data) : output.data;
});
div.style.cursor = "pointer";
let image = document.createElement("div");
let previewHeight = parseInt(256*height/width);
image.setAttribute("style",
"width:256px; height:" + previewHeight + "px;" +
"max-height: 256px;" +
"background-image: url('" + data + "');" +
"background-size: 256px " + previewHeight + "px;" +
"margin: 4px; display: block");
div.appendChild(image);
throw new Task.Result(div);
});
}
}
return processScreenshot(args, context.environment.chromeDocument);
},
},
{
item: "command",
runAt: "server",
name: "screenshot_server",
hidden: true,
returnType: "imageSummary",
params: [ filenameParam, standardParams ],
exec: function(args, context) {
return processScreenshot(args, context.environment.document);
},
}
];
/**
* This function simply handles the --delay argument before calling
* processScreenshotNow
*/
function processScreenshot(args, document) {
if (args.delay > 0) {
return new Promise((resolve, reject) => {
document.defaultView.setTimeout(() => {
processScreenshotNow(args, document).then(resolve, reject);
}, args.delay * 1000);
});
}
else {
return processScreenshotNow(args, document);
}
}
/**
* There are several possible destinations for the screenshot, SKIP is used
* in processScreenshotNow() whenever one of them is not used
*/
const SKIP = Promise.resolve();
/**
* This is just like exec, except the 'delay' has been handled already so
* this is where we do that actual work of process the screenshot
*/
function processScreenshotNow(args, document) {
const reply = createScreenshotData(document, args);
const loadContext = document.defaultView
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsILoadContext);
const fileNeeded = args.filename != FILENAME_DEFAULT_VALUE ||
(!args.imgur && !args.clipboard);
return Promise.all([
args.clipboard ? saveToClipboard(loadContext, reply) : SKIP,
args.imgur ? uploadToImgur(reply) : SKIP,
fileNeeded ? saveToFile(loadContext, reply) : SKIP,
]).then(() => reply);
}
/**
* This does the dirty work of creating a base64 string out of an
* area of the browser window
*/
function createScreenshotData(document, args) {
const window = document.defaultView;
let left = 0;
let top = 0;
let width;
let height;
const currentX = window.scrollX;
const currentY = window.scrollY;
if (args.fullpage) {
// Bug 961832: GCLI screenshot shows fixed position element in wrong
// position if we don't scroll to top
window.scrollTo(0,0);
width = window.innerWidth + window.scrollMaxX;
height = window.innerHeight + window.scrollMaxY;
}
else if (args.selector) {
const lh = new LayoutHelpers(window);
({ top, left, width, height }) = lh.getRect(args.selector, window);
}
else {
left = window.scrollX;
top = window.scrollY;
width = window.innerWidth;
height = window.innerHeight;
}
const winUtils = window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
const scrollbarHeight = {};
const scrollbarWidth = {};
winUtils.getScrollbarSize(false, scrollbarWidth, scrollbarHeight);
width -= scrollbarWidth.value;
height -= scrollbarHeight.value;
const canvas = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext("2d");
ctx.drawWindow(window, left, top, width, height, "#fff");
const data = canvas.toDataURL("image/png", "");
// See comment above on bug 961832
if (args.fullpage) {
window.scrollTo(currentX, currentY);
}
return {
destinations: [],
data: data,
height: height,
width: width,
filename: getFilename(args.filename),
};
}
/**
* We may have a filename specified in args, or we might have to generate
* one.
*/
function getFilename(defaultName) {
// Create a name for the file if not present
if (defaultName != FILENAME_DEFAULT_VALUE) {
return defaultName;
}
const date = new Date();
let dateString = date.getFullYear() + "-" + (date.getMonth() + 1) +
"-" + date.getDate();
dateString = dateString.split("-").map(function(part) {
if (part.length == 1) {
part = "0" + part;
}
return part;
}).join("-");
const timeString = date.toTimeString().replace(/:/g, ".").split(" ")[0];
return l10n.lookupFormat("screenshotGeneratedFilename",
[ dateString, timeString ]) + ".png";
}
/**
* Save the image data to the clipboard. This returns a promise, so it can
* be treated exactly like imgur / file processing, but it's really sync
* for now.
*/
function saveToClipboard(loadContext, reply) {
try {
const io = Cc["@mozilla.org/network/io-service;1"]
.getService(Ci.nsIIOService);
const channel = io.newChannel2(reply.data, null, null,
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_IMAGE);
const input = channel.open();
const imgTools = Cc["@mozilla.org/image/tools;1"]
.getService(Ci.imgITools);
const container = {};
imgTools.decodeImageData(input, channel.contentType, container);
const wrapped = Cc["@mozilla.org/supports-interface-pointer;1"]
.createInstance(Ci.nsISupportsInterfacePointer);
wrapped.data = container.value;
const trans = Cc["@mozilla.org/widget/transferable;1"]
.createInstance(Ci.nsITransferable);
trans.init(loadContext);
trans.addDataFlavor(channel.contentType);
trans.setTransferData(channel.contentType, wrapped, -1);
const clip = Cc["@mozilla.org/widget/clipboard;1"]
.getService(Ci.nsIClipboard);
clip.setData(trans, null, Ci.nsIClipboard.kGlobalClipboard);
reply.destinations.push(l10n.lookup("screenshotCopied"));
}
catch (ex) {
console.error(ex);
reply.destinations.push(l10n.lookup("screenshotErrorCopying"));
}
return Promise.resolve();
}
/**
* Upload screenshot data to Imgur, returning a promise of a URL (as a string)
*/
function uploadToImgur(reply) {
return new Promise((resolve, reject) => {
const xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
.createInstance(Ci.nsIXMLHttpRequest);
const fd = Cc["@mozilla.org/files/formdata;1"]
.createInstance(Ci.nsIDOMFormData);
fd.append("image", reply.data.split(",")[1]);
fd.append("type", "base64");
fd.append("title", reply.filename);
const postURL = Services.prefs.getCharPref("devtools.gcli.imgurUploadURL");
const clientID = "Client-ID " + Services.prefs.getCharPref("devtools.gcli.imgurClientID");
xhr.open("POST", postURL);
xhr.setRequestHeader("Authorization", clientID);
xhr.send(fd);
xhr.responseType = "json";
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
reply.href = xhr.response.data.link;
reply.destinations.push(l10n.lookupFormat("screenshotImgurError",
[ reply.href ]));
}
else {
reply.destinations.push(l10n.lookup("screenshotImgurError"));
}
resolve();
}
}
});
}
/**
* Save the screenshot data to disk, returning a promise which
* is resolved on completion
*/
function saveToFile(loadContext, reply) {
return Task.spawn(function*() {
try {
let filename = reply.filename;
// Check there is a .png extension to filename
if (!filename.match(/.png$/i)) {
filename += ".png";
}
// If the filename is relative, tack it onto the download directory
if (!filename.match(/[\\\/]/)) {
const preferredDir = yield Downloads.getPreferredDownloadsDirectory();
filename = OS.Path.join(preferredDir, filename);
reply.filename = filename;
}
const file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
file.initWithPath(filename);
const ioService = Cc["@mozilla.org/network/io-service;1"]
.getService(Ci.nsIIOService);
const Persist = Ci.nsIWebBrowserPersist;
const persist = Cc["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
.createInstance(Persist);
persist.persistFlags = Persist.PERSIST_FLAGS_REPLACE_EXISTING_FILES |
Persist.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION;
// TODO: UTF8? For an image?
const source = ioService.newURI(reply.data, "UTF8", null);
persist.saveURI(source, null, null, 0, null, null, file, loadContext);
reply.destinations.push(l10n.lookup("screenshotSavedToFile") + " \"" + filename + "\"");
}
catch (ex) {
console.error(ex);
reply.destinations.push(l10n.lookup("screenshotErrorSavingToFile") + " " + filename);
}
});
}

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

@ -9,6 +9,7 @@ const Services = require("Services");
const { OS } = require("resource://gre/modules/osfile.jsm");
const { devtools } = require("resource://gre/modules/devtools/Loader.jsm");
const gcli = require("gcli/index");
const l10n = require("gcli/l10n");
const BRAND_SHORT_NAME = Cc["@mozilla.org/intl/stringbundle;1"]
.getService(Ci.nsIStringBundleService)
@ -18,14 +19,16 @@ const BRAND_SHORT_NAME = Cc["@mozilla.org/intl/stringbundle;1"]
exports.items = [
{
name: "tools",
description: gcli.lookupFormat("toolsDesc2", [ BRAND_SHORT_NAME ]),
manual: gcli.lookupFormat("toolsManual2", [ BRAND_SHORT_NAME ]),
description: l10n.lookupFormat("toolsDesc2", [ BRAND_SHORT_NAME ]),
manual: l10n.lookupFormat("toolsManual2", [ BRAND_SHORT_NAME ]),
get hidden() gcli.hiddenByChromePref(),
},
{
item: "command",
runAt: "client",
name: "tools srcdir",
description: gcli.lookup("toolsSrcdirDesc"),
manual: gcli.lookupFormat("toolsSrcdirManual2", [ BRAND_SHORT_NAME ]),
description: l10n.lookup("toolsSrcdirDesc"),
manual: l10n.lookupFormat("toolsSrcdirManual2", [ BRAND_SHORT_NAME ]),
get hidden() gcli.hiddenByChromePref(),
params: [
{
@ -35,7 +38,7 @@ exports.items = [
filetype: "directory",
existing: "yes"
} */,
description: gcli.lookup("toolsSrcdirDir")
description: l10n.lookup("toolsSrcdirDir")
}
],
returnType: "string",
@ -50,29 +53,33 @@ exports.items = [
Ci.nsISupportsString, str);
devtools.reload();
let msg = gcli.lookupFormat("toolsSrcdirReloaded", [ args.srcdir ]);
let msg = l10n.lookupFormat("toolsSrcdirReloaded", [ args.srcdir ]);
throw new Error(msg);
}
return gcli.lookupFormat("toolsSrcdirNotFound", [ args.srcdir ]);
return l10n.lookupFormat("toolsSrcdirNotFound", [ args.srcdir ]);
});
}
},
{
item: "command",
runAt: "client",
name: "tools builtin",
description: gcli.lookup("toolsBuiltinDesc"),
manual: gcli.lookup("toolsBuiltinManual"),
description: l10n.lookup("toolsBuiltinDesc"),
manual: l10n.lookup("toolsBuiltinManual"),
get hidden() gcli.hiddenByChromePref(),
returnType: "string",
exec: function(args, context) {
Services.prefs.clearUserPref("devtools.loader.srcdir");
devtools.reload();
return gcli.lookup("toolsBuiltinReloaded");
return l10n.lookup("toolsBuiltinReloaded");
}
},
{
item: "command",
runAt: "client",
name: "tools reload",
description: gcli.lookup("toolsReloadDesc"),
description: l10n.lookup("toolsReloadDesc"),
get hidden() {
return gcli.hiddenByChromePref() ||
!Services.prefs.prefHasUserValue("devtools.loader.srcdir");
@ -81,7 +88,7 @@ exports.items = [
returnType: "string",
exec: function(args, context) {
devtools.reload();
return gcli.lookup("toolsReloaded2");
return l10n.lookup("toolsReloaded2");
}
}
];

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