mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
Bug 547453: create a web page inspector for Firefox, r=gavin
This commit is contained in:
parent
cfc66f7a7c
commit
3350ea7bff
@ -21,6 +21,7 @@
|
||||
#
|
||||
# Contributor(s):
|
||||
# Ehsan Akhgari <ehsan.akhgari@gmail.com>
|
||||
# Rob Campbell <rcampbell@mozilla.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@ -598,6 +599,12 @@
|
||||
accesskey="&addons.accesskey;"
|
||||
command="Tools:Addons"/>
|
||||
<menuseparator id="devToolsSeparator"/>
|
||||
<menuitem id="menu_pageinspect"
|
||||
type="checkbox"
|
||||
label="&inspectMenu.label;"
|
||||
accesskey="&inspectMenu.accesskey;"
|
||||
key="&inspectMenu.commandkey;"
|
||||
command="Tools:Inspect"/>
|
||||
<menuitem id="javascriptConsole"
|
||||
label="&errorConsoleCmd.label;"
|
||||
accesskey="&errorConsoleCmd.accesskey;"
|
||||
|
@ -24,6 +24,7 @@
|
||||
# Blake Ross <blakeross@telocity.com>
|
||||
# Shawn Wilsher <me@shawnwilsher.com>
|
||||
# Ehsan Akhgari <ehsan.akhgari@gmail.com>
|
||||
# Rob Campbell <rcampbell@mozilla.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@ -124,6 +125,7 @@
|
||||
|
||||
<command id="Tools:Search" oncommand="BrowserSearch.webSearch();"/>
|
||||
<command id="Tools:Downloads" oncommand="BrowserDownloadsUI();"/>
|
||||
<command id="Tools:Inspect" oncommand="InspectorUI.toggleInspectorUI();"/>
|
||||
<command id="Tools:Addons" oncommand="BrowserOpenAddonsMgr();"/>
|
||||
<command id="Tools:Sanitize"
|
||||
oncommand="Cc['@mozilla.org/browser/browserglue;1'].getService(Ci.nsIBrowserGlue).sanitize(window);"/>
|
||||
@ -205,8 +207,6 @@
|
||||
# system setting to use emacs emulation, and we should respect it. Focus-Search-Box
|
||||
# is a fundamental keybinding and we are maintaining a XP binding so that it is easy
|
||||
# for people to switch to Linux.
|
||||
#
|
||||
# Do *not* tamper with these values without talking to ben@mozilla.org
|
||||
#
|
||||
<key id="key_search" key="&searchFocus.commandkey;" command="Tools:Search" modifiers="accel"/>
|
||||
#ifdef XP_MACOSX
|
||||
@ -222,6 +222,7 @@
|
||||
<key id="key_openDownloads" key="&downloads.commandkey;" command="Tools:Downloads" modifiers="accel"/>
|
||||
#endif
|
||||
<key id="key_errorConsole" key="&errorConsoleCmd.commandkey;" oncommand="toJavaScriptConsole();" modifiers="accel,shift"/>
|
||||
<key id="key_inspect" key="&inspectMenu.commandkey;" command="Tools:Inspect" modifiers="accel,shift"/>
|
||||
<key id="openFileKb" key="&openFileCmd.commandkey;" command="Browser:OpenFile" modifiers="accel"/>
|
||||
<key id="key_savePage" key="&savePageCmd.commandkey;" command="Browser:SavePage" modifiers="accel"/>
|
||||
<key id="printKb" key="&printCmd.commandkey;" command="cmd_print" modifiers="accel"/>
|
||||
|
@ -256,3 +256,10 @@ window[chromehidden~="toolbar"] toolbar:not(.toolbar-primary):not(.chromeclass-m
|
||||
-moz-binding: url("chrome://global/content/bindings/toolbarbutton.xml#toolbarbutton-image");
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Inspector / Highlighter */
|
||||
|
||||
#highlighter-panel {
|
||||
-moz-appearance: none;
|
||||
-moz-window-shadow: none;
|
||||
}
|
||||
|
@ -51,6 +51,7 @@
|
||||
# Dietrich Ayala <dietrich@mozilla.com>
|
||||
# Gavin Sharp <gavin@gavinsharp.com>
|
||||
# Justin Dolske <dolske@mozilla.com>
|
||||
# Rob Campbell <rcampbell@mozilla.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@ -128,6 +129,7 @@ let gInitialPages = [
|
||||
];
|
||||
|
||||
#include browser-fullZoom.js
|
||||
#include inspector.js
|
||||
#include browser-places.js
|
||||
#include browser-tabPreviews.js
|
||||
|
||||
|
@ -33,6 +33,7 @@
|
||||
# Dão Gottwald <dao@mozilla.com>
|
||||
# Ehsan Akhgari <ehsan.akhgari@gmail.com>
|
||||
# Robert Strong <robert.bugzilla@gmail.com>
|
||||
# Rob Campbell <rcampbell@mozilla.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@ -218,6 +219,35 @@
|
||||
</hbox>
|
||||
</panel>
|
||||
|
||||
<panel id="highlighter-panel"
|
||||
hidden="true"
|
||||
ignorekeys="true"
|
||||
noautofocus="true"
|
||||
noautohide="true"
|
||||
onclick="InspectorUI.stopInspecting();"
|
||||
onmousemove="InspectorUI.highlighter.handleMouseMove(event);"/>
|
||||
|
||||
<panel id="inspector-panel"
|
||||
orient="vertical"
|
||||
hidden="true"
|
||||
ignorekeys="true"
|
||||
noautofocus="true"
|
||||
noautohide="true"
|
||||
level="top"
|
||||
aria-labelledby="inspectPagePanelTitle">
|
||||
<tree id="inspector-tree" class="plain" seltype="single" treelines="true"
|
||||
onselect="InspectorUI.onTreeSelected()" flex="1">
|
||||
<treecols>
|
||||
<treecol id="colNodeName" label="nodeName" primary="true"
|
||||
persist="width,hidden,ordinal" flex="1"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol id="colNodeValue" label="nodeValue"
|
||||
persist="width,hidden,ordinal" flex="1"/>
|
||||
</treecols>
|
||||
<treechildren id="inspector-tree-body"/>
|
||||
</tree>
|
||||
</panel>
|
||||
|
||||
<popup id="toolbar-context-menu"
|
||||
onpopupshowing="onViewToolbarsPopupShowing(event);">
|
||||
<menuseparator/>
|
||||
@ -691,11 +721,13 @@
|
||||
label="&pasteCmd.label;"
|
||||
command="cmd_paste"
|
||||
tooltiptext="&pasteButton.tooltip;"/>
|
||||
|
||||
<toolbarbutton id="fullscreen-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
|
||||
observes="View:FullScreen"
|
||||
type="checkbox"
|
||||
label="&fullScreenCmd.label;"
|
||||
tooltiptext="&fullScreenButton.tooltip;"/>
|
||||
|
||||
</toolbarpalette>
|
||||
</toolbox>
|
||||
|
||||
|
758
browser/base/content/inspector.js
Normal file
758
browser/base/content/inspector.js
Normal file
@ -0,0 +1,758 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
#ifdef 0
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Mozilla Inspector Module.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Rob Campbell <rcampbell@mozilla.com> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
#endif
|
||||
|
||||
const INSPECTOR_INVISIBLE_ELEMENTS = {
|
||||
"head": true,
|
||||
"base": true,
|
||||
"basefont": true,
|
||||
"isindex": true,
|
||||
"link": true,
|
||||
"meta": true,
|
||||
"script": true,
|
||||
"style": true,
|
||||
"title": true,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//// PanelHighlighter
|
||||
|
||||
/**
|
||||
* A highlighter mechanism using xul panels.
|
||||
*
|
||||
* @param aBrowser
|
||||
* The XUL browser object for the content window being highlighted.
|
||||
* @param aColor
|
||||
* A string containing an RGB color for the panel background.
|
||||
* @param aBorderSize
|
||||
* A number representing the border thickness of the panel.
|
||||
* @param anOpacity
|
||||
* A number representing the alpha value of the panel background.
|
||||
*/
|
||||
function PanelHighlighter(aBrowser, aColor, aBorderSize, anOpacity)
|
||||
{
|
||||
this.panel = document.getElementById("highlighter-panel");
|
||||
this.panel.hidden = false;
|
||||
this.browser = aBrowser;
|
||||
this.win = this.browser.contentWindow;
|
||||
this.backgroundColor = aColor;
|
||||
this.border = aBorderSize;
|
||||
this.opacity = anOpacity;
|
||||
this.updatePanelStyles();
|
||||
}
|
||||
|
||||
PanelHighlighter.prototype = {
|
||||
|
||||
/**
|
||||
* Update the panel's style object with current settings.
|
||||
* TODO see bugXXXXXX, https://wiki.mozilla.org/Firefox/Projects/Inspector#0.7
|
||||
* and, https://wiki.mozilla.org/Firefox/Projects/Inspector#1.0.
|
||||
*/
|
||||
updatePanelStyles: function PanelHighlighter_updatePanelStyles()
|
||||
{
|
||||
let style = this.panel.style;
|
||||
style.backgroundColor = this.backgroundColor;
|
||||
style.border = "solid blue " + this.border + "px";
|
||||
style.MozBorderRadius = "4px";
|
||||
style.opacity = this.opacity;
|
||||
},
|
||||
|
||||
/**
|
||||
* Highlight this.node, unhilighting first if necessary.
|
||||
*
|
||||
* @param scroll
|
||||
* Boolean determining whether to scroll or not.
|
||||
*/
|
||||
highlight: function PanelHighlighter_highlight(scroll)
|
||||
{
|
||||
// node is not set or node is not highlightable, bail
|
||||
if (!this.isNodeHighlightable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.unhighlight();
|
||||
|
||||
let rect = this.node.getBoundingClientRect();
|
||||
|
||||
if (scroll) {
|
||||
this.node.scrollIntoView();
|
||||
}
|
||||
|
||||
if (this.viewContainsRect(rect)) {
|
||||
// TODO check for offscreen boundaries, bug565301
|
||||
this.panel.openPopup(this.node, "overlap", 0, 0, false, false);
|
||||
this.panel.sizeTo(rect.width, rect.height);
|
||||
} else {
|
||||
this.highlightVisibleRegion(rect);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Highlight the given node.
|
||||
*
|
||||
* @param element
|
||||
* a DOM element to be highlighted
|
||||
* @param params
|
||||
* extra parameters object
|
||||
*/
|
||||
highlightNode: function PanelHighlighter_highlightNode(element, params)
|
||||
{
|
||||
this.node = element;
|
||||
this.highlight(params && params.scroll);
|
||||
},
|
||||
|
||||
/**
|
||||
* Highlight the visible region of the region described by aRect, if any.
|
||||
*
|
||||
* @param aRect
|
||||
* @returns boolean
|
||||
* was a region highlighted?
|
||||
*/
|
||||
highlightVisibleRegion: function PanelHighlighter_highlightVisibleRegion(aRect)
|
||||
{
|
||||
let offsetX = 0;
|
||||
let offsetY = 0;
|
||||
let width = 0;
|
||||
let height = 0;
|
||||
let visibleWidth = this.win.innerWidth;
|
||||
let visibleHeight = this.win.innerHeight;
|
||||
|
||||
// If any of these edges are out-of-bounds, the node's rectangle is
|
||||
// completely out-of-view and we can return.
|
||||
if (aRect.top > visibleHeight || aRect.left > visibleWidth ||
|
||||
aRect.bottom < 0 || aRect.right < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Calculate node offsets, if values are negative, then start the offsets
|
||||
// at their absolute values from node origin. The delta should be the edge
|
||||
// of view.
|
||||
offsetX = aRect.left < 0 ? Math.abs(aRect.left) : 0;
|
||||
offsetY = aRect.top < 0 ? Math.abs(aRect.top) : 0;
|
||||
|
||||
// Calculate actual node width, taking into account the available visible
|
||||
// width and then subtracting the offset for the final dimension.
|
||||
width = aRect.right > visibleWidth ? visibleWidth - aRect.left :
|
||||
aRect.width;
|
||||
width -= offsetX;
|
||||
|
||||
// Calculate actual node height using the same formula as above for width.
|
||||
height = aRect.bottom > visibleHeight ? visibleHeight - aRect.top :
|
||||
aRect.height;
|
||||
height -= offsetY;
|
||||
|
||||
// If width and height are non-negative, open the highlighter popup over the
|
||||
// node and sizeTo width and height.
|
||||
if (width > 0 && height > 0) {
|
||||
this.panel.openPopup(this.node, "overlap", offsetX, offsetY, false,
|
||||
false);
|
||||
this.panel.sizeTo(width, height);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Close the highlighter panel.
|
||||
*/
|
||||
unhighlight: function PanelHighlighter_unhighlight()
|
||||
{
|
||||
if (this.isHighlighting) {
|
||||
this.panel.hidePopup();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Is the highlighter panel open?
|
||||
*
|
||||
* @returns boolean
|
||||
*/
|
||||
get isHighlighting()
|
||||
{
|
||||
return this.panel.state == "open";
|
||||
},
|
||||
|
||||
/**
|
||||
* Return the midpoint of a line from pointA to pointB.
|
||||
*
|
||||
* @param pointA
|
||||
* An object with x and y properties.
|
||||
* @param pointB
|
||||
* An object with x and y properties.
|
||||
* @returns aPoint
|
||||
* An object with x and y properties.
|
||||
*/
|
||||
midPoint: function PanelHighlighter_midPoint(pointA, pointB)
|
||||
{
|
||||
let pointC = { };
|
||||
pointC.x = (pointB.x - pointA.x) / 2 + pointA.x;
|
||||
pointC.y = (pointB.y - pointA.y) / 2 + pointA.y;
|
||||
return pointC;
|
||||
},
|
||||
|
||||
/**
|
||||
* Return the node under the highlighter rectangle. Useful for testing.
|
||||
* Calculation based on midpoint of diagonal from top left to bottom right
|
||||
* of panel.
|
||||
*
|
||||
* @returns a DOM node or null if none
|
||||
*/
|
||||
get highlitNode()
|
||||
{
|
||||
// No highlighter panel? Bail.
|
||||
if (!this.isHighlighting) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let browserRect = this.browser.getBoundingClientRect();
|
||||
let clientRect = this.panel.getBoundingClientRect();
|
||||
|
||||
// Calculate top left point offset minus browser chrome.
|
||||
let a = {
|
||||
x: clientRect.left - browserRect.left,
|
||||
y: clientRect.top - browserRect.top
|
||||
};
|
||||
|
||||
// Calculate bottom right point minus browser chrome.
|
||||
let b = {
|
||||
x: clientRect.right - browserRect.left,
|
||||
y: clientRect.bottom - browserRect.top
|
||||
};
|
||||
|
||||
// Get midpoint of diagonal line.
|
||||
let midpoint = this.midPoint(a, b);
|
||||
|
||||
return this.win.document.elementFromPoint(midpoint.x, midpoint.y);
|
||||
},
|
||||
|
||||
/**
|
||||
* Is this.node highlightable?
|
||||
*
|
||||
* @returns boolean
|
||||
*/
|
||||
isNodeHighlightable: function PanelHighlighter_isNodeHighlightable()
|
||||
{
|
||||
if (!this.node) {
|
||||
return false;
|
||||
}
|
||||
let nodeName = this.node.nodeName.toLowerCase();
|
||||
if (nodeName[0] == '#') {
|
||||
return false;
|
||||
}
|
||||
return !INSPECTOR_INVISIBLE_ELEMENTS[nodeName];
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if the given viewport-relative rect is within the visible area
|
||||
* of the window.
|
||||
*
|
||||
* @param aRect
|
||||
* a CSS rectangle object
|
||||
* @returns boolean
|
||||
*/
|
||||
viewContainsRect: function PanelHighlighter_viewContainsRect(aRect)
|
||||
{
|
||||
let visibleWidth = this.win.innerWidth;
|
||||
let visibleHeight = this.win.innerHeight;
|
||||
|
||||
return ((0 <= aRect.left) && (aRect.right <= visibleWidth) &&
|
||||
(0 <= aRect.top) && (aRect.bottom <= visibleHeight))
|
||||
},
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//// Event Handling
|
||||
|
||||
/**
|
||||
* Handle mousemoves in panel when InspectorUI.inspecting is true.
|
||||
*
|
||||
* @param event
|
||||
* The MouseEvent triggering the method.
|
||||
*/
|
||||
handleMouseMove: function PanelHighlighter_handleMouseMove(event)
|
||||
{
|
||||
if (!InspectorUI.inspecting) {
|
||||
return;
|
||||
}
|
||||
let browserRect = this.browser.getBoundingClientRect();
|
||||
let element = this.win.document.elementFromPoint(event.clientX -
|
||||
browserRect.left, event.clientY - browserRect.top);
|
||||
if (element && element != this.node) {
|
||||
InspectorUI.inspectNode(element);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//// InspectorTreeView
|
||||
|
||||
/**
|
||||
* TreeView object to manage the view of the DOM tree. Wraps and provides an
|
||||
* interface to an inIDOMView object
|
||||
*
|
||||
* @param aWindow
|
||||
* a top-level window object
|
||||
*/
|
||||
function InspectorTreeView(aWindow)
|
||||
{
|
||||
this.tree = document.getElementById("inspector-tree");
|
||||
this.treeBody = document.getElementById("inspector-tree-body");
|
||||
this.view = Cc["@mozilla.org/inspector/dom-view;1"]
|
||||
.createInstance(Ci.inIDOMView);
|
||||
this.view.showSubDocuments = true;
|
||||
this.view.whatToShow = NodeFilter.SHOW_ALL;
|
||||
this.tree.view = this.view;
|
||||
this.contentWindow = aWindow;
|
||||
this.view.rootNode = aWindow.document;
|
||||
this.view.rebuild();
|
||||
}
|
||||
|
||||
InspectorTreeView.prototype = {
|
||||
get editable() { return false; },
|
||||
get selection() { return this.view.selection; },
|
||||
|
||||
/**
|
||||
* Destroy the view.
|
||||
*/
|
||||
destroy: function ITV_destroy()
|
||||
{
|
||||
this.tree.view = null;
|
||||
this.view = null;
|
||||
this.tree = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the cell text at a given row and column.
|
||||
*
|
||||
* @param aRow
|
||||
* The row index of the desired cell.
|
||||
* @param aCol
|
||||
* The column index of the desired cell.
|
||||
* @returns string
|
||||
*/
|
||||
getCellText: function ITV_getCellText(aRow, aCol)
|
||||
{
|
||||
return this.view.getCellText(aRow, aCol);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the index of the selected row.
|
||||
*
|
||||
* @returns number
|
||||
*/
|
||||
get selectionIndex()
|
||||
{
|
||||
return this.selection.currentIndex;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the corresponding node for the currently-selected row in the tree.
|
||||
*
|
||||
* @returns DOMNode
|
||||
*/
|
||||
get selectedNode()
|
||||
{
|
||||
let rowIndex = this.selectionIndex;
|
||||
return this.view.getNodeFromRowIndex(rowIndex);
|
||||
},
|
||||
|
||||
/**
|
||||
* Set the selected row in the table to the specified index.
|
||||
*
|
||||
* @param anIndex
|
||||
* The index to set the selection to.
|
||||
*/
|
||||
set selectedRow(anIndex)
|
||||
{
|
||||
this.view.selection.select(anIndex);
|
||||
this.tree.treeBoxObject.ensureRowIsVisible(anIndex);
|
||||
},
|
||||
|
||||
/**
|
||||
* Set the selected node to the specified document node.
|
||||
*
|
||||
* @param aNode
|
||||
* The document node to select in the tree.
|
||||
*/
|
||||
set selectedNode(aNode)
|
||||
{
|
||||
let rowIndex = this.view.getRowIndexFromNode(aNode);
|
||||
if (rowIndex > -1) {
|
||||
this.selectedRow = rowIndex;
|
||||
} else {
|
||||
this.selectElementInTree(aNode);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Select the given node in the tree, searching for and expanding rows
|
||||
* as-needed.
|
||||
*
|
||||
* @param aNode
|
||||
* The document node to select in the three.
|
||||
* @returns boolean
|
||||
* Whether a node was selected or not if not found.
|
||||
*/
|
||||
selectElementInTree: function ITV_selectElementInTree(aNode)
|
||||
{
|
||||
if (!aNode) {
|
||||
this.view.selection.select(null);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Keep searching until a pre-created ancestor is found, then
|
||||
// open each ancestor until the found element is created.
|
||||
let domUtils = Cc["@mozilla.org/inspector/dom-utils;1"].
|
||||
getService(Ci.inIDOMUtils);
|
||||
let line = [];
|
||||
let parent = aNode;
|
||||
let index = null;
|
||||
|
||||
while (parent) {
|
||||
index = this.view.getRowIndexFromNode(parent);
|
||||
line.push(parent);
|
||||
if (index < 0) {
|
||||
// Row for this node hasn't been created yet.
|
||||
parent = domUtils.getParentForNode(parent,
|
||||
this.view.showAnonymousContent);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// We have all the ancestors, now open them one-by-one from the top
|
||||
// to bottom.
|
||||
let lastIndex;
|
||||
let view = this.tree.treeBoxObject.view;
|
||||
|
||||
for (let i = line.length - 1; i >= 0; i--) {
|
||||
index = this.view.getRowIndexFromNode(line[i]);
|
||||
if (index < 0) {
|
||||
// Can't find the row, so stop trying to descend.
|
||||
break;
|
||||
}
|
||||
if (i > 0 && !view.isContainerOpen(index)) {
|
||||
view.toggleOpenState(index);
|
||||
}
|
||||
lastIndex = index;
|
||||
}
|
||||
|
||||
if (lastIndex >= 0) {
|
||||
this.selectedRow = lastIndex;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//// InspectorUI
|
||||
|
||||
/**
|
||||
* Main controller class for the Inspector.
|
||||
*/
|
||||
var InspectorUI = {
|
||||
browser: null,
|
||||
_showTreePanel: true,
|
||||
_showStylePanel: false,
|
||||
_showDOMPanel: false,
|
||||
highlightColor: "#EEEE66",
|
||||
highlightThickness: 4,
|
||||
highlightOpacity: 0.4,
|
||||
selectEventsSuppressed: false,
|
||||
inspecting: false,
|
||||
|
||||
/**
|
||||
* Toggle the inspector interface elements on or off.
|
||||
*
|
||||
* @param event
|
||||
* The event that requested the UI change. Toolbar button or menu.
|
||||
*/
|
||||
toggleInspectorUI: function InspectorUI_toggleInspectorUI()
|
||||
{
|
||||
let toolsInspectCmd = document.getElementById("Tools:Inspect");
|
||||
if (this.isPanelOpen) {
|
||||
this.closeInspectorUI();
|
||||
toolsInspectCmd.setAttribute("checked", "false");
|
||||
} else {
|
||||
this.openInspectorUI();
|
||||
toolsInspectCmd.setAttribute("checked", "true");
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Is the tree panel open?
|
||||
*
|
||||
* @returns boolean
|
||||
*/
|
||||
get isPanelOpen()
|
||||
{
|
||||
return this.treePanel && this.treePanel.state == "open";
|
||||
},
|
||||
|
||||
/**
|
||||
* Open the inspector's tree panel and initialize it.
|
||||
*/
|
||||
openTreePanel: function InspectorUI_openTreePanel()
|
||||
{
|
||||
if (!this.treePanel) {
|
||||
this.treePanel = document.getElementById("inspector-panel");
|
||||
this.treePanel.hidden = false;
|
||||
}
|
||||
if (!this.isPanelOpen) {
|
||||
const panelWidthRatio = 7 / 8;
|
||||
const panelHeightRatio = 1 / 5;
|
||||
let bar = document.getElementById("status-bar");
|
||||
this.treePanel.openPopup(bar, "overlap", 120, -120, false, false);
|
||||
this.treePanel.sizeTo(this.win.outerWidth * panelWidthRatio,
|
||||
this.win.outerHeight * panelHeightRatio);
|
||||
this.tree = document.getElementById("inspector-tree");
|
||||
this.createDocumentModel();
|
||||
}
|
||||
},
|
||||
|
||||
openStylePanel: function InspectorUI_openStylePanel()
|
||||
{
|
||||
// # todo
|
||||
},
|
||||
|
||||
openDOMPanel: function InspectorUI_openDOMPanel()
|
||||
{
|
||||
// # todo
|
||||
},
|
||||
|
||||
/**
|
||||
* Open inspector UI. tree, style and DOM panels if enabled. Add listeners for
|
||||
* document scrolling and tabContainer.TabSelect.
|
||||
*/
|
||||
openInspectorUI: function InspectorUI_openInspectorUI()
|
||||
{
|
||||
// initialization
|
||||
this.browser = gBrowser.selectedBrowser;
|
||||
this.win = this.browser.contentWindow;
|
||||
|
||||
// open inspector UI
|
||||
if (this._showTreePanel) {
|
||||
this.openTreePanel();
|
||||
}
|
||||
if (this._showStylePanel) {
|
||||
this.openStylePanel();
|
||||
}
|
||||
if (this._showDOMPanel) {
|
||||
this.openDOMPanel();
|
||||
}
|
||||
this.initializeHighlighter();
|
||||
this.startInspecting();
|
||||
this.win.document.addEventListener("scroll", this, false);
|
||||
gBrowser.tabContainer.addEventListener("TabSelect", this, false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Initialize highlighter.
|
||||
*/
|
||||
initializeHighlighter: function InspectorUI_initializeHighlighter()
|
||||
{
|
||||
this.highlighter = new PanelHighlighter(this.browser, this.highlightColor,
|
||||
this.highlightThickness, this.highlightOpacity);
|
||||
},
|
||||
|
||||
/**
|
||||
* Close inspector UI and associated panels. Unhighlight and stop inspecting.
|
||||
* Remove event listeners for document scrolling and
|
||||
* tabContainer.TabSelect.
|
||||
*/
|
||||
closeInspectorUI: function InspectorUI_closeInspectorUI()
|
||||
{
|
||||
this.win.document.removeEventListener("scroll", this, false);
|
||||
gBrowser.tabContainer.removeEventListener("TabSelect", this, false);
|
||||
this.stopInspecting();
|
||||
if (this.highlighter && this.highlighter.isHighlighting) {
|
||||
this.highlighter.unhighlight();
|
||||
}
|
||||
if (this.isPanelOpen) {
|
||||
this.treePanel.hidePopup();
|
||||
this.treeView.destroy();
|
||||
}
|
||||
this.browser = this.win = null; // null out references to browser and window
|
||||
},
|
||||
|
||||
/**
|
||||
* Begin inspecting webpage, attach page event listeners, activate
|
||||
* highlighter event listeners.
|
||||
*/
|
||||
startInspecting: function InspectorUI_startInspecting()
|
||||
{
|
||||
this.attachPageListeners();
|
||||
this.inspecting = true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Stop inspecting webpage, detach page listeners, disable highlighter
|
||||
* event listeners.
|
||||
*/
|
||||
stopInspecting: function InspectorUI_stopInspecting()
|
||||
{
|
||||
if (!this.inspecting)
|
||||
return;
|
||||
this.detachPageListeners();
|
||||
this.inspecting = false;
|
||||
},
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//// Model Creation Methods
|
||||
|
||||
/**
|
||||
* Create treeView object from content window.
|
||||
*/
|
||||
createDocumentModel: function InspectorUI_createDocumentModel()
|
||||
{
|
||||
this.treeView = new InspectorTreeView(this.win);
|
||||
},
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//// Event Handling
|
||||
|
||||
/**
|
||||
* Main callback handler for events.
|
||||
*
|
||||
* @param event
|
||||
* The event to be handled.
|
||||
*/
|
||||
handleEvent: function InspectorUI_handleEvent(event)
|
||||
{
|
||||
switch (event.type) {
|
||||
case "TabSelect":
|
||||
this.closeInspectorUI();
|
||||
break;
|
||||
case "keypress":
|
||||
switch (event.keyCode) {
|
||||
case KeyEvent.DOM_VK_RETURN:
|
||||
case KeyEvent.DOM_VK_ESCAPE:
|
||||
this.stopInspecting();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "mousemove":
|
||||
let element = this.win.document.elementFromPoint(event.clientX,
|
||||
event.clientY);
|
||||
if (element && element != this.node) {
|
||||
this.inspectNode(element);
|
||||
}
|
||||
break;
|
||||
case "click":
|
||||
this.stopInspecting();
|
||||
break;
|
||||
case "scroll":
|
||||
this.highlighter.highlight();
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Event fired when a tree row is selected in the tree panel.
|
||||
*/
|
||||
onTreeSelected: function InspectorUI_onTreeSelected()
|
||||
{
|
||||
if (this.selectEventsSuppressed) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let treeView = this.treeView;
|
||||
let node = treeView.selectedNode;
|
||||
this.highlighter.highlightNode(node); // # todo scrolling causes issues
|
||||
this.stopInspecting();
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Attach event listeners to content window and child windows to enable
|
||||
* highlighting and click to stop inspection.
|
||||
*/
|
||||
attachPageListeners: function InspectorUI_attachPageListeners()
|
||||
{
|
||||
this.win.addEventListener("keypress", this, true);
|
||||
this.browser.addEventListener("mousemove", this, true);
|
||||
this.browser.addEventListener("click", this, true);
|
||||
},
|
||||
|
||||
/**
|
||||
* Detach event listeners from content window and child windows
|
||||
* to disable highlighting.
|
||||
*/
|
||||
detachPageListeners: function InspectorUI_detachPageListeners()
|
||||
{
|
||||
this.win.removeEventListener("keypress", this, true);
|
||||
this.browser.removeEventListener("mousemove", this, true);
|
||||
this.browser.removeEventListener("click", this, true);
|
||||
},
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//// Utility Methods
|
||||
|
||||
/**
|
||||
* inspect the given node, highlighting it on the page and selecting the
|
||||
* correct row in the tree panel
|
||||
*
|
||||
* @param element
|
||||
* the element in the document to inspect
|
||||
*/
|
||||
inspectNode: function InspectorUI_inspectNode(element)
|
||||
{
|
||||
this.highlighter.highlightNode(element);
|
||||
this.selectEventsSuppressed = true;
|
||||
this.treeView.selectedNode = element;
|
||||
this.selectEventsSuppressed = false;
|
||||
},
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//// Utility functions
|
||||
|
||||
/**
|
||||
* debug logging facility
|
||||
* @param msg
|
||||
* text message to send to the log
|
||||
*/
|
||||
_log: function LOG(msg)
|
||||
{
|
||||
Services.console.logStringMessage(msg);
|
||||
},
|
||||
}
|
||||
|
@ -125,6 +125,9 @@ _BROWSER_FILES = \
|
||||
browser_drag.js \
|
||||
browser_gestureSupport.js \
|
||||
browser_getshortcutoruri.js \
|
||||
browser_inspector_initialization.js \
|
||||
browser_inspector_treeSelection.js \
|
||||
browser_inspector_highlighter.js \
|
||||
browser_overflowScroll.js \
|
||||
browser_pageInfo.js \
|
||||
browser_page_style_menu.js \
|
||||
|
123
browser/base/content/test/browser_inspector_highlighter.js
Normal file
123
browser/base/content/test/browser_inspector_highlighter.js
Normal file
@ -0,0 +1,123 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Inspector Highlighter Tests.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Rob Campbell <rcampbell@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
let doc;
|
||||
let h1;
|
||||
|
||||
function createDocument()
|
||||
{
|
||||
let div = doc.createElement("div");
|
||||
let h1 = doc.createElement("h1");
|
||||
let p1 = doc.createElement("p");
|
||||
let p2 = doc.createElement("p");
|
||||
let div2 = doc.createElement("div");
|
||||
let p3 = doc.createElement("p");
|
||||
doc.title = "Inspector Tree Selection Test";
|
||||
h1.textContent = "Inspector Tree Selection Test";
|
||||
p1.textContent = "This is some example text";
|
||||
p2.textContent = "Lorem ipsum dolor sit amet, consectetur adipisicing " +
|
||||
"elit, sed do eiusmod tempor incididunt ut labore et dolore magna " +
|
||||
"aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco " +
|
||||
"laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure " +
|
||||
"dolor in reprehenderit in voluptate velit esse cillum dolore eu " +
|
||||
"fugiat nulla pariatur. Excepteur sint occaecat cupidatat non " +
|
||||
"proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
|
||||
p3.textContent = "Lorem ipsum dolor sit amet, consectetur adipisicing " +
|
||||
"elit, sed do eiusmod tempor incididunt ut labore et dolore magna " +
|
||||
"aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco " +
|
||||
"laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure " +
|
||||
"dolor in reprehenderit in voluptate velit esse cillum dolore eu " +
|
||||
"fugiat nulla pariatur. Excepteur sint occaecat cupidatat non " +
|
||||
"proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
|
||||
div.appendChild(h1);
|
||||
div.appendChild(p1);
|
||||
div.appendChild(p2);
|
||||
div2.appendChild(p3);
|
||||
doc.body.appendChild(div);
|
||||
doc.body.appendChild(div2);
|
||||
setupHighlighterTests();
|
||||
}
|
||||
|
||||
function setupHighlighterTests()
|
||||
{
|
||||
h1 = doc.querySelectorAll("h1")[0];
|
||||
ok(h1, "we have the header node");
|
||||
document.addEventListener("popupshown", runSelectionTests, false);
|
||||
InspectorUI.toggleInspectorUI();
|
||||
}
|
||||
|
||||
function runSelectionTests(evt)
|
||||
{
|
||||
if (evt.target.id != "inspector-panel")
|
||||
return true;
|
||||
document.removeEventListener("popupshown", runSelectionTests, false);
|
||||
document.addEventListener("popupshown", performTestComparisons, false);
|
||||
EventUtils.synthesizeMouse(h1, 2, 2, {type: "mousemove"}, content);
|
||||
}
|
||||
|
||||
function performTestComparisons(evt)
|
||||
{
|
||||
if (evt.target.id != "highlighter-panel")
|
||||
return true;
|
||||
document.removeEventListener("popupshown", performTestComparisons, false);
|
||||
is(h1, InspectorUI.treeView.selectedNode, "selection matches node");
|
||||
ok(InspectorUI.highlighter.isHighlighting, "panel is highlighting");
|
||||
is(InspectorUI.highlighter.highlitNode, h1, "highlighter matches selection");
|
||||
executeSoon(finishUp);
|
||||
}
|
||||
|
||||
function finishUp() {
|
||||
InspectorUI.closeInspectorUI();
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
doc = content.document;
|
||||
waitForFocus(createDocument, content);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,basic tests for inspector";
|
||||
}
|
||||
|
@ -0,0 +1,87 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Inspector Initializationa and Shutdown Tests.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Rob Campbell <rcampbell@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
let doc;
|
||||
|
||||
function startInspectorTests()
|
||||
{
|
||||
ok(InspectorUI, "InspectorUI variable exists");
|
||||
document.addEventListener("popupshown", runInspectorTests, false);
|
||||
InspectorUI.toggleInspectorUI();
|
||||
}
|
||||
|
||||
function runInspectorTests(evt)
|
||||
{
|
||||
if (evt.target.id != "inspector-panel")
|
||||
return true;
|
||||
document.removeEventListener("popupshown", runInspectorTests, false);
|
||||
document.addEventListener("popuphidden", finishInspectorTests, false);
|
||||
ok(InspectorUI.inspecting, "Inspector is highlighting");
|
||||
ok(InspectorUI.isPanelOpen, "Inspector Tree Panel is open");
|
||||
todo(InspectorUI.isStylePanelOpen, "Inspector Style Panel is open");
|
||||
todo(InspectorUI.isDOMPanelOpen, "Inspector DOM Panel is open");
|
||||
InspectorUI.toggleInspectorUI();
|
||||
}
|
||||
|
||||
function finishInspectorTests(evt)
|
||||
{
|
||||
if (evt.target.id != "inspector-panel")
|
||||
return true;
|
||||
document.removeEventListener("popuphidden", finishInspectorTests, false);
|
||||
ok(!InspectorUI.isDOMPanelOpen, "Inspector DOM Panel is closed");
|
||||
ok(!InspectorUI.isStylePanelOpen, "Inspector Style Panel is closed");
|
||||
ok(!InspectorUI.isPanelOpen, "Inspector Tree Panel is closed");
|
||||
ok(!InspectorUI.inspecting, "Inspector is not highlighting");
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
doc = content.document;
|
||||
waitForFocus(startInspectorTests, content);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,basic tests for inspector";
|
||||
}
|
||||
|
114
browser/base/content/test/browser_inspector_treeSelection.js
Normal file
114
browser/base/content/test/browser_inspector_treeSelection.js
Normal file
@ -0,0 +1,114 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Inspector Tree Selection Tests.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Rob Campbell <rcampbell@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
let doc;
|
||||
let h1;
|
||||
|
||||
function createDocument()
|
||||
{
|
||||
let div = doc.createElement("div");
|
||||
let h1 = doc.createElement("h1");
|
||||
let p1 = doc.createElement("p");
|
||||
let p2 = doc.createElement("p");
|
||||
doc.title = "Inspector Tree Selection Test";
|
||||
h1.textContent = "Inspector Tree Selection Test";
|
||||
p1.textContent = "This is some example text";
|
||||
p2.textContent = "Lorem ipsum dolor sit amet, consectetur adipisicing " +
|
||||
"elit, sed do eiusmod tempor incididunt ut labore et dolore magna " +
|
||||
"aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco " +
|
||||
"laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure " +
|
||||
"dolor in reprehenderit in voluptate velit esse cillum dolore eu " +
|
||||
"fugiat nulla pariatur. Excepteur sint occaecat cupidatat non " +
|
||||
"proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
|
||||
div.appendChild(h1);
|
||||
div.appendChild(p1);
|
||||
div.appendChild(p2);
|
||||
// doc.body.addEventListener("DOMSubtreeModified", , false);
|
||||
doc.body.appendChild(div);
|
||||
setupSelectionTests();
|
||||
}
|
||||
|
||||
function setupSelectionTests()
|
||||
{
|
||||
h1 = doc.querySelectorAll("h1")[0];
|
||||
ok(h1, "we have the header node");
|
||||
document.addEventListener("popupshown", runSelectionTests, false);
|
||||
InspectorUI.openInspectorUI();
|
||||
}
|
||||
|
||||
function runSelectionTests(evt)
|
||||
{
|
||||
if (evt.target.id != "inspector-panel")
|
||||
return true;
|
||||
document.removeEventListener("popupshown", runSelectionTests, false);
|
||||
InspectorUI.stopInspecting();
|
||||
document.addEventListener("popupshown", performTestComparisons, false);
|
||||
InspectorUI.treeView.selectedNode = h1;
|
||||
}
|
||||
|
||||
function performTestComparisons(evt)
|
||||
{
|
||||
if (evt.target.id != "highlighter-panel")
|
||||
return true;
|
||||
document.removeEventListener("popupshown", performTestComparisons, false);
|
||||
is(h1, InspectorUI.treeView.selectedNode, "selection matches node");
|
||||
ok(InspectorUI.highlighter.isHighlighting, "panel is highlighting");
|
||||
is(h1, InspectorUI.highlighter.highlitNode, "highlighter highlighting correct node");
|
||||
finishUp();
|
||||
}
|
||||
|
||||
function finishUp() {
|
||||
InspectorUI.closeInspectorUI();
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
doc = content.document;
|
||||
waitForFocus(createDocument, content);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,basic tests for inspector";
|
||||
}
|
||||
|
@ -159,6 +159,10 @@
|
||||
<!ENTITY errorConsoleCmd.accesskey "C">
|
||||
<!ENTITY errorConsoleCmd.commandkey "j">
|
||||
|
||||
<!ENTITY inspectMenu.label "Inspect">
|
||||
<!ENTITY inspectMenu.accesskey "I">
|
||||
<!ENTITY inspectMenu.commandkey "I">
|
||||
|
||||
<!ENTITY fileMenu.label "File">
|
||||
<!ENTITY fileMenu.accesskey "F">
|
||||
<!ENTITY newNavigatorCmd.label "New Window">
|
||||
|
@ -2044,3 +2044,4 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
|
||||
.allTabs-preview:focus > * > .allTabs-preview-inner {
|
||||
-moz-box-shadow: @focusRingShadow@;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user