2015-05-03 22:32:37 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
2013-12-02 14:26:11 +04:00
|
|
|
/* 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/. */
|
|
|
|
|
|
|
|
#ifndef mozilla_dom_shadowroot_h__
|
|
|
|
#define mozilla_dom_shadowroot_h__
|
|
|
|
|
|
|
|
#include "mozilla/dom/DocumentFragment.h"
|
2017-12-21 01:29:21 +03:00
|
|
|
#include "mozilla/dom/DocumentOrShadowRoot.h"
|
2013-12-02 14:26:11 +04:00
|
|
|
#include "nsCOMPtr.h"
|
|
|
|
#include "nsCycleCollectionParticipant.h"
|
2017-06-20 16:57:08 +03:00
|
|
|
#include "nsIdentifierMapEntry.h"
|
2013-12-02 14:26:11 +04:00
|
|
|
#include "nsTHashtable.h"
|
|
|
|
|
2017-10-03 01:05:19 +03:00
|
|
|
class nsAtom;
|
2013-12-02 14:26:11 +04:00
|
|
|
class nsIContent;
|
|
|
|
class nsXBLPrototypeBinding;
|
|
|
|
|
|
|
|
namespace mozilla {
|
2017-12-04 11:06:40 +03:00
|
|
|
|
|
|
|
class EventChainPreVisitor;
|
|
|
|
|
2013-12-02 14:26:11 +04:00
|
|
|
namespace dom {
|
|
|
|
|
|
|
|
class Element;
|
|
|
|
|
2015-03-21 21:35:18 +03:00
|
|
|
class ShadowRoot final : public DocumentFragment,
|
2017-12-21 01:29:21 +03:00
|
|
|
public DocumentOrShadowRoot,
|
2015-03-21 21:35:18 +03:00
|
|
|
public nsStubMutationObserver
|
2013-12-02 14:26:11 +04:00
|
|
|
{
|
|
|
|
public:
|
2017-12-31 22:57:32 +03:00
|
|
|
static ShadowRoot* FromNode(nsINode* aNode)
|
|
|
|
{
|
|
|
|
return aNode->IsShadowRoot() ? static_cast<ShadowRoot*>(aNode) : nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const ShadowRoot* FromNode(const nsINode* aNode)
|
|
|
|
{
|
|
|
|
return aNode->IsShadowRoot() ? static_cast<const ShadowRoot*>(aNode) : nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ShadowRoot* FromNodeOrNull(nsINode* aNode)
|
|
|
|
{
|
|
|
|
return aNode ? FromNode(aNode) : nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const ShadowRoot* FromNodeOrNull(const nsINode* aNode)
|
|
|
|
{
|
|
|
|
return aNode ? FromNode(aNode) : nullptr;
|
|
|
|
}
|
|
|
|
|
2013-12-02 14:26:11 +04:00
|
|
|
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ShadowRoot,
|
|
|
|
DocumentFragment)
|
|
|
|
NS_DECL_ISUPPORTS_INHERITED
|
|
|
|
|
2013-12-02 14:26:12 +04:00
|
|
|
NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
|
|
|
|
NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
|
|
|
|
NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
|
|
|
|
NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
|
|
|
|
|
2017-10-19 09:44:35 +03:00
|
|
|
ShadowRoot(Element* aElement, bool aClosed,
|
2017-09-25 18:09:26 +03:00
|
|
|
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
|
2013-12-02 14:26:12 +04:00
|
|
|
nsXBLPrototypeBinding* aProtoBinding);
|
2013-12-02 14:26:11 +04:00
|
|
|
|
2017-10-19 09:44:35 +03:00
|
|
|
// Shadow DOM v1
|
2018-02-18 16:33:14 +03:00
|
|
|
Element* Host() const
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(GetHost(), "ShadowRoot always has a host, how did we create "
|
|
|
|
"this ShadowRoot?");
|
|
|
|
return GetHost();
|
|
|
|
}
|
|
|
|
|
2017-12-18 00:29:10 +03:00
|
|
|
ShadowRootMode Mode() const
|
2017-10-19 09:44:35 +03:00
|
|
|
{
|
|
|
|
return mMode;
|
|
|
|
}
|
2017-12-18 00:29:10 +03:00
|
|
|
bool IsClosed() const
|
2017-11-02 11:53:44 +03:00
|
|
|
{
|
|
|
|
return mMode == ShadowRootMode::Closed;
|
|
|
|
}
|
2017-10-19 09:44:35 +03:00
|
|
|
|
|
|
|
// [deprecated] Shadow DOM v0
|
2016-09-26 15:03:25 +03:00
|
|
|
void InsertSheet(StyleSheet* aSheet, nsIContent* aLinkingContent);
|
|
|
|
void RemoveSheet(StyleSheet* aSheet);
|
2017-12-18 00:29:10 +03:00
|
|
|
StyleSheetList* StyleSheets()
|
|
|
|
{
|
2017-12-21 01:29:21 +03:00
|
|
|
return &DocumentOrShadowRoot::EnsureDOMStyleSheets();
|
2017-12-18 00:29:10 +03:00
|
|
|
}
|
2013-12-21 10:43:58 +04:00
|
|
|
|
2017-10-17 19:28:42 +03:00
|
|
|
private:
|
2013-12-02 14:26:12 +04:00
|
|
|
|
2017-10-18 16:24:53 +03:00
|
|
|
/**
|
2017-12-04 11:06:34 +03:00
|
|
|
* Try to reassign an element to a slot and returns whether the assignment
|
2017-10-18 17:03:41 +03:00
|
|
|
* changed.
|
|
|
|
*/
|
2017-12-04 11:06:34 +03:00
|
|
|
bool MaybeReassignElement(Element* aElement, const nsAttrValue* aOldValue);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Try to assign aContent to a slot in the shadow tree, returns the assigned
|
|
|
|
* slot if found.
|
|
|
|
*/
|
|
|
|
const HTMLSlotElement* AssignSlotFor(nsIContent* aContent);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Unassign aContent from the assigned slot in the shadow tree, returns the
|
|
|
|
* assigned slot if found.
|
|
|
|
*
|
|
|
|
* Note: slot attribute of aContent may have changed already, so pass slot
|
|
|
|
* name explicity here.
|
|
|
|
*/
|
|
|
|
const HTMLSlotElement* UnassignSlotFor(nsIContent* aContent,
|
|
|
|
const nsAString& aSlotName);
|
2017-10-18 17:03:41 +03:00
|
|
|
|
2017-10-17 19:28:42 +03:00
|
|
|
public:
|
2017-12-04 11:06:34 +03:00
|
|
|
void AddSlot(HTMLSlotElement* aSlot);
|
|
|
|
void RemoveSlot(HTMLSlotElement* aSlot);
|
|
|
|
|
2013-12-21 10:43:58 +04:00
|
|
|
void SetAssociatedBinding(nsXBLBinding* aBinding) { mAssociatedBinding = aBinding; }
|
2013-12-02 14:26:12 +04:00
|
|
|
|
2015-03-21 19:28:04 +03:00
|
|
|
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
2013-12-02 14:26:11 +04:00
|
|
|
|
2017-12-20 08:46:01 +03:00
|
|
|
void AddToIdTable(Element* aElement, nsAtom* aId);
|
|
|
|
void RemoveFromIdTable(Element* aElement, nsAtom* aId);
|
|
|
|
|
2013-12-02 14:26:11 +04:00
|
|
|
// WebIDL methods.
|
2017-12-21 01:29:21 +03:00
|
|
|
using mozilla::dom::DocumentOrShadowRoot::GetElementById;
|
2018-01-15 09:42:47 +03:00
|
|
|
|
|
|
|
Element* GetActiveElement();
|
2013-12-02 14:26:12 +04:00
|
|
|
void GetInnerHTML(nsAString& aInnerHTML);
|
|
|
|
void SetInnerHTML(const nsAString& aInnerHTML, ErrorResult& aError);
|
2014-06-07 12:42:54 +04:00
|
|
|
void StyleSheetChanged();
|
2015-02-09 21:01:23 +03:00
|
|
|
|
2018-02-19 20:15:38 +03:00
|
|
|
bool IsComposedDocParticipant() const
|
|
|
|
{
|
|
|
|
return mIsComposedDocParticipant;
|
|
|
|
}
|
|
|
|
|
2015-02-09 21:01:23 +03:00
|
|
|
void SetIsComposedDocParticipant(bool aIsComposedDocParticipant)
|
|
|
|
{
|
|
|
|
mIsComposedDocParticipant = aIsComposedDocParticipant;
|
|
|
|
}
|
2015-02-24 17:41:43 +03:00
|
|
|
|
2017-12-04 11:06:40 +03:00
|
|
|
nsresult GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
|
|
|
|
|
2013-12-02 14:26:11 +04:00
|
|
|
protected:
|
2014-07-09 01:23:16 +04:00
|
|
|
virtual ~ShadowRoot();
|
2013-12-02 14:26:12 +04:00
|
|
|
|
2017-10-19 09:44:35 +03:00
|
|
|
ShadowRootMode mMode;
|
|
|
|
|
2017-12-04 11:06:34 +03:00
|
|
|
// Map from name of slot to an array of all slots in the shadow DOM with with
|
|
|
|
// the given name. The slots are stored as a weak pointer because the elements
|
|
|
|
// are in the shadow tree and should be kept alive by its parent.
|
|
|
|
nsClassHashtable<nsStringHashKey, nsTArray<mozilla::dom::HTMLSlotElement*>> mSlotMap;
|
2013-12-02 14:26:12 +04:00
|
|
|
nsXBLPrototypeBinding* mProtoBinding;
|
|
|
|
|
|
|
|
// It is necessary to hold a reference to the associated nsXBLBinding
|
|
|
|
// because the binding holds a reference on the nsXBLDocumentInfo that
|
|
|
|
// owns |mProtoBinding|.
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<nsXBLBinding> mAssociatedBinding;
|
2013-12-02 14:26:12 +04:00
|
|
|
|
2015-02-09 21:01:23 +03:00
|
|
|
// Flag to indicate whether the descendants of this shadow root are part of the
|
|
|
|
// composed document. Ideally, we would use a node flag on nodes to
|
|
|
|
// mark whether it is in the composed document, but we have run out of flags
|
|
|
|
// so instead we track it here.
|
|
|
|
bool mIsComposedDocParticipant;
|
2015-07-07 04:26:29 +03:00
|
|
|
|
2017-04-20 22:57:48 +03:00
|
|
|
nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult,
|
|
|
|
bool aPreallocateChildren) const override;
|
2013-12-02 14:26:11 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace dom
|
|
|
|
} // namespace mozilla
|
|
|
|
|
|
|
|
#endif // mozilla_dom_shadowroot_h__
|