Bug 690713 - [highlighter] move DOM related methods from TreePanel.jsm to a new jsm, r=msucan,rcampbell

This commit is contained in:
Paul Rouget 2011-10-11 10:11:10 -03:00
parent 23d638b746
commit 2ac4397240

View File

@ -47,7 +47,7 @@ Cu.import("resource:///modules/domplate.jsm");
Cu.import("resource:///modules/InsideOutBox.jsm");
Cu.import("resource:///modules/Services.jsm");
var EXPORTED_SYMBOLS = ["TreePanel"];
var EXPORTED_SYMBOLS = ["TreePanel", "DOMHelpers"];
const INSPECTOR_URI = "chrome://browser/content/inspector.html";
@ -96,6 +96,8 @@ TreePanel.prototype = {
domplateUtils.setDOM(this.window);
this.DOMHelpers = new DOMHelpers(this.window);
let isOpen = this.isOpen.bind(this);
this.registrationObject = {
@ -315,93 +317,23 @@ TreePanel.prototype = {
getParentObject: function TP_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 == this.window.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 == this.window.Node.DOCUMENT_NODE) {
if (parentNode.defaultView) {
return parentNode.defaultView.frameElement;
}
// parent is document element, but no window at defaultView.
return null;
}
if (!parentNode.localName)
return null;
return parentNode;
return this.DOMHelpers.getParentObject(node);
},
getChildObject: function TP_getChildObject(node, index, previousSibling)
{
if (!node)
return null;
if (node.contentDocument) {
// then the node is a frame
if (index == 0) {
return node.contentDocument.documentElement; // the node's HTMLElement
}
return null;
}
if (node instanceof this.window.GetSVGDocument) {
let svgDocument = node.getSVGDocument();
if (svgDocument) {
// then the node is a frame
if (index == 0) {
return svgDocument.documentElement; // 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 (!domplateUtils.isWhitespaceText(child))
return child;
}
return null; // we have no children worth showing.
return this.DOMHelpers.getChildObject(node, index, previousSibling,
this.showTextNodesWithWhitespace);
},
getFirstChild: function TP_getFirstChild(node)
{
this.treeWalker = node.ownerDocument.createTreeWalker(node,
this.window.NodeFilter.SHOW_ALL, null, false);
return this.treeWalker.firstChild();
return this.DOMHelpers.getFirstChild(node);
},
getNextSibling: function TP_getNextSibling(node)
{
let next = this.treeWalker.nextSibling();
if (!next)
delete this.treeWalker;
return next;
return this.DOMHelpers.getNextSibling(node);
},
/////////////////////////////////////////////////////////////////////
@ -747,7 +679,11 @@ TreePanel.prototype = {
domplateUtils.setDOM(null);
delete this.resizer;
delete this.treeWalker;
if (this.DOMHelpers) {
this.DOMHelpers.destroy();
delete this.DOMHelpers;
}
if (this.treePanelDiv) {
this.treePanelDiv.ownerPanel = null;
@ -777,3 +713,122 @@ TreePanel.prototype = {
}
};
/**
* DOMHelpers
* Makes DOM traversal easier. Goes through iframes.
*
* @constructor
* @param nsIDOMWindow aWindow
* The content window, owning the document to traverse.
*/
function DOMHelpers(aWindow) {
this.window = aWindow;
};
DOMHelpers.prototype = {
getParentObject: function Helpers_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 == this.window.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 == this.window.Node.DOCUMENT_NODE) {
if (parentNode.defaultView) {
return parentNode.defaultView.frameElement;
}
// parent is document element, but no window at defaultView.
return null;
}
if (!parentNode.localName)
return null;
return parentNode;
},
getChildObject: function Helpers_getChildObject(node, index, previousSibling,
showTextNodesWithWhitespace)
{
if (!node)
return null;
if (node.contentDocument) {
// then the node is a frame
if (index == 0) {
return node.contentDocument.documentElement; // the node's HTMLElement
}
return null;
}
if (node instanceof this.window.GetSVGDocument) {
let svgDocument = node.getSVGDocument();
if (svgDocument) {
// then the node is a frame
if (index == 0) {
return svgDocument.documentElement; // 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 (showTextNodesWithWhitespace)
return child;
for (; child; child = this.getNextSibling(child)) {
if (!this.isWhitespaceText(child))
return child;
}
return null; // we have no children worth showing.
},
getFirstChild: function Helpers_getFirstChild(node)
{
let SHOW_ALL = Components.interfaces.nsIDOMNodeFilter.SHOW_ALL;
this.treeWalker = node.ownerDocument.createTreeWalker(node,
SHOW_ALL, null, false);
return this.treeWalker.firstChild();
},
getNextSibling: function Helpers_getNextSibling(node)
{
let next = this.treeWalker.nextSibling();
if (!next)
delete this.treeWalker;
return next;
},
isWhitespaceText: function Helpers_isWhitespaceText(node)
{
return node.nodeType == this.window.Node.TEXT_NODE &&
!/[^\s]/.exec(node.nodeValue);
},
destroy: function Helpers_destroy()
{
delete this.window;
delete this.treeWalker;
}
};