зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1431949 - Show variable values in the CSS variable autocomplete popup. r=jdescottes
This commit is contained in:
Родитель
9bd4654613
Коммит
7f25d63281
|
@ -254,10 +254,16 @@ AutocompletePopup.prototype = {
|
||||||
}
|
}
|
||||||
|
|
||||||
let max = 0;
|
let max = 0;
|
||||||
for (let {label, count} of this.items) {
|
|
||||||
|
for (let {label, postLabel, count} of this.items) {
|
||||||
if (count) {
|
if (count) {
|
||||||
label += count + "";
|
label += count + "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (postLabel) {
|
||||||
|
label += postLabel;
|
||||||
|
}
|
||||||
|
|
||||||
max = Math.max(label.length, max);
|
max = Math.max(label.length, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -422,6 +428,9 @@ AutocompletePopup.prototype = {
|
||||||
* that will be auto completed. When this property is
|
* that will be auto completed. When this property is
|
||||||
* present, |preLabel.length| starting characters will be
|
* present, |preLabel.length| starting characters will be
|
||||||
* removed from label.
|
* 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
|
* - count {Number} [Optional] The number to represent the count of
|
||||||
* autocompleted label.
|
* autocompleted label.
|
||||||
*/
|
*/
|
||||||
|
@ -431,12 +440,15 @@ AutocompletePopup.prototype = {
|
||||||
listItem.setAttribute("id", "autocomplete-item-" + itemIdCounter++);
|
listItem.setAttribute("id", "autocomplete-item-" + itemIdCounter++);
|
||||||
listItem.className = "autocomplete-item";
|
listItem.className = "autocomplete-item";
|
||||||
listItem.setAttribute("data-index", this.items.length);
|
listItem.setAttribute("data-index", this.items.length);
|
||||||
|
|
||||||
if (this.direction) {
|
if (this.direction) {
|
||||||
listItem.setAttribute("dir", this.direction);
|
listItem.setAttribute("dir", this.direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
let label = this._document.createElementNS(HTML_NS, "span");
|
let label = this._document.createElementNS(HTML_NS, "span");
|
||||||
label.textContent = item.label;
|
label.textContent = item.label;
|
||||||
label.className = "autocomplete-value";
|
label.className = "autocomplete-value";
|
||||||
|
|
||||||
if (item.preLabel) {
|
if (item.preLabel) {
|
||||||
let preDesc = this._document.createElementNS(HTML_NS, "span");
|
let preDesc = this._document.createElementNS(HTML_NS, "span");
|
||||||
preDesc.textContent = item.preLabel;
|
preDesc.textContent = item.preLabel;
|
||||||
|
@ -444,7 +456,16 @@ AutocompletePopup.prototype = {
|
||||||
listItem.appendChild(preDesc);
|
listItem.appendChild(preDesc);
|
||||||
label.textContent = item.label.slice(item.preLabel.length);
|
label.textContent = item.label.slice(item.preLabel.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
listItem.appendChild(label);
|
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) {
|
if (item.count && item.count > 1) {
|
||||||
let countDesc = this._document.createElementNS(HTML_NS, "span");
|
let countDesc = this._document.createElementNS(HTML_NS, "span");
|
||||||
countDesc.textContent = item.count;
|
countDesc.textContent = item.count;
|
||||||
|
|
|
@ -1332,7 +1332,10 @@ InplaceEditor.prototype = {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let list = [];
|
let list = [];
|
||||||
|
let postLabelValues = [];
|
||||||
|
|
||||||
if (this.contentType == CONTENT_TYPES.CSS_PROPERTY) {
|
if (this.contentType == CONTENT_TYPES.CSS_PROPERTY) {
|
||||||
list = this._getCSSPropertyList();
|
list = this._getCSSPropertyList();
|
||||||
} else if (this.contentType == CONTENT_TYPES.CSS_VALUE) {
|
} else if (this.contentType == CONTENT_TYPES.CSS_VALUE) {
|
||||||
|
@ -1350,6 +1353,7 @@ InplaceEditor.prototype = {
|
||||||
if (varMatch && varMatch.length == 2) {
|
if (varMatch && varMatch.length == 2) {
|
||||||
startCheckQuery = varMatch[1];
|
startCheckQuery = varMatch[1];
|
||||||
list = this._getCSSVariableNames();
|
list = this._getCSSVariableNames();
|
||||||
|
postLabelValues = list.map(varName => this._getCSSVariableValue(varName));
|
||||||
} else {
|
} else {
|
||||||
list = ["!important",
|
list = ["!important",
|
||||||
...this._getCSSValuesForPropertyName(this.property.name)];
|
...this._getCSSValuesForPropertyName(this.property.name)];
|
||||||
|
@ -1415,7 +1419,8 @@ InplaceEditor.prototype = {
|
||||||
count++;
|
count++;
|
||||||
finalList.push({
|
finalList.push({
|
||||||
preLabel: startCheckQuery,
|
preLabel: startCheckQuery,
|
||||||
label: list[i]
|
label: list[i],
|
||||||
|
postLabel: postLabelValues[i] ? postLabelValues[i] : ""
|
||||||
});
|
});
|
||||||
} else if (count > 0) {
|
} else if (count > 0) {
|
||||||
// Since count was incremented, we had already crossed the entries
|
// Since count was incremented, we had already crossed the entries
|
||||||
|
@ -1518,6 +1523,17 @@ InplaceEditor.prototype = {
|
||||||
_getCSSVariableNames: function() {
|
_getCSSVariableNames: function() {
|
||||||
return Array.from(this.cssVariables.keys()).sort();
|
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,
|
// expected input box value after keypress,
|
||||||
// selected suggestion index (-1 if popup is hidden),
|
// selected suggestion index (-1 if popup is hidden),
|
||||||
// number of suggestions in the popup (0 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 = [
|
const testData = [
|
||||||
["v", "v", -1, 0],
|
["v", "v", -1, 0, null],
|
||||||
["a", "va", -1, 0],
|
["a", "va", -1, 0, null],
|
||||||
["r", "var", -1, 0],
|
["r", "var", -1, 0, null],
|
||||||
["(", "var(", -1, 0],
|
["(", "var(", -1, 0, null],
|
||||||
["-", "var(--abc", 0, 2],
|
["-", "var(--abc", 0, 4, "blue"],
|
||||||
["VK_BACK_SPACE", "var(-", -1, 0],
|
["VK_BACK_SPACE", "var(-", -1, 0, null],
|
||||||
["-", "var(--abc", 0, 2],
|
["-", "var(--abc", 0, 4, "blue"],
|
||||||
["VK_DOWN", "var(--def", 1, 2],
|
["VK_DOWN", "var(--def", 1, 4, "red"],
|
||||||
["VK_DOWN", "var(--abc", 0, 2],
|
["VK_DOWN", "var(--ghi", 2, 4, "green"],
|
||||||
["VK_LEFT", "var(--abc", -1, 0],
|
["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) {
|
const mockGetCSSValuesForPropertyName = function(propertyName) {
|
||||||
return [];
|
return [];
|
||||||
};
|
};
|
||||||
|
|
||||||
const mockGetCSSVariableNames = function() {
|
|
||||||
return [
|
|
||||||
"--abc",
|
|
||||||
"--def",
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
add_task(async function() {
|
add_task(async function() {
|
||||||
await addTab("data:text/html;charset=utf-8," +
|
await addTab("data:text/html;charset=utf-8,inplace editor CSS variable autocomplete");
|
||||||
"inplace editor CSS variable autocomplete");
|
|
||||||
let [host, win, doc] = await createHost();
|
let [host, win, doc] = await createHost();
|
||||||
|
|
||||||
let xulDocument = win.top.document;
|
let xulDocument = win.top.document;
|
||||||
|
@ -61,6 +64,7 @@ add_task(async function() {
|
||||||
property: {
|
property: {
|
||||||
name: "color"
|
name: "color"
|
||||||
},
|
},
|
||||||
|
cssVariables: new Map(CSS_VARIABLES),
|
||||||
done: resolve,
|
done: resolve,
|
||||||
popup: popup
|
popup: popup
|
||||||
}, doc);
|
}, doc);
|
||||||
|
@ -74,7 +78,6 @@ add_task(async function() {
|
||||||
let runAutocompletionTest = async function(editor) {
|
let runAutocompletionTest = async function(editor) {
|
||||||
info("Starting to test for css variable completion");
|
info("Starting to test for css variable completion");
|
||||||
editor._getCSSValuesForPropertyName = mockGetCSSValuesForPropertyName;
|
editor._getCSSValuesForPropertyName = mockGetCSSValuesForPropertyName;
|
||||||
editor._getCSSVariableNames = mockGetCSSVariableNames;
|
|
||||||
|
|
||||||
for (let data of testData) {
|
for (let data of testData) {
|
||||||
await testCompletion(data, editor);
|
await testCompletion(data, editor);
|
||||||
|
|
|
@ -72,10 +72,11 @@ function createSpan(doc) {
|
||||||
* - {String} completion, the expected value of the auto-completion
|
* - {String} completion, the expected value of the auto-completion
|
||||||
* - {Number} index, the index of the selected suggestion in the popup
|
* - {Number} index, the index of the selected suggestion in the popup
|
||||||
* - {Number} total, the total number of suggestions 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
|
* @param {InplaceEditor} editor
|
||||||
* The InplaceEditor instance being tested
|
* 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("Pressing key " + key);
|
||||||
info("Expecting " + completion);
|
info("Expecting " + completion);
|
||||||
|
|
||||||
|
@ -105,6 +106,14 @@ async function testCompletion([key, completion, index, total], editor) {
|
||||||
if (completion !== null) {
|
if (completion !== null) {
|
||||||
is(editor.input.value, completion, "Correct value is autocompleted");
|
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) {
|
if (total === 0) {
|
||||||
ok(!(editor.popup && editor.popup.isOpen), "Popup is closed");
|
ok(!(editor.popup && editor.popup.isOpen), "Popup is closed");
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -101,6 +101,12 @@ html|button, html|select {
|
||||||
.devtools-autocomplete-listbox .autocomplete-item > .autocomplete-value {
|
.devtools-autocomplete-listbox .autocomplete-item > .autocomplete-value {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.devtools-autocomplete-listbox .autocomplete-item > .autocomplete-postlabel {
|
||||||
|
font-style: italic;
|
||||||
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
.devtools-autocomplete-listbox .autocomplete-item > .autocomplete-count {
|
.devtools-autocomplete-listbox .autocomplete-item > .autocomplete-count {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче