mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-30 21:55:31 +00:00
Merge m-c to s-c.
This commit is contained in:
commit
4b3ecc07a6
@ -169,6 +169,7 @@ _BROWSER_FILES = \
|
||||
browser_tabview_bug705621.js \
|
||||
browser_tabview_bug706430.js \
|
||||
browser_tabview_bug706736.js \
|
||||
browser_tabview_bug707466.js \
|
||||
browser_tabview_click_group.js \
|
||||
browser_tabview_dragdrop.js \
|
||||
browser_tabview_exit_button.js \
|
||||
|
60
browser/components/tabview/test/browser_tabview_bug707466.js
Normal file
60
browser/components/tabview/test/browser_tabview_bug707466.js
Normal file
@ -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 {
|
||||
GroupItems.setActiveGroupItem(item);
|
||||
if (!options || !options.dontSetActiveTabInGroup) {
|
||||
let activeTab = item.getActiveTab()
|
||||
let activeTab = item.getActiveTab();
|
||||
if (activeTab)
|
||||
this._setActiveTab(activeTab);
|
||||
}
|
||||
@ -574,7 +574,8 @@ let UI = {
|
||||
TabItems.resumePainting();
|
||||
});
|
||||
} else {
|
||||
self.clearActiveTab();
|
||||
if (!currentTab || !currentTab._tabViewTabItem)
|
||||
self.clearActiveTab();
|
||||
self._isChangingVisibility = false;
|
||||
dispatchEvent(event);
|
||||
|
||||
|
@ -37,7 +37,7 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
|
||||
var EXPORTED_SYMBOLS = [ "Templater" ];
|
||||
var EXPORTED_SYMBOLS = [ "Templater", "template" ];
|
||||
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
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();
|
||||
|
||||
/**
|
||||
* 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 = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @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 {
|
||||
// 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);
|
||||
}.bind(this));
|
||||
// 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
|
||||
// where scripts are prefixed with $.
|
||||
// \uF001 and \uF002 are just unicode chars reserved for private use.
|
||||
value = value.replace(/\$\{([^}]*)\}/g, '\uF001$$$1\uF002');
|
||||
var parts = value.split(/\uF001|\uF002/);
|
||||
value = value.replace(this._templateRegion, '\uF001$$$1\uF002');
|
||||
var parts = value.split(this._splitSpecial);
|
||||
if (parts.length > 1) {
|
||||
parts.forEach(function(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
|
||||
*/
|
||||
Templater.prototype._stripBraces = function(str) {
|
||||
if (!str.match(/\$\{.*\}/g)) {
|
||||
if (!str.match(this._templateRegion)) {
|
||||
this._handleError('Expected ' + str + ' to match ${...}');
|
||||
return str;
|
||||
}
|
||||
@ -427,17 +468,26 @@ Templater.prototype._property = function(path, data, newValue) {
|
||||
* execution failed.
|
||||
*/
|
||||
Templater.prototype._envEval = function(script, data, frame) {
|
||||
with (data) {
|
||||
try {
|
||||
this.stack.push(frame);
|
||||
return eval(script);
|
||||
} catch (ex) {
|
||||
this._handleError('Template error evaluating \'' + script + '\'' +
|
||||
' environment=' + Object.keys(data).join(', '), ex);
|
||||
return script;
|
||||
} finally {
|
||||
this.stack.pop();
|
||||
try {
|
||||
this.stack.push(frame);
|
||||
if (this._isPropertyScript.test(script)) {
|
||||
return this._property(script, data);
|
||||
} else {
|
||||
if (!this.options.allowEval) {
|
||||
this._handleError('allowEval is not set, however \'' + script + '\'' +
|
||||
' can not be resolved using a simple property path.');
|
||||
return '${' + script + '}';
|
||||
}
|
||||
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;
|
||||
|
||||
info('Running ' + options.name);
|
||||
new Templater().processNode(holder, options.data);
|
||||
template(holder, options.data, options.options);
|
||||
|
||||
if (typeof options.result == 'string') {
|
||||
is(holder.innerHTML, options.result, options.name);
|
||||
@ -88,6 +88,7 @@ var tests = [
|
||||
function() { return {
|
||||
name: 'returnDom',
|
||||
template: '<div id="ex2">${__element.ownerDocument.createTextNode(\'pass 2\')}</div>',
|
||||
options: { allowEval: true },
|
||||
data: {},
|
||||
result: '<div id="ex2">pass 2</div>'
|
||||
};},
|
||||
@ -102,6 +103,7 @@ var tests = [
|
||||
function() { return {
|
||||
name: 'ifTrue',
|
||||
template: '<p if="${name !== \'jim\'}">hello ${name}</p>',
|
||||
options: { allowEval: true },
|
||||
data: { name: 'fred' },
|
||||
result: '<p>hello fred</p>'
|
||||
};},
|
||||
@ -109,6 +111,7 @@ var tests = [
|
||||
function() { return {
|
||||
name: 'ifFalse',
|
||||
template: '<p if="${name !== \'jim\'}">hello ${name}</p>',
|
||||
options: { allowEval: true },
|
||||
data: { name: 'jim' },
|
||||
result: ''
|
||||
};},
|
||||
@ -116,6 +119,7 @@ var tests = [
|
||||
function() { return {
|
||||
name: 'simpleLoop',
|
||||
template: '<p foreach="index in ${[ 1, 2, 3 ]}">${index}</p>',
|
||||
options: { allowEval: true },
|
||||
data: {},
|
||||
result: '<p>1</p><p>2</p><p>3</p>'
|
||||
};},
|
||||
@ -127,6 +131,7 @@ var tests = [
|
||||
result: '123'
|
||||
};},
|
||||
|
||||
// Bug 692028: DOMTemplate memory leak with asynchronous arrays
|
||||
// Bug 692031: DOMTemplate async loops do not drop the loop element
|
||||
function() { return {
|
||||
name: 'asyncLoopElement',
|
||||
@ -150,6 +155,7 @@ var tests = [
|
||||
function() { return {
|
||||
name: 'useElement',
|
||||
template: '<p id="pass9">${adjust(__element)}</p>',
|
||||
options: { allowEval: true },
|
||||
data: {
|
||||
adjust: function(element) {
|
||||
is('pass9', element.id, 'useElement adjust');
|
||||
@ -167,6 +173,7 @@ var tests = [
|
||||
later: 'inline'
|
||||
};},
|
||||
|
||||
// Bug 692028: DOMTemplate memory leak with asynchronous arrays
|
||||
function() { return {
|
||||
name: 'asyncArray',
|
||||
template: '<p foreach="i in ${delayed}">${i}</p>',
|
||||
@ -183,6 +190,7 @@ var tests = [
|
||||
later: '<p>4</p><p>5</p><p>6</p>'
|
||||
};},
|
||||
|
||||
// Bug 692028: DOMTemplate memory leak with asynchronous arrays
|
||||
function() { return {
|
||||
name: 'asyncBoth',
|
||||
template: '<p foreach="i in ${delayed}">${i}</p>',
|
||||
@ -195,6 +203,38 @@ var tests = [
|
||||
},
|
||||
result: '<span></span>',
|
||||
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
|
||||
// values, so we need to clone the template first.
|
||||
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) {
|
||||
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
|
||||
*/
|
||||
|
@ -92,6 +92,12 @@ XPCOMUtils.defineLazyGetter(this, "NetUtil", function () {
|
||||
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 () {
|
||||
var obj = {};
|
||||
try {
|
||||
@ -6854,14 +6860,38 @@ GcliTerm.prototype = {
|
||||
|
||||
let output = aEvent.output.output;
|
||||
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 + '">' +
|
||||
output + '</div>');
|
||||
|
||||
output = this.document.createElementNS(HTML_NS, "div");
|
||||
output.appendChild(frag);
|
||||
output + '</div>').firstChild;
|
||||
}
|
||||
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);
|
||||
|
||||
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
|
||||
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/node').startup();
|
||||
require('gcli/cli').startup();
|
||||
require('gcli/commands/help').startup();
|
||||
|
||||
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 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.display = new Display(opts);
|
||||
opts.console = new Console(opts);
|
||||
},
|
||||
|
||||
/**
|
||||
* Undo the effects of createView() to prevent memory leaks
|
||||
*/
|
||||
removeView: function(opts) {
|
||||
opts.display.destroy();
|
||||
delete opts.display;
|
||||
opts.console.destroy();
|
||||
delete opts.console;
|
||||
|
||||
opts.requisition.destroy();
|
||||
delete opts.requisition;
|
||||
@ -1029,7 +1030,8 @@ canon.removeCommand = function removeCommand(commandOrName) {
|
||||
* @param name The name of the command to retrieve
|
||||
*/
|
||||
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 = {};
|
||||
|
||||
/**
|
||||
* XHTML namespace
|
||||
*/
|
||||
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
|
||||
* 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) {
|
||||
if (dom.isXmlDocument(elem.ownerDocument)) {
|
||||
dom.clearElement(elem);
|
||||
html = '<div xmlns="' + dom.NS_XHTML + '">' + html + '</div>';
|
||||
var range = elem.ownerDocument.createRange();
|
||||
var child = range.createContextualFragment(html).childNodes[0];
|
||||
while (child.hasChildNodes()) {
|
||||
elem.appendChild(child.firstChild);
|
||||
try {
|
||||
dom.clearElement(elem);
|
||||
html = '<div xmlns="' + dom.NS_XHTML + '">' + html + '</div>';
|
||||
var range = elem.ownerDocument.createRange();
|
||||
var child = range.createContextualFragment(html).firstChild;
|
||||
while (child.hasChildNodes()) {
|
||||
elem.appendChild(child.firstChild);
|
||||
}
|
||||
}
|
||||
catch (ex) {
|
||||
console.error('Bad XHTML', ex);
|
||||
console.trace();
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -1260,10 +1277,9 @@ dom.setInnerHtml = function(elem, html) {
|
||||
};
|
||||
|
||||
/**
|
||||
* How to detect if we're in an XUL document (and therefore should create
|
||||
* elements in an XHTML namespace)
|
||||
* In a Mozilla XUL document, document.xmlVersion = null, however in Chrome
|
||||
* document.contentType = undefined.
|
||||
* How to detect if we're in an XML document.
|
||||
* In a Mozilla we check that document.xmlVersion = null, however in Chrome
|
||||
* we use document.contentType = undefined.
|
||||
* @param doc The document element to work from (defaulted to the global
|
||||
* '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 */
|
||||
exports.lookupFormat = function(key, swaps) {
|
||||
try {
|
||||
@ -3462,6 +3485,14 @@ exports.unsetDocument = function() {
|
||||
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
|
||||
@ -4042,7 +4073,15 @@ UnassignedAssignment.prototype.setUnassigned = function(args) {
|
||||
*/
|
||||
function Requisition(environment, doc) {
|
||||
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.
|
||||
// @see setCommandConversion()
|
||||
@ -4508,7 +4547,8 @@ Requisition.prototype.exec = function(input) {
|
||||
var outputObject = {
|
||||
command: command,
|
||||
args: args,
|
||||
typed: this.toCanonicalString(),
|
||||
typed: this.toString(),
|
||||
canonical: this.toCanonicalString(),
|
||||
completed: false,
|
||||
start: new Date()
|
||||
};
|
||||
@ -4527,7 +4567,7 @@ Requisition.prototype.exec = function(input) {
|
||||
}).bind(this);
|
||||
|
||||
try {
|
||||
var context = new ExecutionContext(this.environment, this.document);
|
||||
var context = new ExecutionContext(this);
|
||||
var reply = command.exec(args, context);
|
||||
|
||||
if (reply != null && reply.isPromise) {
|
||||
@ -5012,9 +5052,10 @@ exports.Requisition = Requisition;
|
||||
/**
|
||||
* Functions and data related to the execution of a command
|
||||
*/
|
||||
function ExecutionContext(environment, document) {
|
||||
this.environment = environment;
|
||||
this.document = document;
|
||||
function ExecutionContext(requisition) {
|
||||
this.requisition = requisition;
|
||||
this.environment = requisition.environment;
|
||||
this.document = requisition.document;
|
||||
}
|
||||
|
||||
ExecutionContext.prototype.createPromise = function() {
|
||||
@ -5041,7 +5082,275 @@ define('gcli/promise', ['require', 'exports', 'module' ], function(require, expo
|
||||
* 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 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;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function Display(options) {
|
||||
function Console(options) {
|
||||
this.hintElement = options.hintElement;
|
||||
this.gcliTerm = options.gcliTerm;
|
||||
this.consoleWrap = options.consoleWrap;
|
||||
@ -5097,7 +5406,7 @@ function Display(options) {
|
||||
/**
|
||||
* Avoid memory leaks
|
||||
*/
|
||||
Display.prototype.destroy = function() {
|
||||
Console.prototype.destroy = function() {
|
||||
this.chromeWindow.removeEventListener('resize', this.resizer, false);
|
||||
delete this.resizer;
|
||||
delete this.chromeWindow;
|
||||
@ -5122,10 +5431,17 @@ Display.prototype.destroy = function() {
|
||||
/**
|
||||
* 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();
|
||||
// Magic number: 64 is the size of the toolbar above the output area
|
||||
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) {
|
||||
this.hintElement.classList.add('gcliterm-hint-nospace');
|
||||
}
|
||||
@ -5136,20 +5452,14 @@ Display.prototype.resizer = function() {
|
||||
if (isMenuVisible) {
|
||||
this.menu.setMaxHeight(parentHeight);
|
||||
|
||||
// Magic numbers. We have 2 options - lots of complex dom math to derive
|
||||
// the height of a menu item (19 pixels) and the vertical padding
|
||||
// (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.
|
||||
// Magic numbers: 19 = height of a menu item, 22 = total vertical padding
|
||||
// of container
|
||||
var idealMenuHeight = (19 * this.menu.items.length) + 22;
|
||||
|
||||
if (idealMenuHeight > parentHeight) {
|
||||
this.hintElement.style.overflowY = 'scroll';
|
||||
this.hintElement.style.borderBottomColor = 'threedshadow';
|
||||
this.hintElement.classList.add('gcliterm-hint-scroll');
|
||||
}
|
||||
else {
|
||||
this.hintElement.style.overflowY = null;
|
||||
this.hintElement.style.borderBottomColor = 'white';
|
||||
this.hintElement.classList.remove('gcliterm-hint-scroll');
|
||||
}
|
||||
}
|
||||
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
|
||||
* - requisition (required) A GCLI Requisition object whose state is monitored
|
||||
* - completeElement (optional) An element to use
|
||||
* - completionPrompt (optional) The prompt to show before a completion.
|
||||
* Defaults to '»' (double greater-than, a.k.a right guillemet).
|
||||
* - completionPrompt (optional) The prompt - defaults to '\u00bb'
|
||||
* (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) {
|
||||
this.document = options.document || document;
|
||||
@ -5606,7 +5917,7 @@ function Completer(options) {
|
||||
|
||||
this.completionPrompt = typeof options.completionPrompt === 'string'
|
||||
? options.completionPrompt
|
||||
: '»';
|
||||
: '\u00bb';
|
||||
|
||||
if (options.inputBackgroundElement) {
|
||||
this.backgroundElement = options.inputBackgroundElement;
|
||||
@ -5714,50 +6025,85 @@ Completer.prototype.update = function(input) {
|
||||
var current = this.requisition.getAssignmentAt(input.cursor.start);
|
||||
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) {
|
||||
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) {
|
||||
var tab = predictions[0].name;
|
||||
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 suffix = tab.slice(existing.length - numLeadingSpaces);
|
||||
completion += '<span class="gcli-in-ontab">' + suffix + '</span>';
|
||||
contents = tab.slice(existing.length - numLeadingSpaces);
|
||||
} else {
|
||||
// Display the '-> prediction' at the end of the completer element
|
||||
completion += '  <span class="gcli-in-ontab">⇥ ' +
|
||||
tab + '</span>';
|
||||
prefix = ' \u00a0'; // aka
|
||||
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
|
||||
var command = this.requisition.commandAssignment.getValue();
|
||||
if (command && command.name === '{') {
|
||||
if (this.requisition.getAssignment(0).getArg().suffix.indexOf('}') === -1) {
|
||||
completion += '<span class="gcli-in-closebrace">}</span>';
|
||||
}
|
||||
var unclosedJs = command && command.name === '{' &&
|
||||
this.requisition.getAssignment(0).getArg().suffix.indexOf('}') === -1;
|
||||
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
|
||||
*/
|
||||
Completer.prototype.markupStatusScore = function(scores, input) {
|
||||
var completion = '';
|
||||
Completer.prototype.appendMarkupStatus = function(element, scores, input) {
|
||||
if (scores.length === 0) {
|
||||
return completion;
|
||||
return;
|
||||
}
|
||||
|
||||
var document = element.ownerDocument;
|
||||
var i = 0;
|
||||
var lastStatus = -1;
|
||||
var span;
|
||||
var contents = '';
|
||||
|
||||
while (true) {
|
||||
if (lastStatus !== 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);
|
||||
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];
|
||||
}
|
||||
var char = input.typed[i];
|
||||
if (char === ' ') {
|
||||
char = ' ';
|
||||
char = '\u00a0';
|
||||
}
|
||||
completion += char;
|
||||
contents += char;
|
||||
i++;
|
||||
if (i === input.typed.length) {
|
||||
completion += '</span>';
|
||||
span.appendChild(document.createTextNode(contents));
|
||||
this.element.appendChild(span);
|
||||
break;
|
||||
}
|
||||
if (lastStatus !== scores[i]) {
|
||||
completion += '</span>';
|
||||
span.appendChild(document.createTextNode(contents));
|
||||
this.element.appendChild(span);
|
||||
contents = '';
|
||||
}
|
||||
}
|
||||
|
||||
return completion;
|
||||
};
|
||||
|
||||
cliView.Completer = Completer;
|
||||
@ -5867,7 +6215,7 @@ var dom = require('gcli/util').dom;
|
||||
var Status = require('gcli/types').Status;
|
||||
|
||||
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 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
|
||||
this.fields = [];
|
||||
|
||||
this.tmpl = new Templater();
|
||||
// Populated by template
|
||||
this.okElement = null;
|
||||
|
||||
@ -5953,7 +6300,8 @@ ArgFetcher.prototype.onCommandChange = function(ev) {
|
||||
this.fields = [];
|
||||
|
||||
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);
|
||||
this.element.appendChild(reqEle);
|
||||
|
||||
@ -6008,7 +6356,7 @@ ArgFetcher.prototype.getInputFor = function(assignment) {
|
||||
return newField.element;
|
||||
}
|
||||
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
|
||||
console.error(ex);
|
||||
return '';
|
||||
@ -6252,7 +6600,7 @@ function StringField(type, options) {
|
||||
|
||||
this.element = dom.createElement(this.document, 'input');
|
||||
this.element.type = 'text';
|
||||
this.element.className = 'gcli-field';
|
||||
this.element.classList.add('gcli-field');
|
||||
|
||||
this.onInputChange = this.onInputChange.bind(this);
|
||||
this.element.addEventListener('keyup', this.onInputChange, false);
|
||||
@ -6412,7 +6760,7 @@ function SelectionField(type, options) {
|
||||
this.items = [];
|
||||
|
||||
this.element = dom.createElement(this.document, 'select');
|
||||
this.element.className = 'gcli-field';
|
||||
this.element.classList.add('gcli-field');
|
||||
this._addOption({
|
||||
name: l10n.lookupFormat('fieldSelectionSelect', [ options.name ])
|
||||
});
|
||||
@ -6487,8 +6835,8 @@ function JavascriptField(type, options) {
|
||||
this.input = dom.createElement(this.document, 'input');
|
||||
this.input.type = 'text';
|
||||
this.input.addEventListener('keyup', this.onInputChange, false);
|
||||
this.input.style.marginBottom = '0';
|
||||
this.input.className = 'gcli-field';
|
||||
this.input.classList.add('gcli-field');
|
||||
this.input.classList.add('gcli-field-javascript');
|
||||
this.element.appendChild(this.input);
|
||||
|
||||
this.menu = new Menu({ document: this.document, field: true });
|
||||
@ -6680,18 +7028,18 @@ function ArrayField(type, options) {
|
||||
|
||||
// <div class=gcliArrayParent save="${element}">
|
||||
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
|
||||
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.innerHTML = l10n.lookup('fieldArrayAdd');
|
||||
this.element.appendChild(this.addButton);
|
||||
|
||||
// <div class=gcliArrayMbrs save="${mbrElement}">
|
||||
this.container = dom.createElement(this.document, 'div');
|
||||
this.container.className = 'gcliArrayMbrs';
|
||||
this.container.classList.add('gcli-array-members');
|
||||
this.element.appendChild(this.container);
|
||||
|
||||
this.onInputChange = this.onInputChange.bind(this);
|
||||
@ -6734,7 +7082,7 @@ ArrayField.prototype.getConversion = function() {
|
||||
ArrayField.prototype._onAdd = function(ev, subConversion) {
|
||||
// <div class=gcliArrayMbr save="${element}">
|
||||
var element = dom.createElement(this.document, 'div');
|
||||
element.className = 'gcliArrayMbr';
|
||||
element.classList.add('gcli-array-member');
|
||||
this.container.appendChild(element);
|
||||
|
||||
// ${field.element}
|
||||
@ -6752,7 +7100,7 @@ ArrayField.prototype._onAdd = function(ev, subConversion) {
|
||||
|
||||
// <div class=gcliArrayMbrDel onclick="${_onDel}">
|
||||
var delButton = dom.createElement(this.document, 'button');
|
||||
delButton.className = 'gcliArrayMbrDel';
|
||||
delButton.classList.add('gcli-array-member-del');
|
||||
delButton.addEventListener('click', this._onDel, false);
|
||||
delButton.innerHTML = l10n.lookup('fieldArrayDel');
|
||||
element.appendChild(delButton);
|
||||
@ -6794,7 +7142,7 @@ var Conversion = require('gcli/types').Conversion;
|
||||
var Argument = require('gcli/argument').Argument;
|
||||
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 menuHtml = require('text!gcli/ui/menu.html');
|
||||
@ -6877,7 +7225,7 @@ Menu.prototype.show = function(items, error) {
|
||||
}
|
||||
|
||||
var options = this.optTempl.cloneNode(true);
|
||||
new Templater().processNode(options, this);
|
||||
domtemplate.template(options, this, { allowEval: true, stack: 'menu.html' });
|
||||
|
||||
dom.clearElement(this.element);
|
||||
this.element.appendChild(options);
|
||||
@ -6984,18 +7332,6 @@ CommandMenu.prototype.onCommandChange = function(ev) {
|
||||
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.html", [], "\n" +
|
||||
|
@ -83,12 +83,12 @@ function testCallCommands() {
|
||||
is(gcliterm.completeNode.textContent, " ecd", "Completion for \"ecd\"");
|
||||
|
||||
// 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();
|
||||
|
||||
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.");
|
||||
|
||||
gcliterm.clearOutput();
|
||||
|
@ -54,7 +54,7 @@ var Node = Components.interfaces.nsIDOMNode;
|
||||
* 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
|
||||
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/testSplit', require('gclitest/testSplit'));
|
||||
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/testRequire', require('gclitest/testRequire'));
|
||||
examiner.addSuite('gclitest/testJs', require('gclitest/testJs'));
|
||||
|
||||
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
|
||||
*/
|
||||
@ -299,8 +316,8 @@ Test.prototype.run = function() {
|
||||
this.status = stati.fail;
|
||||
this.messages.push('' + ex);
|
||||
console.error(ex);
|
||||
if (console.trace) {
|
||||
console.trace();
|
||||
if (ex.stack) {
|
||||
console.error(ex.stack);
|
||||
}
|
||||
}
|
||||
|
||||
@ -703,11 +720,12 @@ exports.testJavascript = function() {
|
||||
* 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 canon = require('gcli/canon');
|
||||
var util = require('gcli/util');
|
||||
|
||||
var SelectionType = require('gcli/types/basic').SelectionType;
|
||||
var DeferredType = require('gcli/types/basic').DeferredType;
|
||||
@ -725,6 +743,10 @@ commands.setup = function() {
|
||||
|
||||
canon.addCommand(commands.tsv);
|
||||
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.tsn);
|
||||
canon.addCommand(commands.tsnDif);
|
||||
@ -734,11 +756,16 @@ commands.setup = function() {
|
||||
canon.addCommand(commands.tsnExtend);
|
||||
canon.addCommand(commands.tselarr);
|
||||
canon.addCommand(commands.tsm);
|
||||
canon.addCommand(commands.tsg);
|
||||
};
|
||||
|
||||
commands.shutdown = function() {
|
||||
canon.removeCommand(commands.tsv);
|
||||
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.tsn);
|
||||
canon.removeCommand(commands.tsnDif);
|
||||
@ -748,14 +775,15 @@ commands.shutdown = function() {
|
||||
canon.removeCommand(commands.tsnExtend);
|
||||
canon.removeCommand(commands.tselarr);
|
||||
canon.removeCommand(commands.tsm);
|
||||
canon.removeCommand(commands.tsg);
|
||||
|
||||
types.deregisterType(commands.optionType);
|
||||
types.deregisterType(commands.optionValue);
|
||||
};
|
||||
|
||||
|
||||
commands.option1 = { };
|
||||
commands.option2 = { };
|
||||
commands.option1 = { type: types.getType('string') };
|
||||
commands.option2 = { type: types.getType('number') };
|
||||
|
||||
commands.optionType = new SelectionType({
|
||||
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 = {
|
||||
name: 'tsv',
|
||||
params: [
|
||||
{ name: 'optionType', type: 'optionType' },
|
||||
{ name: 'optionValue', type: 'optionValue' }
|
||||
],
|
||||
exec: function(args, context) { }
|
||||
exec: createExec('tsv')
|
||||
};
|
||||
|
||||
commands.tsr = {
|
||||
name: 'tsr',
|
||||
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 = {
|
||||
name: 'tsu',
|
||||
params: [ { name: 'num', type: 'number' } ],
|
||||
exec: function(args, context) { }
|
||||
params: [ { name: 'num', type: { name: 'number', max: 10, min: -5, step: 3 } } ],
|
||||
exec: createExec('tsu')
|
||||
};
|
||||
|
||||
commands.tsn = {
|
||||
@ -817,31 +882,31 @@ commands.tsn = {
|
||||
commands.tsnDif = {
|
||||
name: 'tsn dif',
|
||||
params: [ { name: 'text', type: 'string' } ],
|
||||
exec: function(text) { }
|
||||
exec: createExec('tsnDif')
|
||||
};
|
||||
|
||||
commands.tsnExt = {
|
||||
name: 'tsn ext',
|
||||
params: [ { name: 'text', type: 'string' } ],
|
||||
exec: function(text) { }
|
||||
exec: createExec('tsnExt')
|
||||
};
|
||||
|
||||
commands.tsnExte = {
|
||||
name: 'tsn exte',
|
||||
params: [ { name: 'text', type: 'string' } ],
|
||||
exec: function(text) { }
|
||||
exec: createExec('')
|
||||
};
|
||||
|
||||
commands.tsnExten = {
|
||||
name: 'tsn exten',
|
||||
params: [ { name: 'text', type: 'string' } ],
|
||||
exec: function(text) { }
|
||||
exec: createExec('tsnExte')
|
||||
};
|
||||
|
||||
commands.tsnExtend = {
|
||||
name: 'tsn extend',
|
||||
params: [ { name: 'text', type: 'string' } ],
|
||||
exec: function(text) { }
|
||||
exec: createExec('tsnExtend')
|
||||
};
|
||||
|
||||
commands.tselarr = {
|
||||
@ -850,7 +915,7 @@ commands.tselarr = {
|
||||
{ name: 'num', type: { name: 'selection', data: [ '1', '2', '3' ] } },
|
||||
{ name: 'arr', type: { name: 'array', subtype: 'string' } },
|
||||
],
|
||||
exec: function(args, context) {}
|
||||
exec: createExec('tselarr')
|
||||
};
|
||||
|
||||
commands.tsm = {
|
||||
@ -862,7 +927,31 @@ commands.tsm = {
|
||||
{ name: 'txt', type: 'string' },
|
||||
{ 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
|
||||
@ -1544,6 +1905,8 @@ function undefine() {
|
||||
delete define.modules['gclitest/testSplit'];
|
||||
delete define.modules['gclitest/commands'];
|
||||
delete define.modules['gclitest/testCli'];
|
||||
delete define.modules['gclitest/testExec'];
|
||||
delete define.modules['gclitest/testKeyboard'];
|
||||
delete define.modules['gclitest/testHistory'];
|
||||
delete define.modules['gclitest/testRequire'];
|
||||
delete define.modules['gclitest/requirable'];
|
||||
@ -1556,6 +1919,8 @@ function undefine() {
|
||||
delete define.globalDomain.modules['gclitest/testSplit'];
|
||||
delete define.globalDomain.modules['gclitest/commands'];
|
||||
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/testRequire'];
|
||||
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
|
||||
# number, but the number is bigger than the largest allowed number, this error
|
||||
# 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
|
||||
# number, but the number is lower than the smallest allowed number, this error
|
||||
# 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
|
||||
# an option with a limited number of correct values, but the passed value is
|
||||
@ -94,3 +94,50 @@ nodeParseMultiple=Too many matches (%S)
|
||||
# displayed.
|
||||
nodeParseNone=No matches
|
||||
|
||||
# LOCALIZATION NOTE (helpDesc): A very short description of the 'help'
|
||||
# command. This string is designed to be shown in a menu alongside the command
|
||||
# name, which is why it should be as short as possible. See helpManual for a
|
||||
# fuller description of what it does.
|
||||
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'
|
||||
# command, displayed when the user asks for help on what it does.
|
||||
inspectManual=Investigate the dimensions and properties of an element using \
|
||||
a CSS selector to open the DOM highlighter
|
||||
inspectManual=Investigate the dimensions and properties of an element using a CSS selector to open the DOM highlighter
|
||||
|
||||
# LOCALIZATION NOTE (inspectNodeDesc) A very short string to describe the
|
||||
# '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'
|
||||
# parameter to the 'inspect' command, displayed when the user asks for help
|
||||
# on what it does.
|
||||
inspectNodeManual=A CSS selector for use with Document.querySelector which \
|
||||
identifies a single element
|
||||
inspectNodeManual=A CSS selector for use with Document.querySelector which identifies a single element
|
||||
|
@ -46,7 +46,6 @@
|
||||
height: 100%;
|
||||
vertical-align: middle;
|
||||
background-color: transparent;
|
||||
font: 12px Consolas, "Lucida Console", monospace;
|
||||
}
|
||||
|
||||
.gcliterm-input-node {
|
||||
@ -64,24 +63,6 @@
|
||||
-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 {
|
||||
background: url("chrome://global/skin/icons/commandline.png") 4px center no-repeat;
|
||||
width: 100%;
|
||||
@ -109,19 +90,47 @@
|
||||
border-bottom: 1px solid threedshadow;
|
||||
}
|
||||
|
||||
.gcli-help-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.gcliterm-menu {
|
||||
display: -moz-box;
|
||||
-moz-box-flex: 1;
|
||||
border-bottom-color: white;
|
||||
}
|
||||
|
||||
.gcliterm-hint-scroll {
|
||||
overflow-y: scroll;
|
||||
border-bottom-color: threedshadow;
|
||||
}
|
||||
|
||||
.gcliterm-hint-nospace {
|
||||
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
|
||||
* (i.e we don't attempt to translate 'console.log(x)')
|
||||
@ -151,6 +160,15 @@
|
||||
|
||||
/* 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 */
|
||||
|
||||
.gcli-argfetch {
|
||||
@ -181,7 +199,7 @@
|
||||
.gcli-af-required {
|
||||
font-size: 90%;
|
||||
color: #f66;
|
||||
padding-left: 5px;
|
||||
-moz-padding-start: 5px;
|
||||
}
|
||||
|
||||
.gcli-af-error {
|
||||
@ -197,6 +215,10 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.gcli-field-javascript {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* From: $GCLI/lib/gcli/ui/menu.css */
|
||||
|
||||
.gcli-menu {
|
||||
@ -284,3 +306,45 @@
|
||||
color: #66F;
|
||||
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%;
|
||||
vertical-align: middle;
|
||||
background-color: transparent;
|
||||
font: 12px Consolas, "Lucida Console", monospace;
|
||||
}
|
||||
|
||||
.gcliterm-input-node {
|
||||
@ -64,24 +63,6 @@
|
||||
-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 {
|
||||
background: url("chrome://global/skin/icons/commandline.png") 4px center no-repeat;
|
||||
width: 100%;
|
||||
@ -109,19 +90,47 @@
|
||||
border-bottom: 1px solid threedshadow;
|
||||
}
|
||||
|
||||
.gcli-help-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.gcliterm-menu {
|
||||
display: -moz-box;
|
||||
-moz-box-flex: 1;
|
||||
border-bottom-color: white;
|
||||
}
|
||||
|
||||
.gcliterm-hint-scroll {
|
||||
overflow-y: scroll;
|
||||
border-bottom-color: threedshadow;
|
||||
}
|
||||
|
||||
.gcliterm-hint-nospace {
|
||||
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
|
||||
* (i.e we don't attempt to translate 'console.log(x)')
|
||||
@ -151,10 +160,19 @@
|
||||
|
||||
/* From: $GCLI/mozilla/gcli/ui/gcliterm-pinstripe.css */
|
||||
|
||||
.gcliterm-input-node,
|
||||
.gcliterm-complete-node {
|
||||
font: 11px Menlo, Monaco, monospace;
|
||||
}
|
||||
|
||||
.gcliterm-complete-node {
|
||||
padding-top: 6px !important;
|
||||
}
|
||||
|
||||
.gcli-out-shortcut {
|
||||
font-family: Menlo, Monaco, monospace;
|
||||
}
|
||||
|
||||
/* From: $GCLI/lib/gcli/ui/arg_fetch.css */
|
||||
|
||||
.gcli-argfetch {
|
||||
@ -185,7 +203,7 @@
|
||||
.gcli-af-required {
|
||||
font-size: 90%;
|
||||
color: #f66;
|
||||
padding-left: 5px;
|
||||
-moz-padding-start: 5px;
|
||||
}
|
||||
|
||||
.gcli-af-error {
|
||||
@ -201,6 +219,10 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.gcli-field-javascript {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* From: $GCLI/lib/gcli/ui/menu.css */
|
||||
|
||||
.gcli-menu {
|
||||
@ -288,3 +310,45 @@
|
||||
color: #66F;
|
||||
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%;
|
||||
vertical-align: middle;
|
||||
background-color: transparent;
|
||||
font: 12px Consolas, "Lucida Console", monospace;
|
||||
}
|
||||
|
||||
.gcliterm-input-node {
|
||||
@ -64,24 +63,6 @@
|
||||
-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 {
|
||||
background: url("chrome://global/skin/icons/commandline.png") 4px center no-repeat;
|
||||
width: 100%;
|
||||
@ -109,19 +90,47 @@
|
||||
border-bottom: 1px solid threedshadow;
|
||||
}
|
||||
|
||||
.gcli-help-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.gcliterm-menu {
|
||||
display: -moz-box;
|
||||
-moz-box-flex: 1;
|
||||
border-bottom-color: white;
|
||||
}
|
||||
|
||||
.gcliterm-hint-scroll {
|
||||
overflow-y: scroll;
|
||||
border-bottom-color: threedshadow;
|
||||
}
|
||||
|
||||
.gcliterm-hint-nospace {
|
||||
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
|
||||
* (i.e we don't attempt to translate 'console.log(x)')
|
||||
@ -151,6 +160,15 @@
|
||||
|
||||
/* 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 */
|
||||
|
||||
.gcli-argfetch {
|
||||
@ -181,7 +199,7 @@
|
||||
.gcli-af-required {
|
||||
font-size: 90%;
|
||||
color: #f66;
|
||||
padding-left: 5px;
|
||||
-moz-padding-start: 5px;
|
||||
}
|
||||
|
||||
.gcli-af-error {
|
||||
@ -197,6 +215,10 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.gcli-field-javascript {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* From: $GCLI/lib/gcli/ui/menu.css */
|
||||
|
||||
.gcli-menu {
|
||||
@ -284,3 +306,45 @@
|
||||
color: #66F;
|
||||
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) {
|
||||
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 {
|
||||
// Get the topmost window, in case we're in a frame.
|
||||
var promptWin = domWin.top;
|
||||
|
||||
// Get the chrome window for the content window we're using.
|
||||
// (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)
|
||||
promptBox = chromeWin.getTabModalPromptBox(promptWin);
|
||||
|
Loading…
Reference in New Issue
Block a user