Bug 1347490 - Return isConnected in node grip to indicate if a node is in the DOM tree. r=ochameau

node.isConnected (see https://dom.spec.whatwg.org/#dom-node-isconnected) returns true if the node is
in the DOM tree (including in a shadowDOM tree), which can be used in the frontend to display additional
tools and information.

MozReview-Commit-ID: LjUbkc7VPcB

--HG--
extra : rebase_source : b43644cf869663412a9ed6b956093e7a41afb01f
This commit is contained in:
nchevobbe 2017-04-04 12:08:54 +02:00
Родитель ee69536ac3
Коммит 5534f094a3
4 изменённых файлов: 144 добавлений и 0 удалений

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

@ -1652,6 +1652,7 @@ DebuggerServer.ObjectActorPreviewers.Object = [
kind: "DOMNode",
nodeType: rawObj.nodeType,
nodeName: rawObj.nodeName,
isConnected: rawObj.isConnected === true,
};
if (rawObj instanceof Ci.nsIDOMDocument && rawObj.location) {

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

@ -23,6 +23,7 @@ support-files =
small-image.gif
setup-in-child.js
setup-in-parent.js
webconsole-helpers.js
[test_animation_actor-lifetime.html]
[test_connection-manager.html]
@ -97,5 +98,6 @@ support-files =
[test_styles-modify.html]
[test_styles-svg.html]
[test_unsafeDereference.html]
[test_webconsole-node-grip.html]
[test_websocket-server.html]
skip-if = false

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

@ -0,0 +1,68 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>DOMNode Object actor test</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
<script type="application/javascript" src="webconsole-helpers.js"></script>
<script>
"use strict";
const TEST_URL = "data:text/html,<html><body>Hello</body></html>";
window.onload = async function () {
SimpleTest.waitForExplicitFinish();
try {
let {
consoleClient,
} = await attachURL(TEST_URL);
await testNotInTreeElementNode(consoleClient);
await testInTreeElementNode(consoleClient);
await testNotInTreeTextNode(consoleClient);
await testInTreeTextNode(consoleClient);
} catch (e) {
ok(false, `Error thrown: ${e.message}`);
}
SimpleTest.finish();
};
async function testNotInTreeElementNode(consoleClient) {
info("Testing isConnected property on a ElementNode not in the DOM tree");
let {result} = await consoleClient.evaluateJS("document.createElement(\"div\")");
is(result.preview.isConnected, false,
"isConnected is false since we only created the element");
}
async function testInTreeElementNode(consoleClient) {
info("Testing isConnected property on a ElementNode in the DOM tree");
let {result} = await consoleClient.evaluateJS("document.body");
is(result.preview.isConnected, true,
"isConnected is true as expected, since the element was retrieved from the DOM tree");
}
async function testNotInTreeTextNode(consoleClient) {
info("Testing isConnected property on a TextNode not in the DOM tree");
let {result} = await consoleClient.evaluateJS("document.createTextNode(\"Hello\")");
is(result.preview.isConnected, false,
"isConnected is false since we only created the element");
}
async function testInTreeTextNode(consoleClient) {
info("Testing isConnected property on a TextNode in the DOM tree");
let {result} = await consoleClient.evaluateJS("document.body.firstChild");
is(result.preview.isConnected, true,
"isConnected is true as expected, since the element was retrieved from the DOM tree");
}
</script>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
</html>

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

@ -0,0 +1,73 @@
/* exported attachURL, evaluateJS */
"use strict";
var Cu = Components.utils;
const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
const {DebuggerClient} = require("devtools/shared/client/main");
const {DebuggerServer} = require("devtools/server/main");
const Services = require("Services");
// Always log packets when running tests.
Services.prefs.setBoolPref("devtools.debugger.log", true);
SimpleTest.registerCleanupFunction(function () {
Services.prefs.clearUserPref("devtools.debugger.log");
});
if (!DebuggerServer.initialized) {
DebuggerServer.init();
DebuggerServer.addBrowserActors();
SimpleTest.registerCleanupFunction(function () {
DebuggerServer.destroy();
});
}
/**
* Open a tab, load the url, find the tab with the debugger server,
* and attach the console to it.
*
* @param {string} url : url to navigate to
* @return {Promise} Promise resolving when the console is attached.
* The Promise resolves with an object containing :
* - tab: the attached tab
* - tabClient: the tab client
* - consoleClient: the console client
* - cleanup: a generator function which can be called to close
* the opened tab and disconnect its debugger client.
*/
async function attachURL(url) {
let win = window.open(url, "_blank");
let client = null;
let cleanup = function* () {
if (client) {
yield client.close();
client = null;
}
if (win) {
win.close();
win = null;
}
};
SimpleTest.registerCleanupFunction(cleanup);
client = new DebuggerClient(DebuggerServer.connectPipe());
await client.connect();
let {tabs} = await client.listTabs();
let attachedTab = tabs.find(tab => tab.url === url);
if (!attachedTab) {
throw new Error(`Could not find a tab matching URL ${url}`);
}
const [, tabClient] = await client.attachTab(attachedTab.actor);
const [, consoleClient] = await client.attachConsole(attachedTab.consoleActor, []);
return {
tab: attachedTab,
tabClient,
consoleClient,
cleanup,
};
}