Bug 572038 - Create new Tree Panel for Inspector, r=gavin, a=blocking2.0

This commit is contained in:
Rob Campbell 2010-08-31 14:31:48 -03:00
parent 52ca170fe4
commit 29601b34ea
27 changed files with 4294 additions and 347 deletions

View File

@ -56,6 +56,7 @@ endif
EXTRA_JS_MODULES = \
content/openLocationLastURL.jsm \
content/NetworkPrioritizer.jsm \
content/domplate.jsm \
content/stylePanel.jsm \
$(NULL)

View File

@ -234,13 +234,15 @@
onmousemove="InspectorUI.highlighter.handleMouseMove(event);"
onMozMousePixelScroll="InspectorUI.highlighter.handlePixelScroll(event);"/>
<panel id="inspector-panel"
<panel id="inspector-tree-panel"
orient="vertical"
hidden="true"
ignorekeys="true"
noautofocus="true"
noautohide="true"
titlebar="normal"
close="true"
onpopuphiding="InspectorUI.closeInspectorUI(true);"
label="&inspectPanelTitle.label;">
<toolbar id="inspector-toolbar"
nowindowdrag="true">
@ -270,20 +272,13 @@
class="toolbarbutton-text"
oncommand="InspectorUI.toggleDOMPanel();"/>
</toolbar>
<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>
<browser id="inspector-tree-browser"
flex="1"
type="content"
disablesecurity="true"
src="chrome://browser/content/inspector.html"
onclick="InspectorUI.onTreeClick(event);"
disablehistory="true" />
<hbox align="end">
<spacer flex="1" />
<resizer dir="bottomend" />

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,639 @@
/*
* Software License Agreement (BSD License)
*
* Copyright (c) 2007, Parakey Inc.
* All rights reserved.
*
* Redistribution and use of this software in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* * Neither the name of Parakey Inc. nor the names of its
* contributors may be used to endorse or promote products
* derived from this software without specific prior
* written permission of Parakey Inc.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Creator:
* Joe Hewitt
* Contributors
* John J. Barton (IBM Almaden)
* Jan Odvarko (Mozilla Corp.)
* Max Stepanov (Aptana Inc.)
* Rob Campbell (Mozilla Corp.)
* Hans Hillen (Paciello Group, Mozilla)
* Curtis Bartley (Mozilla Corp.)
* Mike Collins (IBM Almaden)
* Kevin Decker
* Mike Ratcliffe (Comartis AG)
* Hernan Rodríguez Colmeiro
* Austin Andrews
* Christoph Dorn
* Steven Roussey (AppCenter Inc, Network54)
*/
///////////////////////////////////////////////////////////////////////////
//// InsideOutBox
/**
* InsideOutBoxView is a simple interface definition for views implementing
* InsideOutBox controls. All implementors must define these methods.
* Implemented in InspectorUI.
*/
/*
InsideOutBoxView = {
//
* Retrieves the parent object for a given child object.
* @param aChild
* The child node to retrieve the parent object for.
* @returns a DOM node | null
//
getParentObject: function(aChild) {},
//
* Retrieves a given child node.
*
* If both index and previousSibling are passed, the implementation
* may assume that previousSibling will be the return for getChildObject
* with index-1.
* @param aParent
* The parent object of the child object to retrieve.
* @param aIndex
* The index of the child object to retrieve from aParent.
* @param aPreviousSibling
* The previous sibling of the child object to retrieve.
* Supercedes aIndex.
* @returns a DOM object | null
//
getChildObject: function(aParent, aIndex, aPreviousSibling) {},
//
* Renders the HTML representation of the object. Should return an HTML
* object which will be displayed to the user.
* @param aObject
* The object to create the box object for.
* @param aIsRoot
* Is the object the root object. May not be used in all
* implementations.
* @returns an object box | null
//
createObjectBox: function(aObject, aIsRoot) {},
//
* Convenience wrappers for classList API.
* @param aObject
* DOM node to query/set.
* @param aClassName
* String containing the class name to query/set.
//
hasClass: function(aObject, aClassName) {},
addClass: function(aObject, aClassName) {},
removeClass: function(aObject, aClassName) {}
};
*/
/**
* Creates a tree based on objects provided by a separate "view" object.
*
* Construction uses an "inside-out" algorithm, meaning that the view's job is
* first to tell us the ancestry of each object, and secondarily its
* descendants.
*
* Constructor
* @param aView
* The view requiring the InsideOutBox.
* @param aBox
* The box object containing the InsideOutBox. Required to add/remove
* children during box manipulation (toggling opened or closed).
*/
function InsideOutBox(aView, aBox)
{
this.view = aView;
this.box = aBox;
this.rootObject = null;
this.rootObjectBox = null;
this.selectedObjectBox = null;
this.highlightedObjectBox = null;
this.scrollIntoView = false;
};
InsideOutBox.prototype =
{
/**
* Highlight the given object node in the tree.
* @param aObject
* the object to highlight.
* @returns objectBox
*/
highlight: function IOBox_highlight(aObject)
{
let objectBox = this.createObjectBox(aObject);
this.highlightObjectBox(objectBox);
return objectBox;
},
/**
* Open the given object node in the tree.
* @param aObject
* The object node to open.
* @returns objectBox
*/
openObject: function IOBox_openObject(aObject)
{
let object = aObject;
let firstChild = this.view.getChildObject(object, 0);
if (firstChild)
object = firstChild;
return this.openToObject(object);
},
/**
* Open the tree up to the given object node.
* @param aObject
* The object in the tree to open to.
* @returns objectBox
*/
openToObject: function IOBox_openToObject(aObject)
{
let objectBox = this.createObjectBox(aObject);
this.openObjectBox(objectBox);
return objectBox;
},
/**
* Select the given object node in the tree.
* @param aObject
* The object node to select.
* @param makeBoxVisible
* Boolean. Open the object box in the tree?
* @param forceOpen
* Force the object box open by expanding all elements in the tree?
* @param scrollIntoView
* Scroll the objectBox into view?
* @returns objectBox
*/
select:
function IOBox_select(aObject, makeBoxVisible, forceOpen, scrollIntoView)
{
let objectBox = this.createObjectBox(aObject);
this.selectObjectBox(objectBox, forceOpen);
if (makeBoxVisible) {
this.openObjectBox(objectBox);
if (scrollIntoView) {
objectBox.scrollIntoView(true);
}
}
return objectBox;
},
/**
* Expands/contracts the given object, depending on its state.
* @param aObject
* The tree node to expand/contract.
*/
toggleObject: function IOBox_toggleObject(aObject)
{
let box = this.createObjectBox(aObject);
if (!(this.view.hasClass(box, "open")))
this.expandObjectBox(box);
else
this.contractObjectBox(box);
},
/**
* Expand the given object in the tree.
* @param aObject
* The tree node to expand.
*/
expandObject: function IOBox_expandObject(aObject)
{
let objectBox = this.createObjectBox(aObject);
if (objectBox)
this.expandObjectBox(objectBox);
},
/**
* Contract the given object in the tree.
* @param aObject
* The tree node to contract.
*/
contractObject: function IOBox_contractObject(aObject)
{
let objectBox = this.createObjectBox(aObject);
if (objectBox)
this.contractObjectBox(objectBox);
},
/**
* General method for iterating over an object's ancestors and performing
* some function.
* @param aObject
* The object whose ancestors we wish to iterate over.
* @param aCallback
* The function to call with the object as argument.
*/
iterateObjectAncestors: function IOBox_iterateObjectAncesors(aObject, aCallback)
{
let object = aObject;
if (!(aCallback && typeof(aCallback) == "function")) {
this.view._log("Illegal argument in IOBox.iterateObjectAncestors");
return;
}
while ((object = this.getParentObjectBox(object)))
aCallback(object);
},
/**
* Highlight the given objectBox in the tree.
* @param aObjectBox
* The objectBox to highlight.
*/
highlightObjectBox: function IOBox_highlightObjectBox(aObjectBox)
{
let self = this;
if (!aObjectBox)
return;
if (this.highlightedObjectBox) {
this.view.removeClass(this.highlightedObjectBox, "highlighted");
this.iterateObjectAncestors(this.highlightedObjectBox, function (box) {
self.view.removeClass(box, "highlightOpen");
});
}
this.highlightedObjectBox = aObjectBox;
this.view.addClass(aObjectBox, "highlighted");
this.iterateObjectAncestors(this.highlightedObjectBox, function (box) {
self.view.addClass(box, "highlightOpen");
});
aObjectBox.scrollIntoView(true);
},
/**
* Select the given objectBox in the tree, forcing it to be open if necessary.
* @param aObjectBox
* The objectBox to select.
* @param forceOpen
* Force the box (subtree) to be open?
*/
selectObjectBox: function IOBox_selectObjectBox(aObjectBox, forceOpen)
{
let isSelected = this.selectedObjectBox &&
aObjectBox == this.selectedObjectBox;
// aObjectBox is already selected, return
if (isSelected)
return;
if (this.selectedObjectBox)
this.view.removeClass(this.selectedObjectBox, "selected");
this.selectedObjectBox = aObjectBox;
if (aObjectBox) {
this.view.addClass(aObjectBox, "selected");
// Force it open the first time it is selected
if (forceOpen)
this.expandObjectBox(aObjectBox, true);
}
},
/**
* Open the ancestors of the given object box.
* @param aObjectBox
* The object box to open.
*/
openObjectBox: function IOBox_openObjectBox(aObjectBox)
{
if (!aObjectBox)
return;
let self = this;
this.iterateObjectAncestors(aObjectBox, function (box) {
self.view.addClass(box, "open");
let labelBox = box.querySelector(".nodeLabelBox");
if (labelBox)
labelBox.setAttribute("aria-expanded", "true");
});
},
/**
* Expand the given object box.
* @param aObjectBox
* The object box to expand.
*/
expandObjectBox: function IOBox_expandObjectBox(aObjectBox)
{
let nodeChildBox = this.getChildObjectBox(aObjectBox);
// no children means nothing to expand, return
if (!nodeChildBox)
return;
if (!aObjectBox.populated) {
let firstChild = this.view.getChildObject(aObjectBox.repObject, 0);
this.populateChildBox(firstChild, nodeChildBox);
}
let labelBox = aObjectBox.querySelector(".nodeLabelBox");
if (labelBox)
labelBox.setAttribute("aria-expanded", "true");
this.view.addClass(aObjectBox, "open");
},
/**
* Contract the given object box.
* @param aObjectBox
* The object box to contract.
*/
contractObjectBox: function IOBox_contractObjectBox(aObjectBox)
{
this.view.removeClass(aObjectBox, "open");
let nodeLabel = aObjectBox.querySelector(".nodeLabel");
let labelBox = nodeLabel.querySelector(".nodeLabelBox");
if (labelBox)
labelBox.setAttribute("aria-expanded", "false");
},
/**
* Toggle the given object box, forcing open if requested.
* @param aObjectBox
* The object box to toggle.
* @param forceOpen
* Force the objectbox open?
*/
toggleObjectBox: function IOBox_toggleObjectBox(aObjectBox, forceOpen)
{
let isOpen = this.view.hasClass(aObjectBox, "open");
if (!forceOpen && isOpen)
this.contractObjectBox(aObjectBox);
else if (!isOpen)
this.expandObjectBox(aObjectBox);
},
/**
* Creates all of the boxes for an object, its ancestors, and siblings.
* @param aObject
* The tree node to create the object boxes for.
* @returns anObjectBox or null
*/
createObjectBox: function IOBox_createObjectBox(aObject)
{
if (!aObject)
return null;
this.rootObject = this.getRootNode(aObject) || aObject;
// Get or create all of the boxes for the target and its ancestors
let objectBox = this.createObjectBoxes(aObject, this.rootObject);
if (!objectBox)
return null;
if (aObject == this.rootObject)
return objectBox;
return this.populateChildBox(aObject, objectBox.parentNode);
},
/**
* Creates all of the boxes for an object, its ancestors, and siblings up to
* a root.
* @param aObject
* The tree's object node to create the object boxes for.
* @param aRootObject
* The root object at which to stop building object boxes.
* @returns an object box or null
*/
createObjectBoxes: function IOBox_createObjectBoxes(aObject, aRootObject)
{
if (!aObject)
return null;
if (aObject == aRootObject) {
if (!this.rootObjectBox || this.rootObjectBox.repObject != aRootObject) {
if (this.rootObjectBox) {
try {
this.box.removeChild(this.rootObjectBox);
} catch (exc) {
InspectorUI._log("this.box.removeChild(this.rootObjectBox) FAILS " +
this.box + " must not contain " + this.rootObjectBox);
}
}
this.highlightedObjectBox = null;
this.selectedObjectBox = null;
this.rootObjectBox = this.view.createObjectBox(aObject, true);
this.box.appendChild(this.rootObjectBox);
}
return this.rootObjectBox;
}
let parentNode = this.view.getParentObject(aObject);
let parentObjectBox = this.createObjectBoxes(parentNode, aRootObject);
if (!parentObjectBox)
return null;
let parentChildBox = this.getChildObjectBox(parentObjectBox);
if (!parentChildBox)
return null;
let childObjectBox = this.findChildObjectBox(parentChildBox, aObject);
return childObjectBox ? childObjectBox
: this.populateChildBox(aObject, parentChildBox);
},
/**
* Locate the object box for a given object node.
* @param aObject
* The given object node in the tree.
* @returns an object box or null.
*/
findObjectBox: function IOBox_findObjectBox(aObject)
{
if (!aObject)
return null;
if (aObject == this.rootObject)
return this.rootObjectBox;
let parentNode = this.view.getParentObject(aObject);
let parentObjectBox = this.findObjectBox(parentNode);
if (!parentObjectBox)
return null;
let parentChildBox = this.getChildObjectBox(parentObjectBox);
if (!parentChildBox)
return null;
return this.findChildObjectBox(parentChildBox, aObject);
},
getAncestorByClass: function IOBox_getAncestorByClass(node, className)
{
for (let parent = node; parent; parent = parent.parentNode) {
if (this.view.hasClass(parent, className))
return parent;
}
return null;
},
/**
* We want all children of the parent of repObject.
*/
populateChildBox: function IOBox_populateChildBox(repObject, nodeChildBox)
{
if (!repObject)
return null;
let parentObjectBox = this.getAncestorByClass(nodeChildBox, "nodeBox");
if (parentObjectBox.populated)
return this.findChildObjectBox(nodeChildBox, repObject);
let lastSiblingBox = this.getChildObjectBox(nodeChildBox);
let siblingBox = nodeChildBox.firstChild;
let targetBox = null;
let view = this.view;
let targetSibling = null;
let parentNode = view.getParentObject(repObject);
for (let i = 0; 1; ++i) {
targetSibling = view.getChildObject(parentNode, i, targetSibling);
if (!targetSibling)
break;
// Check if we need to start appending, or continue to insert before
if (lastSiblingBox && lastSiblingBox.repObject == targetSibling)
lastSiblingBox = null;
if (!siblingBox || siblingBox.repObject != targetSibling) {
let newBox = view.createObjectBox(targetSibling);
if (newBox) {
if (lastSiblingBox)
nodeChildBox.insertBefore(newBox, lastSiblingBox);
else
nodeChildBox.appendChild(newBox);
}
siblingBox = newBox;
}
if (targetSibling == repObject)
targetBox = siblingBox;
if (siblingBox && siblingBox.repObject == targetSibling)
siblingBox = siblingBox.nextSibling;
}
if (targetBox)
parentObjectBox.populated = true;
return targetBox;
},
/**
* Get the parent object box of a given object box.
* @params aObjectBox
* The object box of the parent.
* @returns an object box or null
*/
getParentObjectBox: function IOBox_getParentObjectBox(aObjectBox)
{
let parent = aObjectBox.parentNode ? aObjectBox.parentNode.parentNode : null;
return parent && parent.repObject ? parent : null;
},
/**
* Get the child object box of a given object box.
* @param aObjectBox
* The object box whose child you want.
* @returns an object box or null
*/
getChildObjectBox: function IOBox_getChildObjectBox(aObjectBox)
{
return aObjectBox.querySelector(".nodeChildBox");
},
/**
* Find the child object box for a given repObject within the subtree
* rooted at aParentNodeBox.
* @param aParentNodeBox
* root of the subtree in which to search for repObject.
* @param aRepObject
* The object you wish to locate in the subtree.
* @returns an object box or null
*/
findChildObjectBox: function IOBox_findChildObjectBox(aParentNodeBox, aRepObject)
{
let childBox = aParentNodeBox.firstChild;
while (childBox) {
if (childBox.repObject == aRepObject)
return childBox;
childBox = childBox.nextSibling;
}
return null; // not found
},
/**
* Determines if the given node is an ancestor of the current root.
* @param aNode
* The node to look for within the tree.
* @returns boolean
*/
isInExistingRoot: function IOBox_isInExistingRoot(aNode)
{
let parentNode = aNode;
while (parentNode && parentNode != this.rootObject) {
parentNode = this.view.getParentObject(parentNode);
}
return parentNode == this.rootObject;
},
/**
* Get the root node of a given node.
* @param aNode
* The node whose root you wish to retrieve.
* @returns a root node or null
*/
getRootNode: function IOBox_getRootNode(aNode)
{
let node = aNode;
let tmpNode;
while ((tmpNode = this.view.getParentObject(node)))
node = tmpNode;
return node;
},
};

