Bug 796061 - Part 2: Remove mInsertionParentTable from nsBindingManager. r=mrbkap

This commit is contained in:
William Chen
2013-07-17 09:05:06 -07:00
parent 1e57e7dfef
commit 21071ccf55
14 changed files with 146 additions and 124 deletions

View File

@@ -218,6 +218,8 @@ public:
virtual nsXBLBinding *GetXBLBinding() const MOZ_OVERRIDE;
virtual void SetXBLBinding(nsXBLBinding* aBinding,
nsBindingManager* aOldBindingManager = nullptr) MOZ_OVERRIDE;
virtual nsIContent *GetXBLInsertionParent() const;
virtual void SetXBLInsertionParent(nsIContent* aContent);
virtual bool IsLink(nsIURI** aURI) const MOZ_OVERRIDE;
virtual void DestroyContent() MOZ_OVERRIDE;
@@ -367,6 +369,11 @@ public:
* XBL binding installed on the element.
*/
nsRefPtr<nsXBLBinding> mXBLBinding;
/**
* XBL binding installed on the lement.
*/
nsCOMPtr<nsIContent> mXBLInsertionParent;
};
protected:

View File

@@ -639,6 +639,21 @@ public:
virtual void SetXBLBinding(nsXBLBinding* aBinding,
nsBindingManager* aOldBindingManager = nullptr) = 0;
/**
* Gets the insertion parent element of the XBL binding.
* The insertion parent is our one true parent in the transformed DOM.
*
* @return the insertion parent element.
*/
virtual nsIContent *GetXBLInsertionParent() const = 0;
/**
* Sets the insertion parent element of the XBL binding.
*
* @param aContent The insertion parent element.
*/
virtual void SetXBLInsertionParent(nsIContent* aContent) = 0;
/**
* Returns the content node that is the parent of this node in the flattened
* tree. For nodes that are not filtered into an insertion point, this

View File

@@ -150,8 +150,7 @@ nsIContent*
nsIContent::GetFlattenedTreeParent() const
{
if (HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
nsIContent* parent = OwnerDoc()->BindingManager()->
GetInsertionParent(const_cast<nsIContent*>(this));
nsIContent* parent = GetXBLInsertionParent();
if (parent) {
return parent;
}
@@ -568,6 +567,9 @@ FragmentOrElement::nsDOMSlots::Traverse(nsCycleCollectionTraversalCallback &cb,
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mXBLBinding");
cb.NoteNativeChild(mXBLBinding, NS_CYCLE_COLLECTION_PARTICIPANT(nsXBLBinding));
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mXBLInsertionParent");
cb.NoteXPCOMChild(mXBLInsertionParent.get());
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mChildrenList");
cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIDOMNodeList*, mChildrenList));
@@ -587,6 +589,7 @@ FragmentOrElement::nsDOMSlots::Unlink(bool aIsXUL)
if (aIsXUL)
NS_IF_RELEASE(mControllers);
mXBLBinding = nullptr;
mXBLInsertionParent = nullptr;
mChildrenList = nullptr;
mUndoManager = nullptr;
if (mClassList) {
@@ -806,8 +809,7 @@ nsIContent::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
// check for an anonymous parent
// XXX XBL2/sXBL issue
if (HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
nsIContent* insertionParent = OwnerDoc()->BindingManager()->
GetInsertionParent(this);
nsIContent* insertionParent = GetXBLInsertionParent();
NS_ASSERTION(!(aVisitor.mEventTargetAtParent && insertionParent &&
aVisitor.mEventTargetAtParent != insertionParent),
"Retargeting and having insertion parent!");
@@ -943,6 +945,29 @@ FragmentOrElement::SetXBLBinding(nsXBLBinding* aBinding,
}
}
nsIContent*
FragmentOrElement::GetXBLInsertionParent() const
{
if (HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
nsDOMSlots *slots = GetExistingDOMSlots();
if (slots) {
return slots->mXBLInsertionParent;
}
}
return nullptr;
}
void
FragmentOrElement::SetXBLInsertionParent(nsIContent* aContent)
{
nsDOMSlots *slots = DOMSlots();
if (aContent) {
SetFlags(NODE_MAY_BE_IN_BINDING_MNGR);
}
slots->mXBLInsertionParent = aContent;
}
nsresult
FragmentOrElement::InsertChildAt(nsIContent* aKid,
uint32_t aIndex,

View File

@@ -3567,8 +3567,7 @@ nsContentUtils::HasMutationListeners(nsINode* aNode,
if (aNode->IsNodeOfType(nsINode::eCONTENT)) {
nsIContent* content = static_cast<nsIContent*>(aNode);
nsIContent* insertionParent =
doc->BindingManager()->GetInsertionParent(content);
nsIContent* insertionParent = content->GetXBLInsertionParent();
if (insertionParent) {
aNode = insertionParent;
continue;

View File

@@ -86,11 +86,21 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsGenericDOMDataNode)
return NS_SUCCESS_INTERRUPTED_TRAVERSE;
}
nsDataSlots *slots = tmp->GetExistingDataSlots();
if (slots) {
slots->Traverse(cb);
}
tmp->OwnerDoc()->BindingManager()->Traverse(tmp, cb);
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGenericDOMDataNode)
nsINode::Unlink(tmp);
nsDataSlots *slots = tmp->GetExistingDataSlots();
if (slots) {
slots->Unlink();
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN(nsGenericDOMDataNode)
@@ -649,6 +659,29 @@ nsGenericDOMDataNode::SetXBLBinding(nsXBLBinding* aBinding,
{
}
nsIContent *
nsGenericDOMDataNode::GetXBLInsertionParent() const
{
if (HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
nsDataSlots *slots = GetExistingDataSlots();
if (slots) {
return slots->mXBLInsertionParent;
}
}
return nullptr;
}
void
nsGenericDOMDataNode::SetXBLInsertionParent(nsIContent* aContent)
{
nsDataSlots *slots = DataSlots();
if (aContent) {
SetFlags(NODE_MAY_BE_IN_BINDING_MNGR);
}
slots->mXBLInsertionParent = aContent;
}
bool
nsGenericDOMDataNode::IsNodeOfType(uint32_t aFlags) const
{
@@ -694,6 +727,19 @@ nsGenericDOMDataNode::CreateSlots()
return new nsDataSlots();
}
void
nsGenericDOMDataNode::nsDataSlots::Traverse(nsCycleCollectionTraversalCallback &cb)
{
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mXBLInsertionParent");
cb.NoteXPCOMChild(mXBLInsertionParent.get());
}
void
nsGenericDOMDataNode::nsDataSlots::Unlink()
{
mXBLInsertionParent = nullptr;
}
//----------------------------------------------------------------------
// Implementation of the nsIDOMText interface

View File

@@ -144,6 +144,8 @@ public:
virtual nsXBLBinding *GetXBLBinding() const MOZ_OVERRIDE;
virtual void SetXBLBinding(nsXBLBinding* aBinding,
nsBindingManager* aOldBindingManager = nullptr) MOZ_OVERRIDE;
virtual nsIContent *GetXBLInsertionParent() const;
virtual void SetXBLInsertionParent(nsIContent* aContent);
virtual bool IsNodeOfType(uint32_t aFlags) const MOZ_OVERRIDE;
virtual bool IsLink(nsIURI** aURI) const MOZ_OVERRIDE;
@@ -231,11 +233,19 @@ protected:
{
}
void Traverse(nsCycleCollectionTraversalCallback &cb);
void Unlink();
/**
* The nearest enclosing content node with a binding that created us.
* @see nsIContent::GetBindingParent
*/
nsIContent* mBindingParent; // [Weak]
/**
* @see nsIContent::GetXBLInsertionParent
*/
nsCOMPtr<nsIContent> mXBLInsertionParent;
};
// Override from nsINode

