Bug 1431949 - Show variable values in the CSS variable autocomplete popup. r=jdescottes

This commit is contained in:
Sarah Childs 2018-04-03 20:32:22 -04:00
Родитель 9bd4654613
Коммит 7f25d63281
5 изменённых файлов: 78 добавлений и 23 удалений

Просмотреть файл

@ -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;

Просмотреть файл

@ -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);
},
};
/**

Просмотреть файл

@ -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);

Просмотреть файл

@ -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 {

Просмотреть файл

@ -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 {