Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(782)

Unified Diff: third_party/WebKit/Source/devtools/front_end/components/JavaScriptAutocomplete.js

Issue 2639703002: DevTools: Console: Provide autocompletions for Maps (Closed)
Patch Set: doc Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/devtools/front_end/components/JavaScriptAutocomplete.js
diff --git a/third_party/WebKit/Source/devtools/front_end/components/JavaScriptAutocomplete.js b/third_party/WebKit/Source/devtools/front_end/components/JavaScriptAutocomplete.js
index b9aad4f0374aa194fbc76020491617051507f0b3..b74b3ae96889ceeda02d323cf8e7a2da18f75fdf 100644
--- a/third_party/WebKit/Source/devtools/front_end/components/JavaScriptAutocomplete.js
+++ b/third_party/WebKit/Source/devtools/front_end/components/JavaScriptAutocomplete.js
@@ -14,13 +14,24 @@ Components.JavaScriptAutocomplete.CompletionGroup;
* @return {!Promise<!UI.SuggestBox.Suggestions>}
*/
Components.JavaScriptAutocomplete.completionsForTextInCurrentContext = function(text, query, force) {
+ var clippedExpression = Components.JavaScriptAutocomplete._clipExpression(text, true);
+ var mapCompletionsPromise = Components.JavaScriptAutocomplete._mapCompletions(text, query);
+ return Components.JavaScriptAutocomplete.completionsForExpression(clippedExpression, query, force)
+ .then(completions => mapCompletionsPromise.then(mapCompletions => mapCompletions.concat(completions)));
+};
+
+/**
+ * @param {string} text
+ * @param {boolean=} allowEndingBracket
+ * @return {string}
+ */
+Components.JavaScriptAutocomplete._clipExpression = function(text, allowEndingBracket) {
dgozman 2017/01/20 00:30:32 You always pass |true| as a second parameter.
einbinder 2017/01/23 22:40:53 Fixed.
var index;
var stopChars = new Set('=:({;,!+-*/&|^<>`'.split(''));
var whiteSpaceChars = new Set(' \r\n\t'.split(''));
var continueChars = new Set('[. \r\n\t'.split(''));
for (index = text.length - 1; index >= 0; index--) {
- // Pass less stop characters to rangeOfWord so the range will be a more complete expression.
if (stopChars.has(text.charAt(index)))
break;
if (whiteSpaceChars.has(text.charAt(index)) && !continueChars.has(text.charAt(index - 1)))
@@ -35,16 +46,111 @@ Components.JavaScriptAutocomplete.completionsForTextInCurrentContext = function(
if (character === ']')
bracketCount++;
// Allow an open bracket at the end for property completion.
- if (character === '[' && index < clippedExpression.length - 1) {
+ if (character === '[' && (index < clippedExpression.length - 1 || !allowEndingBracket)) {
bracketCount--;
if (bracketCount < 0)
break;
}
index--;
}
- clippedExpression = clippedExpression.substring(index + 1).trim();
+ return clippedExpression.substring(index + 1).trim();
+};
+
+/**
+ * @param {string} text
+ * @param {string} query
+ * @return {!Promise<!UI.SuggestBox.Suggestions>}
+ */
+Components.JavaScriptAutocomplete._mapCompletions = function(text, query) {
+ var mapMatch = text.match(/\.\s*[gs]et\s*\(\s*$/);
dgozman 2017/01/20 00:30:32 Support delete as well.
einbinder 2017/01/23 22:40:53 Done.
+ var executionContext = UI.context.flavor(SDK.ExecutionContext);
+ if (!executionContext || !mapMatch)
+ return Promise.resolve([]);
+
+ var clippedExpression = Components.JavaScriptAutocomplete._clipExpression(text.substring(0, mapMatch.index), true);
+ var fufill;
dgozman 2017/01/20 00:30:32 typo: fufill
einbinder 2017/01/23 22:40:54 Done.
+ var promise = new Promise(x => fufill = x);
+ executionContext.evaluate(clippedExpression, 'completion', true, true, false, false, false, evaluated);
+ return promise;
+
+ /**
+ * @param {?SDK.RemoteObject} result
+ * @param {!Protocol.Runtime.ExceptionDetails=} exceptionDetails
+ */
+ function evaluated(result, exceptionDetails) {
+ if (!result || !!exceptionDetails || result.subtype !== 'map') {
+ fufill([]);
+ return;
+ }
+ result.getOwnPropertiesPromise().then(extractEntriesProperty);
+ }
+
+ /**
+ * @param {!{properties: ?Array<!SDK.RemoteObjectProperty>, internalProperties: ?Array<!SDK.RemoteObjectProperty>}} properties
+ */
+ function extractEntriesProperty(properties) {
+ var internalProperties = properties.internalProperties || [];
+ var entriesProperty = internalProperties.find(property => property.name === '[[Entries]]');
+ if (!entriesProperty) {
+ fufill([]);
+ return;
+ }
+ entriesProperty.value.callFunctionJSONPromise(getEntries).then(keysObj => gotKeys(Object.keys(keysObj)));
+ }
- return Components.JavaScriptAutocomplete.completionsForExpression(clippedExpression, query, force);
+ /**
+ * @suppressReceiverCheck
+ * @this {!Array<{key:?, value:?}>}
+ * @return {!Object}
+ */
+ function getEntries() {
+ var result = {__proto__: null};
+ for (var i = 0; i < this.length; i++) {
+ if (typeof this[i].key === 'string')
+ result[this[i].key] = true;
+ }
+ return result;
+ }
+
+ /**
+ * @param {!Array<string>} rawKeys
+ */
+ function gotKeys(rawKeys) {
+ var caseSensitivePrefix = [];
+ var caseInsensitivePrefix = [];
+ var caseSensitiveAnywhere = [];
+ var caseInsensitiveAnywhere = [];
+ var quoteChar = '"';
+ if (query.startsWith('\''))
+ quoteChar = '\'';
+ var endChar = ')';
+ if (mapMatch[0].indexOf('s') !== -1)
+ endChar = ', ';
+
+ var keys = rawKeys.sort(String.naturalOrderComparator).map(key => quoteChar + key + quoteChar + endChar);
+
+ for (var key of keys) {
+ if (key.length < query.length)
+ continue;
+ if (query.length && key.toLowerCase().indexOf(query.toLowerCase()) === -1)
+ continue;
+ // Substitute actual newlines with newline characters. @see crbug.com/498421
+ var title = key.split('\n').join('\\n');
+
+ if (key.startsWith(query))
+ caseSensitivePrefix.push({title: title, priority: 4});
+ else if (key.toLowerCase().startsWith(query.toLowerCase()))
+ caseInsensitivePrefix.push({title: title, priority: 3});
+ else if (key.indexOf(query) !== -1)
+ caseSensitiveAnywhere.push({title: title, priority: 2});
+ else
+ caseInsensitiveAnywhere.push({title: title, priority: 1});
+ }
+ var suggestions = caseSensitivePrefix.concat(caseInsensitivePrefix, caseSensitiveAnywhere, caseInsensitiveAnywhere);
+ if (suggestions.length)
+ suggestions[0].subtitle = 'Keys';
dgozman 2017/01/20 00:30:32 UIString('Keys')
einbinder 2017/01/23 22:40:54 Done.
+ fufill(suggestions);
+ }
};
/**

Powered by Google App Engine
This is Rietveld 408576698