View File

@ -0,0 +1,11 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<link rel="stylesheet" href="chrome://browser/skin/inspector.css" type="text/css"/>
</head>
<body role="application">
</body>
</html>

View File

@ -41,6 +41,8 @@
* ***** END LICENSE BLOCK ***** */
#endif
#include insideOutBox.js
const INSPECTOR_INVISIBLE_ELEMENTS = {
"head": true,
"base": true,
@ -272,7 +274,7 @@ PanelHighlighter.prototype = {
let visibleWidth = this.win.innerWidth;
let visibleHeight = this.win.innerHeight;
return ((0 <= aRect.left) && (aRect.right <= visibleWidth) &&
return ((0 <= aRect.left) && (aRect.right <= visibleWidth) &&
(0 <= aRect.top) && (aRect.bottom <= visibleHeight))
},
@ -322,169 +324,6 @@ PanelHighlighter.prototype = {
}
};
///////////////////////////////////////////////////////////////////////////
//// 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 -1 if there is no row selected.
*/
get selectionIndex()
{
return this.selection ? this.selection.currentIndex : -1;
},
/**
* Get the corresponding node for the currently-selected row in the tree.
*
* @returns DOMNode|null
*/
get selectedNode()
{
let rowIndex = this.selectionIndex;
return rowIndex > -1 ? this.view.getNodeFromRowIndex(rowIndex) : null;
},
/**
* 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
@ -494,6 +333,7 @@ InspectorTreeView.prototype = {
var InspectorUI = {
browser: null,
selectEventsSuppressed: false,
showTextNodesWithWhitespace: false,
inspecting: false,
/**
@ -504,7 +344,7 @@ var InspectorUI = {
*/
toggleInspectorUI: function IUI_toggleInspectorUI(aEvent)
{
if (this.isPanelOpen) {
if (this.isTreePanelOpen) {
this.closeInspectorUI(true);
} else {
this.openInspectorUI();
@ -533,8 +373,8 @@ var InspectorUI = {
this.stylePanel.hidePopup();
} else {
this.openStylePanel();
if (this.treeView.selectedNode) {
this.updateStylePanel(this.treeView.selectedNode);
if (this.selection) {
this.updateStylePanel(this.selection);
}
}
},
@ -549,8 +389,8 @@ var InspectorUI = {
} else {
this.clearDOMPanel();
this.openDOMPanel();
if (this.treeView.selectedNode) {
this.updateDOMPanel(this.treeView.selectedNode);
if (this.selection) {
this.updateDOMPanel(this.selection);
}
}
},
@ -560,7 +400,7 @@ var InspectorUI = {
*
* @returns boolean
*/
get isPanelOpen()
get isTreePanelOpen()
{
return this.treePanel && this.treePanel.state == "open";
},
@ -585,26 +425,165 @@ var InspectorUI = {
return this.domPanel && this.domPanel.state == "open";
},
/**
* Return the default selection element for the inspected document.
*/
get defaultSelection()
{
let doc = this.win.document;
return doc.documentElement.lastElementChild;
},
/**
* Open the inspector's tree panel and initialize it.
*/
openTreePanel: function IUI_openTreePanel()
{
if (!this.treePanel) {
this.treePanel = document.getElementById("inspector-panel");
this.treePanel = document.getElementById("inspector-tree-panel");
this.treePanel.hidden = false;
}
if (!this.isPanelOpen) {
const panelWidthRatio = 7 / 8;
const panelHeightRatio = 1 / 5;
let bar = document.getElementById("status-bar");
this.treePanel.openPopupAtScreen(this.win.screenX + 80,
this.win.outerHeight + this.win.screenY);
this.treePanel.sizeTo(this.win.outerWidth * panelWidthRatio,
this.win.outerHeight * panelHeightRatio);
this.tree = document.getElementById("inspector-tree");
this.createDocumentModel();
const panelWidthRatio = 7 / 8;
const panelHeightRatio = 1 / 5;
this.treePanel.openPopup(this.browser, "overlap", 80, this.win.innerHeight,
false, false);
this.treePanel.sizeTo(this.win.outerWidth * panelWidthRatio,
this.win.outerHeight * panelHeightRatio);
this.treeBrowser = document.getElementById("inspector-tree-browser");
let self = this;
this.treeBrowser.addEventListener("load", function() {
self.treeBrowser.removeEventListener("load", arguments.callee, true);
self.treeBrowserDocument = self.treeBrowser.contentDocument;
self.treePanelDiv = self.treeBrowserDocument.createElement("div");
self.treeBrowserDocument.body.appendChild(self.treePanelDiv);
self.treePanelDiv.ownerPanel = self;
self.ioBox = new InsideOutBox(self, self.treePanelDiv);
self.ioBox.createObjectBox(self.win.document.documentElement);
if (InspectorStore.hasID(self.winID)) {
let selectedNode = InspectorStore.getValue(self.winID, "selectedNode");
if (selectedNode) {
self.inspectNode(selectedNode);
}
} else {
InspectorStore.addStore(self.winID);
InspectorStore.setValue(self.winID, "selectedNode", null);
self.win.addEventListener("pagehide", self, true);
}
Services.obs.notifyObservers(null, "inspector-opened", null);
}, true);
this.treeBrowser.reload();
},
createObjectBox: function IUI_createObjectBox(object, isRoot)
{
let tag = this.domplateUtils.getNodeTag(object);
if (tag)
return tag.replace({object: object}, this.treeBrowserDocument);
},
getParentObject: function IUI_getParentObject(node)
{
let parentNode = node ? node.parentNode : null;
if (!parentNode) {
// Documents have no parentNode; Attr, Document, DocumentFragment, Entity,
// and Notation. top level windows have no parentNode
if (node && node == Node.DOCUMENT_NODE) {
// document type
if (node.defaultView) {
let embeddingFrame = node.defaultView.frameElement;
if (embeddingFrame)
return embeddingFrame.parentNode;
}
}
// a Document object without a parentNode or window
return null; // top level has no parent
}
if (parentNode.nodeType == Node.DOCUMENT_NODE) {
if (parentNode.defaultView) {
return parentNode.defaultView.frameElement;
}
if (this.embeddedBrowserParents) {
let skipParent = this.embeddedBrowserParents[node];
// HTML element? could be iframe?
if (skipParent)
return skipParent;
} else // parent is document element, but no window at defaultView.
return null;
} else if (!parentNode.localName) {
return null;
}
return parentNode;
},
getChildObject: function IUI_getChildObject(node, index, previousSibling)
{
if (!node)
return null;
if (node.contentDocument) {
// then the node is a frame
if (index == 0) {
if (!this.embeddedBrowserParents)
this.embeddedBrowserParents = {};
let skipChild = node.contentDocument.documentElement;
this.embeddedBrowserParents[skipChild] = node;
return skipChild; // the node's HTMLElement
}
return null;
}
if (node instanceof GetSVGDocument) {
// then the node is a frame
if (index == 0) {
if (!this.embeddedBrowserParents)
this.embeddedBrowserParents = {};
let skipChild = node.getSVGDocument().documentElement;
this.embeddedBrowserParents[skipChild] = node;
return skipChild; // the node's SVGElement
}
return null;
}
let child = null;
if (previousSibling) // then we are walking
child = this.getNextSibling(previousSibling);
else
child = this.getFirstChild(node);
if (this.showTextNodesWithWhitespace)
return child;
for (; child; child = this.getNextSibling(child)) {
if (!this.domplateUtils.isWhitespaceText(child))
return child;
}
return null; // we have no children worth showing.
},
getFirstChild: function IUI_getFirstChild(node)
{
this.treeWalker = node.ownerDocument.createTreeWalker(node,
NodeFilter.SHOW_ALL, null, false);
return this.treeWalker.firstChild();
},
getNextSibling: function IUI_getNextSibling(node)
{
let next = this.treeWalker.nextSibling();
if (!next)
delete this.treeWalker;
return next;
},
/**
@ -664,6 +643,10 @@ var InspectorUI = {
this.browser = gBrowser.selectedBrowser;
this.win = this.browser.contentWindow;
this.winID = this.getWindowID(this.win);
if (!this.domplate) {
Cu.import("resource:///modules/domplate.jsm", this);
this.domplateUtils.setDOM(window);
}
// DOM panel initialization and loading (via PropertyPanel.jsm)
let objectPanelTitle = this.strings.
@ -705,17 +688,6 @@ var InspectorUI = {
if (InspectorStore.isEmpty()) {
gBrowser.tabContainer.addEventListener("TabSelect", this, false);
}
if (InspectorStore.hasID(this.winID)) {
let selectedNode = InspectorStore.getValue(this.winID, "selectedNode");
if (selectedNode) {
this.inspectNode(selectedNode);
}
} else {
InspectorStore.addStore(this.winID);
InspectorStore.setValue(this.winID, "selectedNode", null);
this.win.addEventListener("pagehide", this, true);
}
},
/**
@ -736,13 +708,21 @@ var InspectorUI = {
*/
closeInspectorUI: function IUI_closeInspectorUI(aClearStore)
{
if (this.closing || !this.win || !this.browser) {
return;
}
this.closing = true;
if (aClearStore) {
InspectorStore.deleteStore(this.winID);
this.win.removeEventListener("pagehide", this, true);
} else {
// Update the store before closing.
InspectorStore.setValue(this.winID, "selectedNode",
this.treeView.selectedNode);
if (this.selection) {
InspectorStore.setValue(this.winID, "selectedNode",
this.selection);
}
InspectorStore.setValue(this.winID, "inspecting", this.inspecting);
}
@ -756,10 +736,28 @@ var InspectorUI = {
if (this.highlighter && this.highlighter.isHighlighting) {
this.highlighter.unhighlight();
}
if (this.isPanelOpen) {
if (this.isTreePanelOpen)
this.treePanel.hidePopup();
this.treeView.destroy();
if (this.treePanelDiv) {
this.treePanelDiv.ownerPanel = null;
let parent = this.treePanelDiv.parentNode;
parent.removeChild(this.treePanelDiv);
delete this.treePanelDiv;
delete this.treeBrowserDocument;
}
if (this.treeBrowser)
delete this.treeBrowser;
delete this.ioBox;
if (this.domplate) {
this.domplateUtils.setDOM(null);
delete this.domplate;
delete this.HTMLTemplates;
delete this.domplateUtils;
}
if (this.isStylePanelOpen) {
this.stylePanel.hidePopup();
}
@ -772,6 +770,9 @@ var InspectorUI = {
this.inspectCmd.setAttribute("checked", false);
this.browser = this.win = null; // null out references to browser and window
this.winID = null;
this.selection = null;
this.closing = false;
Services.obs.notifyObservers(null, "inspector-closed", null);
},
/**
@ -798,23 +799,40 @@ var InspectorUI = {
this.inspecting = false;
this.toggleDimForPanel(this.stylePanel);
this.toggleDimForPanel(this.domPanel);
if (this.treeView.selection) {
this.updateStylePanel(this.treeView.selectedNode);
this.updateDOMPanel(this.treeView.selectedNode);
if (this.highlighter.node) {
this.select(this.highlighter.node, true, true);
}
},
/**
* Select an object in the tree view.
* @param aNode
* node to inspect
* @param forceUpdate
* force an update?
* @param aScroll
* force scroll?
*/
select: function IUI_select(aNode, forceUpdate, aScroll)
{
if (!aNode)
aNode = this.defaultSelection;
if (forceUpdate || aNode != this.selection) {
this.selection = aNode;
let box = this.ioBox.createObjectBox(this.selection);
if (!this.inspecting) {
this.highlighter.highlightNode(this.selection);
this.updateStylePanel(this.selection);
this.updateDOMPanel(this.selection);
}
this.ioBox.select(aNode, true, true, aScroll);
}
},
/////////////////////////////////////////////////////////////////////////
//// Model Creation Methods
/**
* Create treeView object from content window.
*/
createDocumentModel: function IUI_createDocumentModel()
{
this.treeView = new InspectorTreeView(this.win);
},
/**
* Add a new item to the style panel listbox.
*
@ -879,8 +897,8 @@ var InspectorUI = {
createStyleItems: function IUI_createStyleItems(aRules, aSections)
{
this.createStyleRuleItems(aRules);
let inheritedString =
this.strings.GetStringFromName("style.inheritedFrom");
let inheritedString =
this.strings.GetStringFromName("style.inheritedFrom");
aSections.forEach(function(section) {
let sectionTitle = section.element.tagName;
if (section.element.id)
@ -954,19 +972,25 @@ var InspectorUI = {
{
let winID = null;
let win = null;
let inspectorClosed = false;
switch (event.type) {
case "TabSelect":
winID = this.getWindowID(gBrowser.selectedBrowser.contentWindow);
if (this.isPanelOpen && winID != this.winID) {
if (this.isTreePanelOpen && winID != this.winID) {
this.closeInspectorUI(false);
inspectorClosed = true;
}
if (winID && InspectorStore.hasID(winID)) {
this.openInspectorUI();
}
if (InspectorStore.isEmpty()) {
if (inspectorClosed && this.closing) {
Services.obs.addObserver(function () {
InspectorUI.openInspectorUI();
}, "inspector-closed", false);
} else {
this.openInspectorUI();
}
} else if (InspectorStore.isEmpty()) {
gBrowser.tabContainer.removeEventListener("TabSelect", this, false);
}
break;
@ -1014,24 +1038,31 @@ var InspectorUI = {
},
/**
* Event fired when a tree row is selected in the tree panel.
* Handle click events in the html tree panel.
* @param aEvent
* The mouse event.
*/
onTreeSelected: function IUI_onTreeSelected()
onTreeClick: function IUI_onTreeClick(aEvent)
{
if (this.selectEventsSuppressed) {
return false;
let node;
let target = aEvent.target;
let hitTwisty = false;
if (this.hasClass(target, "twisty")) {
node = this.getRepObject(aEvent.target.nextSibling);
hitTwisty = true;
} else {
node = this.getRepObject(aEvent.target);
}
let node = this.treeView.selectedNode;
this.highlighter.highlightNode(node);
this.stopInspecting();
this.updateStylePanel(node);
this.updateDOMPanel(node);
return true;
if (node) {
if (hitTwisty)
this.ioBox.toggleObject(node);
this.select(node, false, false);
}
},
/**
* Attach event listeners to content window and child windows to enable
* Attach event listeners to content window and child windows to enable
* highlighting and click to stop inspection.
*/
attachPageListeners: function IUI_attachPageListeners()
@ -1066,14 +1097,14 @@ var InspectorUI = {
{
this.highlighter.highlightNode(aNode);
this.selectEventsSuppressed = true;
this.treeView.selectedNode = aNode;
this.select(aNode, true, true);
this.selectEventsSuppressed = false;
this.updateStylePanel(aNode);
this.updateDOMPanel(aNode);
},
/**
* Find an element from the given coordinates. This method descends through
* Find an element from the given coordinates. This method descends through
* frames to find the element the user clicked inside frames.
*
* @param DOMDocument aDocument the document to look into.
@ -1104,6 +1135,47 @@ var InspectorUI = {
///////////////////////////////////////////////////////////////////////////
//// Utility functions
/**
* Does the given object have a class attribute?
* @param aNode
* the DOM node.
* @param aClass
* The class string.
* @returns boolean
*/
hasClass: function IUI_hasClass(aNode, aClass)
{
if (!(aNode instanceof Element))
return false;
return aNode.classList.contains(aClass);
},
/**
* Add the class name to the given object.
* @param aNode
* the DOM node.
* @param aClass
* The class string.
*/
addClass: function IUI_addClass(aNode, aClass)
{
if (aNode instanceof Element)
aNode.classList.add(aClass);
},
/**
* Remove the class name from the given object
* @param aNode
* the DOM node.
* @param aClass
* The class string.
*/
removeClass: function IUI_removeClass(aNode, aClass)
{
if (aNode instanceof Element)
aNode.classList.remove(aClass);
},
/**
* Retrieve the unique ID of a window object.
*
@ -1127,7 +1199,32 @@ var InspectorUI = {
},
/**
* debug logging facility
* Get the "repObject" from the HTML panel's domplate-constructed DOM node.
* In this system, a "repObject" is the Object being Represented by the box
* object. It is the "real" object that we're building our facade around.
*
* @param element
* The element in the HTML panel the user clicked.
* @returns either a real node or null
*/
getRepObject: function IUI_getRepObject(element)
{
let target = null;
for (let child = element; child; child = child.parentNode) {
if (this.hasClass(child, "repTarget"))
target = child;
if (child.repObject) {
if (!target && this.hasClass(child.repObject, "repIgnore"))
break;
else
return child.repObject;
}
}
return null;
},
/**
* @param msg
* text message to send to the log
*/

View File

@ -312,3 +312,4 @@ var style = {
}
},
};

View File

@ -161,6 +161,9 @@ _BROWSER_FILES = \
browser_inspector_scrolling.js \
browser_inspector_store.js \
browser_inspector_tab_switch.js \
browser_inspector_treePanel_output.js \
browser_inspector_treePanel_input.html \
browser_inspector_treePanel_result.html \
browser_pageInfo.js \
browser_page_style_menu.js \
browser_pinnedTabs.js \
@ -182,6 +185,7 @@ _BROWSER_FILES = \
browser_visibleTabs_bookmarkAllTabs.js \
browser_visibleTabs_tabPreview.js \
discovery.html \
domplate_test.js \
moz.png \
test_bug435035.html \
test_bug462673.html \
@ -197,7 +201,7 @@ _BROWSER_FILES = \
browser_tabMatchesInAwesomebar.js \
file_bug550565_popup.html \
file_bug550565_favicon.ico \
$(NULL)
$(NULL)
ifneq (cocoa,$(MOZ_WIDGET_TOOLKIT))
_BROWSER_FILES += \

View File

@ -56,7 +56,7 @@ function createDocument()
'<p id="closing">end transmission</p>\n' +
'</div>';
doc.title = "Inspector DOM Test";
document.addEventListener("popupshown", runDOMTests, false);
Services.obs.addObserver(runDOMTests, "inspector-opened", false);
InspectorUI.openInspectorUI();
}
@ -71,19 +71,17 @@ function nodeGenerator()
let first = doc.getElementById("first");
InspectorUI.inspectNode(first);
yield;
let closing = doc.getElementById("#closing");
let closing = doc.getElementById("closing");
InspectorUI.inspectNode(closing);
yield;
}
function runDOMTests(evt)
function runDOMTests()
{
if (evt.target.id != "inspector-dom-panel")
return true;
InspectorUI._log("runDOMtests");
document.removeEventListener("popupshown", runDOMTests, false);
InspectorUI.stopInspecting();
Services.obs.removeObserver(runDOMTests, "inspector-opened", false);
document.addEventListener("popupshown", performTestComparisons, false);
InspectorUI.stopInspecting();
testGen = nodeGenerator();
testGen.next();
}
@ -94,7 +92,7 @@ function performTestComparisons(evt)
if (evt.target.id != "highlighter-panel")
return true;
ok(InspectorUI.treeView.selectedNode, "selection");
ok(InspectorUI.selection, "selection");
ok(InspectorUI.isDOMPanelOpen, "DOM panel is open?");
ok(InspectorUI.highlighter.isHighlighting, "panel is highlighting");
ok(InspectorUI.domTreeView.rowCount > 0, "domBox has items");

View File

@ -78,15 +78,13 @@ function setupHighlighterTests()
{
h1 = doc.querySelectorAll("h1")[0];
ok(h1, "we have the header node");
document.addEventListener("popupshown", runSelectionTests, false);
Services.obs.addObserver(runSelectionTests, "inspector-opened", false);
InspectorUI.toggleInspectorUI();
}
function runSelectionTests(evt)
function runSelectionTests()
{
if (evt.target.id != "inspector-panel")
return true;
document.removeEventListener("popupshown", runSelectionTests, false);
Services.obs.removeObserver(runSelectionTests, "inspector-opened", false);
document.addEventListener("popupshown", performTestComparisons, false);
EventUtils.synthesizeMouse(h1, 2, 2, {type: "mousemove"}, content);
}
@ -96,7 +94,7 @@ function performTestComparisons(evt)
if (evt.target.id != "highlighter-panel")
return true;
document.removeEventListener("popupshown", performTestComparisons, false);
is(h1, InspectorUI.treeView.selectedNode, "selection matches node");
is(h1, InspectorUI.selection, "selection matches node");
ok(InspectorUI.highlighter.isHighlighting, "panel is highlighting");
is(InspectorUI.highlighter.highlitNode, h1, "highlighter matches selection");
executeSoon(finishUp);

View File

@ -79,30 +79,27 @@ function createDocument()
function setupIframeTests()
{
document.addEventListener("popupshown", runIframeTests, false);
InspectorUI.toggleInspectorUI();
Services.obs.addObserver(runIframeTests, "inspector-opened", false);
InspectorUI.openInspectorUI();
}
function runIframeTests(evt)
function runIframeTests()
{
if (evt.target.id != "inspector-panel")
return true;
document.removeEventListener("popupshown", runIframeTests, false);
Services.obs.removeObserver(runIframeTests, "inspector-opened", false);
document.addEventListener("popupshown", performTestComparisons1, false);
EventUtils.synthesizeMouse(div1, 2, 2, {type: "mousemove"},
iframe1.contentWindow);
}
function performTestComparisons1(evt)
{
if (evt.target.id != "highlighter-panel")
if (evt.target.id != "highlighter-panel") {
return true;
}
document.removeEventListener("popupshown", performTestComparisons1, false);
document.removeEventListener(evt.type, arguments.callee, false);
is(InspectorUI.treeView.selectedNode, div1, "selection matches div1 node");
is(InspectorUI.selection, div1, "selection matches div1 node");
is(InspectorUI.highlighter.highlitNode, div1, "highlighter matches selection");
document.addEventListener("popupshown", performTestComparisons2, false);
@ -113,12 +110,13 @@ function performTestComparisons1(evt)
function performTestComparisons2(evt)
{
if (evt.target.id != "highlighter-panel")
if (evt.target.id != "highlighter-panel") {
return true;
}
document.removeEventListener("popupshown", performTestComparisons2, false);
document.removeEventListener(evt.type, arguments.callee, false);
is(InspectorUI.treeView.selectedNode, div2, "selection matches div2 node");
is(InspectorUI.selection, div2, "selection matches div2 node");
is(InspectorUI.highlighter.highlitNode, div2, "highlighter matches selection");
executeSoon(finishUp);
@ -139,7 +137,7 @@ function test()
doc = content.document;
waitForFocus(createDocument, content);
}, true);
content.location = "data:text/html,iframe tests for inspector";
}

View File

@ -42,31 +42,27 @@ let doc;
function startInspectorTests()
{
ok(InspectorUI, "InspectorUI variable exists");
document.addEventListener("popupshown", runInspectorTests, false);
Services.obs.addObserver(runInspectorTests, "inspector-opened", false);
InspectorUI.toggleInspectorUI();
}
function runInspectorTests(evt)
function runInspectorTests()
{
if (evt.target.id != "inspector-dom-panel")
return true;
document.removeEventListener("popupshown", runInspectorTests, false);
document.addEventListener("popuphidden", finishInspectorTests, false);
Services.obs.removeObserver(runInspectorTests, "inspector-opened", false);
Services.obs.addObserver(finishInspectorTests, "inspector-closed", false);
ok(InspectorUI.inspecting, "Inspector is highlighting");
ok(InspectorUI.isPanelOpen, "Inspector Tree Panel is open");
ok(InspectorUI.isTreePanelOpen, "Inspector Tree Panel is open");
ok(InspectorUI.isStylePanelOpen, "Inspector Style Panel is open");
ok(InspectorUI.isDOMPanelOpen, "Inspector DOM Panel is open");
InspectorUI.toggleInspectorUI();
}
function finishInspectorTests(evt)
function finishInspectorTests()
{
if (evt.target.id != "inspector-dom-panel")
return true;
document.removeEventListener("popuphidden", finishInspectorTests, false);
Services.obs.removeObserver(finishInspectorTests, "inspector-closed", 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.isTreePanelOpen, "Inspector Tree Panel is closed");
ok(!InspectorUI.inspecting, "Inspector is not highlighting");
gBrowser.removeCurrentTab();
finish();

View File

@ -65,17 +65,13 @@ function createDocument()
function toggleInspector()
{
document.addEventListener("popupshown", inspectNode, false);
Services.obs.addObserver(inspectNode, "inspector-opened", false);
InspectorUI.toggleInspectorUI();
}
function inspectNode(aEvent)
function inspectNode()
{
if (aEvent.target.id != "inspector-panel") {
return true;
}
document.removeEventListener("popupshown", inspectNode, false);
Services.obs.removeObserver(inspectNode, "inspector-opened", false);
document.addEventListener("popupshown", performScrollingTest, false);
InspectorUI.inspectNode(div)

View File

@ -64,7 +64,7 @@ function setupStyleTests()
{
spans = doc.querySelectorAll("span");
ok(spans, "captain, we have the spans");
document.addEventListener("popupshown", runStyleTests, false);
Services.obs.addObserver(runStyleTests, "inspector-opened", false);
InspectorUI.openInspectorUI();
}
@ -76,11 +76,9 @@ function spanGenerator()
}
}
function runStyleTests(evt)
function runStyleTests()
{
if (evt.target.id != "inspector-style-panel")
return true;
document.removeEventListener("popupshown", runStyleTests, false);
Services.obs.removeObserver(runStyleTests, "inspector-opened", false);
document.addEventListener("popupshown", performTestComparisons, false);
InspectorUI.stopInspecting();
testGen = spanGenerator();
@ -92,7 +90,7 @@ function performTestComparisons(evt)
if (evt.target.id != "highlighter-panel")
return true;
ok(InspectorUI.treeView.selectedNode, "selection");
ok(InspectorUI.selection, "selection");
ok(InspectorUI.isStylePanelOpen, "style panel is open?");
ok(InspectorUI.highlighter.isHighlighting, "panel is highlighting");
ok(InspectorUI.styleBox.itemCount > 0, "styleBox has items");

View File

@ -49,21 +49,17 @@ function inspectorTabOpen1()
ok(!InspectorUI.inspecting, "Inspector is not highlighting");
ok(InspectorStore.isEmpty(), "InspectorStore is empty");
document.addEventListener("popupshown", inspectorUIOpen1, false);
InspectorUI.toggleInspectorUI();
Services.obs.addObserver(inspectorUIOpen1, "inspector-opened", false);
InspectorUI.openInspectorUI();
}
function inspectorUIOpen1(evt)
function inspectorUIOpen1()
{
if (evt.target.id != "inspector-style-panel") {
return true;
}
document.removeEventListener(evt.type, arguments.callee, false);
Services.obs.removeObserver(inspectorUIOpen1, "inspector-opened", false);
// Make sure the inspector is open.
ok(InspectorUI.inspecting, "Inspector is highlighting");
ok(InspectorUI.isPanelOpen, "Inspector Tree Panel is open");
ok(InspectorUI.isTreePanelOpen, "Inspector Tree Panel is open");
ok(InspectorUI.isStylePanelOpen, "Inspector Style Panel is open");
ok(!InspectorStore.isEmpty(), "InspectorStore is not empty");
is(InspectorStore.length, 1, "InspectorStore.length = 1");
@ -71,8 +67,7 @@ function inspectorUIOpen1(evt)
// Highlight a node.
div = content.document.getElementsByTagName("div")[0];
InspectorUI.inspectNode(div);
is(InspectorUI.treeView.selectedNode, div,
"selection matches the div element");
is(InspectorUI.selection, div, "selection matches the div element");
// Open the second tab.
tab2 = gBrowser.addTab();
@ -95,21 +90,17 @@ function inspectorTabOpen2()
is(InspectorStore.length, 1, "InspectorStore.length = 1");
// Activate the inspector again.
document.addEventListener("popupshown", inspectorUIOpen2, false);
InspectorUI.toggleInspectorUI();
Services.obs.addObserver(inspectorUIOpen2, "inspector-opened", false);
InspectorUI.openInspectorUI();
}
function inspectorUIOpen2(evt)
function inspectorUIOpen2()
{
if (evt.target.id != "inspector-style-panel") {
return true;
}
document.removeEventListener(evt.type, arguments.callee, false);
Services.obs.removeObserver(inspectorUIOpen2, "inspector-opened", false);
// Make sure the inspector is open.
ok(InspectorUI.inspecting, "Inspector is highlighting");
ok(InspectorUI.isPanelOpen, "Inspector Tree Panel is open");
ok(InspectorUI.isTreePanelOpen, "Inspector Tree Panel is open");
ok(InspectorUI.isStylePanelOpen, "Inspector Style Panel is open");
is(InspectorStore.length, 2, "InspectorStore.length = 2");
@ -118,50 +109,40 @@ function inspectorUIOpen2(evt)
ok(!InspectorUI.inspecting, "Inspector is not highlighting");
// Switch back to tab 1.
document.addEventListener("popupshown", inspectorFocusTab1, false);
Services.obs.addObserver(inspectorFocusTab1, "inspector-opened", false);
gBrowser.selectedTab = tab1;
}
function inspectorFocusTab1(evt)
function inspectorFocusTab1()
{
if (evt.target.id != "inspector-style-panel") {
return true;
}
document.removeEventListener(evt.type, arguments.callee, false);
Services.obs.removeObserver(inspectorFocusTab1, "inspector-opened", false);
// Make sure the inspector is still open.
ok(InspectorUI.inspecting, "Inspector is highlighting");
ok(InspectorUI.isPanelOpen, "Inspector Tree Panel is open");
ok(InspectorUI.isTreePanelOpen, "Inspector Tree Panel is open");
ok(InspectorUI.isStylePanelOpen, "Inspector Style Panel is open");
is(InspectorStore.length, 2, "InspectorStore.length = 2");
is(InspectorUI.treeView.selectedNode, div,
"selection matches the div element");
is(InspectorUI.selection, div, "selection matches the div element");
// Switch back to tab 2.
document.addEventListener("popupshown", inspectorFocusTab2, false);
Services.obs.addObserver(inspectorFocusTab2, "inspector-opened", false);
gBrowser.selectedTab = tab2;
}
function inspectorFocusTab2(evt)
function inspectorFocusTab2()
{
if (evt.target.id != "inspector-style-panel") {
return true;
}
document.removeEventListener(evt.type, arguments.callee, false);
Services.obs.removeObserver(inspectorFocusTab2, "inspector-opened", false);
// Make sure the inspector is still open.
ok(!InspectorUI.inspecting, "Inspector is not highlighting");
ok(InspectorUI.isPanelOpen, "Inspector Tree Panel is open");
ok(InspectorUI.isTreePanelOpen, "Inspector Tree Panel is open");
ok(InspectorUI.isStylePanelOpen, "Inspector Style Panel is open");
is(InspectorStore.length, 2, "InspectorStore.length = 2");
isnot(InspectorUI.treeView.selectedNode, div,
"selection does not match the div element");
isnot(InspectorUI.selection, div, "selection does not match the div element");
// Remove tab 1.
tab1window = gBrowser.getBrowserForTab(tab1).contentWindow;
tab1window.addEventListener("unload", inspectorTabUnload1, false);
tab1window.addEventListener("pagehide", inspectorTabUnload1, false);
gBrowser.removeTab(tab1);
}
@ -172,7 +153,7 @@ function inspectorTabUnload1(evt)
// Make sure the Inspector is still open and that the state is correct.
ok(!InspectorUI.inspecting, "Inspector is not highlighting");
ok(InspectorUI.isPanelOpen, "Inspector Tree Panel is open");
ok(InspectorUI.isTreePanelOpen, "Inspector Tree Panel is open");
ok(InspectorUI.isStylePanelOpen, "Inspector Style Panel is open");
is(InspectorStore.length, 1, "InspectorStore.length = 1");

View File

@ -0,0 +1,33 @@
<!DOCTYPE html>
<html xml:lang="en">
<head>
<meta charset="utf-8">
<title>Inspector tree panel test</title>
<style type="text/css"><!--
#duplicate { color: green }
--></style>
<script type="text/javascript"><!--
function fooBarBaz(arg1) {
return true; // do nothing
}
// --></script>
</head>
<body arbitrary:attribute="value">
<p>Inspector tree panel test.</p>
<div id="foo" class="foo bar baz" style="border:1px solid red;
unknownProperty: unknownValue; color: withUnkownValue">
<unknownTag unknownAttribute="fooBar">
<p unknownAttribute="fooBar" data-test1="value">hello world!</p>
</unknownTag>
</div>
<div id="duplicate" id="duplicate" id="different" class="test" class="foo"
fooBar="baz" fooBar="bazbaz">test</div>
<iframe src="data:text/html,&lt;div&gt;hello from an iframe!&lt;/div&gt;">no
frames!</iframe>
<!-- hello world from a comment! -->
</body>
</html>

View 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 iframe 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):
* Mihai Șucan <mihai.sucan@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
* 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 = null;
let xhr = null;
let expectedResult = "";
const TEST_URI = "http://mochi.test:8888/browser/browser/base/content/test/browser_inspector_treePanel_input.html";
const RESULT_URI = "http://mochi.test:8888/browser/browser/base/content/test/browser_inspector_treePanel_result.html";
function tabFocused()
{
xhr = new XMLHttpRequest();
xhr.onreadystatechange = xhr_onReadyStateChange;
xhr.open("GET", RESULT_URI, true);
xhr.send(null);
}
function xhr_onReadyStateChange() {
if (xhr.readyState != 4) {
return;
}
is(xhr.status, 200, "xhr.status is 200");
ok(!!xhr.responseText, "xhr.responseText is available");
expectedResult = xhr.responseText.replace(/^\s+|\s+$/mg, '');
xhr = null;
Services.obs.addObserver(inspectorOpened, "inspector-opened", false);
InspectorUI.openInspectorUI();
}
function inspectorOpened()
{
Services.obs.removeObserver(inspectorOpened, "inspector-opened", false);
ok(InspectorUI.inspecting, "Inspector is highlighting");
ok(InspectorUI.isTreePanelOpen, "Inspector Tree Panel is open");
InspectorUI.stopInspecting();
ok(!InspectorUI.inspecting, "Inspector is not highlighting");
let elements = doc.querySelectorAll("meta, script, style, p[unknownAttribute]");
for (let i = 0; i < elements.length; i++) {
InspectorUI.inspectNode(elements[i]);
}
let iframe = doc.querySelector("iframe");
ok(iframe, "Found the iframe tag");
ok(iframe.contentDocument, "Found the iframe.contentDocument");
let iframeDiv = iframe.contentDocument.querySelector("div");
ok(iframeDiv, "Found the div element inside the iframe");
InspectorUI.inspectNode(iframeDiv);
ok(InspectorUI.treePanelDiv, "InspectorUI.treePanelDiv is available");
is(InspectorUI.treePanelDiv.innerHTML.replace(/^\s+|\s+$/mg, ''),
expectedResult, "treePanelDiv.innerHTML is correct");
expectedResult = null;
Services.obs.addObserver(inspectorClosed, "inspector-closed", false);
InspectorUI.closeInspectorUI();
}
function inspectorClosed()
{
Services.obs.removeObserver(inspectorClosed, "inspector-closed", false);
ok(!InspectorUI.inspecting, "Inspector is not highlighting");
ok(!InspectorUI.isTreePanelOpen, "Inspector Tree Panel is not open");
gBrowser.removeCurrentTab();
finish();
}
function test()
{
waitForExplicitFinish();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function(evt) {
gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee, true);
doc = content.document;
waitForFocus(tabFocused, content);
}, true);
content.location = TEST_URI;
}

File diff suppressed because one or more lines are too long

View File

@ -68,18 +68,16 @@ function setupSelectionTests()
{
h1 = doc.querySelectorAll("h1")[0];
ok(h1, "we have the header node");
document.addEventListener("popupshown", runSelectionTests, false);
Services.obs.addObserver(runSelectionTests, "inspector-opened", false);
InspectorUI.openInspectorUI();
}
function runSelectionTests(evt)
function runSelectionTests()
{
if (evt.target.id != "inspector-panel")
return true;
document.removeEventListener("popupshown", runSelectionTests, false);
Services.obs.removeObserver(runSelectionTests, "inspector-opened", false);
InspectorUI.stopInspecting();
document.addEventListener("popupshown", performTestComparisons, false);
InspectorUI.treeView.selectedNode = h1;
InspectorUI.inspectNode(h1);
}
function performTestComparisons(evt)
@ -87,7 +85,7 @@ function performTestComparisons(evt)
if (evt.target.id != "highlighter-panel")
return true;
document.removeEventListener("popupshown", performTestComparisons, false);
is(h1, InspectorUI.treeView.selectedNode, "selection matches node");
is(h1, InspectorUI.selection, "selection matches node");
ok(InspectorUI.highlighter.isHighlighting, "panel is highlighting");
is(h1, InspectorUI.highlighter.highlitNode, "highlighter highlighting correct node");
finishUp();

View File

@ -0,0 +1,84 @@
/* -*- 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 Domplate Test.
*
* 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 div;
let plate;
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
Components.utils.import("resource:///modules/domplate.jsm");
function createDocument()
{
doc.body.innerHTML = '<div id="first">no</div>';
doc.title = "Domplate Test";
setupDomplateTests();
}
function setupDomplateTests()
{
ok(domplate, "domplate is defined");
plate = domplate({tag: domplate.DIV("Hello!")});
ok(plate, "template is defined");
div = doc.getElementById("first");
ok(div, "we have our div");
plate.tag.replace({}, div, template);
is(div.innerText, "Hello!", "Is the div's innerText replaced?");
finishUp();
}
function finishUp()
{
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 domplate tests";
}

View File

@ -30,6 +30,7 @@ browser.jar:
* content/browser/browser-tabPreviews.xml (content/browser-tabPreviews.xml)
* content/browser/credits.xhtml (content/credits.xhtml)
* content/browser/fullscreen-video.xhtml (content/fullscreen-video.xhtml)
* content/browser/inspector.html (content/inspector.html)
* content/browser/pageinfo/pageInfo.xul (content/pageinfo/pageInfo.xul)
* content/browser/pageinfo/pageInfo.js (content/pageinfo/pageInfo.js)
* content/browser/pageinfo/pageInfo.css (content/pageinfo/pageInfo.css)

View File

@ -0,0 +1,377 @@
/*
* Software License Agreement (BSD License)
*
* Copyright (c) 2007, Parakey Inc.
* All rights reserved.
*
* Redistribution and use of this software in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* * Neither the name of Parakey Inc. nor the names of its
* contributors may be used to endorse or promote products
* derived from this software without specific prior
* written permission of Parakey Inc.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Creator:
* Joe Hewitt
* Contributors
* John J. Barton (IBM Almaden)
* Jan Odvarko (Mozilla Corp.)
* Max Stepanov (Aptana Inc.)
* Rob Campbell (Mozilla Corp.)
* Hans Hillen (Paciello Group, Mozilla)
* Curtis Bartley (Mozilla Corp.)
* Mike Collins (IBM Almaden)
* Kevin Decker
* Mike Ratcliffe (Comartis AG)
* Hernan Rodríguez Colmeiro
* Austin Andrews
* Christoph Dorn
* Steven Roussey (AppCenter Inc, Network54)
*/
html {
background-color: -moz-dialog;
}
body {
margin: 0;
overflow: auto;
font-family: Lucida Grande, sans-serif;
font-size: 11px;
border-top: 1px solid #BBB9BA;
}
h1 {
font-size: 17px;
border-bottom: 1px solid threedlightshadow;
}
a {
color: #0000ff;
}
pre {
margin: 0;
font: inherit;
}
code {
display: block;
white-space: pre;
}
/* DOMPlate */
.objectLink-element,
.objectLink-textNode,
.objectLink-function,
.objectBox-stackTrace,
.objectLink-profile {
font-family: Menlo, Andale Mono, monospace;
}
.objectLink-textNode {
white-space: pre-wrap;
}
.objectLink-styleRule,
.objectLink-element,
.objectLink-textNode {
color: #000088;
}
.selectorTag,
.selectorId,
.selectorClass {
font-family: Menlo, Andale Mono, monospace;
font-weight: normal;
}
.selectorTag {
color: #0000FF;
}
.selectorId {
color: DarkBlue;
}
.selectorClass {
color: red;
}
.selectorHidden > .selectorTag {
color: #5F82D9;
}
.selectorHidden > .selectorId {
color: #888888;
}
.selectorHidden > .selectorClass {
color: #D86060;
}
.selectorValue {
font-family: Menlo, Andale Mono, monospace;
font-style: italic;
color: #555555;
}
.panelNode-html {
-moz-box-sizing: padding-box;
padding: 4px 0 0 2px;
}
.nodeBox {
position: relative;
font-family: Menlo, Andale Mono, monospace;
padding-left: 13px;
-moz-user-select: -moz-none;
}
.nodeBox.search-selection {
-moz-user-select: text;
}
.twisty {
position: absolute;
left: 0px;
top: 0px;
width: 14px;
height: 14px;
}
.nodeChildBox {
margin-left: 12px;
display: none;
}
.nodeLabel,
.nodeCloseLabel {
margin: -2px 2px 0 2px;
border: 2px solid transparent;
-moz-border-radius: 3px;
padding: 0 2px;
color: #000088;
}
.nodeCloseLabel {
display: none;
}
.nodeTag {
cursor: pointer;
color: blue;
}
.nodeValue {
color: #FF0000;
font-weight: normal;
}
.nodeText,
.nodeComment {
margin: 0 2px;
vertical-align: top;
}
.nodeText {
color: #333333;
}
.docType {
position: absolute;
top: -16px;
font-family: Menlo, Andale Mono, monospace;
padding-left: 8px;
color: #999;
white-space: nowrap;
font-style: italic;
}
.htmlNodeBox {
top: 16px;
}
.nodeWhiteSpace {
border: 1px solid LightGray;
white-space: pre; /* otherwise the border will be collapsed around zero pixels */
margin-left: 1px;
color: gray;
}
.nodeWhiteSpace_Space {
border: 1px solid #ddd;
}
.nodeTextEntity {
border: 1px solid gray;
white-space: pre; /* otherwise the border will be collapsed around zero pixels */
margin-left: 1px;
}
.nodeComment {
color: DarkGreen;
}
.nodeBox.highlightOpen > .nodeLabel {
background-color: #EEEEEE;
}
.nodeBox.highlightOpen > .nodeCloseLabel,
.nodeBox.highlightOpen > .nodeChildBox,
.nodeBox.open > .nodeCloseLabel,
.nodeBox.open > .nodeChildBox {
display: block;
}
.nodeBox.selected > .nodeLabel > .nodeLabelBox,
.nodeBox.selected > .nodeLabel {
border-color: Highlight;
background-color: Highlight;
color: HighlightText !important;
}
.nodeBox.selected > .nodeLabel > .nodeLabelBox,
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeTag,
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue,
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeText {
color: inherit !important;
}
.nodeBox.highlighted > .nodeLabel {
border-color: Highlight !important;
background-color: cyan !important;
color: #000000 !important;
}
.nodeBox.highlighted > .nodeLabel > .nodeLabelBox,
.nodeBox.highlighted > .nodeLabel > .nodeLabelBox > .nodeTag,
.nodeBox.highlighted > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue,
.nodeBox.highlighted > .nodeLabel > .nodeLabelBox > .nodeText {
color: #000000 !important;
}
.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox,
.nodeBox.nodeHidden .nodeCloseLabel,
.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox > .nodeText,
.nodeBox.nodeHidden .nodeText {
color: #888888;
}
.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox > .nodeTag,
.nodeBox.nodeHidden .nodeCloseLabel > .nodeCloseLabelBox > .nodeTag {
color: #5F82D9;
}
.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue {
color: #D86060;
}
.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox,
.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeTag,
.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue,
.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeText {
color: SkyBlue !important;
}
.nodeBox.mutated > .nodeLabel,
.nodeAttr.mutated,
.nodeValue.mutated,
.nodeText.mutated,
.nodeBox.mutated > .nodeText {
background-color: #EFFF79;
color: #FF0000 !important;
}
.nodeBox.selected.mutated > .nodeLabel,
.nodeBox.selected.mutated > .nodeLabel > .nodeLabelBox,
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeAttr.mutated > .nodeValue,
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue.mutated,
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeText.mutated {
background-color: #EFFF79;
border-color: #EFFF79;
color: #FF0000 !important;
}
.logRow-dirxml {
padding-left: 0;
}
.soloElement > .nodeBox {
padding-left: 0;
}
.useA11y .nodeLabel.focused {
outline: 2px solid #FF9933;
-moz-outline-radius: 3px;
outline-offset: -2px;
}
.useA11y .nodeLabelBox:focus {
outline: none;
}
/* from panel.css */
/* HTML panel */
.nodeBox.selected > .nodeLabel > .nodeLabelBox,
.nodeBox.selected > .nodeLabel {
border-color: #3875d7;
background-color: #3875d7;
color: #FFFFFF !important;
}
.nodeBox.highlighted > .nodeLabel {
border-color: #3875d7 !important;
}
/************************************************************************************************/
/* Twisties */
.twisty
{
-moz-appearance: treetwisty;
}
.nodeBox.highlightOpen > .nodeLabel > .twisty,
.nodeBox.open > .nodeLabel > .twisty
{
-moz-appearance: treetwistyopen;
}
/************************************************************************************************/
/* HTML panel */
.nodeBox.selected > .nodeLabel > .nodeLabelBox,
.nodeBox.selected > .nodeLabel {
border-color: #3875d7;
background-color: #3875d7;
color: #FFFFFF !important;
}
.nodeBox.highlighted > .nodeLabel {
border-color: #3875d7 !important;
}

View File

@ -13,6 +13,7 @@ browser.jar:
* skin/classic/browser/browser.css (browser.css)
* skin/classic/browser/engineManager.css (engineManager.css)
skin/classic/browser/fullscreen-video.css
skin/classic/browser/inspector.css
skin/classic/browser/Geolocation-16.png
skin/classic/browser/Geolocation-64.png
skin/classic/browser/Go-arrow.png

View File

@ -0,0 +1,365 @@
/*
* Software License Agreement (BSD License)
*
* Copyright (c) 2007, Parakey Inc.
* All rights reserved.
*
* Redistribution and use of this software in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* * Neither the name of Parakey Inc. nor the names of its
* contributors may be used to endorse or promote products
* derived from this software without specific prior
* written permission of Parakey Inc.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Creator:
* Joe Hewitt
* Contributors
* John J. Barton (IBM Almaden)
* Jan Odvarko (Mozilla Corp.)
* Max Stepanov (Aptana Inc.)
* Rob Campbell (Mozilla Corp.)
* Hans Hillen (Paciello Group, Mozilla)
* Curtis Bartley (Mozilla Corp.)
* Mike Collins (IBM Almaden)
* Kevin Decker
* Mike Ratcliffe (Comartis AG)
* Hernan Rodríguez Colmeiro
* Austin Andrews
* Christoph Dorn
* Steven Roussey (AppCenter Inc, Network54)
*/
html {
background-color: -moz-dialog;
}
body {
margin: 0;
overflow: auto;
font-family: Lucida Grande, sans-serif;
font-size: 11px;
border-top: 1px solid #BBB9BA;
}
h1 {
font-size: 17px;
border-bottom: 1px solid threedlightshadow;
}
a {
color: #0000ff;
}
pre {
margin: 0;
font: inherit;
}
code {
display: block;
white-space: pre;
}
/* DOMPlate */
.objectLink-element,
.objectLink-textNode,
.objectLink-function,
.objectBox-stackTrace,
.objectLink-profile {
font-family: Menlo, Andale Mono, monospace;
}
.objectLink-textNode {
white-space: pre-wrap;
}
.objectLink-styleRule,
.objectLink-element,
.objectLink-textNode {
color: #000088;
}
.selectorTag,
.selectorId,
.selectorClass {
font-family: Menlo, Andale Mono, monospace;
font-weight: normal;
}
.selectorTag {
color: #0000FF;
}
.selectorId {
color: DarkBlue;
}
.selectorClass {
color: red;
}
.selectorHidden > .selectorTag {
color: #5F82D9;
}
.selectorHidden > .selectorId {
color: #888888;
}
.selectorHidden > .selectorClass {
color: #D86060;
}
.selectorValue {
font-family: Menlo, Andale Mono, monospace;
font-style: italic;
color: #555555;
}
.panelNode-html {
-moz-box-sizing: padding-box;
padding: 4px 0 0 2px;
}
.nodeBox {
position: relative;
font-family: Menlo, Andale Mono, monospace;
padding-left: 13px;
-moz-user-select: -moz-none;
}
.nodeBox.search-selection {
-moz-user-select: text;
}
.twisty {
position: absolute;
left: 0px;
top: 0px;
width: 14px;
height: 14px;
}
.nodeChildBox {
margin-left: 12px;
display: none;
}
.nodeLabel,
.nodeCloseLabel {
margin: -2px 2px 0 2px;
border: 2px solid transparent;
-moz-border-radius: 3px;
padding: 0 2px;
color: #000088;
}
.nodeCloseLabel {
display: none;
}
.nodeTag {
cursor: pointer;
color: blue;
}
.nodeValue {
color: #FF0000;
font-weight: normal;
}
.nodeText,
.nodeComment {
margin: 0 2px;
vertical-align: top;
}
.nodeText {
color: #333333;
}
.docType {
position: absolute;
top: -16px;
font-family: Menlo, Andale Mono, monospace;
padding-left: 8px;
color: #999;
white-space: nowrap;
font-style: italic;
}
.htmlNodeBox {
top: 16px;
}
.nodeWhiteSpace {
border: 1px solid LightGray;
white-space: pre; /* otherwise the border will be collapsed around zero pixels */
margin-left: 1px;
color: gray;
}
.nodeWhiteSpace_Space {
border: 1px solid #ddd;
}
.nodeTextEntity {
border: 1px solid gray;
white-space: pre; /* otherwise the border will be collapsed around zero pixels */
margin-left: 1px;
}
.nodeComment {
color: DarkGreen;
}
.nodeBox.highlightOpen > .nodeLabel {
background-color: #EEEEEE;
}
.nodeBox.highlightOpen > .nodeCloseLabel,
.nodeBox.highlightOpen > .nodeChildBox,
.nodeBox.open > .nodeCloseLabel,
.nodeBox.open > .nodeChildBox {
display: block;
}
.nodeBox.selected > .nodeLabel > .nodeLabelBox,
.nodeBox.selected > .nodeLabel {
border-color: Highlight;
background-color: Highlight;
color: HighlightText !important;
}
.nodeBox.selected > .nodeLabel > .nodeLabelBox,
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeTag,
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue,
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeText {
color: inherit !important;
}
.nodeBox.highlighted > .nodeLabel {
border-color: Highlight !important;
background-color: cyan !important;
color: #000000 !important;
}
.nodeBox.highlighted > .nodeLabel > .nodeLabelBox,
.nodeBox.highlighted > .nodeLabel > .nodeLabelBox > .nodeTag,
.nodeBox.highlighted > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue,
.nodeBox.highlighted > .nodeLabel > .nodeLabelBox > .nodeText {
color: #000000 !important;
}
.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox,
.nodeBox.nodeHidden .nodeCloseLabel,
.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox > .nodeText,
.nodeBox.nodeHidden .nodeText {
color: #888888;
}
.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox > .nodeTag,
.nodeBox.nodeHidden .nodeCloseLabel > .nodeCloseLabelBox > .nodeTag {
color: #5F82D9;
}
.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue {
color: #D86060;
}
.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox,
.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeTag,
.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue,
.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeText {
color: SkyBlue !important;
}
.nodeBox.mutated > .nodeLabel,
.nodeAttr.mutated,
.nodeValue.mutated,
.nodeText.mutated,
.nodeBox.mutated > .nodeText {
background-color: #EFFF79;
color: #FF0000 !important;
}
.nodeBox.selected.mutated > .nodeLabel,
.nodeBox.selected.mutated > .nodeLabel > .nodeLabelBox,
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeAttr.mutated > .nodeValue,
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue.mutated,
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeText.mutated {
background-color: #EFFF79;
border-color: #EFFF79;
color: #FF0000 !important;
}
.logRow-dirxml {
padding-left: 0;
}
.soloElement > .nodeBox {
padding-left: 0;
}
.nodeBox.selected > .nodeLabel > .nodeLabelBox,
.nodeBox.selected > .nodeLabel {
border-color: #3875d7;
background-color: #3875d7;
color: #FFFFFF !important;
}
.nodeBox.highlighted > .nodeLabel {
border-color: #3875d7 !important;
}
/************************************************************************************************/
/* Twisties */
.twisty
{
-moz-appearance: treetwisty;
}
.nodeBox.highlightOpen > .nodeLabel > .twisty,
.nodeBox.open > .nodeLabel > .twisty
{
-moz-appearance: treetwistyopen;
}
.memberRow.hasChildren > .memberLabelCell > .memberLabel,
.hasHeaders .netHrefLabel {
background-position: 2px 2px;
}
.nodeBox.selected > .nodeLabel > .nodeLabelBox,
.nodeBox.selected > .nodeLabel {
border-color: #3875d7;
background-color: #3875d7;
color: #FFFFFF !important;
}
.nodeBox.highlighted > .nodeLabel {
border-color: #3875d7 !important;
}

View File

@ -64,6 +64,7 @@ browser.jar:
skin/classic/browser/feeds/audioFeedIcon.png (feeds/audioFeedIcon.png)
skin/classic/browser/feeds/audioFeedIcon16.png (feeds/audioFeedIcon16.png)
skin/classic/browser/setDesktopBackground.css
skin/classic/browser/inspector.css
skin/classic/browser/monitor.png
skin/classic/browser/monitor_16-10.png
skin/classic/browser/places/allBookmarks.png (places/allBookmarks.png)

View File

@ -0,0 +1,350 @@
/*
* Software License Agreement (BSD License)
*
* Copyright (c) 2007, Parakey Inc.
* All rights reserved.
*
* Redistribution and use of this software in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* * Neither the name of Parakey Inc. nor the names of its
* contributors may be used to endorse or promote products
* derived from this software without specific prior
* written permission of Parakey Inc.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Creator:
* Joe Hewitt
* Contributors
* John J. Barton (IBM Almaden)
* Jan Odvarko (Mozilla Corp.)
* Max Stepanov (Aptana Inc.)
* Rob Campbell (Mozilla Corp.)
* Hans Hillen (Paciello Group, Mozilla)
* Curtis Bartley (Mozilla Corp.)
* Mike Collins (IBM Almaden)
* Kevin Decker
* Mike Ratcliffe (Comartis AG)
* Hernan Rodríguez Colmeiro
* Austin Andrews
* Christoph Dorn
* Steven Roussey (AppCenter Inc, Network54)
*/
html {
background-color: -moz-dialog;
}
body {
margin: 0;
overflow: auto;
font-family: Lucida Grande, sans-serif;
font-size: 11px;
}
h1 {
font-size: 17px;
border-bottom: 1px solid threedlightshadow;
}
a {
color: #0000ff;
}
pre {
margin: 0;
font: inherit;
}
code {
display: block;
white-space: pre;
}
/* DOMPlate */
.objectLink-element,
.objectLink-textNode,
.objectLink-function,
.objectBox-stackTrace,
.objectLink-profile {
font-family: Menlo, Andale Mono, monospace;
}
.objectLink-textNode {
white-space: pre-wrap;
}
.objectLink-styleRule,
.objectLink-element,
.objectLink-textNode {
color: #000088;
}
.selectorTag,
.selectorId,
.selectorClass {
font-family: Menlo, Andale Mono, monospace;
font-weight: normal;
}
.selectorTag {
color: #0000FF;
}
.selectorId {
color: DarkBlue;
}
.selectorClass {
color: red;
}
.selectorHidden > .selectorTag {
color: #5F82D9;
}
.selectorHidden > .selectorId {
color: #888888;
}
.selectorHidden > .selectorClass {
color: #D86060;
}
.selectorValue {
font-family: Menlo, Andale Mono, monospace;
font-style: italic;
color: #555555;
}
.panelNode-html {
-moz-box-sizing: padding-box;
padding: 4px 0 0 2px;
}
.nodeBox {
position: relative;
font-family: Menlo, Andale Mono, monospace;
padding-left: 13px;
-moz-user-select: -moz-none;
}
.nodeBox.search-selection {
-moz-user-select: text;
}
.twisty {
position: absolute;
left: 0px;
top: 0px;
width: 14px;
height: 14px;
}
.nodeChildBox {
margin-left: 12px;
display: none;
}
.nodeLabel,
.nodeCloseLabel {
margin: -2px 2px 0 2px;
border: 2px solid transparent;
-moz-border-radius: 3px;
padding: 0 2px;
color: #000088;
}
.nodeCloseLabel {
display: none;
}
.nodeTag {
cursor: pointer;
color: blue;
}
.nodeValue {
color: #FF0000;
font-weight: normal;
}
.nodeText,
.nodeComment {
margin: 0 2px;
vertical-align: top;
}
.nodeText {
color: #333333;
}
.docType {
position: absolute;
top: -16px;
font-family: Menlo, Andale Mono, monospace;
padding-left: 8px;
color: #999;
white-space: nowrap;
font-style: italic;
}
.htmlNodeBox {
top: 16px;
}
.nodeWhiteSpace {
border: 1px solid LightGray;
white-space: pre;
margin-left: 1px;
color: gray;
}
.nodeWhiteSpace_Space {
border: 1px solid #ddd;
}
.nodeTextEntity {
border: 1px solid gray;
white-space: pre;
margin-left: 1px;
}
.nodeComment {
color: DarkGreen;
}
.nodeBox.highlightOpen > .nodeLabel {
background-color: #EEEEEE;
}
.nodeBox.highlightOpen > .nodeCloseLabel,
.nodeBox.highlightOpen > .nodeChildBox,
.nodeBox.open > .nodeCloseLabel,
.nodeBox.open > .nodeChildBox {
display: block;
}
.nodeBox.selected > .nodeLabel > .nodeLabelBox,
.nodeBox.selected > .nodeLabel {
border-color: Highlight;
background-color: Highlight;
color: HighlightText !important;
}
.nodeBox.selected > .nodeLabel > .nodeLabelBox,
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeTag,
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue,
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeText {
color: inherit !important;
}
.nodeBox.highlighted > .nodeLabel {
border-color: Highlight !important;
background-color: cyan !important;
color: #000000 !important;
}
.nodeBox.highlighted > .nodeLabel > .nodeLabelBox,
.nodeBox.highlighted > .nodeLabel > .nodeLabelBox > .nodeTag,
.nodeBox.highlighted > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue,
.nodeBox.highlighted > .nodeLabel > .nodeLabelBox > .nodeText {
color: #000000 !important;
}
.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox,
.nodeBox.nodeHidden .nodeCloseLabel,
.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox > .nodeText,
.nodeBox.nodeHidden .nodeText {
color: #888888;
}
.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox > .nodeTag,
.nodeBox.nodeHidden .nodeCloseLabel > .nodeCloseLabelBox > .nodeTag {
color: #5F82D9;
}
.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue {
color: #D86060;
}
.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox,
.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeTag,
.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue,
.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeText {
color: SkyBlue !important;
}
.nodeBox.mutated > .nodeLabel,
.nodeAttr.mutated,
.nodeValue.mutated,
.nodeText.mutated,
.nodeBox.mutated > .nodeText {
background-color: #EFFF79;
color: #FF0000 !important;
}
.nodeBox.selected.mutated > .nodeLabel,
.nodeBox.selected.mutated > .nodeLabel > .nodeLabelBox,
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeAttr.mutated > .nodeValue,
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue.mutated,
.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeText.mutated {
background-color: #EFFF79;
border-color: #EFFF79;
color: #FF0000 !important;
}
.logRow-dirxml {
padding-left: 0;
}
.soloElement > .nodeBox {
padding-left: 0;
}
.nodeBox.selected > .nodeLabel > .nodeLabelBox,
.nodeBox.selected > .nodeLabel {
border-color: #3875d7;
background-color: #3875d7;
color: #FFFFFF !important;
}
.nodeBox.highlighted > .nodeLabel {
border-color: #3875d7 !important;
}
/* Twisties */
.twisty
{
background-repeat: no-repeat;
background-position: center;
background-image: url("chrome://global/skin/tree/twisty-clsd.png") !important;
}
.nodeBox.highlightOpen > .nodeLabel > .twisty,
.nodeBox.open > .nodeLabel > .twisty
{
background-image: url("chrome://global/skin/tree/twisty-open.png") !important;
}

View File

@ -57,6 +57,7 @@ browser.jar:
skin/classic/browser/feeds/videoFeedIcon16.png (feeds/videoFeedIcon16.png)
skin/classic/browser/feeds/subscribe.css (feeds/subscribe.css)
skin/classic/browser/feeds/subscribe-ui.css (feeds/subscribe-ui.css)
skin/classic/browser/inspector.css
skin/classic/browser/places/places.css (places/places.css)
* skin/classic/browser/places/organizer.css (places/organizer.css)
skin/classic/browser/places/bookmark.png (places/bookmark.png)
@ -171,6 +172,7 @@ browser.jar:
skin/classic/aero/browser/feeds/videoFeedIcon.png (feeds/videoFeedIcon-aero.png)
skin/classic/aero/browser/feeds/videoFeedIcon16.png (feeds/videoFeedIcon16-aero.png)
skin/classic/aero/browser/feeds/subscribe.css (feeds/subscribe.css)
skin/classic/aero/browser/inspector.css
* skin/classic/aero/browser/places/places.css (places/places-aero.css)
* skin/classic/aero/browser/places/organizer.css (places/organizer-aero.css)
skin/classic/aero/browser/places/bookmark.png (places/bookmark-aero.png)