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 Components.JavaScriptAutocomplete = {}; | 5 Components.JavaScriptAutocomplete = {}; |
6 | 6 |
7 /** @typedef {{title:(string|undefined), items:Array<string>}} */ | 7 /** @typedef {{title:(string|undefined), items:Array<string>}} */ |
8 Components.JavaScriptAutocomplete.CompletionGroup; | 8 Components.JavaScriptAutocomplete.CompletionGroup; |
9 | 9 |
10 /** | 10 /** |
11 * @param {string} text | 11 * @param {string} text |
12 * @param {string} query | 12 * @param {string} query |
13 * @param {boolean=} force | 13 * @param {boolean=} force |
14 * @return {!Promise<!UI.SuggestBox.Suggestions>} | 14 * @return {!Promise<!UI.SuggestBox.Suggestions>} |
15 */ | 15 */ |
16 Components.JavaScriptAutocomplete.completionsForTextInCurrentContext = function( text, query, force) { | 16 Components.JavaScriptAutocomplete.completionsForTextInCurrentContext = function( text, query, force) { |
17 var clippedExpression = Components.JavaScriptAutocomplete._clipExpression(text , true); | |
18 var mapCompletionsPromise = Components.JavaScriptAutocomplete._mapCompletions( text, query); | |
19 return Components.JavaScriptAutocomplete.completionsForExpression(clippedExpre ssion, query, force) | |
dgozman
2017/01/18 17:02:39
Should this be Promise.all instead?
einbinder
2017/01/19 01:20:40
The promise has already been triggered. Promise.al
| |
20 .then(completions => mapCompletionsPromise.then(mapCompletions => mapCompl etions.concat(completions))); | |
21 }; | |
22 | |
23 /** | |
24 * @param {string} text | |
25 * @param {boolean=} allowEndingBracket | |
26 * @return {string} | |
27 */ | |
28 Components.JavaScriptAutocomplete._clipExpression = function(text, allowEndingBr acket) { | |
17 var index; | 29 var index; |
18 var stopChars = new Set(' =:({;,!+-*/&|^<>`'.split('')); | 30 var stopChars = new Set(' =:({;,!+-*/&|^<>`'.split('')); |
19 for (index = text.length - 1; index >= 0; index--) { | 31 for (index = text.length - 1; index >= 0; index--) { |
20 // Pass less stop characters to rangeOfWord so the range will be a more comp lete expression. | |
21 if (stopChars.has(text.charAt(index))) | 32 if (stopChars.has(text.charAt(index))) |
22 break; | 33 break; |
23 } | 34 } |
24 var clippedExpression = text.substring(index + 1); | 35 var clippedExpression = text.substring(index + 1); |
25 var bracketCount = 0; | 36 var bracketCount = 0; |
26 | 37 |
27 index = clippedExpression.length - 1; | 38 index = clippedExpression.length - 1; |
28 while (index >= 0) { | 39 while (index >= 0) { |
29 var character = clippedExpression.charAt(index); | 40 var character = clippedExpression.charAt(index); |
30 if (character === ']') | 41 if (character === ']') |
31 bracketCount++; | 42 bracketCount++; |
32 // Allow an open bracket at the end for property completion. | 43 // Allow an open bracket at the end for property completion. |
33 if (character === '[' && index < clippedExpression.length - 1) { | 44 if (character === '[' && (index < clippedExpression.length - 1 || !allowEndi ngBracket)) { |
34 bracketCount--; | 45 bracketCount--; |
35 if (bracketCount < 0) | 46 if (bracketCount < 0) |
36 break; | 47 break; |
37 } | 48 } |
38 index--; | 49 index--; |
39 } | 50 } |
40 clippedExpression = clippedExpression.substring(index + 1); | 51 return clippedExpression.substring(index + 1); |
41 | |
42 return Components.JavaScriptAutocomplete.completionsForExpression(clippedExpre ssion, query, force); | |
43 }; | 52 }; |
44 | 53 |
45 /** | 54 /** |
55 * @param {string} text | |
56 * @param {string} query | |
57 * @return {!Promise<!UI.SuggestBox.Suggestions>} | |
58 */ | |
59 Components.JavaScriptAutocomplete._mapCompletions = function(text, query) { | |
60 var mapMatch = text.match(/\.\s*[gs]et\s*\(\s*$/); | |
61 var executionContext = UI.context.flavor(SDK.ExecutionContext); | |
62 if (!executionContext || !mapMatch) | |
63 return Promise.resolve([]); | |
64 | |
65 var clippedExpression = Components.JavaScriptAutocomplete._clipExpression(text .substring(0, mapMatch.index), true); | |
66 var fufill; | |
67 var promise = new Promise(x => fufill = x); | |
68 executionContext.evaluate(clippedExpression, 'completion', true, true, false, true, false, evaluated); | |
69 return promise; | |
70 | |
71 /** | |
72 * @param {?SDK.RemoteObject} result | |
dgozman
2017/01/18 17:02:39
indentation is off
einbinder
2017/01/19 01:20:40
Fixed.
| |
73 * @param {!Protocol.Runtime.ExceptionDetails=} exceptionDetails | |
74 */ | |
75 function evaluated(result, exceptionDetails) { | |
76 if (!result || !!exceptionDetails || !result.preview || result.preview.subty pe !== 'map') { | |
dgozman
2017/01/18 17:02:39
Don't use preview:
- subtype is available in Remot
einbinder
2017/01/19 01:20:40
Done.
| |
77 fufill([]); | |
78 return; | |
79 } | |
80 | |
81 var caseSensitivePrefix = []; | |
82 var caseInsensitivePrefix = []; | |
83 var caseSensitiveAnywhere = []; | |
84 var caseInsensitiveAnywhere = []; | |
85 var qouteChar = '"'; | |
86 if (query.startsWith('\'')) | |
87 qouteChar = '\''; | |
88 var endChar = ')'; | |
89 if (mapMatch[0].indexOf('s') !== -1) | |
90 endChar = ', '; | |
91 var keys = result.preview.entries.filter(entry => entry.key.type === 'string ') | |
92 .map(entry => entry.key.description) | |
93 .sort(String.naturalOrderComparator) | |
94 .map(key => qouteChar + key + qouteChar + endChar); | |
95 | |
96 for (var key of keys) { | |
97 if (key.length < query.length) | |
98 continue; | |
99 if (query.length && key.toLowerCase().indexOf(query.toLowerCase()) === -1) | |
100 continue; | |
101 // Substitute actual newlines with newline characters. @see crbug.com/4984 21 | |
102 var title = key.split('\n').join('\\n'); | |
103 | |
104 if (key.startsWith(query)) | |
105 caseSensitivePrefix.push({title: title, priority: 4}); | |
106 else if (key.toLowerCase().startsWith(query.toLowerCase())) | |
107 caseInsensitivePrefix.push({title: title, priority: 3}); | |
108 else if (key.indexOf(query) !== -1) | |
109 caseSensitiveAnywhere.push({title: title, priority: 2}); | |
110 else | |
111 caseInsensitiveAnywhere.push({title: title, priority: 1}); | |
112 } | |
113 var suggestions = caseSensitivePrefix.concat(caseInsensitivePrefix, caseSens itiveAnywhere, caseInsensitiveAnywhere); | |
114 if (suggestions.length) | |
115 suggestions[0].subtitle = 'Keys'; | |
116 fufill(suggestions); | |
117 } | |
118 }; | |
119 | |
120 /** | |
46 * @param {string} expressionString | 121 * @param {string} expressionString |
47 * @param {string} query | 122 * @param {string} query |
48 * @param {boolean=} force | 123 * @param {boolean=} force |
49 * @return {!Promise<!UI.SuggestBox.Suggestions>} | 124 * @return {!Promise<!UI.SuggestBox.Suggestions>} |
50 */ | 125 */ |
51 Components.JavaScriptAutocomplete.completionsForExpression = function(expression String, query, force) { | 126 Components.JavaScriptAutocomplete.completionsForExpression = function(expression String, query, force) { |
52 var executionContext = UI.context.flavor(SDK.ExecutionContext); | 127 var executionContext = UI.context.flavor(SDK.ExecutionContext); |
53 if (!executionContext) | 128 if (!executionContext) |
54 return Promise.resolve([]); | 129 return Promise.resolve([]); |
55 | 130 |
(...skipping 285 matching lines...) Loading... | |
341 function itemComparator(a, b) { | 416 function itemComparator(a, b) { |
342 var aStartsWithUnderscore = a.startsWith('_'); | 417 var aStartsWithUnderscore = a.startsWith('_'); |
343 var bStartsWithUnderscore = b.startsWith('_'); | 418 var bStartsWithUnderscore = b.startsWith('_'); |
344 if (aStartsWithUnderscore && !bStartsWithUnderscore) | 419 if (aStartsWithUnderscore && !bStartsWithUnderscore) |
345 return 1; | 420 return 1; |
346 if (bStartsWithUnderscore && !aStartsWithUnderscore) | 421 if (bStartsWithUnderscore && !aStartsWithUnderscore) |
347 return -1; | 422 return -1; |
348 return String.naturalOrderComparator(a, b); | 423 return String.naturalOrderComparator(a, b); |
349 } | 424 } |
350 }; | 425 }; |
OLD | NEW |