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'); } });