mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 912189 - Show CSS value autocomplete without waiting for first character, r=mratcliffe
This commit is contained in:
parent
88ee061ba3
commit
39c6ebd12c
@ -33,12 +33,12 @@ const TEST_DATA = [
|
||||
['VK_TAB', 'style="dominant-baseline', 24, 24, true],
|
||||
['VK_TAB', 'style="direction', 16, 16, true],
|
||||
['click_1', 'style="display', 14, 14, false],
|
||||
[':', 'style="display:', 15, 15, false],
|
||||
[':', 'style="display:-moz-box', 15, 23, true],
|
||||
['n', 'style="display:none', 16, 19, false],
|
||||
['VK_BACK_SPACE', 'style="display:n', 16, 16, false],
|
||||
['VK_BACK_SPACE', 'style="display:', 15, 15, false],
|
||||
[' ', 'style="display: ', 16, 16, false],
|
||||
[' ', 'style="display: ', 17, 17, false],
|
||||
[' ', 'style="display: -moz-box', 16, 24, true],
|
||||
[' ', 'style="display: -moz-box', 17, 25, true],
|
||||
['i', 'style="display: inherit', 18, 24, true],
|
||||
['VK_RIGHT', 'style="display: inherit', 24, 24, false],
|
||||
[';', 'style="display: inherit;', 25, 25, false],
|
||||
@ -51,11 +51,11 @@ const TEST_DATA = [
|
||||
[' ', 'style="display: inherit; color ', 32, 32, false],
|
||||
['c', 'style="display: inherit; color c ', 33, 33, false],
|
||||
['VK_BACK_SPACE', 'style="display: inherit; color ', 32, 32, false],
|
||||
[':', 'style="display: inherit; color : ', 33, 33, false],
|
||||
[':', 'style="display: inherit; color :aliceblue ', 33, 42, true],
|
||||
['c', 'style="display: inherit; color :cadetblue ', 34, 42, true],
|
||||
['VK_DOWN', 'style="display: inherit; color :chartreuse ', 34, 43, true],
|
||||
['VK_RIGHT', 'style="display: inherit; color :chartreuse ', 43, 43, false],
|
||||
[' ', 'style="display: inherit; color :chartreuse ', 44, 44, false],
|
||||
[' ', 'style="display: inherit; color :chartreuse !important; ', 44, 55, true],
|
||||
['!', 'style="display: inherit; color :chartreuse !important; ', 45, 55, false],
|
||||
['VK_RIGHT', 'style="display: inherit; color :chartreuse !important; ', 55, 55, false],
|
||||
['VK_RETURN', 'style="display: inherit; color :chartreuse !important;"', -1, -1, false]
|
||||
|
@ -203,6 +203,10 @@ function InplaceEditor(aOptions, aEvent)
|
||||
}
|
||||
this.input.focus();
|
||||
|
||||
if (this.contentType == CONTENT_TYPES.CSS_VALUE && this.input.value == "") {
|
||||
this._maybeSuggestCompletion(true);
|
||||
}
|
||||
|
||||
this.input.addEventListener("blur", this._onBlur, false);
|
||||
this.input.addEventListener("keypress", this._onKeyPress, false);
|
||||
this.input.addEventListener("input", this._onInput, false);
|
||||
@ -853,6 +857,7 @@ InplaceEditor.prototype = {
|
||||
if (increment && this._incrementValue(increment) ) {
|
||||
this._updateSize();
|
||||
prevent = true;
|
||||
cycling = true;
|
||||
} else if (increment && this.popup && this.popup.isOpen) {
|
||||
cycling = true;
|
||||
prevent = true;
|
||||
@ -891,6 +896,12 @@ InplaceEditor.prototype = {
|
||||
|
||||
// Now we don't want to suggest anything as we are moving out.
|
||||
this._preventSuggestions = true;
|
||||
// But we still want to show suggestions for css values. i.e. moving out
|
||||
// of css property input box in forward direction
|
||||
if (this.contentType == CONTENT_TYPES.CSS_PROPERTY &&
|
||||
direction == FOCUS_FORWARD) {
|
||||
this._preventSuggestions = false;
|
||||
}
|
||||
|
||||
let input = this.input;
|
||||
|
||||
@ -992,8 +1003,11 @@ InplaceEditor.prototype = {
|
||||
|
||||
/**
|
||||
* Handles displaying suggestions based on the current input.
|
||||
*
|
||||
* @param {boolean} aNoAutoInsert
|
||||
* true if you don't want to automatically insert the first suggestion
|
||||
*/
|
||||
_maybeSuggestCompletion: function() {
|
||||
_maybeSuggestCompletion: function(aNoAutoInsert) {
|
||||
// Since we are calling this method from a keypress event handler, the
|
||||
// |input.value| does not include currently typed character. Thus we perform
|
||||
// this method async.
|
||||
@ -1013,7 +1027,7 @@ InplaceEditor.prototype = {
|
||||
}
|
||||
let query = input.value.slice(0, input.selectionStart);
|
||||
let startCheckQuery = query;
|
||||
if (!query) {
|
||||
if (query == null) {
|
||||
return;
|
||||
}
|
||||
let list = [];
|
||||
@ -1030,43 +1044,54 @@ InplaceEditor.prototype = {
|
||||
|
||||
list =
|
||||
["!important", ...domUtils.getCSSValuesForProperty(this.property.name)];
|
||||
|
||||
if (query == "") {
|
||||
// Do not suggest '!important' without any manually typed character.
|
||||
list.splice(0, 1);
|
||||
}
|
||||
} else if (this.contentType == CONTENT_TYPES.CSS_MIXED &&
|
||||
/^\s*style\s*=/.test(query)) {
|
||||
// Detecting if cursor is at property or value;
|
||||
let match = query.match(/([:;"'=]?)\s*([^"';:=]+)$/);
|
||||
if (match && match.length == 3) {
|
||||
let match = query.match(/([:;"'=]?)\s*([^"';:=]+)?$/);
|
||||
if (match && match.length >= 2) {
|
||||
if (match[1] == ":") { // We are in CSS value completion
|
||||
let propertyName =
|
||||
query.match(/[;"'=]\s*([^"';:= ]+)\s*:\s*[^"';:=]+$/)[1];
|
||||
query.match(/[;"'=]\s*([^"';:= ]+)\s*:\s*[^"';:=]*$/)[1];
|
||||
list =
|
||||
["!important;", ...domUtils.getCSSValuesForProperty(propertyName)];
|
||||
let matchLastQuery = /([^\s,.\/]+$)/.exec(match[2]);
|
||||
let matchLastQuery = /([^\s,.\/]+$)/.exec(match[2] || "");
|
||||
if (matchLastQuery) {
|
||||
startCheckQuery = matchLastQuery[0];
|
||||
} else {
|
||||
startCheckQuery = "";
|
||||
}
|
||||
if (!match[2]) {
|
||||
// Don't suggest '!important' without any manually typed character
|
||||
list.splice(0, 1);
|
||||
}
|
||||
} else if (match[1]) { // We are in CSS property name completion
|
||||
list = CSSPropertyList;
|
||||
startCheckQuery = match[2];
|
||||
}
|
||||
if (!startCheckQuery) {
|
||||
if (startCheckQuery == null) {
|
||||
// This emit is mainly to make the test flow simpler.
|
||||
this.emit("after-suggest", "nothing to autocomplete");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
list.some(item => {
|
||||
if (startCheckQuery && item.startsWith(startCheckQuery)) {
|
||||
input.value = query + item.slice(startCheckQuery.length) +
|
||||
input.value.slice(query.length);
|
||||
input.setSelectionRange(query.length, query.length + item.length -
|
||||
startCheckQuery.length);
|
||||
this._updateSize();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
if (!aNoAutoInsert) {
|
||||
list.some(item => {
|
||||
if (startCheckQuery != null && item.startsWith(startCheckQuery)) {
|
||||
input.value = query + item.slice(startCheckQuery.length) +
|
||||
input.value.slice(query.length);
|
||||
input.setSelectionRange(query.length, query.length + item.length -
|
||||
startCheckQuery.length);
|
||||
this._updateSize();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!this.popup) {
|
||||
// This emit is mainly to make the test flow simpler.
|
||||
@ -1076,7 +1101,7 @@ InplaceEditor.prototype = {
|
||||
let finalList = [];
|
||||
let length = list.length;
|
||||
for (let i = 0, count = 0; i < length && count < MAX_POPUP_ENTRIES; i++) {
|
||||
if (startCheckQuery && list[i].startsWith(startCheckQuery)) {
|
||||
if (startCheckQuery != null && list[i].startsWith(startCheckQuery)) {
|
||||
count++;
|
||||
finalList.push({
|
||||
preLabel: startCheckQuery,
|
||||
@ -1088,7 +1113,7 @@ InplaceEditor.prototype = {
|
||||
// which would have started with query, assuming that list is sorted.
|
||||
break;
|
||||
}
|
||||
else if (list[i][0] > startCheckQuery[0]) {
|
||||
else if (startCheckQuery != null && list[i][0] > startCheckQuery[0]) {
|
||||
// We have crossed all possible matches alphabetically.
|
||||
break;
|
||||
}
|
||||
@ -1100,6 +1125,9 @@ InplaceEditor.prototype = {
|
||||
this.inputCharWidth;
|
||||
this.popup.setItems(finalList);
|
||||
this.popup.openPopup(this.input, x);
|
||||
if (aNoAutoInsert) {
|
||||
this.popup.selectedIndex = -1;
|
||||
}
|
||||
} else {
|
||||
this.popup.hidePopup();
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ let testData = [
|
||||
["VK_DOWN", {}, "blanchedalmond", 1, 4],
|
||||
["VK_DOWN", {}, "blue", 2, 4],
|
||||
["VK_RIGHT", {}, "blue", -1, 0],
|
||||
[" ", {}, "blue ", -1, 0],
|
||||
[" ", {}, "blue !important", 0, 10],
|
||||
["!", {}, "blue !important", 0, 0],
|
||||
["VK_BACK_SPACE", {}, "blue !", -1, 0],
|
||||
["VK_BACK_SPACE", {}, "blue ", -1, 0],
|
||||
|
@ -23,7 +23,7 @@ let brace;
|
||||
let testData = [
|
||||
["d", {}, "direction", 0, 3],
|
||||
["VK_DOWN", {}, "display", 1, 3],
|
||||
["VK_TAB", {}, "", -1, 0],
|
||||
["VK_TAB", {}, "", -1, 10],
|
||||
["n", {}, "none", -1, 0],
|
||||
["VK_TAB", {shiftKey: true}, "display", -1, 0],
|
||||
["VK_BACK_SPACE", {}, "", -1, 0],
|
||||
@ -36,7 +36,7 @@ let testData = [
|
||||
["VK_DOWN", {}, "rosybrown", 3, 5],
|
||||
["VK_DOWN", {}, "royalblue", 4, 5],
|
||||
["VK_RIGHT", {}, "royalblue", -1, 0],
|
||||
[" ", {}, "royalblue ", -1, 0],
|
||||
[" ", {}, "royalblue !important", 0, 10],
|
||||
["!", {}, "royalblue !important", 0, 0],
|
||||
["VK_ESCAPE", {}, null, -1, 0]
|
||||
];
|
||||
|
Loading…
Reference in New Issue
Block a user