From 5f8de423f190bbb79a62f804151bc24824fa32d8 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 2 Feb 2018 04:16:08 -0500 Subject: Add m-esr52 at 52.6.0 --- dom/base/ShadowRoot.cpp | 765 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 765 insertions(+) create mode 100644 dom/base/ShadowRoot.cpp (limited to 'dom/base/ShadowRoot.cpp') diff --git a/dom/base/ShadowRoot.cpp b/dom/base/ShadowRoot.cpp new file mode 100644 index 000000000..9540754f7 --- /dev/null +++ b/dom/base/ShadowRoot.cpp @@ -0,0 +1,765 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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 "ChildIterator.h" +#include "nsContentUtils.h" +#include "nsDOMClassInfoID.h" +#include "nsIDOMHTMLElement.h" +#include "nsIStyleSheetLinkingElement.h" +#include "mozilla/dom/Element.h" +#include "mozilla/dom/HTMLContentElement.h" +#include "mozilla/dom/HTMLShadowElement.h" +#include "nsXBLPrototypeBinding.h" +#include "mozilla/StyleSheet.h" +#include "mozilla/StyleSheetInlines.h" + +using namespace mozilla; +using namespace mozilla::dom; + +NS_IMPL_CYCLE_COLLECTION_CLASS(ShadowRoot) + +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ShadowRoot, + DocumentFragment) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPoolHost) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStyleSheetList) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOlderShadow) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mYoungerShadow) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAssociatedBinding) + for (auto iter = tmp->mIdentifierMap.ConstIter(); !iter.Done(); + iter.Next()) { + iter.Get()->Traverse(&cb); + } +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END + +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ShadowRoot, + DocumentFragment) + if (tmp->mPoolHost) { + tmp->mPoolHost->RemoveMutationObserver(tmp); + } + NS_IMPL_CYCLE_COLLECTION_UNLINK(mPoolHost) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mStyleSheetList) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mOlderShadow) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mYoungerShadow) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mAssociatedBinding) + tmp->mIdentifierMap.Clear(); +NS_IMPL_CYCLE_COLLECTION_UNLINK_END + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ShadowRoot) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIContent) + NS_INTERFACE_MAP_ENTRY(nsIMutationObserver) +NS_INTERFACE_MAP_END_INHERITING(DocumentFragment) + +NS_IMPL_ADDREF_INHERITED(ShadowRoot, DocumentFragment) +NS_IMPL_RELEASE_INHERITED(ShadowRoot, DocumentFragment) + +ShadowRoot::ShadowRoot(nsIContent* aContent, + already_AddRefed&& aNodeInfo, + nsXBLPrototypeBinding* aProtoBinding) + : DocumentFragment(aNodeInfo), mPoolHost(aContent), + mProtoBinding(aProtoBinding), mShadowElement(nullptr), + mInsertionPointChanged(false), mIsComposedDocParticipant(false) +{ + SetHost(aContent); + + // Nodes in a shadow tree should never store a value + // in the subtree root pointer, nodes in the shadow tree + // track the subtree root using GetContainingShadow(). + ClearSubtreeRootPointer(); + + SetFlags(NODE_IS_IN_SHADOW_TREE); + + DOMSlots()->mBindingParent = aContent; + DOMSlots()->mContainingShadow = this; + + // Add the ShadowRoot as a mutation observer on the host to watch + // for mutations because the insertion points in this ShadowRoot + // may need to be updated when the host children are modified. + mPoolHost->AddMutationObserver(this); +} + +ShadowRoot::~ShadowRoot() +{ + if (mPoolHost) { + // mPoolHost may have been unlinked or a new ShadowRoot may have been + // creating, making this one obsolete. + mPoolHost->RemoveMutationObserver(this); + } + + UnsetFlags(NODE_IS_IN_SHADOW_TREE); + + // nsINode destructor expects mSubtreeRoot == this. + SetSubtreeRootPointer(this); + + SetHost(nullptr); +} + +JSObject* +ShadowRoot::WrapObject(JSContext* aCx, JS::Handle aGivenProto) +{ + return mozilla::dom::ShadowRootBinding::Wrap(aCx, this, aGivenProto); +} + +ShadowRoot* +ShadowRoot::FromNode(nsINode* aNode) +{ + if (aNode->IsInShadowTree() && !aNode->GetParentNode()) { + MOZ_ASSERT(aNode->NodeType() == nsIDOMNode::DOCUMENT_FRAGMENT_NODE, + "ShadowRoot is a document fragment."); + return static_cast(aNode); + } + + return nullptr; +} + +void +ShadowRoot::StyleSheetChanged() +{ + mProtoBinding->FlushSkinSheets(); + + nsIPresShell* shell = OwnerDoc()->GetShell(); + if (shell) { + OwnerDoc()->BeginUpdate(UPDATE_STYLE); + shell->RecordShadowStyleChange(this); + OwnerDoc()->EndUpdate(UPDATE_STYLE); + } +} + +void +ShadowRoot::InsertSheet(StyleSheet* aSheet, + nsIContent* aLinkingContent) +{ + nsCOMPtr + linkingElement = do_QueryInterface(aLinkingContent); + MOZ_ASSERT(linkingElement, "The only styles in a ShadowRoot should come " + "from