Bug 1940748 - [devtools] Add missing ~ in RegExp to handle sibling selector in markup view search autocomplete. r=devtools-reviewers,ochameau.
browser_inspector_search-02.js is modified as it was already checking combination selectors. The existing assertion now uses the checkMarkupSearchSuggestions shared helper to make it easier to follow. Differential Revision: https://phabricator.services.mozilla.com/D233857
This commit is contained in:
@@ -391,16 +391,16 @@ class SelectorAutocompleter extends EventEmitter {
|
|||||||
const items = [];
|
const items = [];
|
||||||
|
|
||||||
for (let [value, , state] of list) {
|
for (let [value, , state] of list) {
|
||||||
if (query.match(/[\s>+]$/)) {
|
if (query.match(/[\s>+~]$/)) {
|
||||||
// for cases like 'div ' or 'div >' or 'div+'
|
// for cases like 'div ', 'div >', 'div+' or 'div~'
|
||||||
value = query + value;
|
value = query + value;
|
||||||
} else if (query.match(/[\s>+][\.#a-zA-Z][^\s>+\.#\[]*$/)) {
|
} else if (query.match(/[\s>+~][\.#a-zA-Z][^\s>+~\.#\[]*$/)) {
|
||||||
// for cases like 'div #a' or 'div .a' or 'div > d' and likewise
|
// for cases like 'div #a' or 'div .a' or 'div > d' and likewise
|
||||||
const lastPart = query.match(/[\s>+][\.#a-zA-Z][^\s>+\.#\[]*$/)[0];
|
const lastPart = query.match(/[\s>+~][\.#a-zA-Z][^\s>+~\.#\[]*$/)[0];
|
||||||
value = query.slice(0, -1 * lastPart.length + 1) + value;
|
value = query.slice(0, -1 * lastPart.length + 1) + value;
|
||||||
} else if (query.match(/[a-zA-Z][#\.][^#\.\s+>]*$/)) {
|
} else if (query.match(/[a-zA-Z][#\.][^#\.\s+>~]*$/)) {
|
||||||
// for cases like 'div.class' or '#foo.bar' and likewise
|
// for cases like 'div.class' or '#foo.bar' and likewise
|
||||||
const lastPart = query.match(/[a-zA-Z][#\.][^#\.\s+>]*$/)[0];
|
const lastPart = query.match(/[a-zA-Z][#\.][^#\.\s+>~]*$/)[0];
|
||||||
value = query.slice(0, -1 * lastPart.length + 1) + value;
|
value = query.slice(0, -1 * lastPart.length + 1) + value;
|
||||||
} else if (query.match(/[a-zA-Z]*\[[^\]]*\][^\]]*/)) {
|
} else if (query.match(/[a-zA-Z]*\[[^\]]*\][^\]]*/)) {
|
||||||
// for cases like '[foo].bar' and likewise
|
// for cases like '[foo].bar' and likewise
|
||||||
@@ -478,8 +478,9 @@ class SelectorAutocompleter extends EventEmitter {
|
|||||||
// - 'div.foo s' returns 's'
|
// - 'div.foo s' returns 's'
|
||||||
// - 'div.foo > s' returns 's'
|
// - 'div.foo > s' returns 's'
|
||||||
// - 'div.foo + s' returns 's'
|
// - 'div.foo + s' returns 's'
|
||||||
|
// - 'div.foo ~ s' returns 's'
|
||||||
// - 'div.foo x-el_1' returns 'x-el_1'
|
// - 'div.foo x-el_1' returns 'x-el_1'
|
||||||
const matches = query.match(/[\s>+]?(?<tag>[a-zA-Z0-9_-]*)$/);
|
const matches = query.match(/[\s>+~]?(?<tag>[a-zA-Z0-9_-]*)$/);
|
||||||
firstPart = matches.groups.tag;
|
firstPart = matches.groups.tag;
|
||||||
query = query.slice(0, query.length - firstPart.length);
|
query = query.slice(0, query.length - firstPart.length);
|
||||||
} else if (state === this.States.CLASS) {
|
} else if (state === this.States.CLASS) {
|
||||||
|
|||||||
@@ -7,149 +7,136 @@
|
|||||||
|
|
||||||
const TEST_URL = URL_ROOT + "doc_inspector_search-suggestions.html";
|
const TEST_URL = URL_ROOT + "doc_inspector_search-suggestions.html";
|
||||||
|
|
||||||
// An array of (key, suggestions) pairs where key is a key to press and
|
// See head.js `checkMarkupSearchSuggestions` function
|
||||||
// suggestions is an array of suggestions that should be shown in the popup.
|
|
||||||
// Suggestion is an object with label of the entry and optional count
|
|
||||||
// (defaults to 1)
|
|
||||||
const TEST_DATA = [
|
const TEST_DATA = [
|
||||||
{
|
{
|
||||||
key: "d",
|
key: "d",
|
||||||
suggestions: [{ label: "div" }, { label: "#d1" }, { label: "#d2" }],
|
value: "d",
|
||||||
|
suggestions: ["div", "#d1", "#d2"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "i",
|
key: "i",
|
||||||
suggestions: [{ label: "div" }],
|
value: "di",
|
||||||
|
suggestions: ["div"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "v",
|
key: "v",
|
||||||
|
value: "div",
|
||||||
suggestions: [],
|
suggestions: [],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: " ",
|
key: " ",
|
||||||
suggestions: [{ label: "div div" }, { label: "div span" }],
|
value: "div ",
|
||||||
|
suggestions: ["div div", "div span"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: ">",
|
key: ">",
|
||||||
suggestions: [{ label: "div >div" }, { label: "div >span" }],
|
value: "div >",
|
||||||
|
suggestions: ["div >div", "div >span"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "VK_BACK_SPACE",
|
key: "VK_BACK_SPACE",
|
||||||
suggestions: [{ label: "div div" }, { label: "div span" }],
|
value: "div ",
|
||||||
|
suggestions: ["div div", "div span"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "+",
|
key: "+",
|
||||||
suggestions: [{ label: "div +span" }],
|
value: "div +",
|
||||||
|
suggestions: ["div +span"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "VK_BACK_SPACE",
|
key: "VK_BACK_SPACE",
|
||||||
suggestions: [{ label: "div div" }, { label: "div span" }],
|
value: "div ",
|
||||||
|
suggestions: ["div div", "div span"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "VK_BACK_SPACE",
|
key: "VK_BACK_SPACE",
|
||||||
|
value: "div",
|
||||||
suggestions: [],
|
suggestions: [],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "VK_BACK_SPACE",
|
key: "VK_BACK_SPACE",
|
||||||
suggestions: [{ label: "div" }],
|
value: "di",
|
||||||
|
suggestions: ["div"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "VK_BACK_SPACE",
|
key: "VK_BACK_SPACE",
|
||||||
suggestions: [{ label: "div" }, { label: "#d1" }, { label: "#d2" }],
|
value: "d",
|
||||||
|
suggestions: ["div", "#d1", "#d2"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "VK_BACK_SPACE",
|
key: "VK_BACK_SPACE",
|
||||||
|
value: "",
|
||||||
suggestions: [],
|
suggestions: [],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "p",
|
key: "p",
|
||||||
suggestions: [
|
value: "p",
|
||||||
{ label: "p" },
|
suggestions: ["p", "#p1", "#p2", "#p3"],
|
||||||
{ label: "#p1" },
|
|
||||||
{ label: "#p2" },
|
|
||||||
{ label: "#p3" },
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: " ",
|
key: " ",
|
||||||
suggestions: [{ label: "p strong" }],
|
value: "p ",
|
||||||
|
suggestions: ["p strong"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "+",
|
key: "+",
|
||||||
suggestions: [{ label: "p +button" }, { label: "p +p" }],
|
value: "p +",
|
||||||
|
suggestions: ["p +button", "p +footer", "p +p"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "b",
|
key: "b",
|
||||||
suggestions: [{ label: "p +button" }],
|
value: "p +b",
|
||||||
|
suggestions: ["p +button"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "u",
|
key: "u",
|
||||||
suggestions: [{ label: "p +button" }],
|
value: "p +bu",
|
||||||
|
suggestions: ["p +button"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "t",
|
key: "t",
|
||||||
suggestions: [{ label: "p +button" }],
|
value: "p +but",
|
||||||
|
suggestions: ["p +button"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "t",
|
key: "t",
|
||||||
suggestions: [{ label: "p +button" }],
|
value: "p +butt",
|
||||||
|
suggestions: ["p +button"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "o",
|
key: "o",
|
||||||
suggestions: [{ label: "p +button" }],
|
value: "p +butto",
|
||||||
|
suggestions: ["p +button"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "n",
|
key: "n",
|
||||||
|
value: "p +button",
|
||||||
suggestions: [],
|
suggestions: [],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "+",
|
key: "+",
|
||||||
suggestions: [{ label: "p +button+p" }],
|
value: "p +button+",
|
||||||
|
suggestions: ["p +button+p"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "VK_BACK_SPACE",
|
||||||
|
value: "p +button",
|
||||||
|
suggestions: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "~",
|
||||||
|
value: "p +button~",
|
||||||
|
suggestions: ["p +button~footer", "p +button~p"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "f",
|
||||||
|
value: "p +button~f",
|
||||||
|
suggestions: ["p +button~footer"],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
add_task(async function () {
|
add_task(async function () {
|
||||||
const { inspector } = await openInspectorForURL(TEST_URL);
|
const { inspector } = await openInspectorForURL(TEST_URL);
|
||||||
const searchBox = inspector.searchBox;
|
await checkMarkupSearchSuggestions(inspector, TEST_DATA);
|
||||||
const popup = inspector.searchSuggestions.searchPopup;
|
|
||||||
|
|
||||||
await focusSearchBoxUsingShortcut(inspector.panelWin);
|
|
||||||
|
|
||||||
for (const { key, suggestions } of TEST_DATA) {
|
|
||||||
info("Pressing " + key + " to get " + formatSuggestions(suggestions));
|
|
||||||
|
|
||||||
const command = once(searchBox, "input");
|
|
||||||
const onSearchProcessingDone =
|
|
||||||
inspector.searchSuggestions.once("processing-done");
|
|
||||||
EventUtils.synthesizeKey(key, {}, inspector.panelWin);
|
|
||||||
await command;
|
|
||||||
|
|
||||||
info("Waiting for search query to complete");
|
|
||||||
await onSearchProcessingDone;
|
|
||||||
|
|
||||||
info(
|
|
||||||
"Query completed. Performing checks for input '" +
|
|
||||||
searchBox.value +
|
|
||||||
"' - key pressed: " +
|
|
||||||
key
|
|
||||||
);
|
|
||||||
const actualSuggestions = popup.getItems();
|
|
||||||
|
|
||||||
is(
|
|
||||||
popup.isOpen ? actualSuggestions.length : 0,
|
|
||||||
suggestions.length,
|
|
||||||
"There are expected number of suggestions."
|
|
||||||
);
|
|
||||||
|
|
||||||
for (let i = 0; i < suggestions.length; i++) {
|
|
||||||
is(
|
|
||||||
actualSuggestions[i].label,
|
|
||||||
suggestions[i].label,
|
|
||||||
"The suggestion at " + i + "th index is correct."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function formatSuggestions(suggestions) {
|
|
||||||
return "[" + suggestions.map(s => "'" + s.label + "'").join(", ") + "]";
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -22,6 +22,6 @@
|
|||||||
<p id="p2">#someid</p>
|
<p id="p2">#someid</p>
|
||||||
<button id="b1" disabled>button[disabled]</button>
|
<button id="b1" disabled>button[disabled]</button>
|
||||||
<p id="p3" class="c2"><strong>p>strong</strong></p>
|
<p id="p3" class="c2"><strong>p>strong</strong></p>
|
||||||
|
<footer></footer>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user