Backed out changeset 40f323c3c14e -- Style-editor completion broken

This commit is contained in:
Patrick Brosset 2014-05-22 10:44:35 +02:00
Родитель de4be8677c
Коммит 2f97ac1d46
8 изменённых файлов: 46 добавлений и 239 удалений

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

@ -398,12 +398,16 @@ SelectorSearch.prototype = {
/**
* Populates the suggestions list and show the suggestion popup.
*/
_showPopup: function(aList, aFirstPart, aState) {
_showPopup: function(aList, aFirstPart) {
let total = 0;
let query = this.searchBox.value;
let toLowerCase = false;
let items = [];
for (let [value, count, state] of aList) {
// In case of tagNames, change the case to small.
if (query.match(/.*[\.#][^\.#]{0,}$/) == null) {
toLowerCase = true;
}
for (let [value, count] of aList) {
// for cases like 'div ' or 'div >' or 'div+'
if (query.match(/[\s>+]$/)) {
value = query + value;
@ -418,27 +422,14 @@ SelectorSearch.prototype = {
let lastPart = query.match(/[a-zA-Z][#\.][^#\.\s>+]*$/)[0];
value = query.slice(0, -1 * lastPart.length + 1) + value;
}
let item = {
preLabel: query,
label: value,
count: count
};
// In case of tagNames, change te case to small
if (value.match(/.*[\.#][^\.#]{0,}$/) == null) {
if (toLowerCase) {
item.label = value.toLowerCase();
}
// In case the query's state is tag and the item's state is id or class
// adjust the preLabel
if (aState === this.States.TAG && state === this.States.CLASS) {
item.preLabel = "." + item.preLabel;
}
if (aState === this.States.TAG && state === this.States.ID) {
item.preLabel = "#" + item.preLabel;
}
items.unshift(item);
if (++total > MAX_SUGGESTIONS - 1) {
break;
@ -459,21 +450,19 @@ SelectorSearch.prototype = {
*/
showSuggestions: function() {
let query = this.searchBox.value;
let state = this.state;
let firstPart = "";
if (state == this.States.TAG) {
if (this.state == this.States.TAG) {
// gets the tag that is being completed. For ex. 'div.foo > s' returns 's',
// 'di' returns 'di' and likewise.
firstPart = (query.match(/[\s>+]?([a-zA-Z]*)$/) || ["", query])[1];
query = query.slice(0, query.length - firstPart.length);
}
else if (state == this.States.CLASS) {
else if (this.state == this.States.CLASS) {
// gets the class that is being completed. For ex. '.foo.b' returns 'b'
firstPart = query.match(/\.([^\.]*)$/)[1];
query = query.slice(0, query.length - firstPart.length - 1);
}
else if (state == this.States.ID) {
else if (this.state == this.States.ID) {
// gets the id that is being completed. For ex. '.foo#b' returns 'b'
firstPart = query.match(/#([^#]*)$/)[1];
query = query.slice(0, query.length - firstPart.length - 1);
@ -483,24 +472,21 @@ SelectorSearch.prototype = {
if (/[\s+>~]$/.test(query)) {
query += "*";
}
this._currentSuggesting = query;
return this.walker.getSuggestionsForQuery(query, firstPart, state).then(result => {
return this.walker.getSuggestionsForQuery(query, firstPart, this.state).then(result => {
if (this._currentSuggesting != result.query) {
// This means that this response is for a previous request and the user
// as since typed something extra leading to a new request.
return;
}
this._lastToLastValidSearch = this._lastValidSearch;
if (state == this.States.CLASS) {
if (this.state == this.States.CLASS) {
firstPart = "." + firstPart;
}
else if (state == this.States.ID) {
else if (this.state == this.States.ID) {
firstPart = "#" + firstPart;
}
this._showPopup(result.suggestions, firstPart, state);
this._showPopup(result.suggestions, firstPart);
});
}
};

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

@ -50,4 +50,3 @@ support-files =
[browser_inspector_bug_958169_switch_to_inspector_on_pick.js]
[browser_inspector_bug_961771_picker_stops_on_tool_select.js]
[browser_inspector_bug_962478_picker_stops_on_destroy.js]
[browser_inspector_search-suggests-ids-and-classes.js]

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

@ -15,7 +15,7 @@ function test()
// ] count can be left to represent 1
// ]
let keyStates = [
["d", [["div", 4], ["#d1", 1], ["#d2", 1]]],
["d", [["div", 4]]],
["i", [["div", 4]]],
["v", []],
[" ", [["div div", 2], ["div span", 2]]],
@ -25,7 +25,7 @@ function test()
["VK_BACK_SPACE", [["div div", 2], ["div span", 2]]],
["VK_BACK_SPACE", []],
["VK_BACK_SPACE", [["div", 4]]],
["VK_BACK_SPACE", [["div", 4], ["#d1", 1], ["#d2", 1]]],
["VK_BACK_SPACE", [["div", 4]]],
["VK_BACK_SPACE", []],
["p", []],
[" ", [["p strong"]]],

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

@ -15,7 +15,7 @@ function test()
// ] count can be left to represent 1
// ]
let keyStates = [
["d", [["div", 2], ["#d1", 1], ["#d2", 1]]],
["d", [["div", 2]]],
["i", [["div", 2]]],
["v", []],
[".", [["div.c1"]]],
@ -23,7 +23,7 @@ function test()
["#", [["div#d1"], ["div#d2"]]],
["VK_BACK_SPACE", []],
["VK_BACK_SPACE", [["div", 2]]],
["VK_BACK_SPACE", [["div", 2], ["#d1", 1], ["#d2", 1]]],
["VK_BACK_SPACE", [["div", 2]]],
["VK_BACK_SPACE", []],
[".", [[".c1", 3], [".c2"]]],
["c", [[".c1", 3], [".c2"]]],

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

@ -1,125 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Test that the selector-search input proposes ids and classes even when . and
// # is missing, but that this only occurs when the query is one word (no
// selector combination)
function test()
{
waitForExplicitFinish();
let inspector, searchBox, state, popup;
// The various states of the inspector: [key, suggestions array]
// [
// what key to press,
// suggestions array with count [
// [suggestion1, count1], [suggestion2] ...
// ] count can be left to represent 1
// ]
let keyStates = [
["s", [["span", 1], [".span", 1], ["#span", 1]]],
["p", [["span", 1], [".span", 1], ["#span", 1]]],
["a", [["span", 1], [".span", 1], ["#span", 1]]],
["n", []],
[" ", [["span div", 1]]],
["d", [["span div", 1]]], // mixed tag/class/id suggestions only work for the first word
["VK_BACK_SPACE", [["span div", 1]]],
["VK_BACK_SPACE", []],
["VK_BACK_SPACE", [["span", 1], [".span", 1], ["#span", 1]]],
["VK_BACK_SPACE", [["span", 1], [".span", 1], ["#span", 1]]],
["VK_BACK_SPACE", [["span", 1], [".span", 1], ["#span", 1]]],
["VK_BACK_SPACE", []],
// Test that mixed tags, classes and ids are grouped by types, sorted by
// count and alphabetical order
["b", [
["button", 3],
["body", 1],
[".bc", 3],
[".ba", 1],
[".bb", 1],
["#ba", 1],
["#bb", 1],
["#bc", 1]
]],
];
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function onload() {
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
waitForFocus(setupTest, content);
}, true);
content.location = "data:text/html," +
"<span class='span' id='span'>" +
" <div class='div' id='div'></div>" +
"</span>" +
"<button class='ba bc' id='bc'></button>" +
"<button class='bb bc' id='bb'></button>" +
"<button class='bc' id='ba'></button>";
function $(id) {
if (id == null) return null;
return content.document.getElementById(id);
}
function setupTest()
{
openInspector(startTest);
}
function startTest(aInspector)
{
inspector = aInspector;
searchBox =
inspector.panelWin.document.getElementById("inspector-searchbox");
popup = inspector.searchSuggestions.searchPopup;
focusSearchBoxUsingShortcut(inspector.panelWin, function() {
searchBox.addEventListener("command", checkState, true);
checkStateAndMoveOn(0);
});
}
function checkStateAndMoveOn(index) {
if (index == keyStates.length) {
finishUp();
return;
}
let [key, suggestions] = keyStates[index];
state = index;
info("pressing key " + key + " to get suggestions " +
JSON.stringify(suggestions));
EventUtils.synthesizeKey(key, {}, inspector.panelWin);
}
function checkState(event) {
inspector.searchSuggestions._lastQuery.then(() => {
let [key, suggestions] = keyStates[state];
let actualSuggestions = popup.getItems();
is(popup.isOpen ? actualSuggestions.length: 0, suggestions.length,
"There are expected number of suggestions at " + state + "th step.");
actualSuggestions.reverse();
for (let i = 0; i < suggestions.length; i++) {
is(suggestions[i][0], actualSuggestions[i].label,
"The suggestion at " + i + "th index for " + state +
"th step is correct.")
is(suggestions[i][1] || 1, actualSuggestions[i].count,
"The count for suggestion at " + i + "th index for " + state +
"th step is correct.")
}
checkStateAndMoveOn(state + 1);
});
}
function finishUp() {
searchBox = null;
popup = null;
gBrowser.removeCurrentTab();
finish();
}
}

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

@ -757,54 +757,39 @@ CSSCompleter.prototype = {
result = result.suggestions;
let query = this.selector;
let completion = [];
for (let [value, count, state] of result) {
for (let value of result) {
switch(this.selectorState) {
case SELECTOR_STATES.id:
case SELECTOR_STATES.class:
case SELECTOR_STATES.pseudo:
if (/^[.:#]$/.test(this.completing)) {
value = query.slice(0, query.length - this.completing.length) +
value;
value[0] = query.slice(0, query.length - this.completing.length) +
value[0];
} else {
value = query.slice(0, query.length - this.completing.length - 1) +
value;
value[0] = query.slice(0, query.length - this.completing.length - 1) +
value[0];
}
break;
case SELECTOR_STATES.tag:
value = query.slice(0, query.length - this.completing.length) +
value;
value[0] = query.slice(0, query.length - this.completing.length) +
value[0];
break;
case SELECTOR_STATES.null:
value = query + value;
value[0] = query + value[0];
break;
default:
value = query.slice(0, query.length - this.completing.length) +
value;
value[0] = query.slice(0, query.length - this.completing.length) +
value[0];
}
let item = {
label: value,
completion.push({
label: value[0],
preLabel: query,
text: value,
score: count
};
// In case the query's state is tag and the item's state is id or class
// adjust the preLabel
if (this.selectorState === SELECTOR_STATES.tag &&
state === SELECTOR_STATES.class) {
item.preLabel = "." + item.preLabel;
}
if (this.selectorState === SELECTOR_STATES.tag &&
state === SELECTOR_STATES.id) {
item.preLabel = "#" + item.preLabel;
}
completion.push(item);
text: value[0],
score: value[1]
});
if (completion.length > this.maxEntries - 1)
break;
}

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

@ -21,8 +21,8 @@
[[21, 9], ["-moz-calc", "auto", "calc", "inherit", "initial","unset"]],
[[22, 5], ['color', 'color-interpolation', 'color-interpolation-filters']],
[[25, 26], ['.devtools-toolbarbutton > tab',
'.devtools-toolbarbutton > hbox',
'.devtools-toolbarbutton > .toolbarbutton-menubutton-button']],
'.devtools-toolbarbutton > .toolbarbutton-menubutton-button',
'.devtools-toolbarbutton > hbox']],
[[25, 31], ['.devtools-toolbarbutton > hbox.toolbarbutton-menubutton-button']],
[[29, 20], ['.devtools-menulist:after', '.devtools-menulist:active']],
[[30, 10], ['#devtools-anotherone', '#devtools-itjustgoeson', '#devtools-menu',
@ -31,6 +31,6 @@
[[43, 51], ['.devtools-toolbarbutton:not([checked=true]):hover:after',
'.devtools-toolbarbutton:not([checked=true]):hover:active']],
[[58, 36], ['!important;']],
[[73, 42], [':lang(', ':last-of-type', ':link', ':last-child']],
[[73, 42], [':last-child', ':lang(', ':last-of-type', ':link']],
[[77, 25], ['.visible']],
]

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

@ -674,7 +674,7 @@ var NodeListActor = exports.NodeListActor = protocol.ActorClass({
form: function() {
return {
actor: this.actorID,
length: this.nodeList ? this.nodeList.length : 0
length: this.nodeList.length
}
},
@ -1395,7 +1395,7 @@ var WalkerActor = protocol.ActorClass({
sugs.classes.delete(HIDDEN_CLASS);
for (let [className, count] of sugs.classes) {
if (className.startsWith(completing)) {
result.push(["." + className, count, selectorState]);
result.push(["." + className, count]);
}
}
break;
@ -1409,7 +1409,7 @@ var WalkerActor = protocol.ActorClass({
}
for (let node of nodes) {
if (node.id.startsWith(completing)) {
result.push(["#" + node.id, 1, selectorState]);
result.push(["#" + node.id, 1]);
}
}
break;
@ -1427,20 +1427,9 @@ var WalkerActor = protocol.ActorClass({
}
for (let [tag, count] of sugs.tags) {
if ((new RegExp("^" + completing + ".*", "i")).test(tag)) {
result.push([tag, count, selectorState]);
result.push([tag, count]);
}
}
// For state 'tag' (no preceding # or .) and when there's no query (i.e.
// only one word) then search for the matching classes and ids
if (!query) {
result = [
...result,
...this.getSuggestionsForQuery(null, completing, "class").suggestions,
...this.getSuggestionsForQuery(null, completing, "id").suggestions
];
}
break;
case "null":
@ -1467,38 +1456,11 @@ var WalkerActor = protocol.ActorClass({
}
}
// Sort by count (desc) and name (asc)
result = result.sort((a, b) => {
// Computed a sortable string with first the inverted count, then the name
let sortA = (10000-a[1]) + a[0];
let sortB = (10000-b[1]) + b[0];
// Prefixing ids, classes and tags, to group results
let firstA = a[0].substring(0, 1);
let firstB = b[0].substring(0, 1);
if (firstA === "#") {
sortA = "2" + sortA;
}
else if (firstA === ".") {
sortA = "1" + sortA;
}
else {
sortA = "0" + sortA;
}
if (firstB === "#") {
sortB = "2" + sortB;
}
else if (firstB === ".") {
sortB = "1" + sortB;
}
else {
sortB = "0" + sortB;
}
// String compare
return sortA.localeCompare(sortB);
// Sort alphabetically in increaseing order.
result = result.sort();
// Sort based on count in decreasing order.
result = result.sort(function(a, b) {
return b[1] - a[1];
});
result.slice(0, 25);