diff --git a/browser/devtools/commandline/gcli.jsm b/browser/devtools/commandline/gcli.jsm
index bc836f08bf15..797736838e15 100644
--- a/browser/devtools/commandline/gcli.jsm
+++ b/browser/devtools/commandline/gcli.jsm
@@ -213,14 +213,14 @@ function StringType(typeSpec) {
StringType.prototype = Object.create(Type.prototype);
-StringType.prototype.stringify = function(value) {
+StringType.prototype.stringify = function(value, context) {
if (value == null) {
return '';
}
return value.toString();
};
-StringType.prototype.parse = function(arg) {
+StringType.prototype.parse = function(arg, context) {
if (arg.text == null || arg.text === '') {
return Promise.resolve(new Conversion(undefined, arg, Status.INCOMPLETE, ''));
}
@@ -258,7 +258,7 @@ function NumberType(typeSpec) {
NumberType.prototype = Object.create(Type.prototype);
-NumberType.prototype.stringify = function(value) {
+NumberType.prototype.stringify = function(value, context) {
if (value == null) {
return '';
}
@@ -289,7 +289,7 @@ NumberType.prototype.getMax = function() {
return undefined;
};
-NumberType.prototype.parse = function(arg) {
+NumberType.prototype.parse = function(arg, context) {
if (arg.text.replace(/^\s*-?/, '').length === 0) {
return Promise.resolve(new Conversion(undefined, arg, Status.INCOMPLETE, ''));
}
@@ -327,7 +327,7 @@ NumberType.prototype.parse = function(arg) {
return Promise.resolve(new Conversion(value, arg));
};
-NumberType.prototype.decrement = function(value) {
+NumberType.prototype.decrement = function(value, context) {
if (typeof value !== 'number' || isNaN(value)) {
return this.getMax() || 1;
}
@@ -337,7 +337,7 @@ NumberType.prototype.decrement = function(value) {
return this._boundsCheck(newValue);
};
-NumberType.prototype.increment = function(value) {
+NumberType.prototype.increment = function(value, context) {
if (typeof value !== 'number' || isNaN(value)) {
var min = this.getMin();
return min != null ? min : 0;
@@ -394,17 +394,17 @@ BooleanType.prototype.lookup = [
{ name: 'true', value: true }
];
-BooleanType.prototype.parse = function(arg) {
+BooleanType.prototype.parse = function(arg, context) {
if (arg.type === 'TrueNamedArgument') {
return Promise.resolve(new Conversion(true, arg));
}
if (arg.type === 'FalseNamedArgument') {
return Promise.resolve(new Conversion(false, arg));
}
- return SelectionType.prototype.parse.call(this, arg);
+ return SelectionType.prototype.parse.call(this, arg, context);
};
-BooleanType.prototype.stringify = function(value) {
+BooleanType.prototype.stringify = function(value, context) {
if (value == null) {
return '';
}
@@ -437,33 +437,37 @@ function DelegateType(typeSpec) {
* Child types should implement this method to return an instance of the type
* that should be used. If no type is available, or some sort of temporary
* placeholder is required, BlankType can be used.
+ * @param context An ExecutionContext to allow access to information about the
+ * current state of the command line, or null if one is not available. A
+ * context is available for stringify, parse*, [in|de]crement and getType
+ * functions but not for isImportant
*/
-DelegateType.prototype.delegateType = function() {
+DelegateType.prototype.delegateType = function(context) {
throw new Error('Not implemented');
};
DelegateType.prototype = Object.create(Type.prototype);
-DelegateType.prototype.stringify = function(value) {
- return this.delegateType().stringify(value);
+DelegateType.prototype.stringify = function(value, context) {
+ return this.delegateType(context).stringify(value, context);
};
-DelegateType.prototype.parse = function(arg) {
- return this.delegateType().parse(arg);
+DelegateType.prototype.parse = function(arg, context) {
+ return this.delegateType(context).parse(arg, context);
};
-DelegateType.prototype.decrement = function(value) {
- var delegated = this.delegateType();
- return (delegated.decrement ? delegated.decrement(value) : undefined);
+DelegateType.prototype.decrement = function(value, context) {
+ var delegated = this.delegateType(context);
+ return (delegated.decrement ? delegated.decrement(value, context) : undefined);
};
-DelegateType.prototype.increment = function(value) {
- var delegated = this.delegateType();
- return (delegated.increment ? delegated.increment(value) : undefined);
+DelegateType.prototype.increment = function(value, context) {
+ var delegated = this.delegateType(context);
+ return (delegated.increment ? delegated.increment(value, context) : undefined);
};
-DelegateType.prototype.getType = function() {
- return this.delegateType();
+DelegateType.prototype.getType = function(context) {
+ return this.delegateType(context);
};
Object.defineProperty(DelegateType.prototype, 'isImportant', {
@@ -487,11 +491,11 @@ function BlankType(typeSpec) {
BlankType.prototype = Object.create(Type.prototype);
-BlankType.prototype.stringify = function(value) {
+BlankType.prototype.stringify = function(value, context) {
return '';
};
-BlankType.prototype.parse = function(arg) {
+BlankType.prototype.parse = function(arg, context) {
return Promise.resolve(new Conversion(undefined, arg));
};
@@ -518,7 +522,7 @@ function ArrayType(typeSpec) {
ArrayType.prototype = Object.create(Type.prototype);
-ArrayType.prototype.stringify = function(values) {
+ArrayType.prototype.stringify = function(values, context) {
if (values == null) {
return '';
}
@@ -526,7 +530,7 @@ ArrayType.prototype.stringify = function(values) {
return values.join(' ');
};
-ArrayType.prototype.parse = function(arg) {
+ArrayType.prototype.parse = function(arg, context) {
if (arg.type !== 'ArrayArgument') {
console.error('non ArrayArgument to ArrayType.parse', arg);
throw new Error('non ArrayArgument to ArrayType.parse');
@@ -537,7 +541,7 @@ ArrayType.prototype.parse = function(arg) {
// the status of individual conversions in addition to the overall state.
// |subArg.conversion| allows us to do that easily.
var subArgParse = function(subArg) {
- return this.subtype.parse(subArg).then(function(conversion) {
+ return this.subtype.parse(subArg, context).then(function(conversion) {
subArg.conversion = conversion;
return conversion;
}.bind(this));
@@ -1925,8 +1929,10 @@ function Type() {
* Convert the given value to a string representation.
* Where possible, there should be round-tripping between values and their
* string representations.
+ * @param value The object to convert into a string
+ * @param context An ExecutionContext to allow basic Requisition access
*/
-Type.prototype.stringify = function(value) {
+Type.prototype.stringify = function(value, context) {
throw new Error('Not implemented');
};
@@ -1935,9 +1941,10 @@ Type.prototype.stringify = function(value) {
* Where possible, there should be round-tripping between values and their
* string representations.
* @param arg An instance of Argument to convert.
+ * @param context An ExecutionContext to allow basic Requisition access
* @return Conversion
*/
-Type.prototype.parse = function(arg) {
+Type.prototype.parse = function(arg, context) {
throw new Error('Not implemented');
};
@@ -1946,8 +1953,8 @@ Type.prototype.parse = function(arg) {
* but instead have a string.
* @see #parse(arg)
*/
-Type.prototype.parseString = function(str) {
- return this.parse(new Argument(str));
+Type.prototype.parseString = function(str, context) {
+ return this.parse(new Argument(str), context);
};
/**
@@ -1962,7 +1969,7 @@ Type.prototype.name = undefined;
* If there is some concept of a higher value, return it,
* otherwise return undefined.
*/
-Type.prototype.increment = function(value) {
+Type.prototype.increment = function(value, context) {
return undefined;
};
@@ -1970,7 +1977,7 @@ Type.prototype.increment = function(value) {
* If there is some concept of a lower value, return it,
* otherwise return undefined.
*/
-Type.prototype.decrement = function(value) {
+Type.prototype.decrement = function(value, context) {
return undefined;
};
@@ -1988,8 +1995,9 @@ Type.prototype.getBlank = function() {
* This is something of a hack for the benefit of DelegateType which needs to
* be able to lie about it's type for fields to accept it as one of their own.
* Sub-types can ignore this unless they're DelegateType.
+ * @param context An ExecutionContext to allow basic Requisition access
*/
-Type.prototype.getType = function() {
+Type.prototype.getType = function(context) {
return this;
};
@@ -2756,7 +2764,7 @@ function SelectionType(typeSpec) {
SelectionType.prototype = Object.create(Type.prototype);
-SelectionType.prototype.stringify = function(value) {
+SelectionType.prototype.stringify = function(value, context) {
if (value == null) {
return '';
}
@@ -2963,7 +2971,7 @@ SelectionType.prototype._addToPredictions = function(predictions, option, arg) {
predictions.push(option);
};
-SelectionType.prototype.parse = function(arg) {
+SelectionType.prototype.parse = function(arg, context) {
return this._findPredictions(arg).then(function(predictions) {
if (predictions.length === 0) {
var msg = l10n.lookupFormat('typesSelectionNomatch', [ arg.text ]);
@@ -2971,12 +2979,6 @@ SelectionType.prototype.parse = function(arg) {
Promise.resolve(predictions));
}
- // This is something of a hack it basically allows us to tell the
- // setting type to forget its last setting hack.
- if (this.noMatch) {
- this.noMatch();
- }
-
if (predictions[0].name === arg.text) {
var value = predictions[0].value;
return new Conversion(value, arg, Status.VALID, '',
@@ -3008,7 +3010,7 @@ SelectionType.prototype.getBlank = function() {
* for SelectionType, up is down and down is up.
* Sorry.
*/
-SelectionType.prototype.decrement = function(value) {
+SelectionType.prototype.decrement = function(value, context) {
var lookup = util.synchronize(this.getLookup());
var index = this._findValue(lookup, value);
if (index === -1) {
@@ -3024,7 +3026,7 @@ SelectionType.prototype.decrement = function(value) {
/**
* See note on SelectionType.decrement()
*/
-SelectionType.prototype.increment = function(value) {
+SelectionType.prototype.increment = function(value, context) {
var lookup = util.synchronize(this.getLookup());
var index = this._findValue(lookup, value);
if (index === -1) {
@@ -3262,9 +3264,9 @@ ParamType.prototype.lookup = function() {
return displayedParams;
};
-ParamType.prototype.parse = function(arg) {
+ParamType.prototype.parse = function(arg, context) {
if (this.isIncompleteName) {
- return SelectionType.prototype.parse.call(this, arg);
+ return SelectionType.prototype.parse.call(this, arg, context);
}
else {
var message = l10n.lookup('cliUnusedArg');
@@ -3312,7 +3314,7 @@ CommandType.prototype._addToPredictions = function(predictions, option, arg) {
}
};
-CommandType.prototype.parse = function(arg) {
+CommandType.prototype.parse = function(arg, context) {
// Especially at startup, predictions live over the time that things change
// so we provide a completion function rather than completion values
var predictFunc = function() {
@@ -3553,8 +3555,12 @@ function Parameter(paramSpec, command, groupName) {
// optional, neither are required to parse and stringify.
if (this._defaultValue != null) {
try {
- var defaultText = this.type.stringify(this.paramSpec.defaultValue);
- this.type.parseString(defaultText).then(function(defaultConversion) {
+ // Passing null in for a context is bound to get us into trouble some day
+ // in which case we'll need to mock one up in some way
+ var context = null;
+ var defaultText = this.type.stringify(this.paramSpec.defaultValue, context);
+ var parsed = this.type.parseString(defaultText, context);
+ parsed.then(function(defaultConversion) {
if (defaultConversion.getStatus() !== Status.VALID) {
console.error('In ' + this.command.name + '/' + this.name +
': Error round tripping defaultValue. status = ' +
@@ -3874,7 +3880,7 @@ function JavascriptType(typeSpec) {
JavascriptType.prototype = Object.create(Type.prototype);
-JavascriptType.prototype.stringify = function(value) {
+JavascriptType.prototype.stringify = function(value, context) {
if (value == null) {
return '';
}
@@ -3887,7 +3893,7 @@ JavascriptType.prototype.stringify = function(value) {
*/
JavascriptType.MAX_COMPLETION_MATCHES = 10;
-JavascriptType.prototype.parse = function(arg) {
+JavascriptType.prototype.parse = function(arg, context) {
var typed = arg.text;
var scope = globalObject;
@@ -4453,14 +4459,14 @@ function NodeType(typeSpec) {
NodeType.prototype = Object.create(Type.prototype);
-NodeType.prototype.stringify = function(value) {
+NodeType.prototype.stringify = function(value, context) {
if (value == null) {
return '';
}
return value.__gcliQuery || 'Error';
};
-NodeType.prototype.parse = function(arg) {
+NodeType.prototype.parse = function(arg, context) {
if (arg.text === '') {
return Promise.resolve(new Conversion(undefined, arg, Status.INCOMPLETE));
}
@@ -4524,14 +4530,14 @@ NodeListType.prototype.getBlank = function() {
return new Conversion(exports._empty, new BlankArgument(), Status.VALID);
};
-NodeListType.prototype.stringify = function(value) {
+NodeListType.prototype.stringify = function(value, context) {
if (value == null) {
return '';
}
return value.__gcliQuery || 'Error';
};
-NodeListType.prototype.parse = function(arg) {
+NodeListType.prototype.parse = function(arg, context) {
if (arg.text === '') {
return Promise.resolve(new Conversion(undefined, arg, Status.INCOMPLETE));
}
@@ -4961,18 +4967,6 @@ exports.shutdown = function() {
types.unregisterType(SettingValueType);
};
-/**
- * This is a whole new level of nasty. 'setting' and 'settingValue' are a pair
- * for obvious reasons. settingValue is a delegate type - it delegates to the
- * type of the setting, but how do we implement the defer function - how does
- * it work out its paired setting?
- * In another parallel universe we pass the requisition to all the parse
- * methods so we can extract the args in SettingValueType.parse, however that
- * seems like a lot of churn for a simple way to connect 2 things. So we're
- * hacking. SettingType tries to keep 'lastSetting' up to date.
- */
-var lastSetting = null;
-
/**
* A type for selecting a known setting
*/
@@ -4990,41 +4984,30 @@ SettingType.prototype.lookup = function() {
});
};
-SettingType.prototype.noMatch = function() {
- lastSetting = null;
-};
-
-SettingType.prototype.stringify = function(option) {
- lastSetting = option;
- return SelectionType.prototype.stringify.call(this, option);
-};
-
-SettingType.prototype.parse = function(arg) {
- var promise = SelectionType.prototype.parse.call(this, arg);
- promise.then(function(conversion) {
- lastSetting = conversion.value;
- });
- return promise;
-};
-
SettingType.prototype.name = 'setting';
/**
* A type for entering the value of a known setting
+ * @param typeSpec Customization object, can contain the following:
+ * - settingParamName The name of the setting parameter so we can customize the
+ * type that we are expecting to read
*/
function SettingValueType(typeSpec) {
+ this.settingParamName = typeSpec.settingParamName || 'setting';
}
SettingValueType.prototype = Object.create(DelegateType.prototype);
-SettingValueType.prototype.delegateType = function() {
- if (lastSetting != null) {
- return lastSetting.type;
- }
- else {
- return types.getType('blank');
+SettingValueType.prototype.delegateType = function(context) {
+ if (context != null) {
+ var setting = context.getArgsObject()[this.settingParamName];
+ if (setting != null) {
+ return setting.type;
+ }
}
+
+ return types.getType('blank');
};
SettingValueType.prototype.name = 'settingValue';
@@ -5704,31 +5687,6 @@ Assignment.prototype.isInName = function() {
this.conversion.arg.prefix.slice(-1) !== ' ';
};
-/**
- * Make sure that there is some content for this argument by using an
- * Argument of '' if needed.
- */
-Assignment.prototype.ensureVisibleArgument = function() {
- // It isn't clear if we should be sending events from this method.
- // It should only be called when structural changes are happening in which
- // case we're going to ignore the event anyway. But on the other hand
- // perhaps this function shouldn't need to know how it is used, and should
- // do the inefficient thing.
- if (this.conversion.arg.type !== 'BlankArgument') {
- return false;
- }
-
- var arg = this.conversion.arg.beget({
- text: '',
- prefixSpace: this.param instanceof CommandAssignment
- });
- // For trivial input like { test: '' }, parse() should be synchronous ...
- this.conversion = util.synchronize(this.param.type.parse(arg));
- this.conversion.assign(this);
-
- return true;
-};
-
/**
* Work out what the status of the current conversion is which involves looking
* not only at the conversion, but also checking if data has been provided
@@ -5887,7 +5845,8 @@ function UnassignedAssignment(requisition, arg) {
this.onAssignmentChange = util.createEvent('UnassignedAssignment.onAssignmentChange');
// synchronize is ok because we can be sure that param type is synchronous
- this.conversion = util.synchronize(this.param.type.parse(arg));
+ var parsed = this.param.type.parse(arg, requisition.context);
+ this.conversion = util.synchronize(parsed);
this.conversion.assign(this);
}
@@ -6238,7 +6197,8 @@ Requisition.prototype.setAssignment = function(assignment, arg, options) {
setAssignmentInternal(arg);
}
else {
- return assignment.param.type.parse(arg).then(function(conversion) {
+ var parsed = assignment.param.type.parse(arg, this.context);
+ return parsed.then(function(conversion) {
setAssignmentInternal(conversion);
}.bind(this));
}
@@ -6367,9 +6327,10 @@ Requisition.prototype._addSpace = function(assignment) {
* Replace the current value with the lower value if such a concept exists.
*/
Requisition.prototype.decrement = function(assignment) {
- var replacement = assignment.param.type.decrement(assignment.conversion.value);
+ var replacement = assignment.param.type.decrement(assignment.conversion.value,
+ this.context);
if (replacement != null) {
- var str = assignment.param.type.stringify(replacement);
+ var str = assignment.param.type.stringify(replacement, this.context);
var arg = assignment.conversion.arg.beget({ text: str });
var promise = this.setAssignment(assignment, arg);
util.synchronize(promise);
@@ -6380,9 +6341,10 @@ Requisition.prototype.decrement = function(assignment) {
* Replace the current value with the higher value if such a concept exists.
*/
Requisition.prototype.increment = function(assignment) {
- var replacement = assignment.param.type.increment(assignment.conversion.value);
+ var replacement = assignment.param.type.increment(assignment.conversion.value,
+ this.context);
if (replacement != null) {
- var str = assignment.param.type.stringify(replacement);
+ var str = assignment.param.type.stringify(replacement, this.context);
var arg = assignment.conversion.arg.beget({ text: str });
var promise = this.setAssignment(assignment, arg);
util.synchronize(promise);
@@ -6408,7 +6370,7 @@ Requisition.prototype.toCanonicalString = function() {
// named parameters in place of positional params. Both can wait.
if (assignment.value !== assignment.param.defaultValue) {
line.push(' ');
- line.push(type.stringify(assignment.value));
+ line.push(type.stringify(assignment.value, this.context));
}
}, this);
@@ -6737,7 +6699,7 @@ Requisition.prototype.clear = function() {
this._args = [ arg ];
var commandType = this.commandAssignment.param.type;
- var conversion = util.synchronize(commandType.parse(arg));
+ var conversion = util.synchronize(commandType.parse(arg, this.context));
this.setAssignment(this.commandAssignment, conversion,
{ skipArgUpdate: true });
@@ -7081,7 +7043,7 @@ Requisition.prototype._split = function(args) {
new MergedArgument(args, 0, argsUsed);
// Making this promise synchronous is OK because we know that commandType
// is a synchronous type.
- conversion = util.synchronize(commandType.parse(arg));
+ conversion = util.synchronize(commandType.parse(arg, this.context));
// We only want to carry on if this command is a parent command,
// which means that there is a commandAssignment, but not one with
@@ -7351,6 +7313,7 @@ exports.createExecutionContext = function(requisition) {
type: type
};
},
+ getArgsObject: requisition.getArgsObject.bind(requisition),
defer: function() {
return Promise.defer();
},
@@ -7897,10 +7860,10 @@ StringField.prototype.setConversion = function(conversion) {
StringField.prototype.getConversion = function() {
// This tweaks the prefix/suffix of the argument to fit
this.arg = this.arg.beget({ text: this.element.value, prefixSpace: true });
- return this.type.parse(this.arg);
+ return this.type.parse(this.arg, this.requisition.context);
};
-StringField.claim = function(type) {
+StringField.claim = function(type, context) {
return type instanceof StringType ? Field.MATCH : Field.BASIC;
};
@@ -7932,7 +7895,7 @@ function NumberField(type, options) {
NumberField.prototype = Object.create(Field.prototype);
-NumberField.claim = function(type) {
+NumberField.claim = function(type, context) {
return type instanceof NumberType ? Field.MATCH : Field.NO_MATCH;
};
@@ -7952,7 +7915,7 @@ NumberField.prototype.setConversion = function(conversion) {
NumberField.prototype.getConversion = function() {
this.arg = this.arg.beget({ text: this.element.value, prefixSpace: true });
- return this.type.parse(this.arg);
+ return this.type.parse(this.arg, this.requisition.context);
};
@@ -7977,7 +7940,7 @@ function BooleanField(type, options) {
BooleanField.prototype = Object.create(Field.prototype);
-BooleanField.claim = function(type) {
+BooleanField.claim = function(type, context) {
return type instanceof BooleanType ? Field.MATCH : Field.NO_MATCH;
};
@@ -8004,7 +7967,7 @@ BooleanField.prototype.getConversion = function() {
else {
arg = new Argument(' ' + this.element.checked);
}
- return this.type.parse(arg);
+ return this.type.parse(arg, this.requisition.context);
};
@@ -8044,7 +8007,7 @@ DelegateField.prototype.update = function() {
this.element.appendChild(this.field.element);
};
-DelegateField.claim = function(type) {
+DelegateField.claim = function(type, context) {
return type instanceof DelegateType ? Field.MATCH : Field.NO_MATCH;
};
@@ -8106,7 +8069,7 @@ function ArrayField(type, options) {
ArrayField.prototype = Object.create(Field.prototype);
-ArrayField.claim = function(type) {
+ArrayField.claim = function(type, context) {
return type instanceof ArrayType ? Field.MATCH : Field.NO_MATCH;
};
@@ -8307,7 +8270,7 @@ Field.prototype.isImportant = false;
* to a type. This allows claims of various strength to be weighted up.
* See the Field.*MATCH values.
*/
-Field.claim = function() {
+Field.claim = function(type, context) {
throw new Error('Field should not be used directly');
};
@@ -8384,7 +8347,7 @@ exports.getField = function(type, options) {
var ctor;
var highestClaim = -1;
fieldCtors.forEach(function(fieldCtor) {
- var claim = fieldCtor.claim(type);
+ var claim = fieldCtor.claim(type, options.requisition.context);
if (claim > highestClaim) {
highestClaim = claim;
ctor = fieldCtor;
@@ -8418,7 +8381,7 @@ function BlankField(type, options) {
BlankField.prototype = Object.create(Field.prototype);
-BlankField.claim = function(type) {
+BlankField.claim = function(type, context) {
return type instanceof BlankType ? Field.MATCH : Field.NO_MATCH;
};
@@ -8427,7 +8390,7 @@ BlankField.prototype.setConversion = function(conversion) {
};
BlankField.prototype.getConversion = function() {
- return this.type.parse(new Argument());
+ return this.type.parse(new Argument(), this.requisition.context);
};
exports.addField(BlankField);
@@ -8516,7 +8479,7 @@ function JavascriptField(type, options) {
JavascriptField.prototype = Object.create(Field.prototype);
-JavascriptField.claim = function(type) {
+JavascriptField.claim = function(type, context) {
return type instanceof JavascriptType ? Field.TOOLTIP_MATCH : Field.NO_MATCH;
};
@@ -8564,7 +8527,8 @@ JavascriptField.prototype.setConversion = function(conversion) {
};
JavascriptField.prototype.itemClicked = function(ev) {
- Promise.resolve(this.type.parse(ev.arg)).then(function(conversion) {
+ var parsed = this.type.parse(ev.arg, this.requisition.context);
+ Promise.resolve(parsed).then(function(conversion) {
this.onFieldChange({ conversion: conversion });
this.setMessage(conversion.message);
}.bind(this), util.errorHandler);
@@ -8581,7 +8545,7 @@ JavascriptField.prototype.onInputChange = function(ev) {
JavascriptField.prototype.getConversion = function() {
// This tweaks the prefix/suffix of the argument to fit
this.arg = new ScriptArgument(this.input.value, '{ ', ' }');
- return this.type.parse(this.arg);
+ return this.type.parse(this.arg, this.requisition.context);
};
JavascriptField.DEFAULT_VALUE = '__JavascriptField.DEFAULT_VALUE';
@@ -8914,7 +8878,7 @@ function SelectionField(type, options) {
SelectionField.prototype = Object.create(Field.prototype);
-SelectionField.claim = function(type) {
+SelectionField.claim = function(type, context) {
if (type instanceof BooleanType) {
return Field.BASIC;
}
@@ -8976,8 +8940,8 @@ function SelectionTooltipField(type, options) {
SelectionTooltipField.prototype = Object.create(Field.prototype);
-SelectionTooltipField.claim = function(type) {
- return type.getType() instanceof SelectionType ?
+SelectionTooltipField.claim = function(type, context) {
+ return type.getType(context) instanceof SelectionType ?
Field.TOOLTIP_MATCH :
Field.NO_MATCH;
};
@@ -9007,7 +8971,8 @@ SelectionTooltipField.prototype.setConversion = function(conversion) {
};
SelectionTooltipField.prototype.itemClicked = function(ev) {
- Promise.resolve(this.type.parse(ev.arg)).then(function(conversion) {
+ var parsed = this.type.parse(ev.arg, this.requisition.context);
+ Promise.resolve(parsed).then(function(conversion) {
this.onFieldChange({ conversion: conversion });
this.setMessage(conversion.message);
}.bind(this), util.errorHandler);
@@ -9024,7 +8989,7 @@ SelectionTooltipField.prototype.onInputChange = function(ev) {
SelectionTooltipField.prototype.getConversion = function() {
// This tweaks the prefix/suffix of the argument to fit
this.arg = this.arg.beget({ text: this.input.value });
- return this.type.parse(this.arg);
+ return this.type.parse(this.arg, this.requisition.context);
};
/**
@@ -10425,7 +10390,7 @@ Inputter.prototype.handleKeyUp = function(ev) {
else {
// See notes above for the UP key
if (this.assignment.getStatus() === Status.VALID) {
- this.requisition.decrement(this.assignment);
+ this.requisition.decrement(this.assignment, this.requisition.context);
// See notes on focusManager.onInputChange in onKeyDown
if (this.focusManager) {
this.focusManager.onInputChange();
diff --git a/browser/devtools/commandline/test/browser_gcli_cli.js b/browser/devtools/commandline/test/browser_gcli_cli.js
index f88197a11442..92b4dd6e00cf 100644
--- a/browser/devtools/commandline/test/browser_gcli_cli.js
+++ b/browser/devtools/commandline/test/browser_gcli_cli.js
@@ -179,7 +179,7 @@ exports.testTsv = function(options) {
cursor: 4,
current: 'optionType',
status: 'ERROR',
- predictions: [ 'option1', 'option2' ],
+ predictions: [ 'option1', 'option2', 'option3' ],
unassigned: [ ],
tooltipState: 'true:importantFieldFlag',
args: {
@@ -219,7 +219,7 @@ exports.testTsv = function(options) {
cursor: 5,
current: 'optionType',
status: 'ERROR',
- predictions: [ 'option1', 'option2' ],
+ predictions: [ 'option1', 'option2', 'option3' ],
unassigned: [ ],
tooltipState: 'true:importantFieldFlag',
args: {
@@ -248,7 +248,7 @@ exports.testTsv = function(options) {
cursor: 10,
current: 'optionType',
status: 'ERROR',
- predictions: [ 'option1', 'option2' ],
+ predictions: [ 'option1', 'option2', 'option3' ],
unassigned: [ ],
tooltipState: 'true:importantFieldFlag',
args: {
diff --git a/browser/devtools/commandline/test/browser_gcli_resource.js b/browser/devtools/commandline/test/browser_gcli_resource.js
index e30d2202429d..155a9b5cf183 100644
--- a/browser/devtools/commandline/test/browser_gcli_resource.js
+++ b/browser/devtools/commandline/test/browser_gcli_resource.js
@@ -142,11 +142,13 @@ function checkPrediction(res, prediction) {
var name = prediction.name;
var value = prediction.value;
- return res.parseString(name).then(function(conversion) {
+ // resources don't need context so cheat and pass in null
+ var context = null;
+ return res.parseString(name, context).then(function(conversion) {
assert.is(conversion.getStatus(), Status.VALID, 'status VALID for ' + name);
assert.is(conversion.value, value, 'value for ' + name);
- var strung = res.stringify(value);
+ var strung = res.stringify(value, context);
assert.is(strung, name, 'stringify for ' + name);
assert.is(typeof value.loadContents, 'function', 'resource for ' + name);
diff --git a/browser/devtools/commandline/test/browser_gcli_types.js b/browser/devtools/commandline/test/browser_gcli_types.js
index 2e93391618f6..79bacd9e935c 100644
--- a/browser/devtools/commandline/test/browser_gcli_types.js
+++ b/browser/devtools/commandline/test/browser_gcli_types.js
@@ -90,7 +90,7 @@ exports.testDefault = function(options) {
exports.testNullDefault = function(options) {
forEachType(options, { defaultValue: null }, function(type) {
- assert.is(type.stringify(null), '', 'stringify(null) for ' + type.name);
+ assert.is(type.stringify(null, null), '', 'stringify(null) for ' + type.name);
});
};
diff --git a/browser/devtools/commandline/test/mockCommands.js b/browser/devtools/commandline/test/mockCommands.js
index 4ac60b781c67..49631e7d2e7e 100644
--- a/browser/devtools/commandline/test/mockCommands.js
+++ b/browser/devtools/commandline/test/mockCommands.js
@@ -111,50 +111,34 @@ mockCommands.shutdown = function(opts) {
mockCommands.option1 = { type: types.getType('string') };
mockCommands.option2 = { type: types.getType('number') };
-
-var lastOption = undefined;
-var debug = false;
+mockCommands.option3 = { type: types.getType({
+ name: 'selection',
+ lookup: [
+ { name: 'one', value: 1 },
+ { name: 'two', value: 2 },
+ { name: 'three', value: 3 }
+ ]
+})};
mockCommands.optionType = new SelectionType({
name: 'optionType',
lookup: [
{ name: 'option1', value: mockCommands.option1 },
- { name: 'option2', value: mockCommands.option2 }
- ],
- noMatch: function() {
- lastOption = undefined;
- if (debug) {
- console.log('optionType.noMatch: lastOption = undefined');
- }
- },
- stringify: function(option) {
- lastOption = option;
- if (debug) {
- console.log('optionType.stringify: lastOption = ', lastOption);
- }
- return SelectionType.prototype.stringify.call(this, option);
- },
- parse: function(arg) {
- var promise = SelectionType.prototype.parse.call(this, arg);
- promise.then(function(conversion) {
- lastOption = conversion.value;
- if (debug) {
- console.log('optionType.parse: lastOption = ', lastOption);
- }
- });
- return promise;
- }
+ { name: 'option2', value: mockCommands.option2 },
+ { name: 'option3', value: mockCommands.option3 }
+ ]
});
mockCommands.optionValue = new DelegateType({
name: 'optionValue',
- delegateType: function() {
- if (lastOption && lastOption.type) {
- return lastOption.type;
- }
- else {
- return types.getType('blank');
+ delegateType: function(context) {
+ if (context != null) {
+ var option = context.getArgsObject().optionType;
+ if (option != null) {
+ return option.type;
+ }
}
+ return types.getType('blank');
}
});