mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1076866 - Rect highlighter; r=bgrins
This commit is contained in:
parent
e352807814
commit
35bf6cdf38
@ -11,6 +11,8 @@ support-files =
|
||||
doc_inspector_highlighter-comments.html
|
||||
doc_inspector_highlighter_csstransform.html
|
||||
doc_inspector_highlighter.html
|
||||
doc_inspector_highlighter_rect.html
|
||||
doc_inspector_highlighter_rect_iframe.html
|
||||
doc_inspector_infobar_01.html
|
||||
doc_inspector_infobar_02.html
|
||||
doc_inspector_menu.html
|
||||
@ -41,6 +43,8 @@ support-files =
|
||||
[browser_inspector_highlighter-hover_03.js]
|
||||
[browser_inspector_highlighter-iframes.js]
|
||||
[browser_inspector_highlighter-options.js]
|
||||
[browser_inspector_highlighter-rect_01.js]
|
||||
[browser_inspector_highlighter-rect_02.js]
|
||||
[browser_inspector_highlighter-selector_01.js]
|
||||
[browser_inspector_highlighter-selector_02.js]
|
||||
[browser_inspector_iframe-navigation.js]
|
||||
|
@ -0,0 +1,118 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test that the custom rect highlighter provides the right API, ensures that
|
||||
// the input is valid and that it does create a box with the right dimensions,
|
||||
// at the right position.
|
||||
|
||||
const TEST_URL = "data:text/html;charset=utf-8,Rect Highlighter Test";
|
||||
|
||||
add_task(function*() {
|
||||
let {inspector, toolbox} = yield openInspectorForURL(TEST_URL);
|
||||
let front = inspector.inspector;
|
||||
let highlighter = yield front.getHighlighterByType("RectHighlighter");
|
||||
let body = yield getNodeFront("body", inspector);
|
||||
|
||||
info("Make sure the highlighter returned is correct");
|
||||
|
||||
ok(highlighter, "The RectHighlighter custom type was created");
|
||||
is(highlighter.typeName, "customhighlighter",
|
||||
"The RectHighlighter has the right type");
|
||||
ok(highlighter.show && highlighter.hide,
|
||||
"The RectHighlighter has the expected show/hide methods");
|
||||
|
||||
info("Check that the highlighter is hidden by default");
|
||||
|
||||
let hidden = yield getAttribute(highlighter, "hidden");
|
||||
is(hidden, "true", "The highlighter is hidden by default");
|
||||
|
||||
info("Check that nothing is shown if no rect is passed");
|
||||
|
||||
yield highlighter.show(body);
|
||||
hidden = yield getAttribute(highlighter, "hidden");
|
||||
is(hidden, "true", "The highlighter is hidden when no rect is passed");
|
||||
|
||||
info("Check that nothing is shown if rect is incomplete or invalid");
|
||||
|
||||
yield highlighter.show(body, {
|
||||
rect: {x: 0, y: 0}
|
||||
});
|
||||
hidden = yield getAttribute(highlighter, "hidden");
|
||||
is(hidden, "true", "The highlighter is hidden when the rect is incomplete");
|
||||
|
||||
yield highlighter.show(body, {
|
||||
rect: {x: 0, y: 0, width: -Infinity, height: 0}
|
||||
});
|
||||
hidden = yield getAttribute(highlighter, "hidden");
|
||||
is(hidden, "true", "The highlighter is hidden when the rect is invalid (1)");
|
||||
|
||||
yield highlighter.show(body, {
|
||||
rect: {x: 0, y: 0, width: 5, height: -45}
|
||||
});
|
||||
hidden = yield getAttribute(highlighter, "hidden");
|
||||
is(hidden, "true", "The highlighter is hidden when the rect is invalid (2)");
|
||||
|
||||
yield highlighter.show(body, {
|
||||
rect: {x: "test", y: 0, width: 5, height: 5}
|
||||
});
|
||||
hidden = yield getAttribute(highlighter, "hidden");
|
||||
is(hidden, "true", "The highlighter is hidden when the rect is invalid (3)");
|
||||
|
||||
info("Check that the highlighter is displayed when valid options are passed");
|
||||
|
||||
yield highlighter.show(body, {
|
||||
rect: {x: 5, y: 5, width: 50, height: 50}
|
||||
});
|
||||
hidden = yield getAttribute(highlighter, "hidden");
|
||||
ok(!hidden, "The highlighter is displayed");
|
||||
let style = yield getAttribute(highlighter, "style");
|
||||
is(style, "left:5px;top:5px;width:50px;height:50px;",
|
||||
"The highlighter is positioned correctly");
|
||||
|
||||
info("Check that the highlighter can be displayed at x=0 y=0");
|
||||
|
||||
yield highlighter.show(body, {
|
||||
rect: {x: 0, y: 0, width: 50, height: 50}
|
||||
});
|
||||
hidden = yield getAttribute(highlighter, "hidden");
|
||||
ok(!hidden, "The highlighter is displayed when x=0 and y=0");
|
||||
style = yield getAttribute(highlighter, "style");
|
||||
is(style, "left:0px;top:0px;width:50px;height:50px;",
|
||||
"The highlighter is positioned correctly");
|
||||
|
||||
info("Check that the highlighter is hidden when dimensions are 0");
|
||||
|
||||
yield highlighter.show(body, {
|
||||
rect: {x: 0, y: 0, width: 0, height: 0}
|
||||
});
|
||||
hidden = yield getAttribute(highlighter, "hidden");
|
||||
is(hidden, "true", "The highlighter is hidden width and height are 0");
|
||||
|
||||
info("Check that a fill color can be passed");
|
||||
|
||||
yield highlighter.show(body, {
|
||||
rect: {x: 100, y: 200, width: 500, height: 200},
|
||||
fill: "red"
|
||||
});
|
||||
hidden = yield getAttribute(highlighter, "hidden");
|
||||
ok(!hidden, "The highlighter is displayed");
|
||||
style = yield getAttribute(highlighter, "style");
|
||||
is(style, "left:100px;top:200px;width:500px;height:200px;background:red;",
|
||||
"The highlighter has the right background color");
|
||||
|
||||
yield highlighter.hide();
|
||||
yield highlighter.finalize();
|
||||
gBrowser.removeCurrentTab();
|
||||
});
|
||||
|
||||
function* getAttribute(highlighter, name) {
|
||||
let {data: value} = yield executeInContent("Test:GetHighlighterAttribute", {
|
||||
nodeID: "highlighted-rect",
|
||||
name: name,
|
||||
actorID: highlighter.actorID
|
||||
});
|
||||
return value;
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test that the custom rect highlighter positions the rectangle relative to the
|
||||
// viewport of the context node we pass to it.
|
||||
|
||||
const TEST_URL = TEST_URL_ROOT + "doc_inspector_highlighter_rect.html";
|
||||
|
||||
add_task(function*() {
|
||||
let {inspector, toolbox} = yield openInspectorForURL(TEST_URL);
|
||||
let front = inspector.inspector;
|
||||
let highlighter = yield front.getHighlighterByType("RectHighlighter");
|
||||
|
||||
info("Showing the rect highlighter in the context of the iframe");
|
||||
|
||||
// Get the reference to a context node inside the iframe
|
||||
let childBody = yield getNodeFrontInFrame("body", "iframe", inspector);
|
||||
yield highlighter.show(childBody, {
|
||||
rect: {x: 50, y: 50, width: 100, height: 100}
|
||||
});
|
||||
|
||||
let style = yield getAttribute(highlighter, "style");
|
||||
|
||||
// The parent body has margin=50px and border=10px
|
||||
// The parent iframe also has margin=50px and border=10px
|
||||
// = 50 + 10 + 50 + 10 = 120px
|
||||
// The rect is aat x=50 and y=50, so left and top should be 170px
|
||||
is(style, "left:170px;top:170px;width:100px;height:100px;",
|
||||
"The highlighter is correctly positioned");
|
||||
|
||||
yield highlighter.hide();
|
||||
yield highlighter.finalize();
|
||||
gBrowser.removeCurrentTab();
|
||||
});
|
||||
|
||||
function* getAttribute(highlighter, name) {
|
||||
let {data: value} = yield executeInContent("Test:GetHighlighterAttribute", {
|
||||
nodeID: "highlighted-rect",
|
||||
name: name,
|
||||
actorID: highlighter.actorID
|
||||
});
|
||||
return value;
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>rect highlighter parent test page</title>
|
||||
<style type="text/css">
|
||||
body {
|
||||
margin: 50px;
|
||||
border: 10px solid red;
|
||||
}
|
||||
|
||||
iframe {
|
||||
border: 10px solid yellow;
|
||||
padding: 0;
|
||||
margin: 50px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="doc_inspector_highlighter_rect_iframe.html"></iframe>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,15 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>rect highlighter child test page</title>
|
||||
<style type="text/css">
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -257,8 +257,8 @@ function getNodeFront(selector, {walker}) {
|
||||
* to highlight the node upon selection
|
||||
* @return {Promise} Resolves when the inspector is updated with the new node
|
||||
*/
|
||||
let getNodeFrontInFrame = Task.async(function*(selector, frameSelector, inspector,
|
||||
reason="test") {
|
||||
let getNodeFrontInFrame = Task.async(function*(selector, frameSelector,
|
||||
inspector, reason="test") {
|
||||
let iframe = yield getNodeFront(frameSelector, inspector);
|
||||
let {nodes} = yield inspector.walker.children(iframe);
|
||||
return inspector.walker.querySelector(nodes[0], selector);
|
||||
|
@ -170,3 +170,11 @@
|
||||
stroke-dasharray: 5 3;
|
||||
stroke-width: 2;
|
||||
}
|
||||
|
||||
/* Rect highlighter */
|
||||
|
||||
:-moz-native-anonymous .highlighted-rect {
|
||||
position: absolute;
|
||||
background: #80d4ff;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
@ -48,7 +48,8 @@ const SIMPLE_OUTLINE_SHEET = ".__fx-devtools-hide-shortcut__ {" +
|
||||
let HIGHLIGHTER_CLASSES = exports.HIGHLIGHTER_CLASSES = {
|
||||
"BoxModelHighlighter": BoxModelHighlighter,
|
||||
"CssTransformHighlighter": CssTransformHighlighter,
|
||||
"SelectorHighlighter": SelectorHighlighter
|
||||
"SelectorHighlighter": SelectorHighlighter,
|
||||
"RectHighlighter": RectHighlighter
|
||||
};
|
||||
|
||||
/**
|
||||
@ -343,7 +344,17 @@ let CustomHighlighterActor = exports.CustomHighlighterActor = protocol.ActorClas
|
||||
},
|
||||
|
||||
/**
|
||||
* Display the highlighter on a given NodeActor.
|
||||
* Show the highlighter.
|
||||
* This calls through to the highlighter instance's |show(node, options)|
|
||||
* method.
|
||||
*
|
||||
* Most custom highlighters are made to highlight DOM nodes, hence the first
|
||||
* NodeActor argument (NodeActor as in toolkit/devtools/server/actor/inspector).
|
||||
* Note however that some highlighters use this argument merely as a context
|
||||
* node: the RectHighlighter for instance uses it to calculate the absolute
|
||||
* position of the provided rect. The SelectHighlighter uses it as a base node
|
||||
* to run the provided CSS selector on.
|
||||
*
|
||||
* @param NodeActor The node to be highlighted
|
||||
* @param Object Options for the custom highlighter
|
||||
*/
|
||||
@ -1472,6 +1483,86 @@ SelectorHighlighter.prototype = {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The RectHighlighter is a class that draws a rectangle highlighter at specific
|
||||
* coordinates.
|
||||
* It does *not* highlight DOM nodes, but rects.
|
||||
* It also does *not* update dynamically, it only highlights a rect and remains
|
||||
* there as long as it is shown.
|
||||
*/
|
||||
function RectHighlighter(tabActor) {
|
||||
this.win = tabActor.window;
|
||||
this.layoutHelpers = new LayoutHelpers(this.win);
|
||||
this.markup = new CanvasFrameAnonymousContentHelper(tabActor,
|
||||
this._buildMarkup.bind(this));
|
||||
}
|
||||
|
||||
RectHighlighter.prototype = {
|
||||
_buildMarkup: function() {
|
||||
let doc = this.win.document;
|
||||
|
||||
let container = doc.createElement("div");
|
||||
container.className = "highlighter-container";
|
||||
container.innerHTML = '<div id="highlighted-rect" ' +
|
||||
'class="highlighted-rect" hidden="true">';
|
||||
|
||||
return container;
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
this.win = null;
|
||||
this.layoutHelpers = null;
|
||||
this.markup.destroy();
|
||||
},
|
||||
|
||||
_hasValidOptions: function(options) {
|
||||
let isValidNb = n => typeof n === "number" && n >= 0 && isFinite(n);
|
||||
return options && options.rect &&
|
||||
isValidNb(options.rect.x) &&
|
||||
isValidNb(options.rect.y) &&
|
||||
options.rect.width && isValidNb(options.rect.width) &&
|
||||
options.rect.height && isValidNb(options.rect.height);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {DOMNode} node The highlighter rect is relatively positioned to the
|
||||
* viewport this node is in. Using the provided node, the highligther will get
|
||||
* the parent documentElement and use it as context to position the
|
||||
* highlighter correctly.
|
||||
* @param {Object} options Accepts the following options:
|
||||
* - rect: mandatory object that should have the x, y, width, height properties
|
||||
* - fill: optional fill color for the rect
|
||||
*/
|
||||
show: function(node, options) {
|
||||
if (!this._hasValidOptions(options) || !node || !node.ownerDocument) {
|
||||
this.hide();
|
||||
return;
|
||||
}
|
||||
|
||||
let contextNode = node.ownerDocument.documentElement;
|
||||
|
||||
// Caculate the absolute rect based on the context node's adjusted quads.
|
||||
let {bounds} = this.layoutHelpers.getAdjustedQuads(contextNode);
|
||||
let x = "left:" + (bounds.x + options.rect.x) + "px;";
|
||||
let y = "top:" + (bounds.y + options.rect.y) + "px;";
|
||||
let width = "width:" + options.rect.width + "px;";
|
||||
let height = "height:" + options.rect.height + "px;";
|
||||
|
||||
let style = x + y + width + height;
|
||||
if (options.fill) {
|
||||
style += "background:" + options.fill + ";";
|
||||
}
|
||||
|
||||
// Set the coordinates of the highlighter and show it
|
||||
this.markup.setAttributeForElement("highlighted-rect", "style", style);
|
||||
this.markup.removeAttributeForElement("highlighted-rect", "hidden");
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
this.markup.setAttributeForElement("highlighted-rect", "hidden", "true");
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The SimpleOutlineHighlighter is a class that has the same API than the
|
||||
* BoxModelHighlighter, but adds a pseudo-class on the target element itself
|
||||
|
@ -128,7 +128,8 @@ RootActor.prototype = {
|
||||
customHighlighters: [
|
||||
"BoxModelHighlighter",
|
||||
"CssTransformHighlighter",
|
||||
"SelectorHighlighter"
|
||||
"SelectorHighlighter",
|
||||
"RectHighlighter"
|
||||
],
|
||||
// Whether the inspector actor implements the getImageDataFromURL
|
||||
// method that returns data-uris for image URLs. This is used for image
|
||||
|
Loading…
Reference in New Issue
Block a user