mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 962647 - Nodes searched in the inspector selector-search box now appear correctly in the markup-view; r=harth
This commit is contained in:
parent
df93062b9a
commit
ac63b04c1c
@ -262,25 +262,13 @@ InspectorPanel.prototype = {
|
||||
* Hooks the searchbar to show result and auto completion suggestions.
|
||||
*/
|
||||
setupSearchBox: function InspectorPanel_setupSearchBox() {
|
||||
let searchDoc;
|
||||
if (this.target.isLocalTab) {
|
||||
searchDoc = this.browser.contentDocument;
|
||||
} else if (this.target.window) {
|
||||
searchDoc = this.target.window.document;
|
||||
} else {
|
||||
searchDoc = null;
|
||||
}
|
||||
// Initiate the selectors search object.
|
||||
let setNodeFunction = function(eventName, node) {
|
||||
this.selection.setNodeFront(node, "selectorsearch");
|
||||
}.bind(this);
|
||||
if (this.searchSuggestions) {
|
||||
this.searchSuggestions.destroy();
|
||||
this.searchSuggestions = null;
|
||||
}
|
||||
this.searchBox = this.panelDoc.getElementById("inspector-searchbox");
|
||||
this.searchSuggestions = new SelectorSearch(this, searchDoc, this.searchBox);
|
||||
this.searchSuggestions.on("node-selected", setNodeFunction);
|
||||
this.searchSuggestions = new SelectorSearch(this, this.searchBox);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
const EventEmitter = require("devtools/shared/event-emitter");
|
||||
const promise = require("sdk/core/promise");
|
||||
|
||||
loader.lazyGetter(this, "AutocompletePopup", () => require("devtools/shared/autocomplete-popup").AutocompletePopup);
|
||||
@ -19,16 +18,12 @@ const MAX_SUGGESTIONS = 15;
|
||||
* @param InspectorPanel aInspector
|
||||
* The InspectorPanel whose `walker` attribute should be used for
|
||||
* document traversal.
|
||||
* @param nsIDOMDocument aContentDocument
|
||||
* The content document which inspector is attached to, or null if
|
||||
* a remote document.
|
||||
* @param nsiInputElement aInputNode
|
||||
* The input element to which the panel will be attached and from where
|
||||
* search input will be taken.
|
||||
*/
|
||||
function SelectorSearch(aInspector, aContentDocument, aInputNode) {
|
||||
function SelectorSearch(aInspector, aInputNode) {
|
||||
this.inspector = aInspector;
|
||||
this.doc = aContentDocument;
|
||||
this.searchBox = aInputNode;
|
||||
this.panelDoc = this.searchBox.ownerDocument;
|
||||
|
||||
@ -55,7 +50,7 @@ function SelectorSearch(aInspector, aContentDocument, aInputNode) {
|
||||
direction: "ltr",
|
||||
theme: "auto",
|
||||
onClick: this._onListBoxKeypress,
|
||||
onKeypress: this._onListBoxKeypress,
|
||||
onKeypress: this._onListBoxKeypress
|
||||
};
|
||||
this.searchPopup = new AutocompletePopup(this.panelDoc, options);
|
||||
|
||||
@ -66,8 +61,6 @@ function SelectorSearch(aInspector, aContentDocument, aInputNode) {
|
||||
// For testing, we need to be able to wait for the most recent node request
|
||||
// to finish. Tests can watch this promise for that.
|
||||
this._lastQuery = promise.resolve(null);
|
||||
|
||||
EventEmitter.decorate(this);
|
||||
}
|
||||
|
||||
exports.SelectorSearch = SelectorSearch;
|
||||
@ -165,23 +158,21 @@ SelectorSearch.prototype = {
|
||||
/**
|
||||
* Removes event listeners and cleans up references.
|
||||
*/
|
||||
destroy: function SelectorSearch_destroy() {
|
||||
destroy: function() {
|
||||
// event listeners.
|
||||
this.searchBox.removeEventListener("command", this._onHTMLSearch, true);
|
||||
this.searchBox.removeEventListener("keypress", this._onSearchKeypress, true);
|
||||
this.searchPopup.destroy();
|
||||
this.searchPopup = null;
|
||||
this.searchBox = null;
|
||||
this.doc = null;
|
||||
this.panelDoc = null;
|
||||
this._searchResults = null;
|
||||
this._searchSuggestions = null;
|
||||
EventEmitter.decorate(this);
|
||||
},
|
||||
|
||||
_selectResult: function(index) {
|
||||
return this._searchResults.item(index).then(node => {
|
||||
this.emit("node-selected", node);
|
||||
this.inspector.selection.setNodeFront(node, "selectorsearch");
|
||||
});
|
||||
},
|
||||
|
||||
@ -189,7 +180,7 @@ SelectorSearch.prototype = {
|
||||
* The command callback for the input box. This function is automatically
|
||||
* invoked as the user is typing if the input box type is search.
|
||||
*/
|
||||
_onHTMLSearch: function SelectorSearch__onHTMLSearch() {
|
||||
_onHTMLSearch: function() {
|
||||
let query = this.searchBox.value;
|
||||
if (query == this._lastSearched) {
|
||||
return;
|
||||
@ -256,7 +247,7 @@ SelectorSearch.prototype = {
|
||||
}
|
||||
return this._selectResult(0).then(() => {
|
||||
this.searchBox.classList.remove("devtools-no-search-result");
|
||||
}).then( () => this.showSuggestions());
|
||||
}).then(() => this.showSuggestions());
|
||||
}
|
||||
if (query.match(/[\s>+]$/)) {
|
||||
this._lastValidSearch = query + "*";
|
||||
@ -273,7 +264,7 @@ SelectorSearch.prototype = {
|
||||
/**
|
||||
* Handles keypresses inside the input box.
|
||||
*/
|
||||
_onSearchKeypress: function SelectorSearch__onSearchKeypress(aEvent) {
|
||||
_onSearchKeypress: function(aEvent) {
|
||||
let query = this.searchBox.value;
|
||||
switch(aEvent.keyCode) {
|
||||
case aEvent.DOM_VK_RETURN:
|
||||
@ -348,7 +339,7 @@ SelectorSearch.prototype = {
|
||||
/**
|
||||
* Handles keypress and mouse click on the suggestions richlistbox.
|
||||
*/
|
||||
_onListBoxKeypress: function SelectorSearch__onListBoxKeypress(aEvent) {
|
||||
_onListBoxKeypress: function(aEvent) {
|
||||
switch(aEvent.keyCode || aEvent.button) {
|
||||
case aEvent.DOM_VK_RETURN:
|
||||
case aEvent.DOM_VK_TAB:
|
||||
@ -404,11 +395,10 @@ SelectorSearch.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Populates the suggestions list and show the suggestion popup.
|
||||
*/
|
||||
_showPopup: function SelectorSearch__showPopup(aList, aFirstPart) {
|
||||
_showPopup: function(aList, aFirstPart) {
|
||||
let total = 0;
|
||||
let query = this.searchBox.value;
|
||||
let toLowerCase = false;
|
||||
@ -458,7 +448,7 @@ SelectorSearch.prototype = {
|
||||
* Suggests classes,ids and tags based on the user input as user types in the
|
||||
* searchbox.
|
||||
*/
|
||||
showSuggestions: function SelectorSearch_showSuggestions() {
|
||||
showSuggestions: function() {
|
||||
let query = this.searchBox.value;
|
||||
let firstPart = "";
|
||||
if (this.state == this.States.TAG) {
|
||||
@ -498,5 +488,5 @@ SelectorSearch.prototype = {
|
||||
}
|
||||
this._showPopup(result.suggestions, firstPart);
|
||||
});
|
||||
},
|
||||
}
|
||||
};
|
||||
|
@ -166,6 +166,9 @@ MarkupView.prototype = {
|
||||
|
||||
_onMouseLeave: function() {
|
||||
this._hideBoxModel();
|
||||
if (this._hoveredNode) {
|
||||
this._containers.get(this._hoveredNode).hovered = false;
|
||||
}
|
||||
this._hoveredNode = null;
|
||||
},
|
||||
|
||||
|
@ -7,6 +7,7 @@ support-files =
|
||||
browser_inspector_markup_subset.html
|
||||
browser_inspector_markup_765105_tooltip.png
|
||||
browser_inspector_markup_950732.html
|
||||
browser_inspector_markup_962647_search.html
|
||||
head.js
|
||||
|
||||
[browser_bug896181_css_mixed_completion_new_attribute.js]
|
||||
@ -28,3 +29,4 @@ skip-if = true
|
||||
[browser_inspector_markup_964014_copy_image_data.js]
|
||||
[browser_inspector_markup_968316_highlit_node_on_hover_then_select.js]
|
||||
[browser_inspector_markup_968316_highlight_node_after_mouseleave_mousemove.js]
|
||||
[browser_inspector_markup_962647_search.js]
|
||||
|
@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<ul>
|
||||
<li>
|
||||
<span>this is an <em>important</em> node</span>
|
||||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,50 @@
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test that searching for nodes using the selector-search input expands and
|
||||
// selects the right nodes in the markup-view, even when those nodes are deeply
|
||||
// nested (and therefore not attached yet when the markup-view is initialized).
|
||||
|
||||
const TEST_URL = "http://mochi.test:8888/browser/browser/devtools/markupview/test/browser_inspector_markup_962647_search.html";
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
let p = content.document.querySelector("p");
|
||||
Task.spawn(function() {
|
||||
info("loading the test page");
|
||||
yield addTab(TEST_URL);
|
||||
|
||||
info("opening the inspector");
|
||||
let {inspector, toolbox} = yield openInspector();
|
||||
|
||||
ok(!getContainerForRawNode(inspector.markup, getNode("em")),
|
||||
"The <em> tag isn't present yet in the markup-view");
|
||||
|
||||
// Searching for the innermost element first makes sure that the inspector
|
||||
// back-end is able to attach the resulting node to the tree it knows at the
|
||||
// moment. When the inspector is started, the <body> is the default selected
|
||||
// node, and only the parents up to the ROOT are known, and its direct children
|
||||
info("searching for the innermost child: <em>");
|
||||
let updated = inspector.once("inspector-updated");
|
||||
searchUsingSelectorSearch("em", inspector);
|
||||
yield updated;
|
||||
|
||||
ok(getContainerForRawNode(inspector.markup, getNode("em")),
|
||||
"The <em> tag is now imported in the markup-view");
|
||||
is(inspector.selection.node, getNode("em"),
|
||||
"The <em> tag is the currently selected node");
|
||||
|
||||
info("searching for other nodes too");
|
||||
for (let node of ["span", "li", "ul"]) {
|
||||
let updated = inspector.once("inspector-updated");
|
||||
searchUsingSelectorSearch(node, inspector);
|
||||
yield updated;
|
||||
is(inspector.selection.node, getNode(node),
|
||||
"The <" + node + "> tag is the currently selected node");
|
||||
}
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
}).then(null, ok.bind(null, false)).then(finish);
|
||||
}
|
@ -68,7 +68,6 @@ function openInspector() {
|
||||
function getContainerForRawNode(markupView, rawNode) {
|
||||
let front = markupView.walker.frontForRawNode(rawNode);
|
||||
let container = markupView.getContainer(front);
|
||||
ok(container, "A markup-container object was found");
|
||||
return container;
|
||||
}
|
||||
|
||||
@ -240,3 +239,26 @@ function redoChange(inspector) {
|
||||
inspector.markup.undo.redo();
|
||||
return mutated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the selector-search input box from the inspector panel
|
||||
* @return {DOMNode}
|
||||
*/
|
||||
function getSelectorSearchBox(inspector) {
|
||||
return inspector.panelWin.document.getElementById("inspector-searchbox");
|
||||
}
|
||||
|
||||
/**
|
||||
* Using the inspector panel's selector search box, search for a given selector.
|
||||
* The selector input string will be entered in the input field and the <ENTER>
|
||||
* keypress will be simulated.
|
||||
* This function won't wait for any events and is not async. It's up to callers
|
||||
* to subscribe to events and react accordingly.
|
||||
*/
|
||||
function searchUsingSelectorSearch(selector, inspector) {
|
||||
info("Entering \"" + selector + "\" into the selector-search input field");
|
||||
let field = getSelectorSearchBox(inspector);
|
||||
field.focus();
|
||||
field.value = selector;
|
||||
EventUtils.sendKey("return", inspector.panelWin);
|
||||
}
|
||||
|
@ -681,12 +681,7 @@ var NodeListActor = exports.NodeListActor = protocol.ActorClass({
|
||||
* Get a single node from the node list.
|
||||
*/
|
||||
item: method(function(index) {
|
||||
let node = this.walker._ref(this.nodeList[index]);
|
||||
let newParents = [node for (node of this.walker.ensurePathToRoot(node))];
|
||||
return {
|
||||
node: node,
|
||||
newParents: newParents
|
||||
}
|
||||
return this.walker.attachElement(this.nodeList[index]);
|
||||
}, {
|
||||
request: { item: Arg(0) },
|
||||
response: RetVal("disconnectedNode")
|
||||
|
Loading…
Reference in New Issue
Block a user