From 7f25d63281af50e86045153f206ef51835f1fa6f Mon Sep 17 00:00:00 2001 From: Sarah Childs Date: Tue, 3 Apr 2018 20:32:22 -0400 Subject: [PATCH] Bug 1431949 - Show variable values in the CSS variable autocomplete popup. r=jdescottes --- devtools/client/shared/autocomplete-popup.js | 23 +++++++++- devtools/client/shared/inplace-editor.js | 18 +++++++- ...nplace-editor_autocomplete_css_variable.js | 43 ++++++++++--------- .../shared/test/helper_inplace_editor.js | 11 ++++- devtools/client/themes/common.css | 6 +++ 5 files changed, 78 insertions(+), 23 deletions(-) diff --git a/devtools/client/shared/autocomplete-popup.js b/devtools/client/shared/autocomplete-popup.js index 0ac7bac851ce..bed81a9eb514 100644 --- a/devtools/client/shared/autocomplete-popup.js +++ b/devtools/client/shared/autocomplete-popup.js @@ -254,10 +254,16 @@ AutocompletePopup.prototype = { } let max = 0; - for (let {label, count} of this.items) { + + for (let {label, postLabel, count} of this.items) { if (count) { label += count + ""; } + + if (postLabel) { + label += postLabel; + } + max = Math.max(label.length, max); } @@ -422,6 +428,9 @@ AutocompletePopup.prototype = { * that will be auto completed. When this property is * present, |preLabel.length| starting characters will be * removed from label. + * - postLabel {String} [Optional] The string that will be displayed + * after the label. Currently used to display the value of + * a desired variable. * - count {Number} [Optional] The number to represent the count of * autocompleted label. */ @@ -431,12 +440,15 @@ AutocompletePopup.prototype = { listItem.setAttribute("id", "autocomplete-item-" + itemIdCounter++); listItem.className = "autocomplete-item"; listItem.setAttribute("data-index", this.items.length); + if (this.direction) { listItem.setAttribute("dir", this.direction); } + let label = this._document.createElementNS(HTML_NS, "span"); label.textContent = item.label; label.className = "autocomplete-value"; + if (item.preLabel) { let preDesc = this._document.createElementNS(HTML_NS, "span"); preDesc.textContent = item.preLabel; @@ -444,7 +456,16 @@ AutocompletePopup.prototype = { listItem.appendChild(preDesc); label.textContent = item.label.slice(item.preLabel.length); } + listItem.appendChild(label); + + if (item.postLabel) { + let postDesc = this._document.createElementNS(HTML_NS, "span"); + postDesc.textContent = item.postLabel; + postDesc.className = "autocomplete-postlabel"; + listItem.appendChild(postDesc); + } + if (item.count && item.count > 1) { let countDesc = this._document.createElementNS(HTML_NS, "span"); countDesc.textContent = item.count; diff --git a/devtools/client/shared/inplace-editor.js b/devtools/client/shared/inplace-editor.js index b21b6c9ee934..2c48d39a950a 100644 --- a/devtools/client/shared/inplace-editor.js +++ b/devtools/client/shared/inplace-editor.js @@ -1332,7 +1332,10 @@ InplaceEditor.prototype = { return; } } + let list = []; + let postLabelValues = []; + if (this.contentType == CONTENT_TYPES.CSS_PROPERTY) { list = this._getCSSPropertyList(); } else if (this.contentType == CONTENT_TYPES.CSS_VALUE) { @@ -1350,6 +1353,7 @@ InplaceEditor.prototype = { if (varMatch && varMatch.length == 2) { startCheckQuery = varMatch[1]; list = this._getCSSVariableNames(); + postLabelValues = list.map(varName => this._getCSSVariableValue(varName)); } else { list = ["!important", ...this._getCSSValuesForPropertyName(this.property.name)]; @@ -1415,7 +1419,8 @@ InplaceEditor.prototype = { count++; finalList.push({ preLabel: startCheckQuery, - label: list[i] + label: list[i], + postLabel: postLabelValues[i] ? postLabelValues[i] : "" }); } else if (count > 0) { // Since count was incremented, we had already crossed the entries @@ -1518,6 +1523,17 @@ InplaceEditor.prototype = { _getCSSVariableNames: function() { return Array.from(this.cssVariables.keys()).sort(); }, + + /** + * Returns the variable's value for the given CSS variable name. + * + * @param {String} varName + * The variable name to retrieve the value of + * @return {String} the variable value to the given CSS variable name + */ + _getCSSVariableValue: function(varName) { + return this.cssVariables.get(varName); + }, }; /** diff --git a/devtools/client/shared/test/browser_inplace-editor_autocomplete_css_variable.js b/devtools/client/shared/test/browser_inplace-editor_autocomplete_css_variable.js index 02fc38fe38e4..3974479ffab0 100644 --- a/devtools/client/shared/test/browser_inplace-editor_autocomplete_css_variable.js +++ b/devtools/client/shared/test/browser_inplace-editor_autocomplete_css_variable.js @@ -21,34 +21,37 @@ loadHelperScript("helper_inplace_editor.js"); // expected input box value after keypress, // selected suggestion index (-1 if popup is hidden), // number of suggestions in the popup (0 if popup is hidden), +// expected post label corresponding with the input box value, // ] const testData = [ - ["v", "v", -1, 0], - ["a", "va", -1, 0], - ["r", "var", -1, 0], - ["(", "var(", -1, 0], - ["-", "var(--abc", 0, 2], - ["VK_BACK_SPACE", "var(-", -1, 0], - ["-", "var(--abc", 0, 2], - ["VK_DOWN", "var(--def", 1, 2], - ["VK_DOWN", "var(--abc", 0, 2], - ["VK_LEFT", "var(--abc", -1, 0], + ["v", "v", -1, 0, null], + ["a", "va", -1, 0, null], + ["r", "var", -1, 0, null], + ["(", "var(", -1, 0, null], + ["-", "var(--abc", 0, 4, "blue"], + ["VK_BACK_SPACE", "var(-", -1, 0, null], + ["-", "var(--abc", 0, 4, "blue"], + ["VK_DOWN", "var(--def", 1, 4, "red"], + ["VK_DOWN", "var(--ghi", 2, 4, "green"], + ["VK_DOWN", "var(--jkl", 3, 4, "yellow"], + ["VK_DOWN", "var(--abc", 0, 4, "blue"], + ["VK_DOWN", "var(--def", 1, 4, "red"], + ["VK_LEFT", "var(--def", -1, 0, null], +]; + +const CSS_VARIABLES = [ + ["--abc", "blue"], + ["--def", "red"], + ["--ghi", "green"], + ["--jkl", "yellow"] ]; const mockGetCSSValuesForPropertyName = function(propertyName) { return []; }; -const mockGetCSSVariableNames = function() { - return [ - "--abc", - "--def", - ]; -}; - add_task(async function() { - await addTab("data:text/html;charset=utf-8," + - "inplace editor CSS variable autocomplete"); + await addTab("data:text/html;charset=utf-8,inplace editor CSS variable autocomplete"); let [host, win, doc] = await createHost(); let xulDocument = win.top.document; @@ -61,6 +64,7 @@ add_task(async function() { property: { name: "color" }, + cssVariables: new Map(CSS_VARIABLES), done: resolve, popup: popup }, doc); @@ -74,7 +78,6 @@ add_task(async function() { let runAutocompletionTest = async function(editor) { info("Starting to test for css variable completion"); editor._getCSSValuesForPropertyName = mockGetCSSValuesForPropertyName; - editor._getCSSVariableNames = mockGetCSSVariableNames; for (let data of testData) { await testCompletion(data, editor); diff --git a/devtools/client/shared/test/helper_inplace_editor.js b/devtools/client/shared/test/helper_inplace_editor.js index fe78d0705353..09e6cf2be2d0 100644 --- a/devtools/client/shared/test/helper_inplace_editor.js +++ b/devtools/client/shared/test/helper_inplace_editor.js @@ -72,10 +72,11 @@ function createSpan(doc) { * - {String} completion, the expected value of the auto-completion * - {Number} index, the index of the selected suggestion in the popup * - {Number} total, the total number of suggestions in the popup + * - {String} postLabel, the expected post label for the selected suggestion * @param {InplaceEditor} editor * The InplaceEditor instance being tested */ -async function testCompletion([key, completion, index, total], editor) { +async function testCompletion([key, completion, index, total, postLabel], editor) { info("Pressing key " + key); info("Expecting " + completion); @@ -105,6 +106,14 @@ async function testCompletion([key, completion, index, total], editor) { if (completion !== null) { is(editor.input.value, completion, "Correct value is autocompleted"); } + + if (postLabel) { + let selectedItem = editor.popup.getItems()[index]; + let selectedElement = editor.popup.elements.get(selectedItem); + ok(selectedElement.textContent.includes(postLabel), + "Selected popup element contains the expected post-label"); + } + if (total === 0) { ok(!(editor.popup && editor.popup.isOpen), "Popup is closed"); } else { diff --git a/devtools/client/themes/common.css b/devtools/client/themes/common.css index 0846bdc4e732..03c9a43adda8 100644 --- a/devtools/client/themes/common.css +++ b/devtools/client/themes/common.css @@ -101,6 +101,12 @@ html|button, html|select { .devtools-autocomplete-listbox .autocomplete-item > .autocomplete-value { margin: 0; padding: 0; + float: left; +} + +.devtools-autocomplete-listbox .autocomplete-item > .autocomplete-postlabel { + font-style: italic; + float: right; } .devtools-autocomplete-listbox .autocomplete-item > .autocomplete-count {