| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 WebInspector.JavaScriptAutocomplete = {}; | 5 Components.JavaScriptAutocomplete = {}; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * @param {!Element} proxyElement | 8 * @param {!Element} proxyElement |
| 9 * @param {!Range} wordRange | 9 * @param {!Range} wordRange |
| 10 * @param {boolean} force | 10 * @param {boolean} force |
| 11 * @param {function(!Array.<string>, number=)} completionsReadyCallback | 11 * @param {function(!Array.<string>, number=)} completionsReadyCallback |
| 12 */ | 12 */ |
| 13 WebInspector.JavaScriptAutocomplete.completionsForTextPromptInCurrentContext = f
unction(proxyElement, wordRange, force, completionsReadyCallback) { | 13 Components.JavaScriptAutocomplete.completionsForTextPromptInCurrentContext = fun
ction(proxyElement, wordRange, force, completionsReadyCallback) { |
| 14 var expressionRange = wordRange.cloneRange(); | 14 var expressionRange = wordRange.cloneRange(); |
| 15 expressionRange.collapse(true); | 15 expressionRange.collapse(true); |
| 16 expressionRange.setStartBefore(proxyElement); | 16 expressionRange.setStartBefore(proxyElement); |
| 17 WebInspector.JavaScriptAutocomplete.completionsForTextInCurrentContext(express
ionRange.toString(), wordRange.toString(), force) | 17 Components.JavaScriptAutocomplete.completionsForTextInCurrentContext(expressio
nRange.toString(), wordRange.toString(), force) |
| 18 .then(completionsReadyCallback); | 18 .then(completionsReadyCallback); |
| 19 }; | 19 }; |
| 20 | 20 |
| 21 /** | 21 /** |
| 22 * @param {string} text | 22 * @param {string} text |
| 23 * @param {string} query | 23 * @param {string} query |
| 24 * @param {boolean=} force | 24 * @param {boolean=} force |
| 25 * @return {!Promise<!Array<string>>} | 25 * @return {!Promise<!Array<string>>} |
| 26 */ | 26 */ |
| 27 WebInspector.JavaScriptAutocomplete.completionsForTextInCurrentContext = functio
n(text, query, force) { | 27 Components.JavaScriptAutocomplete.completionsForTextInCurrentContext = function(
text, query, force) { |
| 28 var index; | 28 var index; |
| 29 var stopChars = new Set(' =:({;,!+-*/&|^<>`'.split('')); | 29 var stopChars = new Set(' =:({;,!+-*/&|^<>`'.split('')); |
| 30 for (index = text.length - 1; index >= 0; index--) { | 30 for (index = text.length - 1; index >= 0; index--) { |
| 31 // Pass less stop characters to rangeOfWord so the range will be a more comp
lete expression. | 31 // Pass less stop characters to rangeOfWord so the range will be a more comp
lete expression. |
| 32 if (stopChars.has(text.charAt(index))) | 32 if (stopChars.has(text.charAt(index))) |
| 33 break; | 33 break; |
| 34 } | 34 } |
| 35 var clippedExpression = text.substring(index + 1); | 35 var clippedExpression = text.substring(index + 1); |
| 36 var bracketCount = 0; | 36 var bracketCount = 0; |
| 37 | 37 |
| 38 index = clippedExpression.length - 1; | 38 index = clippedExpression.length - 1; |
| 39 while (index >= 0) { | 39 while (index >= 0) { |
| 40 var character = clippedExpression.charAt(index); | 40 var character = clippedExpression.charAt(index); |
| 41 if (character === ']') | 41 if (character === ']') |
| 42 bracketCount++; | 42 bracketCount++; |
| 43 // Allow an open bracket at the end for property completion. | 43 // Allow an open bracket at the end for property completion. |
| 44 if (character === '[' && index < clippedExpression.length - 1) { | 44 if (character === '[' && index < clippedExpression.length - 1) { |
| 45 bracketCount--; | 45 bracketCount--; |
| 46 if (bracketCount < 0) | 46 if (bracketCount < 0) |
| 47 break; | 47 break; |
| 48 } | 48 } |
| 49 index--; | 49 index--; |
| 50 } | 50 } |
| 51 clippedExpression = clippedExpression.substring(index + 1); | 51 clippedExpression = clippedExpression.substring(index + 1); |
| 52 | 52 |
| 53 return WebInspector.JavaScriptAutocomplete.completionsForExpression(clippedExp
ression, query, force); | 53 return Components.JavaScriptAutocomplete.completionsForExpression(clippedExpre
ssion, query, force); |
| 54 }; | 54 }; |
| 55 | 55 |
| 56 | 56 |
| 57 /** | 57 /** |
| 58 * @param {string} expressionString | 58 * @param {string} expressionString |
| 59 * @param {string} query | 59 * @param {string} query |
| 60 * @param {boolean=} force | 60 * @param {boolean=} force |
| 61 * @return {!Promise<!Array<string>>} | 61 * @return {!Promise<!Array<string>>} |
| 62 */ | 62 */ |
| 63 WebInspector.JavaScriptAutocomplete.completionsForExpression = function(expressi
onString, query, force) { | 63 Components.JavaScriptAutocomplete.completionsForExpression = function(expression
String, query, force) { |
| 64 var executionContext = WebInspector.context.flavor(WebInspector.ExecutionConte
xt); | 64 var executionContext = UI.context.flavor(SDK.ExecutionContext); |
| 65 if (!executionContext) | 65 if (!executionContext) |
| 66 return Promise.resolve([]); | 66 return Promise.resolve([]); |
| 67 | 67 |
| 68 var lastIndex = expressionString.length - 1; | 68 var lastIndex = expressionString.length - 1; |
| 69 | 69 |
| 70 var dotNotation = (expressionString[lastIndex] === '.'); | 70 var dotNotation = (expressionString[lastIndex] === '.'); |
| 71 var bracketNotation = (expressionString[lastIndex] === '['); | 71 var bracketNotation = (expressionString[lastIndex] === '['); |
| 72 | 72 |
| 73 if (dotNotation || bracketNotation) | 73 if (dotNotation || bracketNotation) |
| 74 expressionString = expressionString.substr(0, lastIndex); | 74 expressionString = expressionString.substr(0, lastIndex); |
| 75 else | 75 else |
| 76 expressionString = ''; | 76 expressionString = ''; |
| 77 | 77 |
| 78 // User is entering float value, do not suggest anything. | 78 // User is entering float value, do not suggest anything. |
| 79 if ((expressionString && !isNaN(expressionString)) || (!expressionString && qu
ery && !isNaN(query))) | 79 if ((expressionString && !isNaN(expressionString)) || (!expressionString && qu
ery && !isNaN(query))) |
| 80 return Promise.resolve([]); | 80 return Promise.resolve([]); |
| 81 | 81 |
| 82 if (!query && !expressionString && !force) | 82 if (!query && !expressionString && !force) |
| 83 return Promise.resolve([]); | 83 return Promise.resolve([]); |
| 84 | 84 |
| 85 var fufill; | 85 var fufill; |
| 86 var promise = new Promise(x => fufill = x); | 86 var promise = new Promise(x => fufill = x); |
| 87 if (!expressionString && executionContext.debuggerModel.selectedCallFrame()) | 87 if (!expressionString && executionContext.debuggerModel.selectedCallFrame()) |
| 88 executionContext.debuggerModel.selectedCallFrame().variableNames(receivedPro
pertyNames); | 88 executionContext.debuggerModel.selectedCallFrame().variableNames(receivedPro
pertyNames); |
| 89 else | 89 else |
| 90 executionContext.evaluate(expressionString, 'completion', true, true, false,
false, false, evaluated); | 90 executionContext.evaluate(expressionString, 'completion', true, true, false,
false, false, evaluated); |
| 91 | 91 |
| 92 return promise; | 92 return promise; |
| 93 /** | 93 /** |
| 94 * @param {?WebInspector.RemoteObject} result | 94 * @param {?SDK.RemoteObject} result |
| 95 * @param {!Protocol.Runtime.ExceptionDetails=} exceptionDetails | 95 * @param {!Protocol.Runtime.ExceptionDetails=} exceptionDetails |
| 96 */ | 96 */ |
| 97 function evaluated(result, exceptionDetails) { | 97 function evaluated(result, exceptionDetails) { |
| 98 if (!result || !!exceptionDetails) { | 98 if (!result || !!exceptionDetails) { |
| 99 fufill([]); | 99 fufill([]); |
| 100 return; | 100 return; |
| 101 } | 101 } |
| 102 | 102 |
| 103 /** | 103 /** |
| 104 * @param {?WebInspector.RemoteObject} object | 104 * @param {?SDK.RemoteObject} object |
| 105 * @return {!Promise<?WebInspector.RemoteObject>} | 105 * @return {!Promise<?SDK.RemoteObject>} |
| 106 */ | 106 */ |
| 107 function extractTarget(object) { | 107 function extractTarget(object) { |
| 108 if (!object) | 108 if (!object) |
| 109 return Promise.resolve(/** @type {?WebInspector.RemoteObject} */(null)); | 109 return Promise.resolve(/** @type {?SDK.RemoteObject} */(null)); |
| 110 if (object.type !== 'object' || object.subtype !== 'proxy') | 110 if (object.type !== 'object' || object.subtype !== 'proxy') |
| 111 return Promise.resolve(/** @type {?WebInspector.RemoteObject} */(object)
); | 111 return Promise.resolve(/** @type {?SDK.RemoteObject} */(object)); |
| 112 return object.getOwnPropertiesPromise().then(extractTargetFromProperties).
then(extractTarget); | 112 return object.getOwnPropertiesPromise().then(extractTargetFromProperties).
then(extractTarget); |
| 113 } | 113 } |
| 114 | 114 |
| 115 /** | 115 /** |
| 116 * @param {!{properties: ?Array<!WebInspector.RemoteObjectProperty>, interna
lProperties: ?Array<!WebInspector.RemoteObjectProperty>}} properties | 116 * @param {!{properties: ?Array<!SDK.RemoteObjectProperty>, internalProperti
es: ?Array<!SDK.RemoteObjectProperty>}} properties |
| 117 * @return {?WebInspector.RemoteObject} | 117 * @return {?SDK.RemoteObject} |
| 118 */ | 118 */ |
| 119 function extractTargetFromProperties(properties) { | 119 function extractTargetFromProperties(properties) { |
| 120 var internalProperties = properties.internalProperties || []; | 120 var internalProperties = properties.internalProperties || []; |
| 121 var target = internalProperties.find(property => property.name === '[[Targ
et]]'); | 121 var target = internalProperties.find(property => property.name === '[[Targ
et]]'); |
| 122 return target ? target.value : null; | 122 return target ? target.value : null; |
| 123 } | 123 } |
| 124 | 124 |
| 125 /** | 125 /** |
| 126 * @param {string=} type | 126 * @param {string=} type |
| 127 * @return {!Object} | 127 * @return {!Object} |
| (...skipping 24 matching lines...) Expand all Loading... |
| 152 continue; | 152 continue; |
| 153 resultSet[names[i]] = true; | 153 resultSet[names[i]] = true; |
| 154 } | 154 } |
| 155 } | 155 } |
| 156 } catch (e) { | 156 } catch (e) { |
| 157 } | 157 } |
| 158 return resultSet; | 158 return resultSet; |
| 159 } | 159 } |
| 160 | 160 |
| 161 /** | 161 /** |
| 162 * @param {?WebInspector.RemoteObject} object | 162 * @param {?SDK.RemoteObject} object |
| 163 */ | 163 */ |
| 164 function completionsForObject(object) { | 164 function completionsForObject(object) { |
| 165 if (!object) | 165 if (!object) |
| 166 receivedPropertyNames(null); | 166 receivedPropertyNames(null); |
| 167 else if (object.type === 'object' || object.type === 'function') | 167 else if (object.type === 'object' || object.type === 'function') |
| 168 object.callFunctionJSON( | 168 object.callFunctionJSON( |
| 169 getCompletions, [WebInspector.RemoteObject.toCallArgument(object.subty
pe)], | 169 getCompletions, [SDK.RemoteObject.toCallArgument(object.subtype)], |
| 170 receivedPropertyNames); | 170 receivedPropertyNames); |
| 171 else if (object.type === 'string' || object.type === 'number' || object.ty
pe === 'boolean') | 171 else if (object.type === 'string' || object.type === 'number' || object.ty
pe === 'boolean') |
| 172 executionContext.evaluate( | 172 executionContext.evaluate( |
| 173 '(' + getCompletions + ')("' + result.type + '")', 'completion', false
, true, true, false, false, | 173 '(' + getCompletions + ')("' + result.type + '")', 'completion', false
, true, true, false, false, |
| 174 receivedPropertyNamesFromEval); | 174 receivedPropertyNamesFromEval); |
| 175 } | 175 } |
| 176 | 176 |
| 177 extractTarget(result).then(completionsForObject); | 177 extractTarget(result).then(completionsForObject); |
| 178 } | 178 } |
| 179 | 179 |
| 180 /** | 180 /** |
| 181 * @param {?WebInspector.RemoteObject} result | 181 * @param {?SDK.RemoteObject} result |
| 182 * @param {!Protocol.Runtime.ExceptionDetails=} exceptionDetails | 182 * @param {!Protocol.Runtime.ExceptionDetails=} exceptionDetails |
| 183 */ | 183 */ |
| 184 function receivedPropertyNamesFromEval(result, exceptionDetails) { | 184 function receivedPropertyNamesFromEval(result, exceptionDetails) { |
| 185 executionContext.target().runtimeAgent().releaseObjectGroup('completion'); | 185 executionContext.target().runtimeAgent().releaseObjectGroup('completion'); |
| 186 if (result && !exceptionDetails) | 186 if (result && !exceptionDetails) |
| 187 receivedPropertyNames(/** @type {!Object} */(result.value)); | 187 receivedPropertyNames(/** @type {!Object} */(result.value)); |
| 188 else | 188 else |
| 189 fufill([]); | 189 fufill([]); |
| 190 } | 190 } |
| 191 | 191 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 218 'monitor', | 218 'monitor', |
| 219 'unmonitor', | 219 'unmonitor', |
| 220 'table', | 220 'table', |
| 221 '$', | 221 '$', |
| 222 '$$', | 222 '$$', |
| 223 '$x' | 223 '$x' |
| 224 ]; | 224 ]; |
| 225 for (var i = 0; i < commandLineAPI.length; ++i) | 225 for (var i = 0; i < commandLineAPI.length; ++i) |
| 226 propertyNames[commandLineAPI[i]] = true; | 226 propertyNames[commandLineAPI[i]] = true; |
| 227 } | 227 } |
| 228 fufill(WebInspector.JavaScriptAutocomplete._completionsForQuery( | 228 fufill(Components.JavaScriptAutocomplete._completionsForQuery( |
| 229 dotNotation, bracketNotation, expressionString, query, Object.keys(propert
yNames))); | 229 dotNotation, bracketNotation, expressionString, query, Object.keys(propert
yNames))); |
| 230 } | 230 } |
| 231 }; | 231 }; |
| 232 | 232 |
| 233 /** | 233 /** |
| 234 * @param {boolean} dotNotation | 234 * @param {boolean} dotNotation |
| 235 * @param {boolean} bracketNotation | 235 * @param {boolean} bracketNotation |
| 236 * @param {string} expressionString | 236 * @param {string} expressionString |
| 237 * @param {string} query | 237 * @param {string} query |
| 238 * @param {!Array.<string>} properties | 238 * @param {!Array.<string>} properties |
| 239 * @return {!Array<string>} | 239 * @return {!Array<string>} |
| 240 */ | 240 */ |
| 241 WebInspector.JavaScriptAutocomplete._completionsForQuery = function(dotNotation,
bracketNotation, expressionString, query, properties) { | 241 Components.JavaScriptAutocomplete._completionsForQuery = function(dotNotation, b
racketNotation, expressionString, query, properties) { |
| 242 if (bracketNotation) { | 242 if (bracketNotation) { |
| 243 if (query.length && query[0] === '\'') | 243 if (query.length && query[0] === '\'') |
| 244 var quoteUsed = '\''; | 244 var quoteUsed = '\''; |
| 245 else | 245 else |
| 246 var quoteUsed = '"'; | 246 var quoteUsed = '"'; |
| 247 } | 247 } |
| 248 | 248 |
| 249 if (!expressionString) { | 249 if (!expressionString) { |
| 250 const keywords = [ | 250 const keywords = [ |
| 251 'break', 'case', 'catch', 'continue', 'default', 'delete', 'do', 'else', '
finally', | 251 'break', 'case', 'catch', 'continue', 'default', 'delete', 'do', 'else', '
finally', |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 caseSensitivePrefix.push(prop); | 285 caseSensitivePrefix.push(prop); |
| 286 else if (property.toLowerCase().startsWith(query.toLowerCase())) | 286 else if (property.toLowerCase().startsWith(query.toLowerCase())) |
| 287 caseInsensitivePrefix.push(prop); | 287 caseInsensitivePrefix.push(prop); |
| 288 else if (property.indexOf(query) !== -1) | 288 else if (property.indexOf(query) !== -1) |
| 289 caseSensitiveAnywhere.push(prop); | 289 caseSensitiveAnywhere.push(prop); |
| 290 else | 290 else |
| 291 caseInsensitiveAnywhere.push(prop); | 291 caseInsensitiveAnywhere.push(prop); |
| 292 } | 292 } |
| 293 return caseSensitivePrefix.concat(caseInsensitivePrefix).concat(caseSensitiveA
nywhere).concat(caseInsensitiveAnywhere); | 293 return caseSensitivePrefix.concat(caseInsensitivePrefix).concat(caseSensitiveA
nywhere).concat(caseInsensitiveAnywhere); |
| 294 }; | 294 }; |
| OLD | NEW |