View File

@@ -50,19 +50,16 @@ public:
const nsAString& aValue,
nsAttrValue& aResult);
void AppendInsertedChild(nsIContent* aChild,
nsBindingManager* aBindingManager)
void AppendInsertedChild(nsIContent* aChild)
{
mInsertedChildren.AppendElement(aChild);
aBindingManager->SetInsertionParent(aChild, GetParent());
aChild->SetXBLInsertionParent(GetParent());
}
void InsertInsertedChildAt(nsIContent* aChild,
uint32_t aIndex,
nsBindingManager* aBindingManager)
void InsertInsertedChildAt(nsIContent* aChild, uint32_t aIndex)
{
mInsertedChildren.InsertElementAt(aIndex, aChild);
aBindingManager->SetInsertionParent(aChild, GetParent());
aChild->SetXBLInsertionParent(GetParent());
}
void RemoveInsertedChild(nsIContent* aChild)
@@ -79,32 +76,32 @@ public:
mInsertedChildren.Clear();
}
void ClearInsertedChildrenAndInsertionParents(nsBindingManager* aBindingManager)
void ClearInsertedChildrenAndInsertionParents()
{
for (uint32_t c = 0; c < mInsertedChildren.Length(); ++c) {
aBindingManager->SetInsertionParent(mInsertedChildren[c], nullptr);
mInsertedChildren[c]->SetXBLInsertionParent(nullptr);
}
mInsertedChildren.Clear();
}
void MaybeSetupDefaultContent(nsBindingManager* aBindingManager)
void MaybeSetupDefaultContent()
{
if (!HasInsertedChildren()) {
for (nsIContent* child = static_cast<nsINode*>(this)->GetFirstChild();
child;
child = child->GetNextSibling()) {
aBindingManager->SetInsertionParent(child, GetParent());
child->SetXBLInsertionParent(GetParent());
}
}
}
void MaybeRemoveDefaultContent(nsBindingManager* aBindingManager)
void MaybeRemoveDefaultContent()
{
if (!HasInsertedChildren()) {
for (nsIContent* child = static_cast<nsINode*>(this)->GetFirstChild();
child;
child = child->GetNextSibling()) {
aBindingManager->SetInsertionParent(child, nullptr);
child->SetXBLInsertionParent(nullptr);
}
}
}

