mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
153 lines
4.4 KiB
C++
153 lines
4.4 KiB
C++
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||
|
|
||
|
#include "mozilla/Preferences.h"
|
||
|
#include "mozilla/dom/ShadowRoot.h"
|
||
|
#include "mozilla/dom/ShadowRootBinding.h"
|
||
|
#include "mozilla/dom/DocumentFragment.h"
|
||
|
#include "nsContentUtils.h"
|
||
|
#include "nsDOMClassInfoID.h"
|
||
|
#include "nsIDOMHTMLElement.h"
|
||
|
#include "mozilla/dom/Element.h"
|
||
|
#include "nsXBLPrototypeBinding.h"
|
||
|
|
||
|
using namespace mozilla;
|
||
|
using namespace mozilla::dom;
|
||
|
|
||
|
static PLDHashOperator
|
||
|
IdentifierMapEntryTraverse(nsIdentifierMapEntry *aEntry, void *aArg)
|
||
|
{
|
||
|
nsCycleCollectionTraversalCallback *cb =
|
||
|
static_cast<nsCycleCollectionTraversalCallback*>(aArg);
|
||
|
aEntry->Traverse(cb);
|
||
|
return PL_DHASH_NEXT;
|
||
|
}
|
||
|
|
||
|
NS_IMPL_CYCLE_COLLECTION_CLASS(ShadowRoot)
|
||
|
|
||
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ShadowRoot,
|
||
|
DocumentFragment)
|
||
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mHost)
|
||
|
tmp->mIdentifierMap.EnumerateEntries(IdentifierMapEntryTraverse, &cb);
|
||
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||
|
|
||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ShadowRoot,
|
||
|
DocumentFragment)
|
||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mHost)
|
||
|
tmp->mIdentifierMap.Clear();
|
||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||
|
|
||
|
DOMCI_DATA(ShadowRoot, ShadowRoot)
|
||
|
|
||
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ShadowRoot)
|
||
|
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIContent)
|
||
|
NS_INTERFACE_MAP_END_INHERITING(DocumentFragment)
|
||
|
|
||
|
NS_IMPL_ADDREF_INHERITED(ShadowRoot, DocumentFragment)
|
||
|
NS_IMPL_RELEASE_INHERITED(ShadowRoot, DocumentFragment)
|
||
|
|
||
|
ShadowRoot::ShadowRoot(nsIContent* aContent,
|
||
|
already_AddRefed<nsINodeInfo> aNodeInfo)
|
||
|
: DocumentFragment(aNodeInfo), mHost(aContent)
|
||
|
{
|
||
|
SetHost(aContent);
|
||
|
SetFlags(NODE_IS_IN_SHADOW_TREE);
|
||
|
// ShadowRoot isn't really in the document but it behaves like it is.
|
||
|
SetInDocument();
|
||
|
DOMSlots()->mBindingParent = aContent;
|
||
|
DOMSlots()->mContainingShadow = this;
|
||
|
}
|
||
|
|
||
|
ShadowRoot::~ShadowRoot()
|
||
|
{
|
||
|
ClearInDocument();
|
||
|
SetHost(nullptr);
|
||
|
}
|
||
|
|
||
|
JSObject*
|
||
|
ShadowRoot::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
|
||
|
{
|
||
|
return mozilla::dom::ShadowRootBinding::Wrap(aCx, aScope, this);
|
||
|
}
|
||
|
|
||
|
ShadowRoot*
|
||
|
ShadowRoot::FromNode(nsINode* aNode)
|
||
|
{
|
||
|
if (aNode->HasFlag(NODE_IS_IN_SHADOW_TREE) && !aNode->GetParentNode()) {
|
||
|
MOZ_ASSERT(aNode->NodeType() == nsIDOMNode::DOCUMENT_FRAGMENT_NODE,
|
||
|
"ShadowRoot is a document fragment.");
|
||
|
return static_cast<ShadowRoot*>(aNode);
|
||
|
}
|
||
|
|
||
|
return nullptr;
|
||
|
}
|
||
|
|
||
|
Element*
|
||
|
ShadowRoot::GetElementById(const nsAString& aElementId)
|
||
|
{
|
||
|
nsIdentifierMapEntry *entry = mIdentifierMap.GetEntry(aElementId);
|
||
|
return entry ? entry->GetIdElement() : nullptr;
|
||
|
}
|
||
|
|
||
|
already_AddRefed<nsContentList>
|
||
|
ShadowRoot::GetElementsByTagName(const nsAString& aTagName)
|
||
|
{
|
||
|
return NS_GetContentList(this, kNameSpaceID_Unknown, aTagName);
|
||
|
}
|
||
|
|
||
|
already_AddRefed<nsContentList>
|
||
|
ShadowRoot::GetElementsByTagNameNS(const nsAString& aNamespaceURI,
|
||
|
const nsAString& aLocalName)
|
||
|
{
|
||
|
int32_t nameSpaceId = kNameSpaceID_Wildcard;
|
||
|
|
||
|
if (!aNamespaceURI.EqualsLiteral("*")) {
|
||
|
nsresult rv =
|
||
|
nsContentUtils::NameSpaceManager()->RegisterNameSpace(aNamespaceURI,
|
||
|
nameSpaceId);
|
||
|
NS_ENSURE_SUCCESS(rv, nullptr);
|
||
|
}
|
||
|
|
||
|
NS_ASSERTION(nameSpaceId != kNameSpaceID_Unknown, "Unexpected namespace ID!");
|
||
|
|
||
|
return NS_GetContentList(this, nameSpaceId, aLocalName);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
ShadowRoot::AddToIdTable(Element* aElement, nsIAtom* aId)
|
||
|
{
|
||
|
nsIdentifierMapEntry *entry =
|
||
|
mIdentifierMap.PutEntry(nsDependentAtomString(aId));
|
||
|
if (entry) {
|
||
|
entry->AddIdElement(aElement);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void
|
||
|
ShadowRoot::RemoveFromIdTable(Element* aElement, nsIAtom* aId)
|
||
|
{
|
||
|
nsIdentifierMapEntry *entry =
|
||
|
mIdentifierMap.GetEntry(nsDependentAtomString(aId));
|
||
|
if (entry) {
|
||
|
entry->RemoveIdElement(aElement);
|
||
|
if (entry->IsEmpty()) {
|
||
|
mIdentifierMap.RawRemoveEntry(entry);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
already_AddRefed<nsContentList>
|
||
|
ShadowRoot::GetElementsByClassName(const nsAString& aClasses)
|
||
|
{
|
||
|
return nsContentUtils::GetElementsByClassName(this, aClasses);
|
||
|
}
|
||
|
|
||
|
bool
|
||
|
ShadowRoot::PrefEnabled()
|
||
|
{
|
||
|
return Preferences::GetBool("dom.webcomponents.enabled", false);
|
||
|
}
|
||
|
|