зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to s-c.
This commit is contained in:
Коммит
4b3ecc07a6
|
@ -169,6 +169,7 @@ _BROWSER_FILES = \
|
||||||
browser_tabview_bug705621.js \
|
browser_tabview_bug705621.js \
|
||||||
browser_tabview_bug706430.js \
|
browser_tabview_bug706430.js \
|
||||||
browser_tabview_bug706736.js \
|
browser_tabview_bug706736.js \
|
||||||
|
browser_tabview_bug707466.js \
|
||||||
browser_tabview_click_group.js \
|
browser_tabview_click_group.js \
|
||||||
browser_tabview_dragdrop.js \
|
browser_tabview_dragdrop.js \
|
||||||
browser_tabview_exit_button.js \
|
browser_tabview_exit_button.js \
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
function test() {
|
||||||
|
waitForExplicitFinish();
|
||||||
|
|
||||||
|
// create two groups and each group has one tab item
|
||||||
|
let newState = {
|
||||||
|
windows: [{
|
||||||
|
tabs: [{
|
||||||
|
entries: [{ url: "about:blank" }],
|
||||||
|
hidden: true,
|
||||||
|
attributes: {},
|
||||||
|
extData: {
|
||||||
|
"tabview-tab":
|
||||||
|
'{"bounds":{"left":21,"top":29,"width":204,"height":153},' +
|
||||||
|
'"userSize":null,"url":"about:blank","groupID":1,' +
|
||||||
|
'"imageData":null,"title":null}'
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
entries: [{ url: "about:blank" }],
|
||||||
|
hidden: false,
|
||||||
|
attributes: {},
|
||||||
|
extData: {
|
||||||
|
"tabview-tab":
|
||||||
|
'{"bounds":{"left":315,"top":29,"width":111,"height":84},' +
|
||||||
|
'"userSize":null,"url":"about:blank","groupID":2,' +
|
||||||
|
'"imageData":null,"title":null}'
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
selected:2,
|
||||||
|
_closedTabs: [],
|
||||||
|
extData: {
|
||||||
|
"tabview-groups": '{"nextID":3,"activeGroupId":2}',
|
||||||
|
"tabview-group":
|
||||||
|
'{"1":{"bounds":{"left":15,"top":5,"width":280,"height":232},' +
|
||||||
|
'"userSize":null,"title":"","id":1},' +
|
||||||
|
'"2":{"bounds":{"left":309,"top":5,"width":267,"height":226},' +
|
||||||
|
'"userSize":null,"title":"","id":2}}',
|
||||||
|
"tabview-ui": '{"pageBounds":{"left":0,"top":0,"width":788,"height":548}}'
|
||||||
|
}, sizemode:"normal"
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
newWindowWithState(newState, function(win) {
|
||||||
|
registerCleanupFunction(function () win.close());
|
||||||
|
|
||||||
|
whenTabViewIsShown(function() {
|
||||||
|
let cw = win.TabView.getContentWindow();
|
||||||
|
|
||||||
|
is(cw.GroupItems.groupItems.length, 2, "There are still two groups");
|
||||||
|
is(win.gBrowser.tabs.length, 1, "There is only one tab");
|
||||||
|
is(cw.UI.getActiveTab(), win.gBrowser.selectedTab._tabViewTabItem, "The last tab is selected");
|
||||||
|
|
||||||
|
finish();
|
||||||
|
}, win);
|
||||||
|
win.gBrowser.removeTab(win.gBrowser.selectedTab);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -475,7 +475,7 @@ let UI = {
|
||||||
} else {
|
} else {
|
||||||
GroupItems.setActiveGroupItem(item);
|
GroupItems.setActiveGroupItem(item);
|
||||||
if (!options || !options.dontSetActiveTabInGroup) {
|
if (!options || !options.dontSetActiveTabInGroup) {
|
||||||
let activeTab = item.getActiveTab()
|
let activeTab = item.getActiveTab();
|
||||||
if (activeTab)
|
if (activeTab)
|
||||||
this._setActiveTab(activeTab);
|
this._setActiveTab(activeTab);
|
||||||
}
|
}
|
||||||
|
@ -574,7 +574,8 @@ let UI = {
|
||||||
TabItems.resumePainting();
|
TabItems.resumePainting();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
self.clearActiveTab();
|
if (!currentTab || !currentTab._tabViewTabItem)
|
||||||
|
self.clearActiveTab();
|
||||||
self._isChangingVisibility = false;
|
self._isChangingVisibility = false;
|
||||||
dispatchEvent(event);
|
dispatchEvent(event);
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
* ***** END LICENSE BLOCK ***** */
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
|
||||||
var EXPORTED_SYMBOLS = [ "Templater" ];
|
var EXPORTED_SYMBOLS = [ "Templater", "template" ];
|
||||||
|
|
||||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||||
const Node = Components.interfaces.nsIDOMNode;
|
const Node = Components.interfaces.nsIDOMNode;
|
||||||
|
@ -45,12 +45,53 @@ const Node = Components.interfaces.nsIDOMNode;
|
||||||
// WARNING: do not 'use_strict' without reading the notes in _envEval();
|
// WARNING: do not 'use_strict' without reading the notes in _envEval();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A templater that allows one to quickly template DOM nodes.
|
* Begin a new templating process.
|
||||||
|
* @param node A DOM element or string referring to an element's id
|
||||||
|
* @param data Data to use in filling out the template
|
||||||
|
* @param options Options to customize the template processing. One of:
|
||||||
|
* - allowEval: boolean (default false) Basic template interpolations are
|
||||||
|
* either property paths (e.g. ${a.b.c.d}), however if allowEval=true then we
|
||||||
|
* allow arbitrary JavaScript
|
||||||
*/
|
*/
|
||||||
function Templater() {
|
function template(node, data, options) {
|
||||||
|
var template = new Templater(options || {});
|
||||||
|
template.processNode(node, data);
|
||||||
|
return template;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a Templater object. Use template() in preference to this ctor.
|
||||||
|
* @deprecated Use template(node, data, options);
|
||||||
|
*/
|
||||||
|
function Templater(options) {
|
||||||
|
if (options == null) {
|
||||||
|
options = { allowEval: true };
|
||||||
|
}
|
||||||
|
this.options = options;
|
||||||
this.stack = [];
|
this.stack = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cached regex used to find ${...} sections in some text.
|
||||||
|
* Performance note: This regex uses ( and ) to capture the 'script' for
|
||||||
|
* further processing. Not all of the uses of this regex use this feature so
|
||||||
|
* if use of the capturing group is a performance drain then we should split
|
||||||
|
* this regex in two.
|
||||||
|
*/
|
||||||
|
Templater.prototype._templateRegion = /\$\{([^}]*)\}/g;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cached regex used to split a string using the unicode chars F001 and F002.
|
||||||
|
* See Templater._processTextNode() for details.
|
||||||
|
*/
|
||||||
|
Templater.prototype._splitSpecial = /\uF001|\uF002/;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cached regex used to detect if a script is capable of being interpreted
|
||||||
|
* using Template._property() or if we need to use Template._envEval()
|
||||||
|
*/
|
||||||
|
Templater.prototype._isPropertyScript = /^[a-zA-Z0-9.]*$/;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recursive function to walk the tree processing the attributes as it goes.
|
* Recursive function to walk the tree processing the attributes as it goes.
|
||||||
* @param node the node to process. If you pass a string in instead of a DOM
|
* @param node the node to process. If you pass a string in instead of a DOM
|
||||||
|
@ -111,7 +152,7 @@ Templater.prototype.processNode = function(node, data) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Replace references in all other attributes
|
// Replace references in all other attributes
|
||||||
var newValue = value.replace(/\$\{[^}]*\}/g, function(path) {
|
var newValue = value.replace(this._templateRegion, function(path) {
|
||||||
return this._envEval(path.slice(2, -1), data, value);
|
return this._envEval(path.slice(2, -1), data, value);
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
// Remove '_' prefix of attribute names so the DOM won't try
|
// Remove '_' prefix of attribute names so the DOM won't try
|
||||||
|
@ -295,8 +336,8 @@ Templater.prototype._processTextNode = function(node, data) {
|
||||||
// We can then split using \uF001 or \uF002 to get an array of strings
|
// We can then split using \uF001 or \uF002 to get an array of strings
|
||||||
// where scripts are prefixed with $.
|
// where scripts are prefixed with $.
|
||||||
// \uF001 and \uF002 are just unicode chars reserved for private use.
|
// \uF001 and \uF002 are just unicode chars reserved for private use.
|
||||||
value = value.replace(/\$\{([^}]*)\}/g, '\uF001$$$1\uF002');
|
value = value.replace(this._templateRegion, '\uF001$$$1\uF002');
|
||||||
var parts = value.split(/\uF001|\uF002/);
|
var parts = value.split(this._splitSpecial);
|
||||||
if (parts.length > 1) {
|
if (parts.length > 1) {
|
||||||
parts.forEach(function(part) {
|
parts.forEach(function(part) {
|
||||||
if (part === null || part === undefined || part === '') {
|
if (part === null || part === undefined || part === '') {
|
||||||
|
@ -363,7 +404,7 @@ Templater.prototype._handleAsync = function(thing, siblingNode, inserter) {
|
||||||
* @return The string stripped of ${ and }, or untouched if it does not match
|
* @return The string stripped of ${ and }, or untouched if it does not match
|
||||||
*/
|
*/
|
||||||
Templater.prototype._stripBraces = function(str) {
|
Templater.prototype._stripBraces = function(str) {
|
||||||
if (!str.match(/\$\{.*\}/g)) {
|
if (!str.match(this._templateRegion)) {
|
||||||
this._handleError('Expected ' + str + ' to match ${...}');
|
this._handleError('Expected ' + str + ' to match ${...}');
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
@ -427,17 +468,26 @@ Templater.prototype._property = function(path, data, newValue) {
|
||||||
* execution failed.
|
* execution failed.
|
||||||
*/
|
*/
|
||||||
Templater.prototype._envEval = function(script, data, frame) {
|
Templater.prototype._envEval = function(script, data, frame) {
|
||||||
with (data) {
|
try {
|
||||||
try {
|
this.stack.push(frame);
|
||||||
this.stack.push(frame);
|
if (this._isPropertyScript.test(script)) {
|
||||||
return eval(script);
|
return this._property(script, data);
|
||||||
} catch (ex) {
|
} else {
|
||||||
this._handleError('Template error evaluating \'' + script + '\'' +
|
if (!this.options.allowEval) {
|
||||||
' environment=' + Object.keys(data).join(', '), ex);
|
this._handleError('allowEval is not set, however \'' + script + '\'' +
|
||||||
return script;
|
' can not be resolved using a simple property path.');
|
||||||
} finally {
|
return '${' + script + '}';
|
||||||
this.stack.pop();
|
}
|
||||||
|
with (data) {
|
||||||
|
return eval(script);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch (ex) {
|
||||||
|
this._handleError('Template error evaluating \'' + script + '\'' +
|
||||||
|
' environment=' + Object.keys(data).join(', '), ex);
|
||||||
|
return '${' + script + '}';
|
||||||
|
} finally {
|
||||||
|
this.stack.pop();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ function runTest(index) {
|
||||||
holder.innerHTML = options.template;
|
holder.innerHTML = options.template;
|
||||||
|
|
||||||
info('Running ' + options.name);
|
info('Running ' + options.name);
|
||||||
new Templater().processNode(holder, options.data);
|
template(holder, options.data, options.options);
|
||||||
|
|
||||||
if (typeof options.result == 'string') {
|
if (typeof options.result == 'string') {
|
||||||
is(holder.innerHTML, options.result, options.name);
|
is(holder.innerHTML, options.result, options.name);
|
||||||
|
@ -88,6 +88,7 @@ var tests = [
|
||||||
function() { return {
|
function() { return {
|
||||||
name: 'returnDom',
|
name: 'returnDom',
|
||||||
template: '<div id="ex2">${__element.ownerDocument.createTextNode(\'pass 2\')}</div>',
|
template: '<div id="ex2">${__element.ownerDocument.createTextNode(\'pass 2\')}</div>',
|
||||||
|
options: { allowEval: true },
|
||||||
data: {},
|
data: {},
|
||||||
result: '<div id="ex2">pass 2</div>'
|
result: '<div id="ex2">pass 2</div>'
|
||||||
};},
|
};},
|
||||||
|
@ -102,6 +103,7 @@ var tests = [
|
||||||
function() { return {
|
function() { return {
|
||||||
name: 'ifTrue',
|
name: 'ifTrue',
|
||||||
template: '<p if="${name !== \'jim\'}">hello ${name}</p>',
|
template: '<p if="${name !== \'jim\'}">hello ${name}</p>',
|
||||||
|
options: { allowEval: true },
|
||||||
data: { name: 'fred' },
|
data: { name: 'fred' },
|
||||||
result: '<p>hello fred</p>'
|
result: '<p>hello fred</p>'
|
||||||
};},
|
};},
|
||||||
|
@ -109,6 +111,7 @@ var tests = [
|
||||||
function() { return {
|
function() { return {
|
||||||
name: 'ifFalse',
|
name: 'ifFalse',
|
||||||
template: '<p if="${name !== \'jim\'}">hello ${name}</p>',
|
template: '<p if="${name !== \'jim\'}">hello ${name}</p>',
|
||||||
|
options: { allowEval: true },
|
||||||
data: { name: 'jim' },
|
data: { name: 'jim' },
|
||||||
result: ''
|
result: ''
|
||||||
};},
|
};},
|
||||||
|
@ -116,6 +119,7 @@ var tests = [
|
||||||
function() { return {
|
function() { return {
|
||||||
name: 'simpleLoop',
|
name: 'simpleLoop',
|
||||||
template: '<p foreach="index in ${[ 1, 2, 3 ]}">${index}</p>',
|
template: '<p foreach="index in ${[ 1, 2, 3 ]}">${index}</p>',
|
||||||
|
options: { allowEval: true },
|
||||||
data: {},
|
data: {},
|
||||||
result: '<p>1</p><p>2</p><p>3</p>'
|
result: '<p>1</p><p>2</p><p>3</p>'
|
||||||
};},
|
};},
|
||||||
|
@ -127,6 +131,7 @@ var tests = [
|
||||||
result: '123'
|
result: '123'
|
||||||
};},
|
};},
|
||||||
|
|
||||||
|
// Bug 692028: DOMTemplate memory leak with asynchronous arrays
|
||||||
// Bug 692031: DOMTemplate async loops do not drop the loop element
|
// Bug 692031: DOMTemplate async loops do not drop the loop element
|
||||||
function() { return {
|
function() { return {
|
||||||
name: 'asyncLoopElement',
|
name: 'asyncLoopElement',
|
||||||
|
@ -150,6 +155,7 @@ var tests = [
|
||||||
function() { return {
|
function() { return {
|
||||||
name: 'useElement',
|
name: 'useElement',
|
||||||
template: '<p id="pass9">${adjust(__element)}</p>',
|
template: '<p id="pass9">${adjust(__element)}</p>',
|
||||||
|
options: { allowEval: true },
|
||||||
data: {
|
data: {
|
||||||
adjust: function(element) {
|
adjust: function(element) {
|
||||||
is('pass9', element.id, 'useElement adjust');
|
is('pass9', element.id, 'useElement adjust');
|
||||||
|
@ -167,6 +173,7 @@ var tests = [
|
||||||
later: 'inline'
|
later: 'inline'
|
||||||
};},
|
};},
|
||||||
|
|
||||||
|
// Bug 692028: DOMTemplate memory leak with asynchronous arrays
|
||||||
function() { return {
|
function() { return {
|
||||||
name: 'asyncArray',
|
name: 'asyncArray',
|
||||||
template: '<p foreach="i in ${delayed}">${i}</p>',
|
template: '<p foreach="i in ${delayed}">${i}</p>',
|
||||||
|
@ -183,6 +190,7 @@ var tests = [
|
||||||
later: '<p>4</p><p>5</p><p>6</p>'
|
later: '<p>4</p><p>5</p><p>6</p>'
|
||||||
};},
|
};},
|
||||||
|
|
||||||
|
// Bug 692028: DOMTemplate memory leak with asynchronous arrays
|
||||||
function() { return {
|
function() { return {
|
||||||
name: 'asyncBoth',
|
name: 'asyncBoth',
|
||||||
template: '<p foreach="i in ${delayed}">${i}</p>',
|
template: '<p foreach="i in ${delayed}">${i}</p>',
|
||||||
|
@ -195,6 +203,38 @@ var tests = [
|
||||||
},
|
},
|
||||||
result: '<span></span>',
|
result: '<span></span>',
|
||||||
later: '<p>4</p><p>5</p><p>6</p>'
|
later: '<p>4</p><p>5</p><p>6</p>'
|
||||||
|
};},
|
||||||
|
|
||||||
|
// Bug 701762: DOMTemplate fails when ${foo()} returns undefined
|
||||||
|
function() { return {
|
||||||
|
name: 'functionReturningUndefiend',
|
||||||
|
template: '<p>${foo()}</p>',
|
||||||
|
options: { allowEval: true },
|
||||||
|
data: {
|
||||||
|
foo: function() {}
|
||||||
|
},
|
||||||
|
result: '<p>undefined</p>'
|
||||||
|
};},
|
||||||
|
|
||||||
|
// Bug 702642: DOMTemplate is relatively slow when evaluating JS ${}
|
||||||
|
function() { return {
|
||||||
|
name: 'propertySimple',
|
||||||
|
template: '<p>${a.b.c}</p>',
|
||||||
|
data: { a: { b: { c: 'hello' } } },
|
||||||
|
result: '<p>hello</p>'
|
||||||
|
};},
|
||||||
|
|
||||||
|
function() { return {
|
||||||
|
name: 'propertyPass',
|
||||||
|
template: '<p>${Math.max(1, 2)}</p>',
|
||||||
|
options: { allowEval: true },
|
||||||
|
result: '<p>2</p>'
|
||||||
|
};},
|
||||||
|
|
||||||
|
function() { return {
|
||||||
|
name: 'propertyFail',
|
||||||
|
template: '<p>${Math.max(1, 2)}</p>',
|
||||||
|
result: '<p>${Math.max(1, 2)}</p>'
|
||||||
};}
|
};}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -214,7 +214,10 @@ CssHtmlTree.processTemplate = function CssHtmlTree_processTemplate(aTemplate,
|
||||||
// All the templater does is to populate a given DOM tree with the given
|
// All the templater does is to populate a given DOM tree with the given
|
||||||
// values, so we need to clone the template first.
|
// values, so we need to clone the template first.
|
||||||
let duplicated = aTemplate.cloneNode(true);
|
let duplicated = aTemplate.cloneNode(true);
|
||||||
new Templater().processNode(duplicated, aData);
|
|
||||||
|
// See https://github.com/mozilla/domtemplate/blob/master/README.md
|
||||||
|
// for docs on the template() function
|
||||||
|
template(duplicated, aData, { allowEval: true });
|
||||||
while (duplicated.firstChild) {
|
while (duplicated.firstChild) {
|
||||||
aDestination.appendChild(duplicated.firstChild);
|
aDestination.appendChild(duplicated.firstChild);
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,40 +62,6 @@ gcli.addCommand({
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
let canon = gcli._internal.require("gcli/canon");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 'help' command
|
|
||||||
*/
|
|
||||||
gcli.addCommand({
|
|
||||||
name: "help",
|
|
||||||
returnType: "html",
|
|
||||||
description: gcli.lookup("helpDesc"),
|
|
||||||
exec: function Command_help(args, context) {
|
|
||||||
let output = [];
|
|
||||||
|
|
||||||
output.push("<strong>" + gcli.lookup("helpAvailable") + ":</strong><br/>");
|
|
||||||
|
|
||||||
let commandNames = canon.getCommandNames();
|
|
||||||
commandNames.sort();
|
|
||||||
|
|
||||||
output.push("<table>");
|
|
||||||
for (let i = 0; i < commandNames.length; i++) {
|
|
||||||
let command = canon.getCommand(commandNames[i]);
|
|
||||||
if (!command.hidden && command.description) {
|
|
||||||
output.push("<tr>");
|
|
||||||
output.push('<th class="gcli-help-right">' + command.name + "</th>");
|
|
||||||
output.push("<td>→ " + command.description + "</td>");
|
|
||||||
output.push("</tr>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
output.push("</table>");
|
|
||||||
|
|
||||||
return output.join("");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 'console' command
|
* 'console' command
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -92,6 +92,12 @@ XPCOMUtils.defineLazyGetter(this, "NetUtil", function () {
|
||||||
return obj.NetUtil;
|
return obj.NetUtil;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
XPCOMUtils.defineLazyGetter(this, "template", function () {
|
||||||
|
var obj = {};
|
||||||
|
Cu.import("resource:///modules/devtools/Templater.jsm", obj);
|
||||||
|
return obj.template;
|
||||||
|
});
|
||||||
|
|
||||||
XPCOMUtils.defineLazyGetter(this, "PropertyPanel", function () {
|
XPCOMUtils.defineLazyGetter(this, "PropertyPanel", function () {
|
||||||
var obj = {};
|
var obj = {};
|
||||||
try {
|
try {
|
||||||
|
@ -6854,14 +6860,38 @@ GcliTerm.prototype = {
|
||||||
|
|
||||||
let output = aEvent.output.output;
|
let output = aEvent.output.output;
|
||||||
if (aEvent.output.command.returnType == "html" && typeof output == "string") {
|
if (aEvent.output.command.returnType == "html" && typeof output == "string") {
|
||||||
let frag = this.document.createRange().createContextualFragment(
|
output = this.document.createRange().createContextualFragment(
|
||||||
'<div xmlns="' + HTML_NS + '" xmlns:xul="' + XUL_NS + '">' +
|
'<div xmlns="' + HTML_NS + '" xmlns:xul="' + XUL_NS + '">' +
|
||||||
output + '</div>');
|
output + '</div>').firstChild;
|
||||||
|
|
||||||
output = this.document.createElementNS(HTML_NS, "div");
|
|
||||||
output.appendChild(frag);
|
|
||||||
}
|
}
|
||||||
this.writeOutput(output);
|
|
||||||
|
// See https://github.com/mozilla/domtemplate/blob/master/README.md
|
||||||
|
// for docs on the template() function
|
||||||
|
let element = this.document.createRange().createContextualFragment(
|
||||||
|
'<richlistitem xmlns="' + XUL_NS + '" clipboardText="${clipboardText}"' +
|
||||||
|
' timestamp="${timestamp}" id="${id}" class="hud-msg-node">' +
|
||||||
|
' <label class="webconsole-timestamp" value="${timestampString}"/>' +
|
||||||
|
' <vbox class="webconsole-msg-icon-container" style="${iconContainerStyle}">' +
|
||||||
|
' <image class="webconsole-msg-icon"/>' +
|
||||||
|
' <spacer flex="1"/>' +
|
||||||
|
' </vbox>' +
|
||||||
|
' <hbox flex="1" class="gcliterm-msg-body">${output}</hbox>' +
|
||||||
|
' <hbox align="start"><label value="1" class="webconsole-msg-repeat"/></hbox>' +
|
||||||
|
'</richlistitem>').firstChild;
|
||||||
|
|
||||||
|
let hud = HUDService.getHudReferenceById(this.hudId);
|
||||||
|
let timestamp = ConsoleUtils.timestamp();
|
||||||
|
template(element, {
|
||||||
|
iconContainerStyle: "margin-left=" + (hud.groupDepth * GROUP_INDENT) + "px",
|
||||||
|
output: output,
|
||||||
|
timestamp: timestamp,
|
||||||
|
timestampString: ConsoleUtils.timestampString(timestamp),
|
||||||
|
clipboardText: output.innerText,
|
||||||
|
id: "console-msg-" + HUDService.sequenceId()
|
||||||
|
});
|
||||||
|
|
||||||
|
ConsoleUtils.setMessageType(element, CATEGORY_OUTPUT, SEVERITY_LOG);
|
||||||
|
ConsoleUtils.outputMessageNode(element, this.hudId);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -686,7 +686,7 @@ var mozl10n = {};
|
||||||
|
|
||||||
})(mozl10n);
|
})(mozl10n);
|
||||||
|
|
||||||
define('gcli/index', ['require', 'exports', 'module' , 'gcli/canon', 'gcli/types/basic', 'gcli/types/javascript', 'gcli/types/node', 'gcli/cli', 'gcli/ui/display'], function(require, exports, module) {
|
define('gcli/index', ['require', 'exports', 'module' , 'gcli/canon', 'gcli/types/basic', 'gcli/types/javascript', 'gcli/types/node', 'gcli/cli', 'gcli/commands/help', 'gcli/ui/console'], function(require, exports, module) {
|
||||||
|
|
||||||
// The API for use by command authors
|
// The API for use by command authors
|
||||||
exports.addCommand = require('gcli/canon').addCommand;
|
exports.addCommand = require('gcli/canon').addCommand;
|
||||||
|
@ -699,9 +699,10 @@ define('gcli/index', ['require', 'exports', 'module' , 'gcli/canon', 'gcli/types
|
||||||
require('gcli/types/javascript').startup();
|
require('gcli/types/javascript').startup();
|
||||||
require('gcli/types/node').startup();
|
require('gcli/types/node').startup();
|
||||||
require('gcli/cli').startup();
|
require('gcli/cli').startup();
|
||||||
|
require('gcli/commands/help').startup();
|
||||||
|
|
||||||
var Requisition = require('gcli/cli').Requisition;
|
var Requisition = require('gcli/cli').Requisition;
|
||||||
var Display = require('gcli/ui/display').Display;
|
var Console = require('gcli/ui/console').Console;
|
||||||
|
|
||||||
var cli = require('gcli/cli');
|
var cli = require('gcli/cli');
|
||||||
var jstype = require('gcli/types/javascript');
|
var jstype = require('gcli/types/javascript');
|
||||||
|
@ -739,15 +740,15 @@ define('gcli/index', ['require', 'exports', 'module' , 'gcli/canon', 'gcli/types
|
||||||
opts.requisition = new Requisition(opts.environment, opts.chromeDocument);
|
opts.requisition = new Requisition(opts.environment, opts.chromeDocument);
|
||||||
}
|
}
|
||||||
|
|
||||||
opts.display = new Display(opts);
|
opts.console = new Console(opts);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Undo the effects of createView() to prevent memory leaks
|
* Undo the effects of createView() to prevent memory leaks
|
||||||
*/
|
*/
|
||||||
removeView: function(opts) {
|
removeView: function(opts) {
|
||||||
opts.display.destroy();
|
opts.console.destroy();
|
||||||
delete opts.display;
|
delete opts.console;
|
||||||
|
|
||||||
opts.requisition.destroy();
|
opts.requisition.destroy();
|
||||||
delete opts.requisition;
|
delete opts.requisition;
|
||||||
|
@ -1029,7 +1030,8 @@ canon.removeCommand = function removeCommand(commandOrName) {
|
||||||
* @param name The name of the command to retrieve
|
* @param name The name of the command to retrieve
|
||||||
*/
|
*/
|
||||||
canon.getCommand = function getCommand(name) {
|
canon.getCommand = function getCommand(name) {
|
||||||
return commands[name];
|
// '|| undefined' is to silence 'reference to undefined property' warnings
|
||||||
|
return commands[name] || undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1190,8 +1192,16 @@ exports.createEvent = function(name) {
|
||||||
|
|
||||||
var dom = {};
|
var dom = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XHTML namespace
|
||||||
|
*/
|
||||||
dom.NS_XHTML = 'http://www.w3.org/1999/xhtml';
|
dom.NS_XHTML = 'http://www.w3.org/1999/xhtml';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XUL namespace
|
||||||
|
*/
|
||||||
|
dom.NS_XUL = 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an HTML or XHTML element depending on whether the document is HTML
|
* Create an HTML or XHTML element depending on whether the document is HTML
|
||||||
* or XML based. Where HTML/XHTML elements are distinguished by whether they
|
* or XML based. Where HTML/XHTML elements are distinguished by whether they
|
||||||
|
@ -1246,12 +1256,19 @@ dom.importCss = function(cssText, doc) {
|
||||||
*/
|
*/
|
||||||
dom.setInnerHtml = function(elem, html) {
|
dom.setInnerHtml = function(elem, html) {
|
||||||
if (dom.isXmlDocument(elem.ownerDocument)) {
|
if (dom.isXmlDocument(elem.ownerDocument)) {
|
||||||
dom.clearElement(elem);
|
try {
|
||||||
html = '<div xmlns="' + dom.NS_XHTML + '">' + html + '</div>';
|
dom.clearElement(elem);
|
||||||
var range = elem.ownerDocument.createRange();
|
html = '<div xmlns="' + dom.NS_XHTML + '">' + html + '</div>';
|
||||||
var child = range.createContextualFragment(html).childNodes[0];
|
var range = elem.ownerDocument.createRange();
|
||||||
while (child.hasChildNodes()) {
|
var child = range.createContextualFragment(html).firstChild;
|
||||||
elem.appendChild(child.firstChild);
|
while (child.hasChildNodes()) {
|
||||||
|
elem.appendChild(child.firstChild);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ex) {
|
||||||
|
console.error('Bad XHTML', ex);
|
||||||
|
console.trace();
|
||||||
|
throw ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1260,10 +1277,9 @@ dom.setInnerHtml = function(elem, html) {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* How to detect if we're in an XUL document (and therefore should create
|
* How to detect if we're in an XML document.
|
||||||
* elements in an XHTML namespace)
|
* In a Mozilla we check that document.xmlVersion = null, however in Chrome
|
||||||
* In a Mozilla XUL document, document.xmlVersion = null, however in Chrome
|
* we use document.contentType = undefined.
|
||||||
* document.contentType = undefined.
|
|
||||||
* @param doc The document element to work from (defaulted to the global
|
* @param doc The document element to work from (defaulted to the global
|
||||||
* 'document' if missing
|
* 'document' if missing
|
||||||
*/
|
*/
|
||||||
|
@ -1479,6 +1495,13 @@ exports.lookup = function(key) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** @see propertyLookup in lib/gcli/l10n.js */
|
||||||
|
exports.propertyLookup = Proxy.create({
|
||||||
|
get: function(rcvr, name) {
|
||||||
|
return exports.lookup(name);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
/** @see lookupFormat in lib/gcli/l10n.js */
|
/** @see lookupFormat in lib/gcli/l10n.js */
|
||||||
exports.lookupFormat = function(key, swaps) {
|
exports.lookupFormat = function(key, swaps) {
|
||||||
try {
|
try {
|
||||||
|
@ -3462,6 +3485,14 @@ exports.unsetDocument = function() {
|
||||||
doc = undefined;
|
doc = undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for the document that contains the nodes we're matching
|
||||||
|
* Most for changing things back to how they were for unit testing
|
||||||
|
*/
|
||||||
|
exports.getDocument = function() {
|
||||||
|
return doc;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A CSS expression that refers to a single node
|
* A CSS expression that refers to a single node
|
||||||
|
@ -4042,7 +4073,15 @@ UnassignedAssignment.prototype.setUnassigned = function(args) {
|
||||||
*/
|
*/
|
||||||
function Requisition(environment, doc) {
|
function Requisition(environment, doc) {
|
||||||
this.environment = environment;
|
this.environment = environment;
|
||||||
this.document = doc || document;
|
this.document = doc;
|
||||||
|
if (this.document == null) {
|
||||||
|
try {
|
||||||
|
this.document = document;
|
||||||
|
}
|
||||||
|
catch (ex) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// The command that we are about to execute.
|
// The command that we are about to execute.
|
||||||
// @see setCommandConversion()
|
// @see setCommandConversion()
|
||||||
|
@ -4508,7 +4547,8 @@ Requisition.prototype.exec = function(input) {
|
||||||
var outputObject = {
|
var outputObject = {
|
||||||
command: command,
|
command: command,
|
||||||
args: args,
|
args: args,
|
||||||
typed: this.toCanonicalString(),
|
typed: this.toString(),
|
||||||
|
canonical: this.toCanonicalString(),
|
||||||
completed: false,
|
completed: false,
|
||||||
start: new Date()
|
start: new Date()
|
||||||
};
|
};
|
||||||
|
@ -4527,7 +4567,7 @@ Requisition.prototype.exec = function(input) {
|
||||||
}).bind(this);
|
}).bind(this);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var context = new ExecutionContext(this.environment, this.document);
|
var context = new ExecutionContext(this);
|
||||||
var reply = command.exec(args, context);
|
var reply = command.exec(args, context);
|
||||||
|
|
||||||
if (reply != null && reply.isPromise) {
|
if (reply != null && reply.isPromise) {
|
||||||
|
@ -5012,9 +5052,10 @@ exports.Requisition = Requisition;
|
||||||
/**
|
/**
|
||||||
* Functions and data related to the execution of a command
|
* Functions and data related to the execution of a command
|
||||||
*/
|
*/
|
||||||
function ExecutionContext(environment, document) {
|
function ExecutionContext(requisition) {
|
||||||
this.environment = environment;
|
this.requisition = requisition;
|
||||||
this.document = document;
|
this.environment = requisition.environment;
|
||||||
|
this.document = requisition.document;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExecutionContext.prototype.createPromise = function() {
|
ExecutionContext.prototype.createPromise = function() {
|
||||||
|
@ -5041,7 +5082,275 @@ define('gcli/promise', ['require', 'exports', 'module' ], function(require, expo
|
||||||
* http://opensource.org/licenses/BSD-3-Clause
|
* http://opensource.org/licenses/BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
define('gcli/ui/display', ['require', 'exports', 'module' , 'gcli/ui/inputter', 'gcli/ui/arg_fetch', 'gcli/ui/menu', 'gcli/ui/focus'], function(require, exports, module) {
|
define('gcli/commands/help', ['require', 'exports', 'module' , 'gcli/canon', 'gcli/util', 'gcli/l10n', 'gcli/ui/domtemplate', 'text!gcli/commands/help.css', 'text!gcli/commands/help_intro.html', 'text!gcli/commands/help_list.html', 'text!gcli/commands/help_man.html'], function(require, exports, module) {
|
||||||
|
var help = exports;
|
||||||
|
|
||||||
|
|
||||||
|
var canon = require('gcli/canon');
|
||||||
|
var util = require('gcli/util');
|
||||||
|
var l10n = require('gcli/l10n');
|
||||||
|
var domtemplate = require('gcli/ui/domtemplate');
|
||||||
|
|
||||||
|
var helpCss = require('text!gcli/commands/help.css');
|
||||||
|
var helpStyle = undefined;
|
||||||
|
var helpIntroHtml = require('text!gcli/commands/help_intro.html');
|
||||||
|
var helpIntroTemplate = undefined;
|
||||||
|
var helpListHtml = require('text!gcli/commands/help_list.html');
|
||||||
|
var helpListTemplate = undefined;
|
||||||
|
var helpManHtml = require('text!gcli/commands/help_man.html');
|
||||||
|
var helpManTemplate = undefined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 'help' command
|
||||||
|
* We delay definition of helpCommandSpec until help.startup() to ensure that
|
||||||
|
* the l10n strings have been loaded
|
||||||
|
*/
|
||||||
|
var helpCommandSpec;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registration and de-registration.
|
||||||
|
*/
|
||||||
|
help.startup = function() {
|
||||||
|
|
||||||
|
helpCommandSpec = {
|
||||||
|
name: 'help',
|
||||||
|
description: l10n.lookup('helpDesc'),
|
||||||
|
manual: l10n.lookup('helpManual'),
|
||||||
|
params: [
|
||||||
|
{
|
||||||
|
name: 'search',
|
||||||
|
type: 'string',
|
||||||
|
description: l10n.lookup('helpSearchDesc'),
|
||||||
|
manual: l10n.lookup('helpSearchManual'),
|
||||||
|
defaultValue: null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
returnType: 'html',
|
||||||
|
|
||||||
|
exec: function(args, context) {
|
||||||
|
help.onFirstUseStartup(context.document);
|
||||||
|
|
||||||
|
var match = canon.getCommand(args.search);
|
||||||
|
if (match) {
|
||||||
|
var clone = helpManTemplate.cloneNode(true);
|
||||||
|
domtemplate.template(clone, getManTemplateData(match, context),
|
||||||
|
{ allowEval: true, stack: 'help_man.html' });
|
||||||
|
return clone;
|
||||||
|
}
|
||||||
|
|
||||||
|
var parent = util.dom.createElement(context.document, 'div');
|
||||||
|
if (!args.search) {
|
||||||
|
parent.appendChild(helpIntroTemplate.cloneNode(true));
|
||||||
|
}
|
||||||
|
parent.appendChild(helpListTemplate.cloneNode(true));
|
||||||
|
domtemplate.template(parent, getListTemplateData(args, context),
|
||||||
|
{ allowEval: true, stack: 'help_intro.html | help_list.html' });
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
canon.addCommand(helpCommandSpec);
|
||||||
|
};
|
||||||
|
|
||||||
|
help.shutdown = function() {
|
||||||
|
canon.removeCommand(helpCommandSpec);
|
||||||
|
|
||||||
|
helpListTemplate = undefined;
|
||||||
|
helpStyle.parentElement.removeChild(helpStyle);
|
||||||
|
helpStyle = undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the command is executed
|
||||||
|
*/
|
||||||
|
help.onFirstUseStartup = function(document) {
|
||||||
|
if (!helpIntroTemplate) {
|
||||||
|
helpIntroTemplate = util.dom.createElement(document, 'div');
|
||||||
|
util.dom.setInnerHtml(helpIntroTemplate, helpIntroHtml);
|
||||||
|
}
|
||||||
|
if (!helpListTemplate) {
|
||||||
|
helpListTemplate = util.dom.createElement(document, 'div');
|
||||||
|
util.dom.setInnerHtml(helpListTemplate, helpListHtml);
|
||||||
|
}
|
||||||
|
if (!helpManTemplate) {
|
||||||
|
helpManTemplate = util.dom.createElement(document, 'div');
|
||||||
|
util.dom.setInnerHtml(helpManTemplate, helpManHtml);
|
||||||
|
}
|
||||||
|
if (!helpStyle && helpCss != null) {
|
||||||
|
helpStyle = util.dom.importCss(helpCss, document);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find an element within the passed element with the class gcli-help-command
|
||||||
|
* and update the requisition to contain this text.
|
||||||
|
*/
|
||||||
|
function updateCommand(element, context) {
|
||||||
|
context.requisition.update({
|
||||||
|
typed: element.querySelector('.gcli-help-command').textContent
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find an element within the passed element with the class gcli-help-command
|
||||||
|
* and execute this text.
|
||||||
|
*/
|
||||||
|
function executeCommand(element, context) {
|
||||||
|
context.requisition.exec({
|
||||||
|
visible: true,
|
||||||
|
typed: element.querySelector('.gcli-help-command').textContent
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a block of data suitable to be passed to the help_list.html template
|
||||||
|
*/
|
||||||
|
function getListTemplateData(args, context) {
|
||||||
|
return {
|
||||||
|
l10n: l10n.propertyLookup,
|
||||||
|
lang: context.document.defaultView.navigator.language,
|
||||||
|
|
||||||
|
onclick: function(ev) {
|
||||||
|
updateCommand(ev.currentTarget, context);
|
||||||
|
},
|
||||||
|
|
||||||
|
ondblclick: function(ev) {
|
||||||
|
executeCommand(ev.currentTarget, context);
|
||||||
|
},
|
||||||
|
|
||||||
|
getHeading: function() {
|
||||||
|
return args.search == null ?
|
||||||
|
'Available Commands:' :
|
||||||
|
'Commands starting with \'' + args.search + '\':';
|
||||||
|
},
|
||||||
|
|
||||||
|
getMatchingCommands: function() {
|
||||||
|
var matching = canon.getCommands().filter(function(command) {
|
||||||
|
if (args.search && command.name.indexOf(args.search) !== 0) {
|
||||||
|
// Filtered out because they don't match the search
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!args.search && command.name.indexOf(' ') != -1) {
|
||||||
|
// We don't show sub commands with plain 'help'
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
matching.sort();
|
||||||
|
return matching;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a block of data suitable to be passed to the help_man.html template
|
||||||
|
*/
|
||||||
|
function getManTemplateData(command, context) {
|
||||||
|
return {
|
||||||
|
l10n: l10n.propertyLookup,
|
||||||
|
lang: context.document.defaultView.navigator.language,
|
||||||
|
|
||||||
|
command: command,
|
||||||
|
|
||||||
|
onclick: function(ev) {
|
||||||
|
updateCommand(ev.currentTarget, context);
|
||||||
|
},
|
||||||
|
|
||||||
|
getTypeDescription: function(param) {
|
||||||
|
var input = '';
|
||||||
|
if (param.defaultValue === undefined) {
|
||||||
|
input = 'required';
|
||||||
|
}
|
||||||
|
else if (param.defaultValue === null) {
|
||||||
|
input = 'optional';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
input = param.defaultValue;
|
||||||
|
}
|
||||||
|
return '(' + param.type.name + ', ' + input + ')';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
/*
|
||||||
|
* Copyright 2009-2011 Mozilla Foundation and contributors
|
||||||
|
* Licensed under the New BSD license. See LICENSE.txt or:
|
||||||
|
* http://opensource.org/licenses/BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
define('gcli/ui/domtemplate', ['require', 'exports', 'module' ], function(require, exports, module) {
|
||||||
|
|
||||||
|
var obj = {};
|
||||||
|
Components.utils.import('resource:///modules/devtools/Templater.jsm', obj);
|
||||||
|
exports.template = obj.template;
|
||||||
|
|
||||||
|
});
|
||||||
|
define("text!gcli/commands/help.css", [], void 0);
|
||||||
|
define("text!gcli/commands/help_intro.html", [], "\n" +
|
||||||
|
"<h2>${l10n.introHeader}</h2>\n" +
|
||||||
|
"\n" +
|
||||||
|
"<p>\n" +
|
||||||
|
" <a target=\"_blank\" href=\"https://developer.mozilla.org/AppLinks/WebConsoleHelp?locale=${lang}\">\n" +
|
||||||
|
" ${l10n.introBody}\n" +
|
||||||
|
" </a>\n" +
|
||||||
|
"</p>\n" +
|
||||||
|
"");
|
||||||
|
|
||||||
|
define("text!gcli/commands/help_list.html", [], "\n" +
|
||||||
|
"<h3>${getHeading()}</h3>\n" +
|
||||||
|
"\n" +
|
||||||
|
"<table>\n" +
|
||||||
|
" <tr foreach=\"command in ${getMatchingCommands()}\"\n" +
|
||||||
|
" onclick=\"${onclick}\" ondblclick=\"${ondblclick}\">\n" +
|
||||||
|
" <th class=\"gcli-help-name\">${command.name}</th>\n" +
|
||||||
|
" <td class=\"gcli-help-arrow\">→</td>\n" +
|
||||||
|
" <td>\n" +
|
||||||
|
" ${command.description}\n" +
|
||||||
|
" <span class=\"gcli-out-shortcut gcli-help-command\">help ${command.name}</span>\n" +
|
||||||
|
" </td>\n" +
|
||||||
|
" </tr>\n" +
|
||||||
|
"</table>\n" +
|
||||||
|
"");
|
||||||
|
|
||||||
|
define("text!gcli/commands/help_man.html", [], "\n" +
|
||||||
|
"<h3>${command.name}</h3>\n" +
|
||||||
|
"\n" +
|
||||||
|
"<h4 class=\"gcli-help-header\">\n" +
|
||||||
|
" ${l10n.helpManSynopsis}:\n" +
|
||||||
|
" <span class=\"gcli-help-synopsis\" onclick=\"${onclick}\">\n" +
|
||||||
|
" <span class=\"gcli-help-command\">${command.name}</span>\n" +
|
||||||
|
" <span foreach=\"param in ${command.params}\">\n" +
|
||||||
|
" ${param.defaultValue !== undefined ? '[' + param.name + ']' : param.name}\n" +
|
||||||
|
" </span>\n" +
|
||||||
|
" </span>\n" +
|
||||||
|
"</h4>\n" +
|
||||||
|
"\n" +
|
||||||
|
"<h4 class=\"gcli-help-header\">${l10n.helpManDescription}:</h4>\n" +
|
||||||
|
"\n" +
|
||||||
|
"<p class=\"gcli-help-description\">\n" +
|
||||||
|
" ${command.manual || command.description}\n" +
|
||||||
|
"</p>\n" +
|
||||||
|
"\n" +
|
||||||
|
"<h4 class=\"gcli-help-header\">${l10n.helpManParameters}:</h4>\n" +
|
||||||
|
"\n" +
|
||||||
|
"<ul class=\"gcli-help-parameter\">\n" +
|
||||||
|
" <li if=\"${command.params.length === 0}\">${l10n.helpManNone}</li>\n" +
|
||||||
|
" <li foreach=\"param in ${command.params}\">\n" +
|
||||||
|
" <tt>${param.name}</tt> ${getTypeDescription(param)}\n" +
|
||||||
|
" <br/>\n" +
|
||||||
|
" ${param.manual || param.description}\n" +
|
||||||
|
" </li>\n" +
|
||||||
|
"</ul>\n" +
|
||||||
|
"");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2009-2011 Mozilla Foundation and contributors
|
||||||
|
* Licensed under the New BSD license. See LICENSE.txt or:
|
||||||
|
* http://opensource.org/licenses/BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
define('gcli/ui/console', ['require', 'exports', 'module' , 'gcli/ui/inputter', 'gcli/ui/arg_fetch', 'gcli/ui/menu', 'gcli/ui/focus'], function(require, exports, module) {
|
||||||
|
|
||||||
var Inputter = require('gcli/ui/inputter').Inputter;
|
var Inputter = require('gcli/ui/inputter').Inputter;
|
||||||
var ArgFetcher = require('gcli/ui/arg_fetch').ArgFetcher;
|
var ArgFetcher = require('gcli/ui/arg_fetch').ArgFetcher;
|
||||||
|
@ -5049,10 +5358,10 @@ var CommandMenu = require('gcli/ui/menu').CommandMenu;
|
||||||
var FocusManager = require('gcli/ui/focus').FocusManager;
|
var FocusManager = require('gcli/ui/focus').FocusManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display is responsible for generating the UI for GCLI, this implementation
|
* Console is responsible for generating the UI for GCLI, this implementation
|
||||||
* is a special case for use inside Firefox
|
* is a special case for use inside Firefox
|
||||||
*/
|
*/
|
||||||
function Display(options) {
|
function Console(options) {
|
||||||
this.hintElement = options.hintElement;
|
this.hintElement = options.hintElement;
|
||||||
this.gcliTerm = options.gcliTerm;
|
this.gcliTerm = options.gcliTerm;
|
||||||
this.consoleWrap = options.consoleWrap;
|
this.consoleWrap = options.consoleWrap;
|
||||||
|
@ -5097,7 +5406,7 @@ function Display(options) {
|
||||||
/**
|
/**
|
||||||
* Avoid memory leaks
|
* Avoid memory leaks
|
||||||
*/
|
*/
|
||||||
Display.prototype.destroy = function() {
|
Console.prototype.destroy = function() {
|
||||||
this.chromeWindow.removeEventListener('resize', this.resizer, false);
|
this.chromeWindow.removeEventListener('resize', this.resizer, false);
|
||||||
delete this.resizer;
|
delete this.resizer;
|
||||||
delete this.chromeWindow;
|
delete this.chromeWindow;
|
||||||
|
@ -5122,10 +5431,17 @@ Display.prototype.destroy = function() {
|
||||||
/**
|
/**
|
||||||
* Called on chrome window resize, or on divider slide
|
* Called on chrome window resize, or on divider slide
|
||||||
*/
|
*/
|
||||||
Display.prototype.resizer = function() {
|
Console.prototype.resizer = function() {
|
||||||
|
// Bug 705109: There are several numbers hard-coded in this function.
|
||||||
|
// This is simpler than calculating them, but error-prone when the UI setup,
|
||||||
|
// the styling or display settings change.
|
||||||
|
|
||||||
var parentRect = this.consoleWrap.getBoundingClientRect();
|
var parentRect = this.consoleWrap.getBoundingClientRect();
|
||||||
|
// Magic number: 64 is the size of the toolbar above the output area
|
||||||
var parentHeight = parentRect.bottom - parentRect.top - 64;
|
var parentHeight = parentRect.bottom - parentRect.top - 64;
|
||||||
|
|
||||||
|
// Magic number: 100 is the size at which we decide the hints are too small
|
||||||
|
// to be useful, so we hide them
|
||||||
if (parentHeight < 100) {
|
if (parentHeight < 100) {
|
||||||
this.hintElement.classList.add('gcliterm-hint-nospace');
|
this.hintElement.classList.add('gcliterm-hint-nospace');
|
||||||
}
|
}
|
||||||
|
@ -5136,20 +5452,14 @@ Display.prototype.resizer = function() {
|
||||||
if (isMenuVisible) {
|
if (isMenuVisible) {
|
||||||
this.menu.setMaxHeight(parentHeight);
|
this.menu.setMaxHeight(parentHeight);
|
||||||
|
|
||||||
// Magic numbers. We have 2 options - lots of complex dom math to derive
|
// Magic numbers: 19 = height of a menu item, 22 = total vertical padding
|
||||||
// the height of a menu item (19 pixels) and the vertical padding
|
// of container
|
||||||
// (22 pixels), or we could just hard-code. The former is *slightly* more
|
|
||||||
// resilient to refactoring (but still breaks with dom structure changes),
|
|
||||||
// the latter is simpler, faster and easier.
|
|
||||||
var idealMenuHeight = (19 * this.menu.items.length) + 22;
|
var idealMenuHeight = (19 * this.menu.items.length) + 22;
|
||||||
|
|
||||||
if (idealMenuHeight > parentHeight) {
|
if (idealMenuHeight > parentHeight) {
|
||||||
this.hintElement.style.overflowY = 'scroll';
|
this.hintElement.classList.add('gcliterm-hint-scroll');
|
||||||
this.hintElement.style.borderBottomColor = 'threedshadow';
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.hintElement.style.overflowY = null;
|
this.hintElement.classList.remove('gcliterm-hint-scroll');
|
||||||
this.hintElement.style.borderBottomColor = 'white';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -5161,7 +5471,7 @@ Display.prototype.resizer = function() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.Display = Display;
|
exports.Console = Console;
|
||||||
|
|
||||||
});
|
});
|
||||||
/*
|
/*
|
||||||
|
@ -5582,8 +5892,9 @@ cliView.Inputter = Inputter;
|
||||||
* - document (required) DOM document to be used in creating elements
|
* - document (required) DOM document to be used in creating elements
|
||||||
* - requisition (required) A GCLI Requisition object whose state is monitored
|
* - requisition (required) A GCLI Requisition object whose state is monitored
|
||||||
* - completeElement (optional) An element to use
|
* - completeElement (optional) An element to use
|
||||||
* - completionPrompt (optional) The prompt to show before a completion.
|
* - completionPrompt (optional) The prompt - defaults to '\u00bb'
|
||||||
* Defaults to '»' (double greater-than, a.k.a right guillemet).
|
* (double greater-than, a.k.a right guillemet). The prompt is used directly
|
||||||
|
* in a TextNode, so HTML entities are not allowed.
|
||||||
*/
|
*/
|
||||||
function Completer(options) {
|
function Completer(options) {
|
||||||
this.document = options.document || document;
|
this.document = options.document || document;
|
||||||
|
@ -5606,7 +5917,7 @@ function Completer(options) {
|
||||||
|
|
||||||
this.completionPrompt = typeof options.completionPrompt === 'string'
|
this.completionPrompt = typeof options.completionPrompt === 'string'
|
||||||
? options.completionPrompt
|
? options.completionPrompt
|
||||||
: '»';
|
: '\u00bb';
|
||||||
|
|
||||||
if (options.inputBackgroundElement) {
|
if (options.inputBackgroundElement) {
|
||||||
this.backgroundElement = options.inputBackgroundElement;
|
this.backgroundElement = options.inputBackgroundElement;
|
||||||
|
@ -5714,50 +6025,85 @@ Completer.prototype.update = function(input) {
|
||||||
var current = this.requisition.getAssignmentAt(input.cursor.start);
|
var current = this.requisition.getAssignmentAt(input.cursor.start);
|
||||||
var predictions = current.getPredictions();
|
var predictions = current.getPredictions();
|
||||||
|
|
||||||
var completion = '<span class="gcli-prompt">' + this.completionPrompt + '</span> ';
|
dom.clearElement(this.element);
|
||||||
|
|
||||||
|
// All this DOM manipulation is equivalent to the HTML below.
|
||||||
|
// It's not a template because it's very simple except appendMarkupStatus()
|
||||||
|
// which is complex due to a need to merge spans.
|
||||||
|
// Bug 707131 questions if we couldn't simplify this to use a template.
|
||||||
|
//
|
||||||
|
// <span class="gcli-prompt">${completionPrompt}</span>
|
||||||
|
// ${appendMarkupStatus()}
|
||||||
|
// ${prefix}
|
||||||
|
// <span class="gcli-in-ontab">${contents}</span>
|
||||||
|
// <span class="gcli-in-closebrace" if="${unclosedJs}">}<span>
|
||||||
|
|
||||||
|
var document = this.element.ownerDocument;
|
||||||
|
var prompt = document.createElement('span');
|
||||||
|
prompt.classList.add('gcli-prompt');
|
||||||
|
prompt.appendChild(document.createTextNode(this.completionPrompt + ' '));
|
||||||
|
this.element.appendChild(prompt);
|
||||||
|
|
||||||
if (input.typed.length > 0) {
|
if (input.typed.length > 0) {
|
||||||
var scores = this.requisition.getInputStatusMarkup(input.cursor.start);
|
var scores = this.requisition.getInputStatusMarkup(input.cursor.start);
|
||||||
completion += this.markupStatusScore(scores, input);
|
this.appendMarkupStatus(this.element, scores, input);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input.typed.length > 0 && predictions.length > 0) {
|
if (input.typed.length > 0 && predictions.length > 0) {
|
||||||
var tab = predictions[0].name;
|
var tab = predictions[0].name;
|
||||||
var existing = current.getArg().text;
|
var existing = current.getArg().text;
|
||||||
if (isStrictCompletion(existing, tab) && input.cursor.start === input.typed.length) {
|
|
||||||
// Display the suffix of the prediction as the completion.
|
var contents;
|
||||||
|
var prefix = null;
|
||||||
|
|
||||||
|
if (isStrictCompletion(existing, tab) &&
|
||||||
|
input.cursor.start === input.typed.length) {
|
||||||
|
// Display the suffix of the prediction as the completion
|
||||||
var numLeadingSpaces = existing.match(/^(\s*)/)[0].length;
|
var numLeadingSpaces = existing.match(/^(\s*)/)[0].length;
|
||||||
var suffix = tab.slice(existing.length - numLeadingSpaces);
|
contents = tab.slice(existing.length - numLeadingSpaces);
|
||||||
completion += '<span class="gcli-in-ontab">' + suffix + '</span>';
|
|
||||||
} else {
|
} else {
|
||||||
// Display the '-> prediction' at the end of the completer element
|
// Display the '-> prediction' at the end of the completer element
|
||||||
completion += '  <span class="gcli-in-ontab">⇥ ' +
|
prefix = ' \u00a0'; // aka
|
||||||
tab + '</span>';
|
contents = '\u21E5 ' + tab; // aka → the right arrow
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (prefix != null) {
|
||||||
|
this.element.appendChild(document.createTextNode(prefix));
|
||||||
|
}
|
||||||
|
|
||||||
|
var suffix = document.createElement('span');
|
||||||
|
suffix.classList.add('gcli-in-ontab');
|
||||||
|
suffix.appendChild(document.createTextNode(contents));
|
||||||
|
this.element.appendChild(suffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
// A hack to add a grey '}' to the end of the command line when we've opened
|
// Add a grey '}' to the end of the command line when we've opened
|
||||||
// with a { but haven't closed it
|
// with a { but haven't closed it
|
||||||
var command = this.requisition.commandAssignment.getValue();
|
var command = this.requisition.commandAssignment.getValue();
|
||||||
if (command && command.name === '{') {
|
var unclosedJs = command && command.name === '{' &&
|
||||||
if (this.requisition.getAssignment(0).getArg().suffix.indexOf('}') === -1) {
|
this.requisition.getAssignment(0).getArg().suffix.indexOf('}') === -1;
|
||||||
completion += '<span class="gcli-in-closebrace">}</span>';
|
if (unclosedJs) {
|
||||||
}
|
var close = document.createElement('span');
|
||||||
|
close.classList.add('gcli-in-closebrace');
|
||||||
|
close.appendChild(document.createTextNode('}'));
|
||||||
|
this.element.appendChild(close);
|
||||||
}
|
}
|
||||||
|
|
||||||
dom.setInnerHtml(this.element, completion);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark-up an array of Status values with spans
|
* Mark-up an array of Status values with spans
|
||||||
*/
|
*/
|
||||||
Completer.prototype.markupStatusScore = function(scores, input) {
|
Completer.prototype.appendMarkupStatus = function(element, scores, input) {
|
||||||
var completion = '';
|
|
||||||
if (scores.length === 0) {
|
if (scores.length === 0) {
|
||||||
return completion;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var document = element.ownerDocument;
|
||||||
var i = 0;
|
var i = 0;
|
||||||
var lastStatus = -1;
|
var lastStatus = -1;
|
||||||
|
var span;
|
||||||
|
var contents = '';
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (lastStatus !== scores[i]) {
|
if (lastStatus !== scores[i]) {
|
||||||
var state = scores[i];
|
var state = scores[i];
|
||||||
|
@ -5765,25 +6111,27 @@ Completer.prototype.markupStatusScore = function(scores, input) {
|
||||||
console.error('No state at i=' + i + '. scores.len=' + scores.length);
|
console.error('No state at i=' + i + '. scores.len=' + scores.length);
|
||||||
state = Status.VALID;
|
state = Status.VALID;
|
||||||
}
|
}
|
||||||
completion += '<span class="gcli-in-' + state.toString().toLowerCase() + '">';
|
span = document.createElement('span');
|
||||||
|
span.classList.add('gcli-in-' + state.toString().toLowerCase());
|
||||||
lastStatus = scores[i];
|
lastStatus = scores[i];
|
||||||
}
|
}
|
||||||
var char = input.typed[i];
|
var char = input.typed[i];
|
||||||
if (char === ' ') {
|
if (char === ' ') {
|
||||||
char = ' ';
|
char = '\u00a0';
|
||||||
}
|
}
|
||||||
completion += char;
|
contents += char;
|
||||||
i++;
|
i++;
|
||||||
if (i === input.typed.length) {
|
if (i === input.typed.length) {
|
||||||
completion += '</span>';
|
span.appendChild(document.createTextNode(contents));
|
||||||
|
this.element.appendChild(span);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (lastStatus !== scores[i]) {
|
if (lastStatus !== scores[i]) {
|
||||||
completion += '</span>';
|
span.appendChild(document.createTextNode(contents));
|
||||||
|
this.element.appendChild(span);
|
||||||
|
contents = '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return completion;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
cliView.Completer = Completer;
|
cliView.Completer = Completer;
|
||||||
|
@ -5867,7 +6215,7 @@ var dom = require('gcli/util').dom;
|
||||||
var Status = require('gcli/types').Status;
|
var Status = require('gcli/types').Status;
|
||||||
|
|
||||||
var getField = require('gcli/ui/field').getField;
|
var getField = require('gcli/ui/field').getField;
|
||||||
var Templater = require('gcli/ui/domtemplate').Templater;
|
var domtemplate = require('gcli/ui/domtemplate');
|
||||||
|
|
||||||
var editorCss = require('text!gcli/ui/arg_fetch.css');
|
var editorCss = require('text!gcli/ui/arg_fetch.css');
|
||||||
var argFetchHtml = require('text!gcli/ui/arg_fetch.html');
|
var argFetchHtml = require('text!gcli/ui/arg_fetch.html');
|
||||||
|
@ -5896,7 +6244,6 @@ function ArgFetcher(options) {
|
||||||
// We cache the fields we create so we can destroy them later
|
// We cache the fields we create so we can destroy them later
|
||||||
this.fields = [];
|
this.fields = [];
|
||||||
|
|
||||||
this.tmpl = new Templater();
|
|
||||||
// Populated by template
|
// Populated by template
|
||||||
this.okElement = null;
|
this.okElement = null;
|
||||||
|
|
||||||
|
@ -5953,7 +6300,8 @@ ArgFetcher.prototype.onCommandChange = function(ev) {
|
||||||
this.fields = [];
|
this.fields = [];
|
||||||
|
|
||||||
var reqEle = this.reqTempl.cloneNode(true);
|
var reqEle = this.reqTempl.cloneNode(true);
|
||||||
this.tmpl.processNode(reqEle, this);
|
domtemplate.template(reqEle, this,
|
||||||
|
{ allowEval: true, stack: 'arg_fetch.html' });
|
||||||
dom.clearElement(this.element);
|
dom.clearElement(this.element);
|
||||||
this.element.appendChild(reqEle);
|
this.element.appendChild(reqEle);
|
||||||
|
|
||||||
|
@ -6008,7 +6356,7 @@ ArgFetcher.prototype.getInputFor = function(assignment) {
|
||||||
return newField.element;
|
return newField.element;
|
||||||
}
|
}
|
||||||
catch (ex) {
|
catch (ex) {
|
||||||
// This is called from within Templater which can make tracing errors hard
|
// This is called from within template() which can make tracing errors hard
|
||||||
// so we log here if anything goes wrong
|
// so we log here if anything goes wrong
|
||||||
console.error(ex);
|
console.error(ex);
|
||||||
return '';
|
return '';
|
||||||
|
@ -6252,7 +6600,7 @@ function StringField(type, options) {
|
||||||
|
|
||||||
this.element = dom.createElement(this.document, 'input');
|
this.element = dom.createElement(this.document, 'input');
|
||||||
this.element.type = 'text';
|
this.element.type = 'text';
|
||||||
this.element.className = 'gcli-field';
|
this.element.classList.add('gcli-field');
|
||||||
|
|
||||||
this.onInputChange = this.onInputChange.bind(this);
|
this.onInputChange = this.onInputChange.bind(this);
|
||||||
this.element.addEventListener('keyup', this.onInputChange, false);
|
this.element.addEventListener('keyup', this.onInputChange, false);
|
||||||
|
@ -6412,7 +6760,7 @@ function SelectionField(type, options) {
|
||||||
this.items = [];
|
this.items = [];
|
||||||
|
|
||||||
this.element = dom.createElement(this.document, 'select');
|
this.element = dom.createElement(this.document, 'select');
|
||||||
this.element.className = 'gcli-field';
|
this.element.classList.add('gcli-field');
|
||||||
this._addOption({
|
this._addOption({
|
||||||
name: l10n.lookupFormat('fieldSelectionSelect', [ options.name ])
|
name: l10n.lookupFormat('fieldSelectionSelect', [ options.name ])
|
||||||
});
|
});
|
||||||
|
@ -6487,8 +6835,8 @@ function JavascriptField(type, options) {
|
||||||
this.input = dom.createElement(this.document, 'input');
|
this.input = dom.createElement(this.document, 'input');
|
||||||
this.input.type = 'text';
|
this.input.type = 'text';
|
||||||
this.input.addEventListener('keyup', this.onInputChange, false);
|
this.input.addEventListener('keyup', this.onInputChange, false);
|
||||||
this.input.style.marginBottom = '0';
|
this.input.classList.add('gcli-field');
|
||||||
this.input.className = 'gcli-field';
|
this.input.classList.add('gcli-field-javascript');
|
||||||
this.element.appendChild(this.input);
|
this.element.appendChild(this.input);
|
||||||
|
|
||||||
this.menu = new Menu({ document: this.document, field: true });
|
this.menu = new Menu({ document: this.document, field: true });
|
||||||
|
@ -6680,18 +7028,18 @@ function ArrayField(type, options) {
|
||||||
|
|
||||||
// <div class=gcliArrayParent save="${element}">
|
// <div class=gcliArrayParent save="${element}">
|
||||||
this.element = dom.createElement(this.document, 'div');
|
this.element = dom.createElement(this.document, 'div');
|
||||||
this.element.className = 'gcliArrayParent';
|
this.element.classList.add('gcli-array-parent');
|
||||||
|
|
||||||
// <button class=gcliArrayMbrAdd onclick="${_onAdd}" save="${addButton}">Add
|
// <button class=gcliArrayMbrAdd onclick="${_onAdd}" save="${addButton}">Add
|
||||||
this.addButton = dom.createElement(this.document, 'button');
|
this.addButton = dom.createElement(this.document, 'button');
|
||||||
this.addButton.className = 'gcliArrayMbrAdd';
|
this.addButton.classList.add('gcli-array-member-add');
|
||||||
this.addButton.addEventListener('click', this._onAdd, false);
|
this.addButton.addEventListener('click', this._onAdd, false);
|
||||||
this.addButton.innerHTML = l10n.lookup('fieldArrayAdd');
|
this.addButton.innerHTML = l10n.lookup('fieldArrayAdd');
|
||||||
this.element.appendChild(this.addButton);
|
this.element.appendChild(this.addButton);
|
||||||
|
|
||||||
// <div class=gcliArrayMbrs save="${mbrElement}">
|
// <div class=gcliArrayMbrs save="${mbrElement}">
|
||||||
this.container = dom.createElement(this.document, 'div');
|
this.container = dom.createElement(this.document, 'div');
|
||||||
this.container.className = 'gcliArrayMbrs';
|
this.container.classList.add('gcli-array-members');
|
||||||
this.element.appendChild(this.container);
|
this.element.appendChild(this.container);
|
||||||
|
|
||||||
this.onInputChange = this.onInputChange.bind(this);
|
this.onInputChange = this.onInputChange.bind(this);
|
||||||
|
@ -6734,7 +7082,7 @@ ArrayField.prototype.getConversion = function() {
|
||||||
ArrayField.prototype._onAdd = function(ev, subConversion) {
|
ArrayField.prototype._onAdd = function(ev, subConversion) {
|
||||||
// <div class=gcliArrayMbr save="${element}">
|
// <div class=gcliArrayMbr save="${element}">
|
||||||
var element = dom.createElement(this.document, 'div');
|
var element = dom.createElement(this.document, 'div');
|
||||||
element.className = 'gcliArrayMbr';
|
element.classList.add('gcli-array-member');
|
||||||
this.container.appendChild(element);
|
this.container.appendChild(element);
|
||||||
|
|
||||||
// ${field.element}
|
// ${field.element}
|
||||||
|
@ -6752,7 +7100,7 @@ ArrayField.prototype._onAdd = function(ev, subConversion) {
|
||||||
|
|
||||||
// <div class=gcliArrayMbrDel onclick="${_onDel}">
|
// <div class=gcliArrayMbrDel onclick="${_onDel}">
|
||||||
var delButton = dom.createElement(this.document, 'button');
|
var delButton = dom.createElement(this.document, 'button');
|
||||||
delButton.className = 'gcliArrayMbrDel';
|
delButton.classList.add('gcli-array-member-del');
|
||||||
delButton.addEventListener('click', this._onDel, false);
|
delButton.addEventListener('click', this._onDel, false);
|
||||||
delButton.innerHTML = l10n.lookup('fieldArrayDel');
|
delButton.innerHTML = l10n.lookup('fieldArrayDel');
|
||||||
element.appendChild(delButton);
|
element.appendChild(delButton);
|
||||||
|
@ -6794,7 +7142,7 @@ var Conversion = require('gcli/types').Conversion;
|
||||||
var Argument = require('gcli/argument').Argument;
|
var Argument = require('gcli/argument').Argument;
|
||||||
var canon = require('gcli/canon');
|
var canon = require('gcli/canon');
|
||||||
|
|
||||||
var Templater = require('gcli/ui/domtemplate').Templater;
|
var domtemplate = require('gcli/ui/domtemplate');
|
||||||
|
|
||||||
var menuCss = require('text!gcli/ui/menu.css');
|
var menuCss = require('text!gcli/ui/menu.css');
|
||||||
var menuHtml = require('text!gcli/ui/menu.html');
|
var menuHtml = require('text!gcli/ui/menu.html');
|
||||||
|
@ -6877,7 +7225,7 @@ Menu.prototype.show = function(items, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var options = this.optTempl.cloneNode(true);
|
var options = this.optTempl.cloneNode(true);
|
||||||
new Templater().processNode(options, this);
|
domtemplate.template(options, this, { allowEval: true, stack: 'menu.html' });
|
||||||
|
|
||||||
dom.clearElement(this.element);
|
dom.clearElement(this.element);
|
||||||
this.element.appendChild(options);
|
this.element.appendChild(options);
|
||||||
|
@ -6984,18 +7332,6 @@ CommandMenu.prototype.onCommandChange = function(ev) {
|
||||||
exports.CommandMenu = CommandMenu;
|
exports.CommandMenu = CommandMenu;
|
||||||
|
|
||||||
|
|
||||||
});
|
|
||||||
/*
|
|
||||||
* Copyright 2009-2011 Mozilla Foundation and contributors
|
|
||||||
* Licensed under the New BSD license. See LICENSE.txt or:
|
|
||||||
* http://opensource.org/licenses/BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
define('gcli/ui/domtemplate', ['require', 'exports', 'module' ], function(require, exports, module) {
|
|
||||||
|
|
||||||
Components.utils.import("resource:///modules/devtools/Templater.jsm");
|
|
||||||
exports.Templater = Templater;
|
|
||||||
|
|
||||||
});
|
});
|
||||||
define("text!gcli/ui/menu.css", [], void 0);
|
define("text!gcli/ui/menu.css", [], void 0);
|
||||||
define("text!gcli/ui/menu.html", [], "\n" +
|
define("text!gcli/ui/menu.html", [], "\n" +
|
||||||
|
|
|
@ -83,12 +83,12 @@ function testCallCommands() {
|
||||||
is(gcliterm.completeNode.textContent, " ecd", "Completion for \"ecd\"");
|
is(gcliterm.completeNode.textContent, " ecd", "Completion for \"ecd\"");
|
||||||
|
|
||||||
// Test a normal command's life cycle
|
// Test a normal command's life cycle
|
||||||
gcliterm.opts.display.inputter.setInput("echo hello world");
|
gcliterm.opts.console.inputter.setInput("echo hello world");
|
||||||
gcliterm.opts.requisition.exec();
|
gcliterm.opts.requisition.exec();
|
||||||
|
|
||||||
let nodes = hud.outputNode.querySelectorAll("description");
|
let nodes = hud.outputNode.querySelectorAll(".gcliterm-msg-body");
|
||||||
|
|
||||||
is(nodes.length, 2, "Right number of output nodes");
|
is(nodes.length, 1, "Right number of output nodes");
|
||||||
ok(/hello world/.test(nodes[0].textContent), "the command's output is correct.");
|
ok(/hello world/.test(nodes[0].textContent), "the command's output is correct.");
|
||||||
|
|
||||||
gcliterm.clearOutput();
|
gcliterm.clearOutput();
|
||||||
|
|
|
@ -54,7 +54,7 @@ var Node = Components.interfaces.nsIDOMNode;
|
||||||
* http://opensource.org/licenses/BSD-3-Clause
|
* http://opensource.org/licenses/BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
define('gclitest/suite', ['require', 'exports', 'module' , 'gcli/index', 'test/examiner', 'gclitest/testTokenize', 'gclitest/testSplit', 'gclitest/testCli', 'gclitest/testHistory', 'gclitest/testRequire', 'gclitest/testJs'], function(require, exports, module) {
|
define('gclitest/suite', ['require', 'exports', 'module' , 'gcli/index', 'test/examiner', 'gclitest/testTokenize', 'gclitest/testSplit', 'gclitest/testCli', 'gclitest/testExec', 'gclitest/testKeyboard', 'gclitest/testHistory', 'gclitest/testRequire', 'gclitest/testJs'], function(require, exports, module) {
|
||||||
|
|
||||||
// We need to make sure GCLI is initialized before we begin testing it
|
// We need to make sure GCLI is initialized before we begin testing it
|
||||||
require('gcli/index');
|
require('gcli/index');
|
||||||
|
@ -67,11 +67,15 @@ define('gclitest/suite', ['require', 'exports', 'module' , 'gcli/index', 'test/e
|
||||||
examiner.addSuite('gclitest/testTokenize', require('gclitest/testTokenize'));
|
examiner.addSuite('gclitest/testTokenize', require('gclitest/testTokenize'));
|
||||||
examiner.addSuite('gclitest/testSplit', require('gclitest/testSplit'));
|
examiner.addSuite('gclitest/testSplit', require('gclitest/testSplit'));
|
||||||
examiner.addSuite('gclitest/testCli', require('gclitest/testCli'));
|
examiner.addSuite('gclitest/testCli', require('gclitest/testCli'));
|
||||||
|
examiner.addSuite('gclitest/testExec', require('gclitest/testExec'));
|
||||||
|
examiner.addSuite('gclitest/testKeyboard', require('gclitest/testKeyboard'));
|
||||||
examiner.addSuite('gclitest/testHistory', require('gclitest/testHistory'));
|
examiner.addSuite('gclitest/testHistory', require('gclitest/testHistory'));
|
||||||
examiner.addSuite('gclitest/testRequire', require('gclitest/testRequire'));
|
examiner.addSuite('gclitest/testRequire', require('gclitest/testRequire'));
|
||||||
examiner.addSuite('gclitest/testJs', require('gclitest/testJs'));
|
examiner.addSuite('gclitest/testJs', require('gclitest/testJs'));
|
||||||
|
|
||||||
examiner.run();
|
examiner.run();
|
||||||
|
console.log('Completed test suite');
|
||||||
|
// examiner.log();
|
||||||
|
|
||||||
});
|
});
|
||||||
/*
|
/*
|
||||||
|
@ -167,6 +171,19 @@ examiner.toRemote = function() {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Output a test summary to console.log
|
||||||
|
*/
|
||||||
|
examiner.log = function() {
|
||||||
|
var remote = this.toRemote();
|
||||||
|
remote.suites.forEach(function(suite) {
|
||||||
|
console.log(suite.name);
|
||||||
|
suite.tests.forEach(function(test) {
|
||||||
|
console.log('- ' + test.name, test.status.name, test.message || '');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used by assert to record a failure against the current test
|
* Used by assert to record a failure against the current test
|
||||||
*/
|
*/
|
||||||
|
@ -299,8 +316,8 @@ Test.prototype.run = function() {
|
||||||
this.status = stati.fail;
|
this.status = stati.fail;
|
||||||
this.messages.push('' + ex);
|
this.messages.push('' + ex);
|
||||||
console.error(ex);
|
console.error(ex);
|
||||||
if (console.trace) {
|
if (ex.stack) {
|
||||||
console.trace();
|
console.error(ex.stack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -703,11 +720,12 @@ exports.testJavascript = function() {
|
||||||
* http://opensource.org/licenses/BSD-3-Clause
|
* http://opensource.org/licenses/BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
define('gclitest/commands', ['require', 'exports', 'module' , 'gcli/canon', 'gcli/types/basic', 'gcli/types'], function(require, exports, module) {
|
define('gclitest/commands', ['require', 'exports', 'module' , 'gcli/canon', 'gcli/util', 'gcli/types/basic', 'gcli/types'], function(require, exports, module) {
|
||||||
var commands = exports;
|
var commands = exports;
|
||||||
|
|
||||||
|
|
||||||
var canon = require('gcli/canon');
|
var canon = require('gcli/canon');
|
||||||
|
var util = require('gcli/util');
|
||||||
|
|
||||||
var SelectionType = require('gcli/types/basic').SelectionType;
|
var SelectionType = require('gcli/types/basic').SelectionType;
|
||||||
var DeferredType = require('gcli/types/basic').DeferredType;
|
var DeferredType = require('gcli/types/basic').DeferredType;
|
||||||
|
@ -725,6 +743,10 @@ commands.setup = function() {
|
||||||
|
|
||||||
canon.addCommand(commands.tsv);
|
canon.addCommand(commands.tsv);
|
||||||
canon.addCommand(commands.tsr);
|
canon.addCommand(commands.tsr);
|
||||||
|
canon.addCommand(commands.tse);
|
||||||
|
canon.addCommand(commands.tsj);
|
||||||
|
canon.addCommand(commands.tsb);
|
||||||
|
canon.addCommand(commands.tss);
|
||||||
canon.addCommand(commands.tsu);
|
canon.addCommand(commands.tsu);
|
||||||
canon.addCommand(commands.tsn);
|
canon.addCommand(commands.tsn);
|
||||||
canon.addCommand(commands.tsnDif);
|
canon.addCommand(commands.tsnDif);
|
||||||
|
@ -734,11 +756,16 @@ commands.setup = function() {
|
||||||
canon.addCommand(commands.tsnExtend);
|
canon.addCommand(commands.tsnExtend);
|
||||||
canon.addCommand(commands.tselarr);
|
canon.addCommand(commands.tselarr);
|
||||||
canon.addCommand(commands.tsm);
|
canon.addCommand(commands.tsm);
|
||||||
|
canon.addCommand(commands.tsg);
|
||||||
};
|
};
|
||||||
|
|
||||||
commands.shutdown = function() {
|
commands.shutdown = function() {
|
||||||
canon.removeCommand(commands.tsv);
|
canon.removeCommand(commands.tsv);
|
||||||
canon.removeCommand(commands.tsr);
|
canon.removeCommand(commands.tsr);
|
||||||
|
canon.removeCommand(commands.tse);
|
||||||
|
canon.removeCommand(commands.tsj);
|
||||||
|
canon.removeCommand(commands.tsb);
|
||||||
|
canon.removeCommand(commands.tss);
|
||||||
canon.removeCommand(commands.tsu);
|
canon.removeCommand(commands.tsu);
|
||||||
canon.removeCommand(commands.tsn);
|
canon.removeCommand(commands.tsn);
|
||||||
canon.removeCommand(commands.tsnDif);
|
canon.removeCommand(commands.tsnDif);
|
||||||
|
@ -748,14 +775,15 @@ commands.shutdown = function() {
|
||||||
canon.removeCommand(commands.tsnExtend);
|
canon.removeCommand(commands.tsnExtend);
|
||||||
canon.removeCommand(commands.tselarr);
|
canon.removeCommand(commands.tselarr);
|
||||||
canon.removeCommand(commands.tsm);
|
canon.removeCommand(commands.tsm);
|
||||||
|
canon.removeCommand(commands.tsg);
|
||||||
|
|
||||||
types.deregisterType(commands.optionType);
|
types.deregisterType(commands.optionType);
|
||||||
types.deregisterType(commands.optionValue);
|
types.deregisterType(commands.optionValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
commands.option1 = { };
|
commands.option1 = { type: types.getType('string') };
|
||||||
commands.option2 = { };
|
commands.option2 = { type: types.getType('number') };
|
||||||
|
|
||||||
commands.optionType = new SelectionType({
|
commands.optionType = new SelectionType({
|
||||||
name: 'optionType',
|
name: 'optionType',
|
||||||
|
@ -789,25 +817,62 @@ commands.optionValue = new DeferredType({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
commands.commandExec = util.createEvent('commands.commandExec');
|
||||||
|
|
||||||
|
function createExec(name) {
|
||||||
|
return function(args, context) {
|
||||||
|
var data = {
|
||||||
|
command: commands[name],
|
||||||
|
args: args,
|
||||||
|
context: context
|
||||||
|
};
|
||||||
|
commands.commandExec(data);
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
commands.tsv = {
|
commands.tsv = {
|
||||||
name: 'tsv',
|
name: 'tsv',
|
||||||
params: [
|
params: [
|
||||||
{ name: 'optionType', type: 'optionType' },
|
{ name: 'optionType', type: 'optionType' },
|
||||||
{ name: 'optionValue', type: 'optionValue' }
|
{ name: 'optionValue', type: 'optionValue' }
|
||||||
],
|
],
|
||||||
exec: function(args, context) { }
|
exec: createExec('tsv')
|
||||||
};
|
};
|
||||||
|
|
||||||
commands.tsr = {
|
commands.tsr = {
|
||||||
name: 'tsr',
|
name: 'tsr',
|
||||||
params: [ { name: 'text', type: 'string' } ],
|
params: [ { name: 'text', type: 'string' } ],
|
||||||
exec: function(args, context) { }
|
exec: createExec('tsr')
|
||||||
|
};
|
||||||
|
|
||||||
|
commands.tse = {
|
||||||
|
name: 'tse',
|
||||||
|
params: [ { name: 'node', type: 'node' } ],
|
||||||
|
exec: createExec('tse')
|
||||||
|
};
|
||||||
|
|
||||||
|
commands.tsj = {
|
||||||
|
name: 'tsj',
|
||||||
|
params: [ { name: 'javascript', type: 'javascript' } ],
|
||||||
|
exec: createExec('tsj')
|
||||||
|
};
|
||||||
|
|
||||||
|
commands.tsb = {
|
||||||
|
name: 'tsb',
|
||||||
|
params: [ { name: 'toggle', type: 'boolean' } ],
|
||||||
|
exec: createExec('tsb')
|
||||||
|
};
|
||||||
|
|
||||||
|
commands.tss = {
|
||||||
|
name: 'tss',
|
||||||
|
exec: createExec('tss')
|
||||||
};
|
};
|
||||||
|
|
||||||
commands.tsu = {
|
commands.tsu = {
|
||||||
name: 'tsu',
|
name: 'tsu',
|
||||||
params: [ { name: 'num', type: 'number' } ],
|
params: [ { name: 'num', type: { name: 'number', max: 10, min: -5, step: 3 } } ],
|
||||||
exec: function(args, context) { }
|
exec: createExec('tsu')
|
||||||
};
|
};
|
||||||
|
|
||||||
commands.tsn = {
|
commands.tsn = {
|
||||||
|
@ -817,31 +882,31 @@ commands.tsn = {
|
||||||
commands.tsnDif = {
|
commands.tsnDif = {
|
||||||
name: 'tsn dif',
|
name: 'tsn dif',
|
||||||
params: [ { name: 'text', type: 'string' } ],
|
params: [ { name: 'text', type: 'string' } ],
|
||||||
exec: function(text) { }
|
exec: createExec('tsnDif')
|
||||||
};
|
};
|
||||||
|
|
||||||
commands.tsnExt = {
|
commands.tsnExt = {
|
||||||
name: 'tsn ext',
|
name: 'tsn ext',
|
||||||
params: [ { name: 'text', type: 'string' } ],
|
params: [ { name: 'text', type: 'string' } ],
|
||||||
exec: function(text) { }
|
exec: createExec('tsnExt')
|
||||||
};
|
};
|
||||||
|
|
||||||
commands.tsnExte = {
|
commands.tsnExte = {
|
||||||
name: 'tsn exte',
|
name: 'tsn exte',
|
||||||
params: [ { name: 'text', type: 'string' } ],
|
params: [ { name: 'text', type: 'string' } ],
|
||||||
exec: function(text) { }
|
exec: createExec('')
|
||||||
};
|
};
|
||||||
|
|
||||||
commands.tsnExten = {
|
commands.tsnExten = {
|
||||||
name: 'tsn exten',
|
name: 'tsn exten',
|
||||||
params: [ { name: 'text', type: 'string' } ],
|
params: [ { name: 'text', type: 'string' } ],
|
||||||
exec: function(text) { }
|
exec: createExec('tsnExte')
|
||||||
};
|
};
|
||||||
|
|
||||||
commands.tsnExtend = {
|
commands.tsnExtend = {
|
||||||
name: 'tsn extend',
|
name: 'tsn extend',
|
||||||
params: [ { name: 'text', type: 'string' } ],
|
params: [ { name: 'text', type: 'string' } ],
|
||||||
exec: function(text) { }
|
exec: createExec('tsnExtend')
|
||||||
};
|
};
|
||||||
|
|
||||||
commands.tselarr = {
|
commands.tselarr = {
|
||||||
|
@ -850,7 +915,7 @@ commands.tselarr = {
|
||||||
{ name: 'num', type: { name: 'selection', data: [ '1', '2', '3' ] } },
|
{ name: 'num', type: { name: 'selection', data: [ '1', '2', '3' ] } },
|
||||||
{ name: 'arr', type: { name: 'array', subtype: 'string' } },
|
{ name: 'arr', type: { name: 'array', subtype: 'string' } },
|
||||||
],
|
],
|
||||||
exec: function(args, context) {}
|
exec: createExec('tselarr')
|
||||||
};
|
};
|
||||||
|
|
||||||
commands.tsm = {
|
commands.tsm = {
|
||||||
|
@ -862,7 +927,31 @@ commands.tsm = {
|
||||||
{ name: 'txt', type: 'string' },
|
{ name: 'txt', type: 'string' },
|
||||||
{ name: 'num', type: { name: 'number', max: 42, min: 0 } },
|
{ name: 'num', type: { name: 'number', max: 42, min: 0 } },
|
||||||
],
|
],
|
||||||
exec: function(args, context) {}
|
exec: createExec('tsm')
|
||||||
|
};
|
||||||
|
|
||||||
|
commands.tsg = {
|
||||||
|
name: 'tsg',
|
||||||
|
hidden: true,
|
||||||
|
description: 'a param group test',
|
||||||
|
params: [
|
||||||
|
{ name: 'solo', type: { name: 'selection', data: [ 'aaa', 'bbb', 'ccc' ] } },
|
||||||
|
{
|
||||||
|
group: 'First',
|
||||||
|
params: [
|
||||||
|
{ name: 'txt1', type: 'string', defaultValue: null },
|
||||||
|
{ name: 'boolean1', type: 'boolean' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
group: 'Second',
|
||||||
|
params: [
|
||||||
|
{ name: 'txt2', type: 'string', defaultValue: 'd' },
|
||||||
|
{ name: 'num2', type: { name: 'number', defaultValue: 42 } }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
exec: createExec('tsg')
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1211,6 +1300,278 @@ exports.testNestedCommand = function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
/*
|
||||||
|
* Copyright 2009-2011 Mozilla Foundation and contributors
|
||||||
|
* Licensed under the New BSD license. See LICENSE.txt or:
|
||||||
|
* http://opensource.org/licenses/BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
define('gclitest/testExec', ['require', 'exports', 'module' , 'gcli/cli', 'gcli/types', 'gcli/canon', 'gclitest/commands', 'gcli/types/node', 'test/assert'], function(require, exports, module) {
|
||||||
|
|
||||||
|
|
||||||
|
var Requisition = require('gcli/cli').Requisition;
|
||||||
|
var Status = require('gcli/types').Status;
|
||||||
|
var canon = require('gcli/canon');
|
||||||
|
var commands = require('gclitest/commands');
|
||||||
|
var nodetype = require('gcli/types/node');
|
||||||
|
|
||||||
|
var test = require('test/assert');
|
||||||
|
|
||||||
|
var actualExec;
|
||||||
|
var actualOutput;
|
||||||
|
|
||||||
|
exports.setup = function() {
|
||||||
|
commands.setup();
|
||||||
|
commands.commandExec.add(onCommandExec);
|
||||||
|
canon.commandOutputManager.addListener(onCommandOutput);
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.shutdown = function() {
|
||||||
|
commands.shutdown();
|
||||||
|
commands.commandExec.remove(onCommandExec);
|
||||||
|
canon.commandOutputManager.removeListener(onCommandOutput);
|
||||||
|
};
|
||||||
|
|
||||||
|
function onCommandExec(ev) {
|
||||||
|
actualExec = ev;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onCommandOutput(ev) {
|
||||||
|
actualOutput = ev.output;
|
||||||
|
}
|
||||||
|
|
||||||
|
function exec(command, expectedArgs) {
|
||||||
|
var environment = {};
|
||||||
|
|
||||||
|
var requisition = new Requisition(environment);
|
||||||
|
var reply = requisition.exec({ typed: command });
|
||||||
|
|
||||||
|
test.is(command.indexOf(actualExec.command.name), 0, 'Command name: ' + command);
|
||||||
|
|
||||||
|
if (reply !== true) {
|
||||||
|
test.ok(false, 'reply = false for command: ' + command);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expectedArgs == null) {
|
||||||
|
test.ok(false, 'expectedArgs == null for ' + command);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (actualExec.args == null) {
|
||||||
|
test.ok(false, 'actualExec.args == null for ' + command);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
test.is(Object.keys(expectedArgs).length, Object.keys(actualExec.args).length,
|
||||||
|
'Arg count: ' + command);
|
||||||
|
Object.keys(expectedArgs).forEach(function(arg) {
|
||||||
|
var expectedArg = expectedArgs[arg];
|
||||||
|
var actualArg = actualExec.args[arg];
|
||||||
|
|
||||||
|
if (Array.isArray(expectedArg)) {
|
||||||
|
if (!Array.isArray(actualArg)) {
|
||||||
|
test.ok(false, 'actual is not an array. ' + command + '/' + arg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
test.is(expectedArg.length, actualArg.length,
|
||||||
|
'Array length: ' + command + '/' + arg);
|
||||||
|
for (var i = 0; i < expectedArg.length; i++) {
|
||||||
|
test.is(expectedArg[i], actualArg[i],
|
||||||
|
'Member: "' + command + '/' + arg + '/' + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
test.is(expectedArg, actualArg, 'Command: "' + command + '" arg: ' + arg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test.is(environment, actualExec.context.environment, 'Environment');
|
||||||
|
|
||||||
|
test.is(false, actualOutput.error, 'output error is false');
|
||||||
|
test.is(command, actualOutput.typed, 'command is typed');
|
||||||
|
test.ok(typeof actualOutput.canonical === 'string', 'canonical exists');
|
||||||
|
|
||||||
|
test.is(actualExec.args, actualOutput.args, 'actualExec.args is actualOutput.args');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
exports.testExec = function() {
|
||||||
|
exec('tss', {});
|
||||||
|
|
||||||
|
// Bug 707008 - GCLI defered types don't work properly
|
||||||
|
// exec('tsv option1 10', { optionType: commands.option1, optionValue: '10' });
|
||||||
|
// exec('tsv option2 10', { optionType: commands.option1, optionValue: 10 });
|
||||||
|
|
||||||
|
exec('tsr fred', { text: 'fred' });
|
||||||
|
exec('tsr fred bloggs', { text: 'fred bloggs' });
|
||||||
|
exec('tsr "fred bloggs"', { text: 'fred bloggs' });
|
||||||
|
|
||||||
|
exec('tsb', { toggle: false });
|
||||||
|
exec('tsb --toggle', { toggle: true });
|
||||||
|
|
||||||
|
exec('tsu 10', { num: 10 });
|
||||||
|
exec('tsu --num 10', { num: 10 });
|
||||||
|
|
||||||
|
// Bug 704829 - Enable GCLI Javascript parameters
|
||||||
|
// The answer to this should be 2
|
||||||
|
exec('tsj { 1 + 1 }', { javascript: '1 + 1' });
|
||||||
|
|
||||||
|
var origDoc = nodetype.getDocument();
|
||||||
|
nodetype.setDocument(mockDoc);
|
||||||
|
exec('tse :root', { node: mockBody });
|
||||||
|
nodetype.setDocument(origDoc);
|
||||||
|
|
||||||
|
exec('tsn dif fred', { text: 'fred' });
|
||||||
|
exec('tsn exten fred', { text: 'fred' });
|
||||||
|
exec('tsn extend fred', { text: 'fred' });
|
||||||
|
|
||||||
|
exec('tselarr 1', { num: '1', arr: [ ] });
|
||||||
|
exec('tselarr 1 a', { num: '1', arr: [ 'a' ] });
|
||||||
|
exec('tselarr 1 a b', { num: '1', arr: [ 'a', 'b' ] });
|
||||||
|
|
||||||
|
exec('tsm a 10 10', { abc: 'a', txt: '10', num: 10 });
|
||||||
|
|
||||||
|
// Bug 707009 - GCLI doesn't always fill in default parameters properly
|
||||||
|
// exec('tsg a', { solo: 'a', txt1: null, boolean1: false, txt2: 'd', num2: 42 });
|
||||||
|
};
|
||||||
|
|
||||||
|
var mockBody = {
|
||||||
|
style: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
var mockDoc = {
|
||||||
|
querySelectorAll: function(css) {
|
||||||
|
if (css === ':root') {
|
||||||
|
return {
|
||||||
|
length: 1,
|
||||||
|
item: function(i) {
|
||||||
|
return mockBody;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
throw new Error('mockDoc.querySelectorAll(\'' + css + '\') error');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
/*
|
||||||
|
* Copyright 2009-2011 Mozilla Foundation and contributors
|
||||||
|
* Licensed under the New BSD license. See LICENSE.txt or:
|
||||||
|
* http://opensource.org/licenses/BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
define('gclitest/testKeyboard', ['require', 'exports', 'module' , 'gcli/cli', 'gcli/types', 'gcli/canon', 'gclitest/commands', 'gcli/types/node', 'test/assert'], function(require, exports, module) {
|
||||||
|
|
||||||
|
|
||||||
|
var Requisition = require('gcli/cli').Requisition;
|
||||||
|
var Status = require('gcli/types').Status;
|
||||||
|
var canon = require('gcli/canon');
|
||||||
|
var commands = require('gclitest/commands');
|
||||||
|
var nodetype = require('gcli/types/node');
|
||||||
|
|
||||||
|
var test = require('test/assert');
|
||||||
|
|
||||||
|
|
||||||
|
exports.setup = function() {
|
||||||
|
commands.setup();
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.shutdown = function() {
|
||||||
|
commands.shutdown();
|
||||||
|
};
|
||||||
|
|
||||||
|
var COMPLETES_TO = 'complete';
|
||||||
|
var KEY_UPS_TO = 'keyup';
|
||||||
|
var KEY_DOWNS_TO = 'keydown';
|
||||||
|
|
||||||
|
function check(initial, action, after) {
|
||||||
|
var requisition = new Requisition();
|
||||||
|
requisition.update({
|
||||||
|
typed: initial,
|
||||||
|
cursor: { start: initial.length, end: initial.length }
|
||||||
|
});
|
||||||
|
var assignment = requisition.getAssignmentAt(initial.length);
|
||||||
|
switch (action) {
|
||||||
|
case COMPLETES_TO:
|
||||||
|
assignment.complete();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_UPS_TO:
|
||||||
|
assignment.increment();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_DOWNS_TO:
|
||||||
|
assignment.decrement();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
test.is(after, requisition.toString(), initial + ' + ' + action + ' -> ' + after);
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.testComplete = function() {
|
||||||
|
check('tsela', COMPLETES_TO, 'tselarr ');
|
||||||
|
check('tsn di', COMPLETES_TO, 'tsn dif ');
|
||||||
|
check('tsg a', COMPLETES_TO, 'tsg aaa ');
|
||||||
|
|
||||||
|
check('{ wind', COMPLETES_TO, '{ window');
|
||||||
|
check('{ window.docum', COMPLETES_TO, '{ window.document');
|
||||||
|
check('{ window.document.titl', COMPLETES_TO, '{ window.document.title ');
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.testIncrDecr = function() {
|
||||||
|
check('tsu -70', KEY_UPS_TO, 'tsu -5');
|
||||||
|
check('tsu -7', KEY_UPS_TO, 'tsu -5');
|
||||||
|
check('tsu -6', KEY_UPS_TO, 'tsu -5');
|
||||||
|
check('tsu -5', KEY_UPS_TO, 'tsu -3');
|
||||||
|
check('tsu -4', KEY_UPS_TO, 'tsu -3');
|
||||||
|
check('tsu -3', KEY_UPS_TO, 'tsu 0');
|
||||||
|
check('tsu -2', KEY_UPS_TO, 'tsu 0');
|
||||||
|
check('tsu -1', KEY_UPS_TO, 'tsu 0');
|
||||||
|
check('tsu 0', KEY_UPS_TO, 'tsu 3');
|
||||||
|
check('tsu 1', KEY_UPS_TO, 'tsu 3');
|
||||||
|
check('tsu 2', KEY_UPS_TO, 'tsu 3');
|
||||||
|
check('tsu 3', KEY_UPS_TO, 'tsu 6');
|
||||||
|
check('tsu 4', KEY_UPS_TO, 'tsu 6');
|
||||||
|
check('tsu 5', KEY_UPS_TO, 'tsu 6');
|
||||||
|
check('tsu 6', KEY_UPS_TO, 'tsu 9');
|
||||||
|
check('tsu 7', KEY_UPS_TO, 'tsu 9');
|
||||||
|
check('tsu 8', KEY_UPS_TO, 'tsu 9');
|
||||||
|
check('tsu 9', KEY_UPS_TO, 'tsu 10');
|
||||||
|
check('tsu 10', KEY_UPS_TO, 'tsu 10');
|
||||||
|
check('tsu 100', KEY_UPS_TO, 'tsu -5');
|
||||||
|
|
||||||
|
check('tsu -70', KEY_DOWNS_TO, 'tsu 10');
|
||||||
|
check('tsu -7', KEY_DOWNS_TO, 'tsu 10');
|
||||||
|
check('tsu -6', KEY_DOWNS_TO, 'tsu 10');
|
||||||
|
check('tsu -5', KEY_DOWNS_TO, 'tsu -5');
|
||||||
|
check('tsu -4', KEY_DOWNS_TO, 'tsu -5');
|
||||||
|
check('tsu -3', KEY_DOWNS_TO, 'tsu -5');
|
||||||
|
check('tsu -2', KEY_DOWNS_TO, 'tsu -3');
|
||||||
|
check('tsu -1', KEY_DOWNS_TO, 'tsu -3');
|
||||||
|
check('tsu 0', KEY_DOWNS_TO, 'tsu -3');
|
||||||
|
check('tsu 1', KEY_DOWNS_TO, 'tsu 0');
|
||||||
|
check('tsu 2', KEY_DOWNS_TO, 'tsu 0');
|
||||||
|
check('tsu 3', KEY_DOWNS_TO, 'tsu 0');
|
||||||
|
check('tsu 4', KEY_DOWNS_TO, 'tsu 3');
|
||||||
|
check('tsu 5', KEY_DOWNS_TO, 'tsu 3');
|
||||||
|
check('tsu 6', KEY_DOWNS_TO, 'tsu 3');
|
||||||
|
check('tsu 7', KEY_DOWNS_TO, 'tsu 6');
|
||||||
|
check('tsu 8', KEY_DOWNS_TO, 'tsu 6');
|
||||||
|
check('tsu 9', KEY_DOWNS_TO, 'tsu 6');
|
||||||
|
check('tsu 10', KEY_DOWNS_TO, 'tsu 9');
|
||||||
|
check('tsu 100', KEY_DOWNS_TO, 'tsu 10');
|
||||||
|
|
||||||
|
// Bug 707007 - GCLI increment and decrement operations cycle through
|
||||||
|
// selection options in the wrong order
|
||||||
|
check('tselarr 1', KEY_DOWNS_TO, 'tselarr 2');
|
||||||
|
check('tselarr 2', KEY_DOWNS_TO, 'tselarr 3');
|
||||||
|
check('tselarr 3', KEY_DOWNS_TO, 'tselarr 1');
|
||||||
|
|
||||||
|
check('tselarr 3', KEY_UPS_TO, 'tselarr 2');
|
||||||
|
};
|
||||||
|
|
||||||
});
|
});
|
||||||
/*
|
/*
|
||||||
* Copyright 2009-2011 Mozilla Foundation and contributors
|
* Copyright 2009-2011 Mozilla Foundation and contributors
|
||||||
|
@ -1544,6 +1905,8 @@ function undefine() {
|
||||||
delete define.modules['gclitest/testSplit'];
|
delete define.modules['gclitest/testSplit'];
|
||||||
delete define.modules['gclitest/commands'];
|
delete define.modules['gclitest/commands'];
|
||||||
delete define.modules['gclitest/testCli'];
|
delete define.modules['gclitest/testCli'];
|
||||||
|
delete define.modules['gclitest/testExec'];
|
||||||
|
delete define.modules['gclitest/testKeyboard'];
|
||||||
delete define.modules['gclitest/testHistory'];
|
delete define.modules['gclitest/testHistory'];
|
||||||
delete define.modules['gclitest/testRequire'];
|
delete define.modules['gclitest/testRequire'];
|
||||||
delete define.modules['gclitest/requirable'];
|
delete define.modules['gclitest/requirable'];
|
||||||
|
@ -1556,6 +1919,8 @@ function undefine() {
|
||||||
delete define.globalDomain.modules['gclitest/testSplit'];
|
delete define.globalDomain.modules['gclitest/testSplit'];
|
||||||
delete define.globalDomain.modules['gclitest/commands'];
|
delete define.globalDomain.modules['gclitest/commands'];
|
||||||
delete define.globalDomain.modules['gclitest/testCli'];
|
delete define.globalDomain.modules['gclitest/testCli'];
|
||||||
|
delete define.globalDomain.modules['gclitest/testExec'];
|
||||||
|
delete define.globalDomain.modules['gclitest/testKeyboard'];
|
||||||
delete define.globalDomain.modules['gclitest/testHistory'];
|
delete define.globalDomain.modules['gclitest/testHistory'];
|
||||||
delete define.globalDomain.modules['gclitest/testRequire'];
|
delete define.globalDomain.modules['gclitest/testRequire'];
|
||||||
delete define.globalDomain.modules['gclitest/requirable'];
|
delete define.globalDomain.modules['gclitest/requirable'];
|
||||||
|
|
|
@ -67,12 +67,12 @@ typesNumberNan=Can't convert "%S" to a number.
|
||||||
# LOCALIZATION NOTE (typesNumberMax): When the command line is passed a
|
# LOCALIZATION NOTE (typesNumberMax): When the command line is passed a
|
||||||
# number, but the number is bigger than the largest allowed number, this error
|
# number, but the number is bigger than the largest allowed number, this error
|
||||||
# message is displayed.
|
# message is displayed.
|
||||||
typesNumberMax=%1$S is greater that maximum allowed: %2$S.
|
typesNumberMax=%1$S is greater than maximum allowed: %2$S.
|
||||||
|
|
||||||
# LOCALIZATION NOTE (typesNumberMin): When the command line is passed a
|
# LOCALIZATION NOTE (typesNumberMin): When the command line is passed a
|
||||||
# number, but the number is lower than the smallest allowed number, this error
|
# number, but the number is lower than the smallest allowed number, this error
|
||||||
# message is displayed.
|
# message is displayed.
|
||||||
typesNumberMin=%1$S is smaller that minimum allowed: %2$S.
|
typesNumberMin=%1$S is smaller than minimum allowed: %2$S.
|
||||||
|
|
||||||
# LOCALIZATION NOTE (typesSelectionNomatch): When the command line is passed
|
# LOCALIZATION NOTE (typesSelectionNomatch): When the command line is passed
|
||||||
# an option with a limited number of correct values, but the passed value is
|
# an option with a limited number of correct values, but the passed value is
|
||||||
|
@ -94,3 +94,50 @@ nodeParseMultiple=Too many matches (%S)
|
||||||
# displayed.
|
# displayed.
|
||||||
nodeParseNone=No matches
|
nodeParseNone=No matches
|
||||||
|
|
||||||
|
# LOCALIZATION NOTE (helpDesc): A very short description of the 'help'
|
||||||
|
# command. This string is designed to be shown in a menu alongside the command
|
||||||
|
# name, which is why it should be as short as possible. See helpManual for a
|
||||||
|
# fuller description of what it does.
|
||||||
|
helpDesc=Get help on the available commands
|
||||||
|
|
||||||
|
# LOCALIZATION NOTE (helpManual): A fuller description of the 'help' command.
|
||||||
|
# Displayed when the user asks for help on what it does.
|
||||||
|
helpManual=Provide help either on a specific command (if a search string is provided and an exact match is found) or on the available commands (if a search string is not provided, or if no exact match is found).
|
||||||
|
|
||||||
|
# LOCALIZATION NOTE (helpSearchDesc): A very short description of the 'search'
|
||||||
|
# parameter to the 'help' command. See helpSearchManual for a fuller
|
||||||
|
# description of what it does. This string is designed to be shown in a dialog
|
||||||
|
# with restricted space, which is why it should be as short as possible.
|
||||||
|
helpSearchDesc=Search string
|
||||||
|
|
||||||
|
# LOCALIZATION NOTE (helpSearchManual): A fuller description of the 'search'
|
||||||
|
# parameter to the 'help' command. Displayed when the user asks for help on
|
||||||
|
# what it does.
|
||||||
|
helpSearchManual=A search string to use in narrowing down the list of commands that are displayed to the user. Any part of the string can match, regular expressions are not supported.
|
||||||
|
|
||||||
|
# LOCALIZATION NOTE (helpManSynopsis): A heading shown at the top of a help
|
||||||
|
# page for a command in the console It labels a summary of the parameters to
|
||||||
|
# the command
|
||||||
|
helpManSynopsis=Synopsis
|
||||||
|
|
||||||
|
# LOCALIZATION NOTE (helpManDescription): A heading shown in a help page for a
|
||||||
|
# command in the console. This heading precedes the top level description.
|
||||||
|
helpManDescription=Description
|
||||||
|
|
||||||
|
# LOCALIZATION NOTE (helpManParameters): A heading shown above the parameters
|
||||||
|
# in a help page for a command in the console.
|
||||||
|
helpManParameters=Parameters
|
||||||
|
|
||||||
|
# LOCALIZATION NOTE (helpManNone): Some text shown under the parameters
|
||||||
|
# heading in a help page for a command which has no parameters.
|
||||||
|
helpManNone=None
|
||||||
|
|
||||||
|
# LOCALIZATION NOTE (introHeader): The heading displayed at the top of the
|
||||||
|
# output for the help command
|
||||||
|
introHeader=Welcome to Firefox Developer Tools
|
||||||
|
|
||||||
|
# LOCALIZATION NOTE (introBody): The text displayed at the top of the output
|
||||||
|
# for the help command, just before the list of commands. This text is wrapped
|
||||||
|
# inside a link to a localized MDN article
|
||||||
|
introBody=For more information see MDN.
|
||||||
|
|
||||||
|
|
|
@ -44,8 +44,7 @@ inspectDesc=Inspect a node
|
||||||
|
|
||||||
# LOCALIZATION NOTE (inspectManual) A fuller description of the 'inspect'
|
# LOCALIZATION NOTE (inspectManual) A fuller description of the 'inspect'
|
||||||
# command, displayed when the user asks for help on what it does.
|
# command, displayed when the user asks for help on what it does.
|
||||||
inspectManual=Investigate the dimensions and properties of an element using \
|
inspectManual=Investigate the dimensions and properties of an element using a CSS selector to open the DOM highlighter
|
||||||
a CSS selector to open the DOM highlighter
|
|
||||||
|
|
||||||
# LOCALIZATION NOTE (inspectNodeDesc) A very short string to describe the
|
# LOCALIZATION NOTE (inspectNodeDesc) A very short string to describe the
|
||||||
# 'node' parameter to the 'inspect' command, which is displayed in a dialog
|
# 'node' parameter to the 'inspect' command, which is displayed in a dialog
|
||||||
|
@ -55,5 +54,4 @@ inspectNodeDesc=CSS selector
|
||||||
# LOCALIZATION NOTE (inspectNodeManual) A fuller description of the 'node'
|
# LOCALIZATION NOTE (inspectNodeManual) A fuller description of the 'node'
|
||||||
# parameter to the 'inspect' command, displayed when the user asks for help
|
# parameter to the 'inspect' command, displayed when the user asks for help
|
||||||
# on what it does.
|
# on what it does.
|
||||||
inspectNodeManual=A CSS selector for use with Document.querySelector which \
|
inspectNodeManual=A CSS selector for use with Document.querySelector which identifies a single element
|
||||||
identifies a single element
|
|
||||||
|
|
|
@ -46,7 +46,6 @@
|
||||||
height: 100%;
|
height: 100%;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
font: 12px Consolas, "Lucida Console", monospace;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.gcliterm-input-node {
|
.gcliterm-input-node {
|
||||||
|
@ -64,24 +63,6 @@
|
||||||
-moz-padding-end: 4px;
|
-moz-padding-end: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gcli-in-valid {
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gcli-in-incomplete {
|
|
||||||
color: #DDD;
|
|
||||||
border-bottom: 1px dotted #999;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gcli-in-error {
|
|
||||||
color: #DDD;
|
|
||||||
border-bottom: 1px dotted #F00;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gcli-in-ontab {
|
|
||||||
color: #999;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gcliterm-stack-node {
|
.gcliterm-stack-node {
|
||||||
background: url("chrome://global/skin/icons/commandline.png") 4px center no-repeat;
|
background: url("chrome://global/skin/icons/commandline.png") 4px center no-repeat;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -109,19 +90,47 @@
|
||||||
border-bottom: 1px solid threedshadow;
|
border-bottom: 1px solid threedshadow;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gcli-help-right {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gcliterm-menu {
|
.gcliterm-menu {
|
||||||
display: -moz-box;
|
display: -moz-box;
|
||||||
-moz-box-flex: 1;
|
-moz-box-flex: 1;
|
||||||
|
border-bottom-color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gcliterm-hint-scroll {
|
||||||
|
overflow-y: scroll;
|
||||||
|
border-bottom-color: threedshadow;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gcliterm-hint-nospace {
|
.gcliterm-hint-nospace {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.gcliterm-msg-body {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 3px;
|
||||||
|
-moz-margin-start: 3px;
|
||||||
|
-moz-margin-end: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Extract from display.css, we only want these 2 rules */
|
||||||
|
|
||||||
|
.gcli-out-shortcut {
|
||||||
|
border: 1px solid #999;
|
||||||
|
border-radius: 3px;
|
||||||
|
padding: 0 4px;
|
||||||
|
margin: 0 4px;
|
||||||
|
font-size: 70%;
|
||||||
|
color: #666;
|
||||||
|
cursor: pointer;
|
||||||
|
vertical-align: bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gcli-out-shortcut:before {
|
||||||
|
color: #66F;
|
||||||
|
content: '\bb';
|
||||||
|
padding: 0 2px;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The language of a console is not en_US or any other common language
|
* The language of a console is not en_US or any other common language
|
||||||
* (i.e we don't attempt to translate 'console.log(x)')
|
* (i.e we don't attempt to translate 'console.log(x)')
|
||||||
|
@ -151,6 +160,15 @@
|
||||||
|
|
||||||
/* From: $GCLI/mozilla/gcli/ui/gcliterm-gnomestripe.css */
|
/* From: $GCLI/mozilla/gcli/ui/gcliterm-gnomestripe.css */
|
||||||
|
|
||||||
|
.gcliterm-input-node,
|
||||||
|
.gcliterm-complete-node {
|
||||||
|
font: 12px "DejaVu Sans Mono", monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gcli-out-shortcut {
|
||||||
|
font-family: "DejaVu Sans Mono", monospace;
|
||||||
|
}
|
||||||
|
|
||||||
/* From: $GCLI/lib/gcli/ui/arg_fetch.css */
|
/* From: $GCLI/lib/gcli/ui/arg_fetch.css */
|
||||||
|
|
||||||
.gcli-argfetch {
|
.gcli-argfetch {
|
||||||
|
@ -181,7 +199,7 @@
|
||||||
.gcli-af-required {
|
.gcli-af-required {
|
||||||
font-size: 90%;
|
font-size: 90%;
|
||||||
color: #f66;
|
color: #f66;
|
||||||
padding-left: 5px;
|
-moz-padding-start: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gcli-af-error {
|
.gcli-af-error {
|
||||||
|
@ -197,6 +215,10 @@
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.gcli-field-javascript {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* From: $GCLI/lib/gcli/ui/menu.css */
|
/* From: $GCLI/lib/gcli/ui/menu.css */
|
||||||
|
|
||||||
.gcli-menu {
|
.gcli-menu {
|
||||||
|
@ -284,3 +306,45 @@
|
||||||
color: #66F;
|
color: #66F;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* From: $GCLI/lib/gcli/commands/help.css */
|
||||||
|
|
||||||
|
.gcli-help-name {
|
||||||
|
text-align: end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gcli-help-arrow {
|
||||||
|
font-size: 70%;
|
||||||
|
color: #AAA;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gcli-help-synopsis {
|
||||||
|
font-family: monospace;
|
||||||
|
font-weight: normal;
|
||||||
|
padding: 0 3px;
|
||||||
|
margin: 0 10px;
|
||||||
|
border: 1px solid #999;
|
||||||
|
border-radius: 3px;
|
||||||
|
color: #666;
|
||||||
|
cursor: pointer;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gcli-help-synopsis:before {
|
||||||
|
color: #66F;
|
||||||
|
content: '\bb';
|
||||||
|
}
|
||||||
|
|
||||||
|
.gcli-help-description {
|
||||||
|
margin: 0 20px;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gcli-help-parameter {
|
||||||
|
margin: 0 30px;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gcli-help-header {
|
||||||
|
margin: 10px 0 6px;
|
||||||
|
}
|
||||||
|
|
|
@ -46,7 +46,6 @@
|
||||||
height: 100%;
|
height: 100%;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
font: 12px Consolas, "Lucida Console", monospace;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.gcliterm-input-node {
|
.gcliterm-input-node {
|
||||||
|
@ -64,24 +63,6 @@
|
||||||
-moz-padding-end: 4px;
|
-moz-padding-end: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gcli-in-valid {
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gcli-in-incomplete {
|
|
||||||
color: #DDD;
|
|
||||||
border-bottom: 1px dotted #999;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gcli-in-error {
|
|
||||||
color: #DDD;
|
|
||||||
border-bottom: 1px dotted #F00;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gcli-in-ontab {
|
|
||||||
color: #999;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gcliterm-stack-node {
|
.gcliterm-stack-node {
|
||||||
background: url("chrome://global/skin/icons/commandline.png") 4px center no-repeat;
|
background: url("chrome://global/skin/icons/commandline.png") 4px center no-repeat;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -109,19 +90,47 @@
|
||||||
border-bottom: 1px solid threedshadow;
|
border-bottom: 1px solid threedshadow;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gcli-help-right {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gcliterm-menu {
|
.gcliterm-menu {
|
||||||
display: -moz-box;
|
display: -moz-box;
|
||||||
-moz-box-flex: 1;
|
-moz-box-flex: 1;
|
||||||
|
border-bottom-color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gcliterm-hint-scroll {
|
||||||
|
overflow-y: scroll;
|
||||||
|
border-bottom-color: threedshadow;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gcliterm-hint-nospace {
|
.gcliterm-hint-nospace {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.gcliterm-msg-body {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 3px;
|
||||||
|
-moz-margin-start: 3px;
|
||||||
|
-moz-margin-end: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Extract from display.css, we only want these 2 rules */
|
||||||
|
|
||||||
|
.gcli-out-shortcut {
|
||||||
|
border: 1px solid #999;
|
||||||
|
border-radius: 3px;
|
||||||
|
padding: 0 4px;
|
||||||
|
margin: 0 4px;
|
||||||
|
font-size: 70%;
|
||||||
|
color: #666;
|
||||||
|
cursor: pointer;
|
||||||
|
vertical-align: bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gcli-out-shortcut:before {
|
||||||
|
color: #66F;
|
||||||
|
content: '\bb';
|
||||||
|
padding: 0 2px;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The language of a console is not en_US or any other common language
|
* The language of a console is not en_US or any other common language
|
||||||
* (i.e we don't attempt to translate 'console.log(x)')
|
* (i.e we don't attempt to translate 'console.log(x)')
|
||||||
|
@ -151,10 +160,19 @@
|
||||||
|
|
||||||
/* From: $GCLI/mozilla/gcli/ui/gcliterm-pinstripe.css */
|
/* From: $GCLI/mozilla/gcli/ui/gcliterm-pinstripe.css */
|
||||||
|
|
||||||
|
.gcliterm-input-node,
|
||||||
|
.gcliterm-complete-node {
|
||||||
|
font: 11px Menlo, Monaco, monospace;
|
||||||
|
}
|
||||||
|
|
||||||
.gcliterm-complete-node {
|
.gcliterm-complete-node {
|
||||||
padding-top: 6px !important;
|
padding-top: 6px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.gcli-out-shortcut {
|
||||||
|
font-family: Menlo, Monaco, monospace;
|
||||||
|
}
|
||||||
|
|
||||||
/* From: $GCLI/lib/gcli/ui/arg_fetch.css */
|
/* From: $GCLI/lib/gcli/ui/arg_fetch.css */
|
||||||
|
|
||||||
.gcli-argfetch {
|
.gcli-argfetch {
|
||||||
|
@ -185,7 +203,7 @@
|
||||||
.gcli-af-required {
|
.gcli-af-required {
|
||||||
font-size: 90%;
|
font-size: 90%;
|
||||||
color: #f66;
|
color: #f66;
|
||||||
padding-left: 5px;
|
-moz-padding-start: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gcli-af-error {
|
.gcli-af-error {
|
||||||
|
@ -201,6 +219,10 @@
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.gcli-field-javascript {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* From: $GCLI/lib/gcli/ui/menu.css */
|
/* From: $GCLI/lib/gcli/ui/menu.css */
|
||||||
|
|
||||||
.gcli-menu {
|
.gcli-menu {
|
||||||
|
@ -288,3 +310,45 @@
|
||||||
color: #66F;
|
color: #66F;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* From: $GCLI/lib/gcli/commands/help.css */
|
||||||
|
|
||||||
|
.gcli-help-name {
|
||||||
|
text-align: end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gcli-help-arrow {
|
||||||
|
font-size: 70%;
|
||||||
|
color: #AAA;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gcli-help-synopsis {
|
||||||
|
font-family: monospace;
|
||||||
|
font-weight: normal;
|
||||||
|
padding: 0 3px;
|
||||||
|
margin: 0 10px;
|
||||||
|
border: 1px solid #999;
|
||||||
|
border-radius: 3px;
|
||||||
|
color: #666;
|
||||||
|
cursor: pointer;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gcli-help-synopsis:before {
|
||||||
|
color: #66F;
|
||||||
|
content: '\bb';
|
||||||
|
}
|
||||||
|
|
||||||
|
.gcli-help-description {
|
||||||
|
margin: 0 20px;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gcli-help-parameter {
|
||||||
|
margin: 0 30px;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gcli-help-header {
|
||||||
|
margin: 10px 0 6px;
|
||||||
|
}
|
||||||
|
|
|
@ -46,7 +46,6 @@
|
||||||
height: 100%;
|
height: 100%;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
font: 12px Consolas, "Lucida Console", monospace;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.gcliterm-input-node {
|
.gcliterm-input-node {
|
||||||
|
@ -64,24 +63,6 @@
|
||||||
-moz-padding-end: 4px;
|
-moz-padding-end: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gcli-in-valid {
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gcli-in-incomplete {
|
|
||||||
color: #DDD;
|
|
||||||
border-bottom: 1px dotted #999;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gcli-in-error {
|
|
||||||
color: #DDD;
|
|
||||||
border-bottom: 1px dotted #F00;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gcli-in-ontab {
|
|
||||||
color: #999;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gcliterm-stack-node {
|
.gcliterm-stack-node {
|
||||||
background: url("chrome://global/skin/icons/commandline.png") 4px center no-repeat;
|
background: url("chrome://global/skin/icons/commandline.png") 4px center no-repeat;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -109,19 +90,47 @@
|
||||||
border-bottom: 1px solid threedshadow;
|
border-bottom: 1px solid threedshadow;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gcli-help-right {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gcliterm-menu {
|
.gcliterm-menu {
|
||||||
display: -moz-box;
|
display: -moz-box;
|
||||||
-moz-box-flex: 1;
|
-moz-box-flex: 1;
|
||||||
|
border-bottom-color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gcliterm-hint-scroll {
|
||||||
|
overflow-y: scroll;
|
||||||
|
border-bottom-color: threedshadow;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gcliterm-hint-nospace {
|
.gcliterm-hint-nospace {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.gcliterm-msg-body {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 3px;
|
||||||
|
-moz-margin-start: 3px;
|
||||||
|
-moz-margin-end: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Extract from display.css, we only want these 2 rules */
|
||||||
|
|
||||||
|
.gcli-out-shortcut {
|
||||||
|
border: 1px solid #999;
|
||||||
|
border-radius: 3px;
|
||||||
|
padding: 0 4px;
|
||||||
|
margin: 0 4px;
|
||||||
|
font-size: 70%;
|
||||||
|
color: #666;
|
||||||
|
cursor: pointer;
|
||||||
|
vertical-align: bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gcli-out-shortcut:before {
|
||||||
|
color: #66F;
|
||||||
|
content: '\bb';
|
||||||
|
padding: 0 2px;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The language of a console is not en_US or any other common language
|
* The language of a console is not en_US or any other common language
|
||||||
* (i.e we don't attempt to translate 'console.log(x)')
|
* (i.e we don't attempt to translate 'console.log(x)')
|
||||||
|
@ -151,6 +160,15 @@
|
||||||
|
|
||||||
/* From: $GCLI/mozilla/gcli/ui/gcliterm-winstripe.css */
|
/* From: $GCLI/mozilla/gcli/ui/gcliterm-winstripe.css */
|
||||||
|
|
||||||
|
.gcliterm-input-node,
|
||||||
|
.gcliterm-complete-node {
|
||||||
|
font: 12px Consolas, "Lucida Console", monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gcli-out-shortcut {
|
||||||
|
font-family: Consolas, Inconsolata, "Courier New", monospace;
|
||||||
|
}
|
||||||
|
|
||||||
/* From: $GCLI/lib/gcli/ui/arg_fetch.css */
|
/* From: $GCLI/lib/gcli/ui/arg_fetch.css */
|
||||||
|
|
||||||
.gcli-argfetch {
|
.gcli-argfetch {
|
||||||
|
@ -181,7 +199,7 @@
|
||||||
.gcli-af-required {
|
.gcli-af-required {
|
||||||
font-size: 90%;
|
font-size: 90%;
|
||||||
color: #f66;
|
color: #f66;
|
||||||
padding-left: 5px;
|
-moz-padding-start: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gcli-af-error {
|
.gcli-af-error {
|
||||||
|
@ -197,6 +215,10 @@
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.gcli-field-javascript {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* From: $GCLI/lib/gcli/ui/menu.css */
|
/* From: $GCLI/lib/gcli/ui/menu.css */
|
||||||
|
|
||||||
.gcli-menu {
|
.gcli-menu {
|
||||||
|
@ -284,3 +306,45 @@
|
||||||
color: #66F;
|
color: #66F;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* From: $GCLI/lib/gcli/commands/help.css */
|
||||||
|
|
||||||
|
.gcli-help-name {
|
||||||
|
text-align: end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gcli-help-arrow {
|
||||||
|
font-size: 70%;
|
||||||
|
color: #AAA;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gcli-help-synopsis {
|
||||||
|
font-family: monospace;
|
||||||
|
font-weight: normal;
|
||||||
|
padding: 0 3px;
|
||||||
|
margin: 0 10px;
|
||||||
|
border: 1px solid #999;
|
||||||
|
border-radius: 3px;
|
||||||
|
color: #666;
|
||||||
|
cursor: pointer;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gcli-help-synopsis:before {
|
||||||
|
color: #66F;
|
||||||
|
content: '\bb';
|
||||||
|
}
|
||||||
|
|
||||||
|
.gcli-help-description {
|
||||||
|
margin: 0 20px;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gcli-help-parameter {
|
||||||
|
margin: 0 30px;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gcli-help-header {
|
||||||
|
margin: 10px 0 6px;
|
||||||
|
}
|
||||||
|
|
|
@ -355,22 +355,17 @@ let PromptUtils = {
|
||||||
getTabModalPrompt : function (domWin) {
|
getTabModalPrompt : function (domWin) {
|
||||||
var promptBox = null;
|
var promptBox = null;
|
||||||
|
|
||||||
// Given a content DOM window, returns the chrome window it's in.
|
|
||||||
function getChromeWindow(aWindow) {
|
|
||||||
var chromeWin = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
|
||||||
.getInterface(Ci.nsIWebNavigation)
|
|
||||||
.QueryInterface(Ci.nsIDocShell)
|
|
||||||
.chromeEventHandler.ownerDocument.defaultView;
|
|
||||||
return chromeWin;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Get the topmost window, in case we're in a frame.
|
// Get the topmost window, in case we're in a frame.
|
||||||
var promptWin = domWin.top;
|
var promptWin = domWin.top;
|
||||||
|
|
||||||
// Get the chrome window for the content window we're using.
|
// Get the chrome window for the content window we're using.
|
||||||
// (Unwrap because we need a non-IDL property below.)
|
// (Unwrap because we need a non-IDL property below.)
|
||||||
var chromeWin = getChromeWindow(promptWin).wrappedJSObject;
|
var chromeWin = promptWin.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||||
|
.getInterface(Ci.nsIWebNavigation)
|
||||||
|
.QueryInterface(Ci.nsIDocShell)
|
||||||
|
.chromeEventHandler.ownerDocument
|
||||||
|
.defaultView.wrappedJSObject;
|
||||||
|
|
||||||
if (chromeWin.getTabModalPromptBox)
|
if (chromeWin.getTabModalPromptBox)
|
||||||
promptBox = chromeWin.getTabModalPromptBox(promptWin);
|
promptBox = chromeWin.getTabModalPromptBox(promptWin);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче