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

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js

Issue 2637593002: DevTools: Autocomplete CSS variables in StylesSidebar (Closed)
Patch Set: Use cascade 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 unified diff | Download patch
« no previous file with comments | « third_party/WebKit/LayoutTests/inspector/elements/styles-3/style-autocomplete-expected.txt ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2007 Apple Inc. All rights reserved. 2 * Copyright (C) 2007 Apple Inc. All rights reserved.
3 * Copyright (C) 2009 Joseph Pecoraro 3 * Copyright (C) 2009 Joseph Pecoraro
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 8 *
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 2335 matching lines...) Expand 10 before | Expand all | Expand 10 after
2346 2346
2347 var applyItemCallback = !isEditingName ? this._applyFreeFlowStyleTextEdit.bi nd(this) : undefined; 2347 var applyItemCallback = !isEditingName ? this._applyFreeFlowStyleTextEdit.bi nd(this) : undefined;
2348 var cssCompletions = []; 2348 var cssCompletions = [];
2349 if (isEditingName) { 2349 if (isEditingName) {
2350 cssCompletions = SDK.cssMetadata().allProperties(); 2350 cssCompletions = SDK.cssMetadata().allProperties();
2351 cssCompletions = 2351 cssCompletions =
2352 cssCompletions.filter(property => SDK.cssMetadata().isSVGProperty(prop erty) === this.node().isSVGNode()); 2352 cssCompletions.filter(property => SDK.cssMetadata().isSVGProperty(prop erty) === this.node().isSVGNode());
2353 } else { 2353 } else {
2354 cssCompletions = SDK.cssMetadata().propertyValues(this.nameElement.textCon tent); 2354 cssCompletions = SDK.cssMetadata().propertyValues(this.nameElement.textCon tent);
2355 } 2355 }
2356 var cssVariables = [];
lushnikov 2017/01/24 01:35:03 nit: this makes sense as a method on MatchedStyles
einbinder 2017/02/03 01:51:54 Done.
2357 for (var style of this._matchedStyles.nodeStyles()) {
2358 for (var property of style.allProperties) {
2359 if (property.name.startsWith('--'))
2360 cssVariables.push(property.name);
2361 }
2362 }
2363 cssVariables.sort(String.naturalOrderComparator);
2356 2364
2357 this._prompt = new Elements.StylesSidebarPane.CSSPropertyPrompt(cssCompletio ns, this, isEditingName); 2365 this._prompt = new Elements.StylesSidebarPane.CSSPropertyPrompt(cssCompletio ns, cssVariables, this, isEditingName);
2358 this._prompt.setAutocompletionTimeout(0); 2366 this._prompt.setAutocompletionTimeout(0);
2359 if (applyItemCallback) { 2367 if (applyItemCallback) {
2360 this._prompt.addEventListener(UI.TextPrompt.Events.ItemApplied, applyItemC allback, this); 2368 this._prompt.addEventListener(UI.TextPrompt.Events.ItemApplied, applyItemC allback, this);
2361 this._prompt.addEventListener(UI.TextPrompt.Events.ItemAccepted, applyItem Callback, this); 2369 this._prompt.addEventListener(UI.TextPrompt.Events.ItemAccepted, applyItem Callback, this);
2362 } 2370 }
2363 var proxyElement = this._prompt.attachAndStartEditing(selectElement, blurLis tener.bind(this, context)); 2371 var proxyElement = this._prompt.attachAndStartEditing(selectElement, blurLis tener.bind(this, context));
2364 this._navigateToSource(selectElement, true); 2372 this._navigateToSource(selectElement, true);
2365 2373
2366 proxyElement.addEventListener('keydown', this._editingNameValueKeyDown.bind( this, context), false); 2374 proxyElement.addEventListener('keydown', this._editingNameValueKeyDown.bind( this, context), false);
2367 proxyElement.addEventListener('keypress', this._editingNameValueKeyPress.bin d(this, context), false); 2375 proxyElement.addEventListener('keypress', this._editingNameValueKeyPress.bin d(this, context), false);
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after
2753 2761
2754 /** @typedef {{expanded: boolean, hasChildren: boolean, isEditingName: boolean, previousContent: string}} */ 2762 /** @typedef {{expanded: boolean, hasChildren: boolean, isEditingName: boolean, previousContent: string}} */
2755 Elements.StylePropertyTreeElement.Context; 2763 Elements.StylePropertyTreeElement.Context;
2756 2764
2757 /** 2765 /**
2758 * @unrestricted 2766 * @unrestricted
2759 */ 2767 */
2760 Elements.StylesSidebarPane.CSSPropertyPrompt = class extends UI.TextPrompt { 2768 Elements.StylesSidebarPane.CSSPropertyPrompt = class extends UI.TextPrompt {
2761 /** 2769 /**
2762 * @param {!Array<string>} cssCompletions 2770 * @param {!Array<string>} cssCompletions
2771 * @param {!Array<string>} cssVariables
2763 * @param {!Elements.StylePropertyTreeElement} treeElement 2772 * @param {!Elements.StylePropertyTreeElement} treeElement
2764 * @param {boolean} isEditingName 2773 * @param {boolean} isEditingName
2765 */ 2774 */
2766 constructor(cssCompletions, treeElement, isEditingName) { 2775 constructor(cssCompletions, cssVariables, treeElement, isEditingName) {
2767 // Use the same callback both for applyItemCallback and acceptItemCallback. 2776 // Use the same callback both for applyItemCallback and acceptItemCallback.
2768 super(); 2777 super();
2769 this.initialize(this._buildPropertyCompletions.bind(this), UI.StyleValueDeli miters); 2778 this.initialize(this._buildPropertyCompletions.bind(this), UI.StyleValueDeli miters);
2770 this._cssCompletions = cssCompletions; 2779 this._cssCompletions = cssCompletions;
2780 this._cssVariables = cssVariables;
2771 this._treeElement = treeElement; 2781 this._treeElement = treeElement;
2772 this._isEditingName = isEditingName; 2782 this._isEditingName = isEditingName;
2773 2783
2774 if (!isEditingName) { 2784 if (!isEditingName) {
2775 this.disableDefaultSuggestionForEmptyInput(); 2785 this.disableDefaultSuggestionForEmptyInput();
2776 2786
2777 // If a CSS value is being edited that has a numeric or hex substring, hin t that precision modifier shortcuts are available. 2787 // If a CSS value is being edited that has a numeric or hex substring, hin t that precision modifier shortcuts are available.
2778 if (treeElement && treeElement.valueElement) { 2788 if (treeElement && treeElement.valueElement) {
2779 var cssValueText = treeElement.valueElement.textContent; 2789 var cssValueText = treeElement.valueElement.textContent;
2780 if (cssValueText.match(/#[\da-f]{3,6}$/i)) { 2790 if (cssValueText.match(/#[\da-f]{3,6}$/i)) {
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
2880 } 2890 }
2881 2891
2882 /** 2892 /**
2883 * @param {string} word 2893 * @param {string} word
2884 * @return {boolean} 2894 * @return {boolean}
2885 */ 2895 */
2886 _isValueSuggestion(word) { 2896 _isValueSuggestion(word) {
2887 if (!word) 2897 if (!word)
2888 return false; 2898 return false;
2889 word = word.toLowerCase(); 2899 word = word.toLowerCase();
2890 return this._cssCompletions.indexOf(word) !== -1; 2900 return this._cssCompletions.indexOf(word) !== -1 || word.startsWith('--');
2891 } 2901 }
2892 2902
2893 /** 2903 /**
2894 * @param {string} expression 2904 * @param {string} expression
2895 * @param {string} query 2905 * @param {string} query
2896 * @param {boolean=} force 2906 * @param {boolean=} force
2897 * @return {!Promise<!UI.SuggestBox.Suggestions>} 2907 * @return {!Promise<!UI.SuggestBox.Suggestions>}
2898 */ 2908 */
2899 _buildPropertyCompletions(expression, query, force) { 2909 _buildPropertyCompletions(expression, query, force) {
2900 var lowerQuery = query.toLowerCase(); 2910 var lowerQuery = query.toLowerCase();
2901 if (!query && !force && (this._isEditingName || expression)) 2911 var editingName = this._isEditingName;
lushnikov 2017/01/24 01:35:03 nit: i understand this is to avoid binding of filt
einbinder 2017/02/03 01:51:54 Done.
2912 var editingVariable = expression.trim().endsWith('var(');
lushnikov 2017/01/24 01:35:03 nit: let's move this down to where it is actually
einbinder 2017/02/03 01:51:54 It is used in the next line.
2913 if (!query && !force && !editingVariable && (editingName || expression))
2902 return Promise.resolve([]); 2914 return Promise.resolve([]);
2903 2915
2904 var prefixResults = []; 2916 var prefixResults = [];
2905 var anywhereResults = []; 2917 var anywhereResults = [];
2906 this._cssCompletions.forEach(filterCompletions.bind(this)); 2918 if (!editingVariable)
lushnikov 2017/01/24 01:35:04 should it be: if (editingVariable) this._cssV
einbinder 2017/02/03 01:51:54 When we are editing the name, we want to show both
2919 this._cssCompletions.forEach(filterCompletions);
2920
2921 if (editingName || editingVariable)
2922 this._cssVariables.forEach(filterCompletions);
2907 var results = prefixResults.concat(anywhereResults); 2923 var results = prefixResults.concat(anywhereResults);
2908 2924 if (!editingName && !results.length && query.length > 1 && '!important'.star tsWith(lowerQuery))
2909 if (!this._isEditingName && !results.length && query.length > 1 && '!importa nt'.startsWith(lowerQuery))
2910 results.push({title: '!important'}); 2925 results.push({title: '!important'});
2911 var userEnteredText = query.replace('-', ''); 2926 var userEnteredText = query.replace('-', '');
2912 if (userEnteredText && (userEnteredText === userEnteredText.toUpperCase())) { 2927 if (userEnteredText && (userEnteredText === userEnteredText.toUpperCase())) {
2913 for (var i = 0; i < results.length; ++i) 2928 for (var i = 0; i < results.length; ++i) {
2914 results[i].title = results[i].title.toUpperCase(); 2929 if (!results[i].title.startsWith('--'))
2930 results[i].title = results[i].title.toUpperCase();
2931 }
2915 } 2932 }
2933 if (editingVariable)
2934 results.forEach(result => result.title += ')');
2916 return Promise.resolve(results); 2935 return Promise.resolve(results);
2917 2936
2918 /** 2937 /**
2919 * @param {string} completion 2938 * @param {string} completion
2920 * @this {Elements.StylesSidebarPane.CSSPropertyPrompt}
2921 */ 2939 */
2922 function filterCompletions(completion) { 2940 function filterCompletions(completion) {
2923 var index = completion.indexOf(lowerQuery); 2941 var index = completion.toLowerCase().indexOf(lowerQuery);
2924 if (index === 0) { 2942 if (index === 0) {
2925 var priority = this._isEditingName ? SDK.cssMetadata().propertyUsageWeig ht(completion) : 1; 2943 var priority = editingName ? SDK.cssMetadata().propertyUsageWeight(compl etion) : 1;
2926 prefixResults.push({title: completion, priority: priority}); 2944 prefixResults.push({title: completion, priority: priority});
2927 } else if (index > -1) { 2945 } else if (index > -1) {
2928 anywhereResults.push({title: completion}); 2946 anywhereResults.push({title: completion});
2929 } 2947 }
2930 } 2948 }
2931 } 2949 }
2932 }; 2950 };
2933 2951
2934 /** 2952 /**
2935 * @unrestricted 2953 * @unrestricted
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
3080 } 3098 }
3081 3099
3082 /** 3100 /**
3083 * @override 3101 * @override
3084 * @return {!UI.ToolbarItem} 3102 * @return {!UI.ToolbarItem}
3085 */ 3103 */
3086 item() { 3104 item() {
3087 return this._button; 3105 return this._button;
3088 } 3106 }
3089 }; 3107 };
OLDNEW
« no previous file with comments | « third_party/WebKit/LayoutTests/inspector/elements/styles-3/style-autocomplete-expected.txt ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698