зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1265759 - Create an HTML replacement for inspector Search Box;r=gl
MozReview-Commit-ID: Elt4NGNh3Pf
This commit is contained in:
Родитель
bf696aae6c
Коммит
40b39ddc7b
|
@ -213,7 +213,7 @@ InspectorPanel.prototype = {
|
|||
this.updateDebuggerPausedWarning = () => {
|
||||
let notificationBox = this._toolbox.getNotificationBox();
|
||||
let notification =
|
||||
notificationBox.getNotificationWithValue("inspector-script-paused");
|
||||
notificationBox.getNotificationWithValue("inspector-script-paused");
|
||||
if (!notification && this._toolbox.currentToolId == "inspector" &&
|
||||
this._toolbox.threadClient.paused) {
|
||||
let message = strings.GetStringFromName("debuggerPausedWarning.message");
|
||||
|
@ -353,9 +353,10 @@ InspectorPanel.prototype = {
|
|||
*/
|
||||
setupSearchBox: function () {
|
||||
this.searchBox = this.panelDoc.getElementById("inspector-searchbox");
|
||||
this.searchClearButton = this.panelDoc.getElementById("inspector-searchinput-clear");
|
||||
this.searchResultsLabel = this.panelDoc.getElementById("inspector-searchlabel");
|
||||
|
||||
this.search = new InspectorSearch(this, this.searchBox);
|
||||
this.search = new InspectorSearch(this, this.searchBox, this.searchClearButton);
|
||||
this.search.on("search-cleared", this._updateSearchResultsLabel);
|
||||
this.search.on("search-result", this._updateSearchResultsLabel);
|
||||
|
||||
|
@ -1456,7 +1457,8 @@ InspectorPanel.prototype = {
|
|||
|
||||
/**
|
||||
* Paste the contents of the clipboard as adjacent HTML to the selected Node.
|
||||
* @param position The position as specified for Element.insertAdjacentHTML
|
||||
* @param position
|
||||
* The position as specified for Element.insertAdjacentHTML
|
||||
* (i.e. "beforeBegin", "afterBegin", "beforeEnd", "afterEnd").
|
||||
*/
|
||||
pasteAdjacentHTML: function (position) {
|
||||
|
@ -1516,8 +1518,8 @@ InspectorPanel.prototype = {
|
|||
/**
|
||||
* Copy the content of a longString (via a promise resolving a
|
||||
* LongStringActor) to the clipboard
|
||||
* @param {Promise} longStringActorPromise promise expected to
|
||||
* resolve a LongStringActor instance
|
||||
* @param {Promise} longStringActorPromise
|
||||
* promise expected to resolve a LongStringActor instance
|
||||
* @return {Promise} promise resolving (with no argument) when the
|
||||
* string is sent to the clipboard
|
||||
*/
|
||||
|
@ -1529,8 +1531,8 @@ InspectorPanel.prototype = {
|
|||
|
||||
/**
|
||||
* Retrieve the content of a longString (via a promise resolving a LongStringActor)
|
||||
* @param {Promise} longStringActorPromise promise expected to
|
||||
* resolve a LongStringActor instance
|
||||
* @param {Promise} longStringActorPromise
|
||||
* promise expected to resolve a LongStringActor instance
|
||||
* @return {Promise} promise resolving with the retrieved string as argument
|
||||
*/
|
||||
_getLongString: function (longStringActorPromise) {
|
||||
|
|
|
@ -4,9 +4,6 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
/* eslint-disable mozilla/reject-some-requires */
|
||||
const {Ci} = require("chrome");
|
||||
/* eslint-enable mozilla/reject-some-requires */
|
||||
const promise = require("promise");
|
||||
const {Task} = require("devtools/shared/task");
|
||||
|
||||
|
@ -20,24 +17,33 @@ const MAX_SUGGESTIONS = 15;
|
|||
/**
|
||||
* Converts any input field into a document search box.
|
||||
*
|
||||
* @param {InspectorPanel} inspector The InspectorPanel whose `walker` attribute
|
||||
* should be used for document traversal.
|
||||
* @param {DOMNode} input The input element to which the panel will be attached
|
||||
* and from where search input will be taken.
|
||||
* @param {InspectorPanel} inspector
|
||||
* The InspectorPanel whose `walker` attribute should be used for
|
||||
* document traversal.
|
||||
* @param {DOMNode} input
|
||||
* The input element to which the panel will be attached and from where
|
||||
* search input will be taken.
|
||||
* @param {DOMNode} clearBtn
|
||||
* The clear button in the input field that will clear the input value.
|
||||
*
|
||||
* Emits the following events:
|
||||
* - search-cleared: when the search box is emptied
|
||||
* - search-result: when a search is made and a result is selected
|
||||
*/
|
||||
function InspectorSearch(inspector, input) {
|
||||
function InspectorSearch(inspector, input, clearBtn) {
|
||||
this.inspector = inspector;
|
||||
this.searchBox = input;
|
||||
this.searchClearButton = clearBtn;
|
||||
this._lastSearched = null;
|
||||
|
||||
this.searchClearButton.hidden = true;
|
||||
|
||||
this._onKeyDown = this._onKeyDown.bind(this);
|
||||
this._onCommand = this._onCommand.bind(this);
|
||||
this._onInput = this._onInput.bind(this);
|
||||
this._onClearSearch = this._onClearSearch.bind(this);
|
||||
this.searchBox.addEventListener("keydown", this._onKeyDown, true);
|
||||
this.searchBox.addEventListener("command", this._onCommand, true);
|
||||
this.searchBox.addEventListener("input", this._onInput, true);
|
||||
this.searchClearButton.addEventListener("click", this._onClearSearch);
|
||||
|
||||
// For testing, we need to be able to wait for the most recent node request
|
||||
// to finish. Tests can watch this promise for that.
|
||||
|
@ -56,8 +62,10 @@ InspectorSearch.prototype = {
|
|||
|
||||
destroy: function () {
|
||||
this.searchBox.removeEventListener("keydown", this._onKeyDown, true);
|
||||
this.searchBox.removeEventListener("command", this._onCommand, true);
|
||||
this.searchBox.removeEventListener("input", this._onInput, true);
|
||||
this.searchClearButton.removeEventListener("click", this._onClearSearch);
|
||||
this.searchBox = null;
|
||||
this.searchClearButton = null;
|
||||
this.autocompleter.destroy();
|
||||
},
|
||||
|
||||
|
@ -97,7 +105,7 @@ InspectorSearch.prototype = {
|
|||
}
|
||||
}),
|
||||
|
||||
_onCommand: function () {
|
||||
_onInput: function () {
|
||||
if (this.searchBox.value.length === 0) {
|
||||
this._onSearch();
|
||||
}
|
||||
|
@ -105,8 +113,10 @@ InspectorSearch.prototype = {
|
|||
|
||||
_onKeyDown: function (event) {
|
||||
if (this.searchBox.value.length === 0) {
|
||||
this.searchClearButton.hidden = true;
|
||||
this.searchBox.removeAttribute("filled");
|
||||
} else {
|
||||
this.searchClearButton.hidden = false;
|
||||
this.searchBox.setAttribute("filled", true);
|
||||
}
|
||||
if (event.keyCode === event.DOM_VK_RETURN) {
|
||||
|
@ -115,10 +125,15 @@ InspectorSearch.prototype = {
|
|||
|
||||
const modifierKey = system.constants.platform === "macosx"
|
||||
? event.metaKey : event.ctrlKey;
|
||||
if (event.keyCode === Ci.nsIDOMKeyEvent.DOM_VK_G && modifierKey) {
|
||||
if (event.keyCode === event.DOM_VK_G && modifierKey) {
|
||||
this._onSearch(event.shiftKey);
|
||||
event.preventDefault();
|
||||
}
|
||||
},
|
||||
|
||||
_onClearSearch: function () {
|
||||
this.searchBox.value = "";
|
||||
this.searchClearButton.hidden = true;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -40,14 +40,15 @@
|
|||
class="devtools-button" />
|
||||
<html:div class="devtools-toolbar-spacer" />
|
||||
<html:span id="inspector-searchlabel" />
|
||||
<textbox id="inspector-searchbox"
|
||||
type="search"
|
||||
timeout="50"
|
||||
class="devtools-searchinput"
|
||||
placeholder="&inspectorSearchHTML.label3;"/>
|
||||
<html:div id="inspector-search" class="devtools-searchbox">
|
||||
<html:input id="inspector-searchbox" class="devtools-searchinput"
|
||||
type="search"
|
||||
placeholder="&inspectorSearchHTML.label3;"/>
|
||||
<html:button id="inspector-searchinput-clear" class="devtools-searchinput-clear" tabindex="-1"></html:button>
|
||||
</html:div>
|
||||
<html:button id="inspector-eyedropper-toggle"
|
||||
title="&inspectorEyeDropper.label;"
|
||||
class="devtools-button command-button-invertable" />
|
||||
title="&inspectorEyeDropper.label;"
|
||||
class="devtools-button command-button-invertable" />
|
||||
<div xmlns="http://www.w3.org/1999/xhtml"
|
||||
id="inspector-sidebar-toggle-box" />
|
||||
</html:div>
|
||||
|
|
|
@ -141,7 +141,7 @@ add_task(function* () {
|
|||
for (let { key, suggestions } of TEST_DATA) {
|
||||
info("Pressing " + key + " to get " + formatSuggestions(suggestions));
|
||||
|
||||
let command = once(searchBox, "command");
|
||||
let command = once(searchBox, "input");
|
||||
EventUtils.synthesizeKey(key, {}, inspector.panelWin);
|
||||
yield command;
|
||||
|
||||
|
|
|
@ -222,7 +222,7 @@ add_task(function* () {
|
|||
for (let { key, suggestions } of TEST_DATA) {
|
||||
info("Pressing " + key + " to get " + formatSuggestions(suggestions));
|
||||
|
||||
let command = once(searchBox, "command");
|
||||
let command = once(searchBox, "input");
|
||||
EventUtils.synthesizeKey(key, {}, inspector.panelWin);
|
||||
yield command;
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ add_task(function* () {
|
|||
for (let {key, suggestions} of TEST_DATA) {
|
||||
info("Pressing " + key + " to get " + formatSuggestions(suggestions));
|
||||
|
||||
let command = once(searchBox, "command");
|
||||
let command = once(searchBox, "input");
|
||||
EventUtils.synthesizeKey(key, {}, inspector.panelWin);
|
||||
yield command;
|
||||
|
||||
|
|
|
@ -1,49 +1,49 @@
|
|||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
"use strict";
|
||||
|
||||
// Test that searching for classes on SVG elements does work (see bug 1219920).
|
||||
|
||||
const TEST_URL = URL_ROOT + "doc_inspector_search-svg.html";
|
||||
|
||||
// An array of (key, suggestions) pairs where key is a key to press and
|
||||
// suggestions is an array of suggestions that should be shown in the popup.
|
||||
const TEST_DATA = [{
|
||||
key: "c",
|
||||
suggestions: ["circle", "clipPath", ".class1", ".class2"]
|
||||
}, {
|
||||
key: "VK_BACK_SPACE",
|
||||
suggestions: []
|
||||
}, {
|
||||
key: ".",
|
||||
suggestions: [".class1", ".class2"]
|
||||
}];
|
||||
|
||||
add_task(function* () {
|
||||
let {inspector} = yield openInspectorForURL(TEST_URL);
|
||||
let {searchBox} = inspector;
|
||||
let popup = inspector.searchSuggestions.searchPopup;
|
||||
|
||||
yield focusSearchBoxUsingShortcut(inspector.panelWin);
|
||||
|
||||
for (let {key, suggestions} of TEST_DATA) {
|
||||
info("Pressing " + key + " to get " + suggestions);
|
||||
|
||||
let command = once(searchBox, "command");
|
||||
EventUtils.synthesizeKey(key, {}, inspector.panelWin);
|
||||
yield command;
|
||||
|
||||
info("Waiting for search query to complete and getting the suggestions");
|
||||
yield inspector.searchSuggestions._lastQuery;
|
||||
let actualSuggestions = popup.getItems().reverse();
|
||||
|
||||
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],
|
||||
"The suggestion at " + i + "th index is correct.");
|
||||
}
|
||||
}
|
||||
});
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
"use strict";
|
||||
|
||||
// Test that searching for classes on SVG elements does work (see bug 1219920).
|
||||
|
||||
const TEST_URL = URL_ROOT + "doc_inspector_search-svg.html";
|
||||
|
||||
// An array of (key, suggestions) pairs where key is a key to press and
|
||||
// suggestions is an array of suggestions that should be shown in the popup.
|
||||
const TEST_DATA = [{
|
||||
key: "c",
|
||||
suggestions: ["circle", "clipPath", ".class1", ".class2"]
|
||||
}, {
|
||||
key: "VK_BACK_SPACE",
|
||||
suggestions: []
|
||||
}, {
|
||||
key: ".",
|
||||
suggestions: [".class1", ".class2"]
|
||||
}];
|
||||
|
||||
add_task(function* () {
|
||||
let {inspector} = yield openInspectorForURL(TEST_URL);
|
||||
let {searchBox} = inspector;
|
||||
let popup = inspector.searchSuggestions.searchPopup;
|
||||
|
||||
yield focusSearchBoxUsingShortcut(inspector.panelWin);
|
||||
|
||||
for (let {key, suggestions} of TEST_DATA) {
|
||||
info("Pressing " + key + " to get " + suggestions);
|
||||
|
||||
let command = once(searchBox, "input");
|
||||
EventUtils.synthesizeKey(key, {}, inspector.panelWin);
|
||||
yield command;
|
||||
|
||||
info("Waiting for search query to complete and getting the suggestions");
|
||||
yield inspector.searchSuggestions._lastQuery;
|
||||
let actualSuggestions = popup.getItems().reverse();
|
||||
|
||||
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],
|
||||
"The suggestion at " + i + "th index is correct.");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,64 +1,64 @@
|
|||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
"use strict";
|
||||
|
||||
// Test that searching for namespaced elements does work.
|
||||
|
||||
const XHTML = `
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<body>
|
||||
<svg:svg width="100" height="100">
|
||||
<svg:clipPath>
|
||||
<svg:rect x="0" y="0" width="10" height="5"></svg:rect>
|
||||
</svg:clipPath>
|
||||
<svg:circle cx="0" cy="0" r="5"></svg:circle>
|
||||
</svg:svg>
|
||||
</body>
|
||||
</html>
|
||||
`;
|
||||
|
||||
const TEST_URI = "data:application/xhtml+xml;charset=utf-8," + encodeURI(XHTML);
|
||||
|
||||
// An array of (key, suggestions) pairs where key is a key to press and
|
||||
// suggestions is an array of suggestions that should be shown in the popup.
|
||||
const TEST_DATA = [{
|
||||
key: "c",
|
||||
suggestions: ["circle", "clipPath"]
|
||||
}, {
|
||||
key: "VK_BACK_SPACE",
|
||||
suggestions: []
|
||||
}, {
|
||||
key: "s",
|
||||
suggestions: ["svg"]
|
||||
}];
|
||||
|
||||
add_task(function* () {
|
||||
let {inspector} = yield openInspectorForURL(TEST_URI);
|
||||
let {searchBox} = inspector;
|
||||
let popup = inspector.searchSuggestions.searchPopup;
|
||||
|
||||
yield focusSearchBoxUsingShortcut(inspector.panelWin);
|
||||
|
||||
for (let {key, suggestions} of TEST_DATA) {
|
||||
info("Pressing " + key + " to get " + suggestions.join(", "));
|
||||
|
||||
let command = once(searchBox, "command");
|
||||
EventUtils.synthesizeKey(key, {}, inspector.panelWin);
|
||||
yield command;
|
||||
|
||||
info("Waiting for search query to complete and getting the suggestions");
|
||||
yield inspector.searchSuggestions._lastQuery;
|
||||
let actualSuggestions = popup.getItems().reverse();
|
||||
|
||||
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],
|
||||
"The suggestion at " + i + "th index is correct.");
|
||||
}
|
||||
}
|
||||
});
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
"use strict";
|
||||
|
||||
// Test that searching for namespaced elements does work.
|
||||
|
||||
const XHTML = `
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<body>
|
||||
<svg:svg width="100" height="100">
|
||||
<svg:clipPath>
|
||||
<svg:rect x="0" y="0" width="10" height="5"></svg:rect>
|
||||
</svg:clipPath>
|
||||
<svg:circle cx="0" cy="0" r="5"></svg:circle>
|
||||
</svg:svg>
|
||||
</body>
|
||||
</html>
|
||||
`;
|
||||
|
||||
const TEST_URI = "data:application/xhtml+xml;charset=utf-8," + encodeURI(XHTML);
|
||||
|
||||
// An array of (key, suggestions) pairs where key is a key to press and
|
||||
// suggestions is an array of suggestions that should be shown in the popup.
|
||||
const TEST_DATA = [{
|
||||
key: "c",
|
||||
suggestions: ["circle", "clipPath"]
|
||||
}, {
|
||||
key: "VK_BACK_SPACE",
|
||||
suggestions: []
|
||||
}, {
|
||||
key: "s",
|
||||
suggestions: ["svg"]
|
||||
}];
|
||||
|
||||
add_task(function* () {
|
||||
let {inspector} = yield openInspectorForURL(TEST_URI);
|
||||
let {searchBox} = inspector;
|
||||
let popup = inspector.searchSuggestions.searchPopup;
|
||||
|
||||
yield focusSearchBoxUsingShortcut(inspector.panelWin);
|
||||
|
||||
for (let {key, suggestions} of TEST_DATA) {
|
||||
info("Pressing " + key + " to get " + suggestions.join(", "));
|
||||
|
||||
let command = once(searchBox, "input");
|
||||
EventUtils.synthesizeKey(key, {}, inspector.panelWin);
|
||||
yield command;
|
||||
|
||||
info("Waiting for search query to complete and getting the suggestions");
|
||||
yield inspector.searchSuggestions._lastQuery;
|
||||
let actualSuggestions = popup.getItems().reverse();
|
||||
|
||||
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],
|
||||
"The suggestion at " + i + "th index is correct.");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -104,7 +104,7 @@ add_task(function* () {
|
|||
for (let { key, suggestions } of TEST_DATA) {
|
||||
info("Pressing " + key + " to get " + formatSuggestions(suggestions));
|
||||
|
||||
let command = once(searchBox, "command");
|
||||
let command = once(searchBox, "input");
|
||||
EventUtils.synthesizeKey(key, {}, inspector.panelWin);
|
||||
yield command;
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ add_task(function* () {
|
|||
info("pressing key " + key + " to get suggestions " +
|
||||
JSON.stringify(expectedSuggestions));
|
||||
|
||||
let onCommand = once(searchBox, "command", true);
|
||||
let onCommand = once(searchBox, "input", true);
|
||||
EventUtils.synthesizeKey(key, {}, inspector.panelWin);
|
||||
yield onCommand;
|
||||
|
||||
|
|
|
@ -27,6 +27,18 @@
|
|||
|
||||
#inspector-searchlabel {
|
||||
overflow: hidden;
|
||||
margin-inline-end: 2px;
|
||||
}
|
||||
|
||||
#inspector-search {
|
||||
flex: unset;
|
||||
}
|
||||
|
||||
/* TODO: bug 1265759: should apply to .devtools-searchinput once all searchbox
|
||||
is converted to html*/
|
||||
#inspector-searchbox {
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Make sure the text is vertically centered in Inspector's
|
||||
|
|
|
@ -26,9 +26,7 @@
|
|||
let inspector = toolbox.getPanel("inspector");
|
||||
inspector.searchBox.focus();
|
||||
|
||||
// Use the binding element since inspector.searchBox is a XUL element.
|
||||
let activeElement = getActiveElement(inspector.panelDoc);
|
||||
activeElement = activeElement.ownerDocument.getBindingParent(activeElement);
|
||||
is(activeElement, inspector.searchBox, "Search box is focused");
|
||||
|
||||
yield toolbox.openSplitConsole();
|
||||
|
@ -45,9 +43,7 @@
|
|||
|
||||
info("Making sure that the search box is refocused after closing the " +
|
||||
"split console");
|
||||
// Use the binding element since inspector.searchBox is a XUL element.
|
||||
activeElement = getActiveElement(inspector.panelDoc);
|
||||
activeElement = activeElement.ownerDocument.getBindingParent(activeElement);
|
||||
is(activeElement, inspector.searchBox, "Search box is focused");
|
||||
|
||||
yield toolbox.destroy();
|
||||
|
|
Загрузка…
Ссылка в новой задаче