1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/browser/devtools/inspector/test/head.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,438 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +const Cu = Components.utils; 1.9 +const Ci = Components.interfaces; 1.10 +const Cc = Components.classes; 1.11 + 1.12 +// Services.prefs.setBoolPref("devtools.debugger.log", true); 1.13 +// SimpleTest.registerCleanupFunction(() => { 1.14 +// Services.prefs.clearUserPref("devtools.debugger.log"); 1.15 +// }); 1.16 + 1.17 +//Services.prefs.setBoolPref("devtools.dump.emit", true); 1.18 + 1.19 +let tempScope = {}; 1.20 +Cu.import("resource://gre/modules/devtools/LayoutHelpers.jsm", tempScope); 1.21 +let LayoutHelpers = tempScope.LayoutHelpers; 1.22 + 1.23 +let {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", tempScope); 1.24 +let TargetFactory = devtools.TargetFactory; 1.25 + 1.26 +Components.utils.import("resource://gre/modules/devtools/Console.jsm", tempScope); 1.27 +let console = tempScope.console; 1.28 + 1.29 +// Import the GCLI test helper 1.30 +let testDir = gTestPath.substr(0, gTestPath.lastIndexOf("/")); 1.31 +Services.scriptloader.loadSubScript(testDir + "../../../commandline/test/helpers.js", this); 1.32 + 1.33 +gDevTools.testing = true; 1.34 +SimpleTest.registerCleanupFunction(() => { 1.35 + gDevTools.testing = false; 1.36 +}); 1.37 + 1.38 +SimpleTest.registerCleanupFunction(() => { 1.39 + console.error("Here we are\n"); 1.40 + let {DebuggerServer} = Cu.import("resource://gre/modules/devtools/dbg-server.jsm", {}); 1.41 + console.error("DebuggerServer open connections: " + Object.getOwnPropertyNames(DebuggerServer._connections).length); 1.42 + 1.43 + Services.prefs.clearUserPref("devtools.dump.emit"); 1.44 + Services.prefs.clearUserPref("devtools.inspector.activeSidebar"); 1.45 +}); 1.46 + 1.47 +/** 1.48 + * Simple DOM node accesor function that takes either a node or a string css 1.49 + * selector as argument and returns the corresponding node 1.50 + * @param {String|DOMNode} nodeOrSelector 1.51 + * @return {DOMNode} 1.52 + */ 1.53 +function getNode(nodeOrSelector) { 1.54 + return typeof nodeOrSelector === "string" ? 1.55 + content.document.querySelector(nodeOrSelector) : 1.56 + nodeOrSelector; 1.57 +} 1.58 + 1.59 +/** 1.60 + * Set the inspector's current selection to a node or to the first match of the 1.61 + * given css selector 1.62 + * @param {InspectorPanel} inspector The instance of InspectorPanel currently 1.63 + * loaded in the toolbox 1.64 + * @param {String} reason Defaults to "test" which instructs the inspector not 1.65 + * to highlight the node upon selection 1.66 + * @param {String} reason Defaults to "test" which instructs the inspector not to highlight the node upon selection 1.67 + * @return a promise that resolves when the inspector is updated with the new 1.68 + * node 1.69 + */ 1.70 +function selectNode(nodeOrSelector, inspector, reason="test") { 1.71 + info("Selecting the node " + nodeOrSelector); 1.72 + let node = getNode(nodeOrSelector); 1.73 + let updated = inspector.once("inspector-updated"); 1.74 + inspector.selection.setNode(node, reason); 1.75 + return updated; 1.76 +} 1.77 + 1.78 +/** 1.79 + * Open the toolbox, with the inspector tool visible. 1.80 + * @param {Function} cb Optional callback, if you don't want to use the returned 1.81 + * promise 1.82 + * @return a promise that resolves when the inspector is ready 1.83 + */ 1.84 +let openInspector = Task.async(function*(cb) { 1.85 + info("Opening the inspector"); 1.86 + let target = TargetFactory.forTab(gBrowser.selectedTab); 1.87 + 1.88 + let inspector, toolbox; 1.89 + 1.90 + // Checking if the toolbox and the inspector are already loaded 1.91 + // The inspector-updated event should only be waited for if the inspector 1.92 + // isn't loaded yet 1.93 + toolbox = gDevTools.getToolbox(target); 1.94 + if (toolbox) { 1.95 + inspector = toolbox.getPanel("inspector"); 1.96 + if (inspector) { 1.97 + info("Toolbox and inspector already open"); 1.98 + if (cb) { 1.99 + return cb(inspector, toolbox); 1.100 + } else { 1.101 + return { 1.102 + toolbox: toolbox, 1.103 + inspector: inspector 1.104 + }; 1.105 + } 1.106 + } 1.107 + } 1.108 + 1.109 + info("Opening the toolbox"); 1.110 + toolbox = yield gDevTools.showToolbox(target, "inspector"); 1.111 + yield waitForToolboxFrameFocus(toolbox); 1.112 + inspector = toolbox.getPanel("inspector"); 1.113 + 1.114 + info("Waiting for the inspector to update"); 1.115 + yield inspector.once("inspector-updated"); 1.116 + 1.117 + if (cb) { 1.118 + return cb(inspector, toolbox); 1.119 + } else { 1.120 + return { 1.121 + toolbox: toolbox, 1.122 + inspector: inspector 1.123 + }; 1.124 + } 1.125 +}); 1.126 + 1.127 +/** 1.128 + * Wait for the toolbox frame to receive focus after it loads 1.129 + * @param {Toolbox} toolbox 1.130 + * @return a promise that resolves when focus has been received 1.131 + */ 1.132 +function waitForToolboxFrameFocus(toolbox) { 1.133 + info("Making sure that the toolbox's frame is focused"); 1.134 + let def = promise.defer(); 1.135 + let win = toolbox.frame.contentWindow; 1.136 + waitForFocus(def.resolve, win); 1.137 + return def.promise; 1.138 +} 1.139 + 1.140 +/** 1.141 + * Open the toolbox, with the inspector tool visible, and the sidebar that 1.142 + * corresponds to the given id selected 1.143 + * @return a promise that resolves when the inspector is ready and the sidebar 1.144 + * view is visible and ready 1.145 + */ 1.146 +let openInspectorSideBar = Task.async(function*(id) { 1.147 + let {toolbox, inspector} = yield openInspector(); 1.148 + 1.149 + if (!hasSideBarTab(inspector, id)) { 1.150 + info("Waiting for the " + id + " sidebar to be ready"); 1.151 + yield inspector.sidebar.once(id + "-ready"); 1.152 + } 1.153 + 1.154 + info("Selecting the " + id + " sidebar"); 1.155 + inspector.sidebar.select(id); 1.156 + 1.157 + return { 1.158 + toolbox: toolbox, 1.159 + inspector: inspector, 1.160 + view: inspector.sidebar.getWindowForTab(id)[id].view 1.161 + }; 1.162 +}); 1.163 + 1.164 +/** 1.165 + * Open the toolbox, with the inspector tool visible, and the computed-view 1.166 + * sidebar tab selected. 1.167 + * @return a promise that resolves when the inspector is ready and the computed 1.168 + * view is visible and ready 1.169 + */ 1.170 +function openComputedView() { 1.171 + return openInspectorSideBar("computedview"); 1.172 +} 1.173 + 1.174 +/** 1.175 + * Open the toolbox, with the inspector tool visible, and the rule-view 1.176 + * sidebar tab selected. 1.177 + * @return a promise that resolves when the inspector is ready and the rule 1.178 + * view is visible and ready 1.179 + */ 1.180 +function openRuleView() { 1.181 + return openInspectorSideBar("ruleview"); 1.182 +} 1.183 + 1.184 +/** 1.185 + * Checks whether the inspector's sidebar corresponding to the given id already 1.186 + * exists 1.187 + * @param {InspectorPanel} 1.188 + * @param {String} 1.189 + * @return {Boolean} 1.190 + */ 1.191 +function hasSideBarTab(inspector, id) { 1.192 + return !!inspector.sidebar.getWindowForTab(id); 1.193 +} 1.194 + 1.195 +function getActiveInspector() 1.196 +{ 1.197 + let target = TargetFactory.forTab(gBrowser.selectedTab); 1.198 + return gDevTools.getToolbox(target).getPanel("inspector"); 1.199 +} 1.200 + 1.201 +function getNodeFront(node) 1.202 +{ 1.203 + let inspector = getActiveInspector(); 1.204 + return inspector.walker.frontForRawNode(node); 1.205 +} 1.206 + 1.207 +function getHighlighter() 1.208 +{ 1.209 + return gBrowser.selectedBrowser.parentNode.querySelector(".highlighter-container"); 1.210 +} 1.211 + 1.212 +function getSimpleBorderRect() { 1.213 + let {p1, p2, p3, p4} = getBoxModelStatus().border.points; 1.214 + 1.215 + return { 1.216 + top: p1.y, 1.217 + left: p1.x, 1.218 + width: p2.x - p1.x, 1.219 + height: p4.y - p1.y 1.220 + }; 1.221 +} 1.222 + 1.223 +function getBoxModelRoot() { 1.224 + let highlighter = getHighlighter(); 1.225 + return highlighter.querySelector(".box-model-root"); 1.226 +} 1.227 + 1.228 +function getBoxModelStatus() { 1.229 + let root = getBoxModelRoot(); 1.230 + let inspector = getActiveInspector(); 1.231 + 1.232 + return { 1.233 + visible: !root.hasAttribute("hidden"), 1.234 + currentNode: inspector.walker.currentNode, 1.235 + margin: { 1.236 + points: getPointsForRegion("margin"), 1.237 + visible: isRegionHidden("margin") 1.238 + }, 1.239 + border: { 1.240 + points: getPointsForRegion("border"), 1.241 + visible: isRegionHidden("border") 1.242 + }, 1.243 + padding: { 1.244 + points: getPointsForRegion("padding"), 1.245 + visible: isRegionHidden("padding") 1.246 + }, 1.247 + content: { 1.248 + points: getPointsForRegion("content"), 1.249 + visible: isRegionHidden("content") 1.250 + }, 1.251 + guides: { 1.252 + top: getGuideStatus("top"), 1.253 + right: getGuideStatus("right"), 1.254 + bottom: getGuideStatus("bottom"), 1.255 + left: getGuideStatus("left") 1.256 + } 1.257 + }; 1.258 +} 1.259 + 1.260 +function getGuideStatus(location) { 1.261 + let root = getBoxModelRoot(); 1.262 + let guide = root.querySelector(".box-model-guide-" + location); 1.263 + 1.264 + return { 1.265 + visible: !guide.hasAttribute("hidden"), 1.266 + x1: guide.getAttribute("x1"), 1.267 + y1: guide.getAttribute("y1"), 1.268 + x2: guide.getAttribute("x2"), 1.269 + y2: guide.getAttribute("y2") 1.270 + }; 1.271 +} 1.272 + 1.273 +function getPointsForRegion(region) { 1.274 + let root = getBoxModelRoot(); 1.275 + let box = root.querySelector(".box-model-" + region); 1.276 + let points = box.getAttribute("points").split(/[, ]/); 1.277 + 1.278 + // We multiply each value by 1 to cast it into a number 1.279 + return { 1.280 + p1: { 1.281 + x: parseFloat(points[0]), 1.282 + y: parseFloat(points[1]) 1.283 + }, 1.284 + p2: { 1.285 + x: parseFloat(points[2]), 1.286 + y: parseFloat(points[3]) 1.287 + }, 1.288 + p3: { 1.289 + x: parseFloat(points[4]), 1.290 + y: parseFloat(points[5]) 1.291 + }, 1.292 + p4: { 1.293 + x: parseFloat(points[6]), 1.294 + y: parseFloat(points[7]) 1.295 + } 1.296 + }; 1.297 +} 1.298 + 1.299 +function isRegionHidden(region) { 1.300 + let root = getBoxModelRoot(); 1.301 + let box = root.querySelector(".box-model-" + region); 1.302 + 1.303 + return !box.hasAttribute("hidden"); 1.304 +} 1.305 + 1.306 +function isHighlighting() 1.307 +{ 1.308 + let root = getBoxModelRoot(); 1.309 + return !root.hasAttribute("hidden"); 1.310 +} 1.311 + 1.312 +function getHighlitNode() 1.313 +{ 1.314 + if (isHighlighting()) { 1.315 + let helper = new LayoutHelpers(window.content); 1.316 + let points = getBoxModelStatus().content.points; 1.317 + let x = (points.p1.x + points.p2.x + points.p3.x + points.p4.x) / 4; 1.318 + let y = (points.p1.y + points.p2.y + points.p3.y + points.p4.y) / 4; 1.319 + 1.320 + return helper.getElementFromPoint(window.content.document, x, y); 1.321 + } 1.322 +} 1.323 + 1.324 +function computedView() 1.325 +{ 1.326 + let sidebar = getActiveInspector().sidebar; 1.327 + let iframe = sidebar.tabbox.querySelector(".iframe-computedview"); 1.328 + return iframe.contentWindow.computedView; 1.329 +} 1.330 + 1.331 +function computedViewTree() 1.332 +{ 1.333 + return computedView().view; 1.334 +} 1.335 + 1.336 +function ruleView() 1.337 +{ 1.338 + let sidebar = getActiveInspector().sidebar; 1.339 + let iframe = sidebar.tabbox.querySelector(".iframe-ruleview"); 1.340 + return iframe.contentWindow.ruleView; 1.341 +} 1.342 + 1.343 +function getComputedView() { 1.344 + let inspector = getActiveInspector(); 1.345 + return inspector.sidebar.getWindowForTab("computedview").computedview.view; 1.346 +} 1.347 + 1.348 +function waitForView(aName, aCallback) { 1.349 + let inspector = getActiveInspector(); 1.350 + if (inspector.sidebar.getTab(aName)) { 1.351 + aCallback(); 1.352 + } else { 1.353 + inspector.sidebar.once(aName + "-ready", aCallback); 1.354 + } 1.355 +} 1.356 + 1.357 +function synthesizeKeyFromKeyTag(aKeyId) { 1.358 + let key = document.getElementById(aKeyId); 1.359 + isnot(key, null, "Successfully retrieved the <key> node"); 1.360 + 1.361 + let modifiersAttr = key.getAttribute("modifiers"); 1.362 + 1.363 + let name = null; 1.364 + 1.365 + if (key.getAttribute("keycode")) 1.366 + name = key.getAttribute("keycode"); 1.367 + else if (key.getAttribute("key")) 1.368 + name = key.getAttribute("key"); 1.369 + 1.370 + isnot(name, null, "Successfully retrieved keycode/key"); 1.371 + 1.372 + let modifiers = { 1.373 + shiftKey: modifiersAttr.match("shift"), 1.374 + ctrlKey: modifiersAttr.match("ctrl"), 1.375 + altKey: modifiersAttr.match("alt"), 1.376 + metaKey: modifiersAttr.match("meta"), 1.377 + accelKey: modifiersAttr.match("accel") 1.378 + } 1.379 + 1.380 + EventUtils.synthesizeKey(name, modifiers); 1.381 +} 1.382 + 1.383 +function focusSearchBoxUsingShortcut(panelWin, callback) { 1.384 + panelWin.focus(); 1.385 + let key = panelWin.document.getElementById("nodeSearchKey"); 1.386 + isnot(key, null, "Successfully retrieved the <key> node"); 1.387 + 1.388 + let modifiersAttr = key.getAttribute("modifiers"); 1.389 + 1.390 + let name = null; 1.391 + 1.392 + if (key.getAttribute("keycode")) { 1.393 + name = key.getAttribute("keycode"); 1.394 + } else if (key.getAttribute("key")) { 1.395 + name = key.getAttribute("key"); 1.396 + } 1.397 + 1.398 + isnot(name, null, "Successfully retrieved keycode/key"); 1.399 + 1.400 + let modifiers = { 1.401 + shiftKey: modifiersAttr.match("shift"), 1.402 + ctrlKey: modifiersAttr.match("ctrl"), 1.403 + altKey: modifiersAttr.match("alt"), 1.404 + metaKey: modifiersAttr.match("meta"), 1.405 + accelKey: modifiersAttr.match("accel") 1.406 + } 1.407 + 1.408 + let searchBox = panelWin.document.getElementById("inspector-searchbox"); 1.409 + searchBox.addEventListener("focus", function onFocus() { 1.410 + searchBox.removeEventListener("focus", onFocus, false); 1.411 + callback && callback(); 1.412 + }, false); 1.413 + EventUtils.synthesizeKey(name, modifiers); 1.414 +} 1.415 + 1.416 +function getComputedPropertyValue(aName) 1.417 +{ 1.418 + let computedview = getComputedView(); 1.419 + let props = computedview.styleDocument.querySelectorAll(".property-view"); 1.420 + 1.421 + for (let prop of props) { 1.422 + let name = prop.querySelector(".property-name"); 1.423 + 1.424 + if (name.textContent === aName) { 1.425 + let value = prop.querySelector(".property-value"); 1.426 + return value.textContent; 1.427 + } 1.428 + } 1.429 +} 1.430 + 1.431 +function getContainerForRawNode(markupView, rawNode) 1.432 +{ 1.433 + let front = markupView.walker.frontForRawNode(rawNode); 1.434 + let container = markupView.getContainer(front); 1.435 + return container; 1.436 +} 1.437 + 1.438 +SimpleTest.registerCleanupFunction(function () { 1.439 + let target = TargetFactory.forTab(gBrowser.selectedTab); 1.440 + gDevTools.closeToolbox(target); 1.441 +});