View File

@@ -197,10 +197,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsBindingManager)
if (tmp->mLoadingDocTable.IsInitialized())
tmp->mLoadingDocTable.Clear();
if (tmp->mInsertionParentTable.ops)
PL_DHashTableFinish(&(tmp->mInsertionParentTable));
tmp->mInsertionParentTable.ops = nullptr;
if (tmp->mWrapperTable.ops)
PL_DHashTableFinish(&(tmp->mWrapperTable));
tmp->mWrapperTable.ops = nullptr;
@@ -263,7 +259,6 @@ nsBindingManager::nsBindingManager(nsIDocument* aDocument)
mAttachedStackSizeOnOutermost(0),
mDocument(aDocument)
{
mInsertionParentTable.ops = nullptr;
mWrapperTable.ops = nullptr;
}
@@ -271,10 +266,6 @@ nsBindingManager::~nsBindingManager(void)
{
mDestroyed = true;
NS_ASSERTION(!mInsertionParentTable.ops || !mInsertionParentTable.entryCount,
"Insertion parent table isn't empty!");
if (mInsertionParentTable.ops)
PL_DHashTableFinish(&mInsertionParentTable);
if (mWrapperTable.ops)
PL_DHashTableFinish(&mWrapperTable);
}
@@ -307,27 +298,6 @@ nsBindingManager::RemoveBoundContent(nsIContent* aContent)
SetWrappedJS(aContent, nullptr);
}
nsIContent*
nsBindingManager::GetInsertionParent(nsIContent* aContent)
{
if (mInsertionParentTable.ops) {
return static_cast<nsIContent*>
(LookupObject(mInsertionParentTable, aContent));
}
return nullptr;
}
nsresult
nsBindingManager::SetInsertionParent(nsIContent* aContent, nsIContent* aParent)
{
if (mDestroyed) {
return NS_OK;
}
return SetOrRemoveObject(mInsertionParentTable, aContent, aParent);
}
nsIXPConnectWrappedJS*
nsBindingManager::GetWrappedJS(nsIContent* aContent)
{
@@ -365,7 +335,7 @@ nsBindingManager::RemovedFromDocumentInternal(nsIContent* aContent,
}
// Clear out insertion parents and content lists.
SetInsertionParent(aContent, nullptr);
aContent->SetXBLInsertionParent(nullptr);
}
nsIAtom*
@@ -955,8 +925,7 @@ nsBindingManager::AppendAllSheets(nsTArray<nsCSSStyleSheet*>& aArray)
}
static void
InsertAppendedContent(nsBindingManager* aManager,
XBLChildrenElement* aPoint,
InsertAppendedContent(XBLChildrenElement* aPoint,
nsIContent* aFirstNewContent)
{
uint32_t insertionIndex;
@@ -979,7 +948,7 @@ InsertAppendedContent(nsBindingManager* aManager,
for (nsIContent* currentChild = aFirstNewContent;
currentChild;
currentChild = currentChild->GetNextSibling()) {
aPoint->InsertInsertedChildAt(currentChild, insertionIndex++, aManager);
aPoint->InsertInsertedChildAt(currentChild, insertionIndex++);
}
}
@@ -1031,10 +1000,10 @@ nsBindingManager::ContentAppended(nsIDocument* aDocument,
first = false;
for (nsIContent* child = aFirstNewContent; child;
child = child->GetNextSibling()) {
point->AppendInsertedChild(child, this);
point->AppendInsertedChild(child);
}
} else {
InsertAppendedContent(this, point, aFirstNewContent);
InsertAppendedContent(point, aFirstNewContent);
}
nsIContent* newParent = point->GetParent();
@@ -1065,7 +1034,7 @@ nsBindingManager::ContentRemoved(nsIDocument* aDocument,
int32_t aIndexInContainer,
nsIContent* aPreviousSibling)
{
SetInsertionParent(aChild, nullptr);
aChild->SetXBLInsertionParent(nullptr);
XBLChildrenElement* point = nullptr;
nsIContent* parent = aContainer;
@@ -1104,7 +1073,7 @@ void
nsBindingManager::ClearInsertionPointsRecursively(nsIContent* aContent)
{
if (aContent->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL)) {
static_cast<XBLChildrenElement*>(aContent)->ClearInsertedChildrenAndInsertionParents(this);
static_cast<XBLChildrenElement*>(aContent)->ClearInsertedChildrenAndInsertionParents();
}
uint32_t childCount = aContent->GetChildCount();
@@ -1124,10 +1093,6 @@ nsBindingManager::DropDocumentReference()
mProcessAttachedQueueEvent->Revoke();
}
if (mInsertionParentTable.ops)
PL_DHashTableFinish(&(mInsertionParentTable));
mInsertionParentTable.ops = nullptr;
if (mBoundContentSet.IsInitialized()) {
mBoundContentSet.Clear();
}
@@ -1139,21 +1104,13 @@ void
nsBindingManager::Traverse(nsIContent *aContent,
nsCycleCollectionTraversalCallback &cb)
{
if (!aContent->HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
return;
}
nsISupports *value;
if (mInsertionParentTable.ops &&
(value = LookupObject(mInsertionParentTable, aContent))) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "[via binding manager] mInsertionParentTable key");
cb.NoteXPCOMChild(aContent);
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "[via binding manager] mInsertionParentTable value");
cb.NoteXPCOMChild(value);
}
// XXXbz how exactly would NODE_MAY_BE_IN_BINDING_MNGR end up on non-elements?
if (!aContent->IsElement()) {
if (!aContent->HasFlag(NODE_MAY_BE_IN_BINDING_MNGR) ||
!aContent->IsElement()) {
// Don't traverse if content is not in this binding manager.
// We also don't traverse non-elements because there should not
// be bindings (checking the flag alone is not sufficient because
// the flag is also set on children of insertion points that may be
// non-elements).
return;
}
@@ -1161,6 +1118,8 @@ nsBindingManager::Traverse(nsIContent *aContent,
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "[via binding manager] mBoundContentSet entry");
cb.NoteXPCOMChild(aContent);
}
nsISupports *value;
if (mWrapperTable.ops &&
(value = LookupObject(mWrapperTable, aContent))) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "[via binding manager] mWrapperTable key");
@@ -1227,7 +1186,7 @@ nsBindingManager::HandleChildInsertion(nsIContent* aContainer,
}
}
point->InsertInsertedChildAt(aChild, index, this);
point->InsertInsertedChildAt(aChild, index);
nsIContent* newParent = point->GetParent();
if (newParent == parent) {

View File

@@ -48,9 +48,6 @@ public:
void AddBoundContent(nsIContent* aContent);
void RemoveBoundContent(nsIContent* aContent);
nsIContent* GetInsertionParent(nsIContent* aContent);
nsresult SetInsertionParent(nsIContent* aContent, nsIContent* aResult);
/**
* Notify the binding manager that an element
* has been removed from its document,
@@ -165,11 +162,6 @@ protected:
// A set of nsIContent that currently have a binding installed.
nsTHashtable<nsRefPtrHashKey<nsIContent> > mBoundContentSet;
// A mapping from nsIContent* to nsIContent*. The insertion parent
// is our one true parent in the transformed DOM. This gives us a
// more-or-less O(1) way of obtaining our transformed parent.
PLDHashTable mInsertionParentTable;
// A mapping from nsIContent* to nsIXPWrappedJS* (an XPConnect
// wrapper for JS objects). For XBL bindings that implement XPIDL
// interfaces, and that get referred to from C++, this table caches

View File

@@ -323,8 +323,6 @@ nsXBLBinding::GenerateAnonymousContent()
bool hasContent = (contentCount > 0);
if (hasContent) {
nsIDocument* doc = mBoundElement->OwnerDoc();
nsBindingManager *bindingManager = doc->BindingManager();
nsCOMPtr<nsINode> clonedNode;
nsCOMArray<nsINode> nodesWithProperties;
@@ -355,7 +353,7 @@ nsXBLBinding::GenerateAnonymousContent()
if (mDefaultInsertionPoint && mInsertionPoints.IsEmpty()) {
ExplicitChildIterator iter(mBoundElement);
for (nsIContent* child = iter.GetNextChild(); child; child = iter.GetNextChild()) {
mDefaultInsertionPoint->AppendInsertedChild(child, bindingManager);
mDefaultInsertionPoint->AppendInsertedChild(child);
}
} else {
// It is odd to come into this code if mInsertionPoints is not empty, but
@@ -365,7 +363,7 @@ nsXBLBinding::GenerateAnonymousContent()
for (nsIContent* child = iter.GetNextChild(); child; child = iter.GetNextChild()) {
XBLChildrenElement* point = FindInsertionPointForInternal(child);
if (point) {
point->AppendInsertedChild(child, bindingManager);
point->AppendInsertedChild(child);
} else {
nsINodeInfo *ni = child->NodeInfo();
if (ni->NamespaceID() != kNameSpaceID_XUL ||
@@ -392,10 +390,10 @@ nsXBLBinding::GenerateAnonymousContent()
// Set binding parent on default content if need
if (mDefaultInsertionPoint) {
mDefaultInsertionPoint->MaybeSetupDefaultContent(bindingManager);
mDefaultInsertionPoint->MaybeSetupDefaultContent();
}
for (uint32_t i = 0; i < mInsertionPoints.Length(); ++i) {
mInsertionPoints[i]->MaybeSetupDefaultContent(bindingManager);
mInsertionPoints[i]->MaybeSetupDefaultContent();
}
mPrototypeBinding->SetInitialAttributes(mBoundElement, mContent);
@@ -702,8 +700,7 @@ nsXBLBinding::UnhookEventHandlers()
}
static void
UpdateInsertionParent(nsBindingManager* aBindingManager,
XBLChildrenElement* aPoint,
UpdateInsertionParent(XBLChildrenElement* aPoint,
nsIContent* aOldBoundElement)
{
if (aPoint->IsDefaultInsertion()) {
@@ -723,9 +720,9 @@ UpdateInsertionParent(nsBindingManager* aBindingManager,
// latter case, the child is now inserted into |aOldBoundElement| from some
// binding above us, so we set its insertion parent to aOldBoundElement.
if (child->GetParentNode() == aOldBoundElement) {
aBindingManager->SetInsertionParent(child, nullptr);
child->SetXBLInsertionParent(nullptr);
} else {
aBindingManager->SetInsertionParent(child, aOldBoundElement);
child->SetXBLInsertionParent(aOldBoundElement);
}
}
}
@@ -837,19 +834,15 @@ nsXBLBinding::ChangeDocument(nsIDocument* aOldDocument, nsIDocument* aNewDocumen
nsXBLBinding::UninstallAnonymousContent(aOldDocument, mContent);
}
nsBindingManager* bindingManager = aOldDocument->BindingManager();
// Now that we've unbound our anonymous content from the tree and updated
// its binding parent, update the insertion parent for content inserted
// into our <children> elements.
if (mDefaultInsertionPoint) {
UpdateInsertionParent(bindingManager, mDefaultInsertionPoint,
mBoundElement);
UpdateInsertionParent(mDefaultInsertionPoint, mBoundElement);
}
for (size_t i = 0; i < mInsertionPoints.Length(); ++i) {
UpdateInsertionParent(bindingManager, mInsertionPoints[i],
mBoundElement);
UpdateInsertionParent(mInsertionPoints[i], mBoundElement);
}
// Now that our inserted children no longer think they're inserted

View File

@@ -6396,8 +6396,7 @@ nsCSSFrameConstructor::GetRangeInsertionPoint(nsIContent* aContainer,
// XXXbz XBL2/sXBL issue
nsIDocument* document = aStartChild->GetDocument();
// XXXbz how would |document| be null here?
if (document &&
document->BindingManager()->GetInsertionParent(aStartChild)) {
if (document && aStartChild->GetXBLInsertionParent()) {
hasInsertion = true;
}
}

View File

@@ -104,12 +104,7 @@ inDOMUtils::GetParentForNode(nsIDOMNode* aNode,
} else if (aShowingAnonymousContent) {
nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
if (content) {
nsIContent* bparent = nullptr;
nsRefPtr<nsBindingManager> bindingManager = inLayoutUtils::GetBindingManagerFor(aNode);
if (bindingManager) {
bparent = bindingManager->GetInsertionParent(content);
}
nsIContent* bparent = content->GetXBLInsertionParent();
parent = do_QueryInterface(bparent);
}
}

View File

@@ -68,19 +68,6 @@ inLayoutUtils::GetEventStateManagerFor(nsIDOMElement *aElement)
return shell->GetPresContext()->EventStateManager();
}
nsBindingManager*
inLayoutUtils::GetBindingManagerFor(nsIDOMNode* aNode)
{
nsCOMPtr<nsIDOMDocument> domdoc;
aNode->GetOwnerDocument(getter_AddRefs(domdoc));
if (domdoc) {
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domdoc);
return doc->BindingManager();
}
return nullptr;
}
nsIDOMDocument*
inLayoutUtils::GetSubDocumentFor(nsIDOMNode* aNode)
{

View File

@@ -6,7 +6,6 @@
#ifndef __inLayoutUtils_h__
#define __inLayoutUtils_h__
class nsBindingManager;
class nsIDOMDocument;
class nsIDOMElement;
class nsIDOMNode;
@@ -24,7 +23,6 @@ public:
static nsIPresShell* GetPresShellFor(nsISupports* aThing);
static nsIFrame* GetFrameFor(nsIDOMElement* aElement);
static nsEventStateManager* GetEventStateManagerFor(nsIDOMElement *aElement);
static nsBindingManager* GetBindingManagerFor(nsIDOMNode* aNode);
static nsIDOMDocument* GetSubDocumentFor(nsIDOMNode* aNode);
static nsIDOMNode* GetContainerFor(nsIDOMDocument* aDoc);
};