forked from mirrors/gecko-dev
Bug 1712140 - Part 3: Add support for parsing and building Declarative ShadowDOMs. r=dom-core,webidl,saschanaz,hsivonen
Differential Revision: https://phabricator.services.mozilla.com/D193675
This commit is contained in:
parent
8d6f163265
commit
65c76f62c7
21 changed files with 424 additions and 23 deletions
|
|
@ -1392,6 +1392,7 @@ Document::Document(const char* aContentType)
|
||||||
mHasUserInteractionTimerScheduled(false),
|
mHasUserInteractionTimerScheduled(false),
|
||||||
mShouldResistFingerprinting(false),
|
mShouldResistFingerprinting(false),
|
||||||
mCloningForSVGUse(false),
|
mCloningForSVGUse(false),
|
||||||
|
mAllowDeclarativeShadowRoots(false),
|
||||||
mXMLDeclarationBits(0),
|
mXMLDeclarationBits(0),
|
||||||
mOnloadBlockCount(0),
|
mOnloadBlockCount(0),
|
||||||
mWriteLevel(0),
|
mWriteLevel(0),
|
||||||
|
|
@ -18931,4 +18932,13 @@ RadioGroupContainer& Document::OwnedRadioGroupContainer() {
|
||||||
return *mRadioGroupContainer;
|
return *mRadioGroupContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Document::SetAllowDeclarativeShadowRoots(
|
||||||
|
bool aAllowDeclarativeShadowRoots) {
|
||||||
|
mAllowDeclarativeShadowRoots = aAllowDeclarativeShadowRoots;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Document::AllowsDeclarativeShadowRoots() const {
|
||||||
|
return mAllowDeclarativeShadowRoots;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace mozilla::dom
|
} // namespace mozilla::dom
|
||||||
|
|
|
||||||
|
|
@ -3858,6 +3858,9 @@ class Document : public nsINode,
|
||||||
*/
|
*/
|
||||||
bool AllowsL10n() const;
|
bool AllowsL10n() const;
|
||||||
|
|
||||||
|
void SetAllowDeclarativeShadowRoots(bool aAllowDeclarativeShadowRoots);
|
||||||
|
bool AllowsDeclarativeShadowRoots() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
RefPtr<DocumentL10n> mDocumentL10n;
|
RefPtr<DocumentL10n> mDocumentL10n;
|
||||||
|
|
||||||
|
|
@ -4820,6 +4823,8 @@ class Document : public nsINode,
|
||||||
// Whether we're cloning the contents of an SVG use element.
|
// Whether we're cloning the contents of an SVG use element.
|
||||||
bool mCloningForSVGUse : 1;
|
bool mCloningForSVGUse : 1;
|
||||||
|
|
||||||
|
bool mAllowDeclarativeShadowRoots : 1;
|
||||||
|
|
||||||
// The fingerprinting protections overrides for this document. The value will
|
// The fingerprinting protections overrides for this document. The value will
|
||||||
// override the default enabled fingerprinting protections for this document.
|
// override the default enabled fingerprinting protections for this document.
|
||||||
// This will only get populated if these is one that comes from the local
|
// This will only get populated if these is one that comes from the local
|
||||||
|
|
|
||||||
|
|
@ -239,6 +239,9 @@ class ShadowRoot final : public DocumentFragment, public DocumentOrShadowRoot {
|
||||||
void SetIsDeclarative(Declarative aIsDeclarative) {
|
void SetIsDeclarative(Declarative aIsDeclarative) {
|
||||||
mIsDeclarative = aIsDeclarative;
|
mIsDeclarative = aIsDeclarative;
|
||||||
}
|
}
|
||||||
|
void SetIsDeclarative(bool aIsDeclarative) {
|
||||||
|
mIsDeclarative = aIsDeclarative ? Declarative::Yes : Declarative::No;
|
||||||
|
}
|
||||||
|
|
||||||
bool IsClonable() const { return mIsClonable == Clonable::Yes; }
|
bool IsClonable() const { return mIsClonable == Clonable::Yes; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5446,6 +5446,34 @@ bool AllowsUnsanitizedContentForAboutNewTab(nsIPrincipal* aPrincipal) {
|
||||||
return aboutModuleFlags & nsIAboutModule::ALLOW_UNSANITIZED_CONTENT;
|
return aboutModuleFlags & nsIAboutModule::ALLOW_UNSANITIZED_CONTENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
void nsContentUtils::SetHTMLUnsafe(FragmentOrElement* aTarget,
|
||||||
|
Element* aContext,
|
||||||
|
const nsAString& aSource) {
|
||||||
|
MOZ_ASSERT(!sFragmentParsingActive, "Re-entrant fragment parsing attempted.");
|
||||||
|
mozilla::AutoRestore<bool> guard(sFragmentParsingActive);
|
||||||
|
sFragmentParsingActive = true;
|
||||||
|
if (!sHTMLFragmentParser) {
|
||||||
|
NS_ADDREF(sHTMLFragmentParser = new nsHtml5StringParser());
|
||||||
|
// Now sHTMLFragmentParser owns the object
|
||||||
|
}
|
||||||
|
|
||||||
|
nsAtom* contextLocalName = aContext->NodeInfo()->NameAtom();
|
||||||
|
int32_t contextNameSpaceID = aContext->GetNameSpaceID();
|
||||||
|
|
||||||
|
RefPtr<Document> doc = aTarget->OwnerDoc();
|
||||||
|
RefPtr<DocumentFragment> fragment = doc->CreateDocumentFragment();
|
||||||
|
nsresult rv = sHTMLFragmentParser->ParseFragment(
|
||||||
|
aSource, fragment, contextLocalName, contextNameSpaceID,
|
||||||
|
fragment->OwnerDoc()->GetCompatibilityMode() == eCompatibility_NavQuirks,
|
||||||
|
true, true);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
NS_WARNING("Failed to parse fragment for SetHTMLUnsafe");
|
||||||
|
}
|
||||||
|
|
||||||
|
aTarget->ReplaceChildren(fragment, IgnoreErrors());
|
||||||
|
}
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
nsresult nsContentUtils::ParseFragmentHTML(
|
nsresult nsContentUtils::ParseFragmentHTML(
|
||||||
const nsAString& aSourceBuffer, nsIContent* aTargetNode,
|
const nsAString& aSourceBuffer, nsIContent* aTargetNode,
|
||||||
|
|
@ -5501,7 +5529,7 @@ nsresult nsContentUtils::ParseFragmentHTML(
|
||||||
|
|
||||||
nsresult rv = sHTMLFragmentParser->ParseFragment(
|
nsresult rv = sHTMLFragmentParser->ParseFragment(
|
||||||
aSourceBuffer, target, aContextLocalName, aContextNamespace, aQuirks,
|
aSourceBuffer, target, aContextLocalName, aContextNamespace, aQuirks,
|
||||||
aPreventScriptExecution);
|
aPreventScriptExecution, false);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
if (fragment) {
|
if (fragment) {
|
||||||
|
|
@ -11339,6 +11367,25 @@ template bool nsContentUtils::AddElementToListByTreeOrder(
|
||||||
nsTArray<RefPtr<HTMLInputElement>>& aList, HTMLInputElement* aChild,
|
nsTArray<RefPtr<HTMLInputElement>>& aList, HTMLInputElement* aChild,
|
||||||
nsIContent* aAncestor);
|
nsIContent* aAncestor);
|
||||||
|
|
||||||
|
nsIContent* nsContentUtils::AttachDeclarativeShadowRoot(nsIContent* aHost,
|
||||||
|
ShadowRootMode aMode,
|
||||||
|
bool aDelegatesFocus) {
|
||||||
|
RefPtr<Element> host = mozilla::dom::Element::FromNodeOrNull(aHost);
|
||||||
|
if (!host) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ShadowRootInit init;
|
||||||
|
init.mMode = aMode;
|
||||||
|
init.mDelegatesFocus = aDelegatesFocus;
|
||||||
|
init.mSlotAssignment = SlotAssignmentMode::Named;
|
||||||
|
init.mClonable = true;
|
||||||
|
|
||||||
|
RefPtr shadowRoot = host->AttachShadow(init, IgnoreErrors(),
|
||||||
|
Element::ShadowRootDeclarative::Yes);
|
||||||
|
return shadowRoot;
|
||||||
|
}
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
std::ostream& operator<<(std::ostream& aOut,
|
std::ostream& operator<<(std::ostream& aOut,
|
||||||
const PreventDefaultResult aPreventDefaultResult) {
|
const PreventDefaultResult aPreventDefaultResult) {
|
||||||
|
|
|
||||||
|
|
@ -176,6 +176,7 @@ class DOMArena;
|
||||||
class Element;
|
class Element;
|
||||||
class Event;
|
class Event;
|
||||||
class EventTarget;
|
class EventTarget;
|
||||||
|
class FragmentOrElement;
|
||||||
class HTMLElement;
|
class HTMLElement;
|
||||||
class HTMLInputElement;
|
class HTMLInputElement;
|
||||||
class IPCTransferable;
|
class IPCTransferable;
|
||||||
|
|
@ -187,6 +188,7 @@ class MessageBroadcaster;
|
||||||
class NodeInfo;
|
class NodeInfo;
|
||||||
class OwningFileOrUSVStringOrFormData;
|
class OwningFileOrUSVStringOrFormData;
|
||||||
class Selection;
|
class Selection;
|
||||||
|
enum class ShadowRootMode : uint8_t;
|
||||||
struct StructuredSerializeOptions;
|
struct StructuredSerializeOptions;
|
||||||
class WorkerPrivate;
|
class WorkerPrivate;
|
||||||
enum class ElementCallbackType;
|
enum class ElementCallbackType;
|
||||||
|
|
@ -1802,6 +1804,9 @@ class nsContentUtils {
|
||||||
bool aPreventScriptExecution,
|
bool aPreventScriptExecution,
|
||||||
mozilla::ErrorResult& aRv);
|
mozilla::ErrorResult& aRv);
|
||||||
|
|
||||||
|
MOZ_CAN_RUN_SCRIPT
|
||||||
|
static void SetHTMLUnsafe(mozilla::dom::FragmentOrElement* aTarget,
|
||||||
|
Element* aContext, const nsAString& aSource);
|
||||||
/**
|
/**
|
||||||
* Invoke the fragment parsing algorithm (innerHTML) using the HTML parser.
|
* Invoke the fragment parsing algorithm (innerHTML) using the HTML parser.
|
||||||
*
|
*
|
||||||
|
|
@ -3457,6 +3462,11 @@ class nsContentUtils {
|
||||||
nsIContent* aContent2,
|
nsIContent* aContent2,
|
||||||
const nsIContent* aCommonAncestor);
|
const nsIContent* aCommonAncestor);
|
||||||
|
|
||||||
|
MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
||||||
|
static nsIContent* AttachDeclarativeShadowRoot(
|
||||||
|
nsIContent* aHost, mozilla::dom::ShadowRootMode aMode,
|
||||||
|
bool aDelegatesFocus);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool InitializeEventTable();
|
static bool InitializeEventTable();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@
|
||||||
#include "mozilla/dom/DebuggerNotificationBinding.h"
|
#include "mozilla/dom/DebuggerNotificationBinding.h"
|
||||||
#include "mozilla/dom/DocumentType.h"
|
#include "mozilla/dom/DocumentType.h"
|
||||||
#include "mozilla/dom/Element.h"
|
#include "mozilla/dom/Element.h"
|
||||||
|
#include "mozilla/dom/ElementBinding.h"
|
||||||
#include "mozilla/dom/Event.h"
|
#include "mozilla/dom/Event.h"
|
||||||
#include "mozilla/dom/Exceptions.h"
|
#include "mozilla/dom/Exceptions.h"
|
||||||
#include "mozilla/dom/Link.h"
|
#include "mozilla/dom/Link.h"
|
||||||
|
|
@ -3614,6 +3615,38 @@ already_AddRefed<nsINode> nsINode::CloneAndAdopt(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (aClone && aNode->IsElement() &&
|
||||||
|
!nodeInfo->GetDocument()->IsStaticDocument()) {
|
||||||
|
// Clone the Shadow DOM
|
||||||
|
ShadowRoot* originalShadowRoot = aNode->AsElement()->GetShadowRoot();
|
||||||
|
if (originalShadowRoot && originalShadowRoot->IsClonable()) {
|
||||||
|
ShadowRootInit init;
|
||||||
|
init.mMode = originalShadowRoot->Mode();
|
||||||
|
init.mDelegatesFocus = originalShadowRoot->DelegatesFocus();
|
||||||
|
init.mSlotAssignment = originalShadowRoot->SlotAssignment();
|
||||||
|
init.mClonable = true;
|
||||||
|
|
||||||
|
RefPtr<ShadowRoot> newShadowRoot =
|
||||||
|
clone->AsElement()->AttachShadow(init, aError);
|
||||||
|
if (NS_WARN_IF(aError.Failed())) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
newShadowRoot->SetIsDeclarative(originalShadowRoot->IsDeclarative());
|
||||||
|
|
||||||
|
if (aDeep) {
|
||||||
|
for (nsIContent* origChild = originalShadowRoot->GetFirstChild();
|
||||||
|
origChild; origChild = origChild->GetNextSibling()) {
|
||||||
|
nsCOMPtr<nsINode> child =
|
||||||
|
CloneAndAdopt(origChild, aClone, aDeep, nodeInfoManager,
|
||||||
|
aReparentScope, newShadowRoot, aError);
|
||||||
|
if (NS_WARN_IF(aError.Failed())) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Cloning template element.
|
// Cloning template element.
|
||||||
if (aDeep && aClone && aNode->IsTemplateElement()) {
|
if (aDeep && aClone && aNode->IsTemplateElement()) {
|
||||||
DocumentFragment* origContent =
|
DocumentFragment* origContent =
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,9 @@
|
||||||
#include "mozilla/dom/HTMLTemplateElementBinding.h"
|
#include "mozilla/dom/HTMLTemplateElementBinding.h"
|
||||||
|
|
||||||
#include "mozilla/dom/Document.h"
|
#include "mozilla/dom/Document.h"
|
||||||
|
#include "mozilla/dom/NameSpaceConstants.h"
|
||||||
|
#include "mozilla/dom/ShadowRootBinding.h"
|
||||||
|
#include "nsGenericHTMLElement.h"
|
||||||
#include "nsGkAtoms.h"
|
#include "nsGkAtoms.h"
|
||||||
#include "nsStyleConsts.h"
|
#include "nsStyleConsts.h"
|
||||||
#include "nsAtom.h"
|
#include "nsAtom.h"
|
||||||
|
|
@ -16,6 +19,13 @@ NS_IMPL_NS_NEW_HTML_ELEMENT(Template)
|
||||||
|
|
||||||
namespace mozilla::dom {
|
namespace mozilla::dom {
|
||||||
|
|
||||||
|
static constexpr nsAttrValue::EnumTable kShadowRootModeTable[] = {
|
||||||
|
{"open", ShadowRootMode::Open},
|
||||||
|
{"closed", ShadowRootMode::Closed},
|
||||||
|
{nullptr, {}}};
|
||||||
|
|
||||||
|
const nsAttrValue::EnumTable* kShadowRootModeDefault = &kShadowRootModeTable[2];
|
||||||
|
|
||||||
HTMLTemplateElement::HTMLTemplateElement(
|
HTMLTemplateElement::HTMLTemplateElement(
|
||||||
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
|
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
|
||||||
: nsGenericHTMLElement(std::move(aNodeInfo)) {
|
: nsGenericHTMLElement(std::move(aNodeInfo)) {
|
||||||
|
|
@ -31,7 +41,7 @@ HTMLTemplateElement::HTMLTemplateElement(
|
||||||
}
|
}
|
||||||
|
|
||||||
HTMLTemplateElement::~HTMLTemplateElement() {
|
HTMLTemplateElement::~HTMLTemplateElement() {
|
||||||
if (mContent) {
|
if (mContent && mContent->GetHost() == this) {
|
||||||
mContent->SetHost(nullptr);
|
mContent->SetHost(nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -44,7 +54,9 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLTemplateElement)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLTemplateElement,
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLTemplateElement,
|
||||||
nsGenericHTMLElement)
|
nsGenericHTMLElement)
|
||||||
if (tmp->mContent) {
|
if (tmp->mContent) {
|
||||||
tmp->mContent->SetHost(nullptr);
|
if (tmp->mContent->GetHost() == tmp) {
|
||||||
|
tmp->mContent->SetHost(nullptr);
|
||||||
|
}
|
||||||
tmp->mContent = nullptr;
|
tmp->mContent = nullptr;
|
||||||
}
|
}
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||||
|
|
@ -61,4 +73,33 @@ JSObject* HTMLTemplateElement::WrapNode(JSContext* aCx,
|
||||||
return HTMLTemplateElement_Binding::Wrap(aCx, this, aGivenProto);
|
return HTMLTemplateElement_Binding::Wrap(aCx, this, aGivenProto);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HTMLTemplateElement::AfterSetAttr(int32_t aNamespaceID, nsAtom* aName,
|
||||||
|
const nsAttrValue* aValue,
|
||||||
|
const nsAttrValue* aOldValue,
|
||||||
|
nsIPrincipal* aMaybeScriptedPrincipal,
|
||||||
|
bool aNotify) {
|
||||||
|
if (aNamespaceID == kNameSpaceID_None && aName == nsGkAtoms::shadowrootmode &&
|
||||||
|
aValue && aValue->Type() == nsAttrValue::ValueType::eEnum &&
|
||||||
|
!mShadowRootMode.isSome()) {
|
||||||
|
mShadowRootMode.emplace(
|
||||||
|
static_cast<ShadowRootMode>(aValue->GetEnumValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
nsGenericHTMLElement::AfterSetAttr(aNamespaceID, aName, aValue, aOldValue,
|
||||||
|
aMaybeScriptedPrincipal, aNotify);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HTMLTemplateElement::ParseAttribute(int32_t aNamespaceID,
|
||||||
|
nsAtom* aAttribute,
|
||||||
|
const nsAString& aValue,
|
||||||
|
nsIPrincipal* aMaybeScriptedPrincipal,
|
||||||
|
nsAttrValue& aResult) {
|
||||||
|
if (aNamespaceID == kNameSpaceID_None &&
|
||||||
|
aAttribute == nsGkAtoms::shadowrootmode) {
|
||||||
|
return aResult.ParseEnumValue(aValue, kShadowRootModeTable, false, nullptr);
|
||||||
|
}
|
||||||
|
return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
|
||||||
|
aMaybeScriptedPrincipal, aResult);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace mozilla::dom
|
} // namespace mozilla::dom
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,11 @@
|
||||||
#define mozilla_dom_HTMLTemplateElement_h
|
#define mozilla_dom_HTMLTemplateElement_h
|
||||||
|
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
|
#include "mozilla/ErrorResult.h"
|
||||||
#include "nsGenericHTMLElement.h"
|
#include "nsGenericHTMLElement.h"
|
||||||
#include "mozilla/dom/DocumentFragment.h"
|
#include "mozilla/dom/DocumentFragment.h"
|
||||||
|
#include "mozilla/dom/ShadowRootBinding.h"
|
||||||
|
#include "nsGkAtoms.h"
|
||||||
|
|
||||||
namespace mozilla::dom {
|
namespace mozilla::dom {
|
||||||
|
|
||||||
|
|
@ -26,9 +29,35 @@ class HTMLTemplateElement final : public nsGenericHTMLElement {
|
||||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLTemplateElement,
|
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLTemplateElement,
|
||||||
nsGenericHTMLElement)
|
nsGenericHTMLElement)
|
||||||
|
|
||||||
|
void AfterSetAttr(int32_t aNamespaceID, nsAtom* aName,
|
||||||
|
const nsAttrValue* aValue, const nsAttrValue* aOldValue,
|
||||||
|
nsIPrincipal* aMaybeScriptedPrincipal,
|
||||||
|
bool aNotify) override;
|
||||||
|
|
||||||
|
bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
||||||
|
const nsAString& aValue,
|
||||||
|
nsIPrincipal* aMaybeScriptedPrincipal,
|
||||||
|
nsAttrValue& aResult) override;
|
||||||
|
|
||||||
virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
|
||||||
|
|
||||||
DocumentFragment* Content() { return mContent; }
|
DocumentFragment* Content() { return mContent; }
|
||||||
|
void SetContent(DocumentFragment* aContent) { mContent = aContent; }
|
||||||
|
|
||||||
|
void GetShadowRootMode(nsAString& aResult) const {
|
||||||
|
GetEnumAttr(nsGkAtoms::shadowrootmode, nullptr, aResult);
|
||||||
|
}
|
||||||
|
void SetShadowRootMode(const nsAString& aValue) {
|
||||||
|
SetHTMLAttr(nsGkAtoms::shadowrootmode, aValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ShadowRootDelegatesFocus() {
|
||||||
|
return GetBoolAttr(nsGkAtoms::shadowrootdelegatesfocus);
|
||||||
|
}
|
||||||
|
void SetShadowRootDelegatesFocus(bool aValue) {
|
||||||
|
SetHTMLBoolAttr(nsGkAtoms::shadowrootdelegatesfocus, aValue,
|
||||||
|
IgnoredErrorResult());
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~HTMLTemplateElement();
|
virtual ~HTMLTemplateElement();
|
||||||
|
|
@ -37,6 +66,7 @@ class HTMLTemplateElement final : public nsGenericHTMLElement {
|
||||||
JS::Handle<JSObject*> aGivenProto) override;
|
JS::Handle<JSObject*> aGivenProto) override;
|
||||||
|
|
||||||
RefPtr<DocumentFragment> mContent;
|
RefPtr<DocumentFragment> mContent;
|
||||||
|
Maybe<ShadowRootMode> mShadowRootMode;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mozilla::dom
|
} // namespace mozilla::dom
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*
|
*
|
||||||
* The origin of this IDL file is
|
* The origin of this IDL file is
|
||||||
* https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html
|
* https://html.spec.whatwg.org/multipage/scripting.html#the-template-element
|
||||||
*
|
*
|
||||||
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
|
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
|
||||||
* liability, trademark and document use rules apply.
|
* liability, trademark and document use rules apply.
|
||||||
|
|
@ -13,5 +13,7 @@
|
||||||
interface HTMLTemplateElement : HTMLElement {
|
interface HTMLTemplateElement : HTMLElement {
|
||||||
[HTMLConstructor] constructor();
|
[HTMLConstructor] constructor();
|
||||||
|
|
||||||
readonly attribute DocumentFragment content;
|
readonly attribute DocumentFragment content;
|
||||||
|
[CEReactions] attribute DOMString shadowRootMode;
|
||||||
|
[CEReactions] attribute boolean shadowRootDelegatesFocus;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -314,6 +314,7 @@ nsresult nsContentDLF::CreateDocument(
|
||||||
nsCOMPtr<nsIDocumentViewer> viewer = NS_NewDocumentViewer();
|
nsCOMPtr<nsIDocumentViewer> viewer = NS_NewDocumentViewer();
|
||||||
|
|
||||||
doc->SetContainer(static_cast<nsDocShell*>(aContainer));
|
doc->SetContainer(static_cast<nsDocShell*>(aContainer));
|
||||||
|
doc->SetAllowDeclarativeShadowRoots(true);
|
||||||
|
|
||||||
// Initialize the document to begin loading the data. An
|
// Initialize the document to begin loading the data. An
|
||||||
// nsIStreamListener connected to the parser is returned in
|
// nsIStreamListener connected to the parser is returned in
|
||||||
|
|
|
||||||
|
|
@ -434,6 +434,8 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||||
|
|
||||||
private boolean forceNoQuirks = false;
|
private boolean forceNoQuirks = false;
|
||||||
|
|
||||||
|
private boolean allowDeclarativeShadowRoots = false;
|
||||||
|
|
||||||
// [NOCPP[
|
// [NOCPP[
|
||||||
|
|
||||||
private boolean reportingDoctype = true;
|
private boolean reportingDoctype = true;
|
||||||
|
|
@ -2958,6 +2960,20 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||||
|| (("http://www.w3.org/1998/Math/MathML" == ns) && (stackNode.getGroup() == MI_MO_MN_MS_MTEXT));
|
|| (("http://www.w3.org/1998/Math/MathML" == ns) && (stackNode.getGroup() == MI_MO_MN_MS_MTEXT));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private T getDeclarativeShadowRoot(T currentNode, T templateNode, HtmlAttributes attributes) {
|
||||||
|
if (!isAllowDeclarativeShadowRoots()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String shadowRootMode = attributes.getValue(AttributeName.SHADOWROOTMODE);
|
||||||
|
if (shadowRootMode == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean shadowRootDelegatesFocus = attributes.contains(AttributeName.SHADOWROOTDELEGATESFOCUS);
|
||||||
|
return getShadowRootFromHost(currentNode, templateNode, shadowRootMode, shadowRootDelegatesFocus);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
|
|
@ -5302,9 +5318,17 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||||
T elt = createElement("http://www.w3.org/1999/xhtml", elementName.getName(), attributes, currentNode
|
T elt = createElement("http://www.w3.org/1999/xhtml", elementName.getName(), attributes, currentNode
|
||||||
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
|
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
|
||||||
);
|
);
|
||||||
appendElement(elt, currentNode);
|
|
||||||
if (ElementName.TEMPLATE == elementName) {
|
if (ElementName.TEMPLATE == elementName) {
|
||||||
elt = getDocumentFragmentForTemplate(elt);
|
T root = getDeclarativeShadowRoot(currentNode, elt, attributes);
|
||||||
|
if (root != null) {
|
||||||
|
setDocumentFragmentForTemplate(elt, root);
|
||||||
|
elt = root;
|
||||||
|
} else {
|
||||||
|
appendElement(elt, currentNode);
|
||||||
|
elt = getDocumentFragmentForTemplate(elt);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
appendElement(elt, currentNode);
|
||||||
}
|
}
|
||||||
StackNode<T> node = createStackNode(elementName, elt
|
StackNode<T> node = createStackNode(elementName, elt
|
||||||
// [NOCPP[
|
// [NOCPP[
|
||||||
|
|
@ -5391,6 +5415,13 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||||
return template;
|
return template;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setDocumentFragmentForTemplate(T template, T fragment) {
|
||||||
|
}
|
||||||
|
|
||||||
|
T getShadowRootFromHost(T host, T template, String shadowRootMode, boolean shadowRootDelegatesFocus) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
T getFormPointerForContext(T context) {
|
T getFormPointerForContext(T context) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
@ -5509,6 +5540,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||||
} else {
|
} else {
|
||||||
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||||
elt = createElement("http://www.w3.org/1999/xhtml", name,
|
elt = createElement("http://www.w3.org/1999/xhtml", name,
|
||||||
|
|
||||||
attributes, formOwner, currentNode
|
attributes, formOwner, currentNode
|
||||||
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
|
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
|
||||||
);
|
);
|
||||||
|
|
@ -5893,6 +5925,14 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||||
this.setForceNoQuirks(isSrcdocDocument);
|
this.setForceNoQuirks(isSrcdocDocument);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isAllowDeclarativeShadowRoots() {
|
||||||
|
return allowDeclarativeShadowRoots;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAllowDeclarativeShadowRoots(boolean allow) {
|
||||||
|
allowDeclarativeShadowRoots = allow;
|
||||||
|
}
|
||||||
|
|
||||||
// [NOCPP[
|
// [NOCPP[
|
||||||
|
|
||||||
public void setNamePolicy(XmlViolationPolicy namePolicy) {
|
public void setNamePolicy(XmlViolationPolicy namePolicy) {
|
||||||
|
|
|
||||||
|
|
@ -678,6 +678,8 @@ void nsHtml5Parser::StartTokenizer(bool aScriptingEnabled) {
|
||||||
|
|
||||||
mTreeBuilder->SetPreventScriptExecution(!aScriptingEnabled);
|
mTreeBuilder->SetPreventScriptExecution(!aScriptingEnabled);
|
||||||
mTreeBuilder->setScriptingEnabled(aScriptingEnabled);
|
mTreeBuilder->setScriptingEnabled(aScriptingEnabled);
|
||||||
|
mTreeBuilder->setAllowDeclarativeShadowRoots(
|
||||||
|
mExecutor->GetDocument()->AllowsDeclarativeShadowRoots());
|
||||||
mTokenizer->start();
|
mTokenizer->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1125,6 +1125,8 @@ nsresult nsHtml5StreamParser::OnStartRequest(nsIRequest* aRequest) {
|
||||||
mTreeBuilder->setScriptingEnabled(scriptingEnabled);
|
mTreeBuilder->setScriptingEnabled(scriptingEnabled);
|
||||||
mTreeBuilder->SetPreventScriptExecution(
|
mTreeBuilder->SetPreventScriptExecution(
|
||||||
!((mMode == NORMAL) && scriptingEnabled));
|
!((mMode == NORMAL) && scriptingEnabled));
|
||||||
|
mTreeBuilder->setAllowDeclarativeShadowRoots(
|
||||||
|
mExecutor->GetDocument()->AllowsDeclarativeShadowRoots());
|
||||||
mTokenizer->start();
|
mTokenizer->start();
|
||||||
mExecutor->Start();
|
mExecutor->Start();
|
||||||
mExecutor->StartReadingFromStage();
|
mExecutor->StartReadingFromStage();
|
||||||
|
|
|
||||||
|
|
@ -24,12 +24,10 @@ nsHtml5StringParser::nsHtml5StringParser()
|
||||||
|
|
||||||
nsHtml5StringParser::~nsHtml5StringParser() {}
|
nsHtml5StringParser::~nsHtml5StringParser() {}
|
||||||
|
|
||||||
nsresult nsHtml5StringParser::ParseFragment(const nsAString& aSourceBuffer,
|
nsresult nsHtml5StringParser::ParseFragment(
|
||||||
nsIContent* aTargetNode,
|
const nsAString& aSourceBuffer, nsIContent* aTargetNode,
|
||||||
nsAtom* aContextLocalName,
|
nsAtom* aContextLocalName, int32_t aContextNamespace, bool aQuirks,
|
||||||
int32_t aContextNamespace,
|
bool aPreventScriptExecution, bool aAllowDeclarativeShadowRoots) {
|
||||||
bool aQuirks,
|
|
||||||
bool aPreventScriptExecution) {
|
|
||||||
NS_ENSURE_TRUE(aSourceBuffer.Length() <= INT32_MAX, NS_ERROR_OUT_OF_MEMORY);
|
NS_ENSURE_TRUE(aSourceBuffer.Length() <= INT32_MAX, NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
|
||||||
Document* doc = aTargetNode->OwnerDoc();
|
Document* doc = aTargetNode->OwnerDoc();
|
||||||
|
|
@ -52,7 +50,7 @@ nsresult nsHtml5StringParser::ParseFragment(const nsAString& aSourceBuffer,
|
||||||
|
|
||||||
mTreeBuilder->SetPreventScriptExecution(aPreventScriptExecution);
|
mTreeBuilder->SetPreventScriptExecution(aPreventScriptExecution);
|
||||||
|
|
||||||
return Tokenize(aSourceBuffer, doc, true);
|
return Tokenize(aSourceBuffer, doc, true, aAllowDeclarativeShadowRoots);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult nsHtml5StringParser::ParseDocument(
|
nsresult nsHtml5StringParser::ParseDocument(
|
||||||
|
|
@ -67,12 +65,14 @@ nsresult nsHtml5StringParser::ParseDocument(
|
||||||
mTreeBuilder->SetPreventScriptExecution(true);
|
mTreeBuilder->SetPreventScriptExecution(true);
|
||||||
|
|
||||||
return Tokenize(aSourceBuffer, aTargetDoc,
|
return Tokenize(aSourceBuffer, aTargetDoc,
|
||||||
aScriptingEnabledForNoscriptParsing);
|
aScriptingEnabledForNoscriptParsing,
|
||||||
|
aTargetDoc->AllowsDeclarativeShadowRoots());
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult nsHtml5StringParser::Tokenize(
|
nsresult nsHtml5StringParser::Tokenize(const nsAString& aSourceBuffer,
|
||||||
const nsAString& aSourceBuffer, Document* aDocument,
|
Document* aDocument,
|
||||||
bool aScriptingEnabledForNoscriptParsing) {
|
bool aScriptingEnabledForNoscriptParsing,
|
||||||
|
bool aDeclarativeShadowRootsAllowed) {
|
||||||
nsIURI* uri = aDocument->GetDocumentURI();
|
nsIURI* uri = aDocument->GetDocumentURI();
|
||||||
|
|
||||||
mBuilder->Init(aDocument, uri, nullptr, nullptr);
|
mBuilder->Init(aDocument, uri, nullptr, nullptr);
|
||||||
|
|
@ -85,6 +85,7 @@ nsresult nsHtml5StringParser::Tokenize(
|
||||||
|
|
||||||
mTreeBuilder->setScriptingEnabled(aScriptingEnabledForNoscriptParsing);
|
mTreeBuilder->setScriptingEnabled(aScriptingEnabledForNoscriptParsing);
|
||||||
mTreeBuilder->setIsSrcdocDocument(aDocument->IsSrcdocDocument());
|
mTreeBuilder->setIsSrcdocDocument(aDocument->IsSrcdocDocument());
|
||||||
|
mTreeBuilder->setAllowDeclarativeShadowRoots(aDeclarativeShadowRootsAllowed);
|
||||||
mBuilder->Start();
|
mBuilder->Start();
|
||||||
mTokenizer->start();
|
mTokenizer->start();
|
||||||
if (!aSourceBuffer.IsEmpty()) {
|
if (!aSourceBuffer.IsEmpty()) {
|
||||||
|
|
|
||||||
|
|
@ -41,11 +41,14 @@ class nsHtml5StringParser : public nsParserBase {
|
||||||
* @param aPreventScriptExecution true to prevent scripts from executing;
|
* @param aPreventScriptExecution true to prevent scripts from executing;
|
||||||
* don't set to false when parsing into a target node that has been bound
|
* don't set to false when parsing into a target node that has been bound
|
||||||
* to tree.
|
* to tree.
|
||||||
|
* @param aAllowDeclarativeShadowRoots allow the creation of declarative
|
||||||
|
* shadow roots.
|
||||||
*/
|
*/
|
||||||
nsresult ParseFragment(const nsAString& aSourceBuffer,
|
nsresult ParseFragment(const nsAString& aSourceBuffer,
|
||||||
nsIContent* aTargetNode, nsAtom* aContextLocalName,
|
nsIContent* aTargetNode, nsAtom* aContextLocalName,
|
||||||
int32_t aContextNamespace, bool aQuirks,
|
int32_t aContextNamespace, bool aQuirks,
|
||||||
bool aPreventScriptExecution);
|
bool aPreventScriptExecution,
|
||||||
|
bool aAllowDeclarativeShadowRoots);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse an entire HTML document from a source string.
|
* Parse an entire HTML document from a source string.
|
||||||
|
|
@ -61,7 +64,8 @@ class nsHtml5StringParser : public nsParserBase {
|
||||||
|
|
||||||
nsresult Tokenize(const nsAString& aSourceBuffer,
|
nsresult Tokenize(const nsAString& aSourceBuffer,
|
||||||
mozilla::dom::Document* aDocument,
|
mozilla::dom::Document* aDocument,
|
||||||
bool aScriptingEnabledForNoscriptParsing);
|
bool aScriptingEnabledForNoscriptParsing,
|
||||||
|
bool aDeclarativeShadowRootsAllowed);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The tree operation executor
|
* The tree operation executor
|
||||||
|
|
|
||||||
|
|
@ -2093,6 +2093,23 @@ bool nsHtml5TreeBuilder::isSpecialParentInForeign(nsHtml5StackNode* stackNode) {
|
||||||
(stackNode->getGroup() == MI_MO_MN_MS_MTEXT));
|
(stackNode->getGroup() == MI_MO_MN_MS_MTEXT));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsIContentHandle* nsHtml5TreeBuilder::getDeclarativeShadowRoot(
|
||||||
|
nsIContentHandle* currentNode, nsIContentHandle* templateNode,
|
||||||
|
nsHtml5HtmlAttributes* attributes) {
|
||||||
|
if (!isAllowDeclarativeShadowRoots()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
nsHtml5String shadowRootMode =
|
||||||
|
attributes->getValue(nsHtml5AttributeName::ATTR_SHADOWROOTMODE);
|
||||||
|
if (!shadowRootMode) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
bool shadowRootDelegatesFocus =
|
||||||
|
attributes->contains(nsHtml5AttributeName::ATTR_SHADOWROOTDELEGATESFOCUS);
|
||||||
|
return getShadowRootFromHost(currentNode, templateNode, shadowRootMode,
|
||||||
|
shadowRootDelegatesFocus);
|
||||||
|
}
|
||||||
|
|
||||||
nsHtml5String nsHtml5TreeBuilder::extractCharsetFromContent(
|
nsHtml5String nsHtml5TreeBuilder::extractCharsetFromContent(
|
||||||
nsHtml5String attributeValue, nsHtml5TreeBuilder* tb) {
|
nsHtml5String attributeValue, nsHtml5TreeBuilder* tb) {
|
||||||
int32_t charsetState = CHARSET_INITIAL;
|
int32_t charsetState = CHARSET_INITIAL;
|
||||||
|
|
@ -4218,9 +4235,18 @@ void nsHtml5TreeBuilder::appendToCurrentNodeAndPushElement(
|
||||||
nsIContentHandle* elt =
|
nsIContentHandle* elt =
|
||||||
createElement(kNameSpaceID_XHTML, elementName->getName(), attributes,
|
createElement(kNameSpaceID_XHTML, elementName->getName(), attributes,
|
||||||
currentNode, htmlCreator(elementName->getHtmlCreator()));
|
currentNode, htmlCreator(elementName->getHtmlCreator()));
|
||||||
appendElement(elt, currentNode);
|
|
||||||
if (nsHtml5ElementName::ELT_TEMPLATE == elementName) {
|
if (nsHtml5ElementName::ELT_TEMPLATE == elementName) {
|
||||||
elt = getDocumentFragmentForTemplate(elt);
|
nsIContentHandle* root =
|
||||||
|
getDeclarativeShadowRoot(currentNode, elt, attributes);
|
||||||
|
if (root) {
|
||||||
|
setDocumentFragmentForTemplate(elt, root);
|
||||||
|
elt = root;
|
||||||
|
} else {
|
||||||
|
appendElement(elt, currentNode);
|
||||||
|
elt = getDocumentFragmentForTemplate(elt);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
appendElement(elt, currentNode);
|
||||||
}
|
}
|
||||||
nsHtml5StackNode* node = createStackNode(elementName, elt);
|
nsHtml5StackNode* node = createStackNode(elementName, elt);
|
||||||
push(node);
|
push(node);
|
||||||
|
|
@ -4482,6 +4508,14 @@ void nsHtml5TreeBuilder::setIsSrcdocDocument(bool isSrcdocDocument) {
|
||||||
this->setForceNoQuirks(isSrcdocDocument);
|
this->setForceNoQuirks(isSrcdocDocument);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool nsHtml5TreeBuilder::isAllowDeclarativeShadowRoots() {
|
||||||
|
return allowDeclarativeShadowRoots;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nsHtml5TreeBuilder::setAllowDeclarativeShadowRoots(bool allow) {
|
||||||
|
allowDeclarativeShadowRoots = allow;
|
||||||
|
}
|
||||||
|
|
||||||
void nsHtml5TreeBuilder::flushCharacters() {
|
void nsHtml5TreeBuilder::flushCharacters() {
|
||||||
if (charBufferLen > 0) {
|
if (charBufferLen > 0) {
|
||||||
if ((mode == IN_TABLE || mode == IN_TABLE_BODY || mode == IN_ROW) &&
|
if ((mode == IN_TABLE || mode == IN_TABLE_BODY || mode == IN_ROW) &&
|
||||||
|
|
|
||||||
|
|
@ -314,6 +314,7 @@ class nsHtml5TreeBuilder : public nsAHtml5TreeBuilderState {
|
||||||
private:
|
private:
|
||||||
bool quirks;
|
bool quirks;
|
||||||
bool forceNoQuirks;
|
bool forceNoQuirks;
|
||||||
|
bool allowDeclarativeShadowRoots;
|
||||||
inline nsHtml5ContentCreatorFunction htmlCreator(
|
inline nsHtml5ContentCreatorFunction htmlCreator(
|
||||||
mozilla::dom::HTMLContentCreatorFunction htmlCreator) {
|
mozilla::dom::HTMLContentCreatorFunction htmlCreator) {
|
||||||
nsHtml5ContentCreatorFunction creator;
|
nsHtml5ContentCreatorFunction creator;
|
||||||
|
|
@ -353,6 +354,9 @@ class nsHtml5TreeBuilder : public nsAHtml5TreeBuilderState {
|
||||||
bool isTemplateContents();
|
bool isTemplateContents();
|
||||||
bool isTemplateModeStackEmpty();
|
bool isTemplateModeStackEmpty();
|
||||||
bool isSpecialParentInForeign(nsHtml5StackNode* stackNode);
|
bool isSpecialParentInForeign(nsHtml5StackNode* stackNode);
|
||||||
|
nsIContentHandle* getDeclarativeShadowRoot(nsIContentHandle* currentNode,
|
||||||
|
nsIContentHandle* templateNode,
|
||||||
|
nsHtml5HtmlAttributes* attributes);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static nsHtml5String extractCharsetFromContent(nsHtml5String attributeValue,
|
static nsHtml5String extractCharsetFromContent(nsHtml5String attributeValue,
|
||||||
|
|
@ -556,6 +560,8 @@ class nsHtml5TreeBuilder : public nsAHtml5TreeBuilderState {
|
||||||
void setScriptingEnabled(bool scriptingEnabled);
|
void setScriptingEnabled(bool scriptingEnabled);
|
||||||
void setForceNoQuirks(bool forceNoQuirks);
|
void setForceNoQuirks(bool forceNoQuirks);
|
||||||
void setIsSrcdocDocument(bool isSrcdocDocument);
|
void setIsSrcdocDocument(bool isSrcdocDocument);
|
||||||
|
bool isAllowDeclarativeShadowRoots();
|
||||||
|
void setAllowDeclarativeShadowRoots(bool allow);
|
||||||
void flushCharacters();
|
void flushCharacters();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,12 @@
|
||||||
#include "ErrorList.h"
|
#include "ErrorList.h"
|
||||||
#include "nsError.h"
|
#include "nsError.h"
|
||||||
#include "nsHtml5AttributeName.h"
|
#include "nsHtml5AttributeName.h"
|
||||||
|
#include "nsHtml5HtmlAttributes.h"
|
||||||
#include "nsHtml5String.h"
|
#include "nsHtml5String.h"
|
||||||
#include "nsNetUtil.h"
|
#include "nsNetUtil.h"
|
||||||
#include "mozilla/dom/FetchPriority.h"
|
#include "mozilla/dom/FetchPriority.h"
|
||||||
|
#include "mozilla/dom/ShadowRoot.h"
|
||||||
|
#include "mozilla/dom/ShadowRootBinding.h"
|
||||||
#include "mozilla/CheckedInt.h"
|
#include "mozilla/CheckedInt.h"
|
||||||
#include "mozilla/Likely.h"
|
#include "mozilla/Likely.h"
|
||||||
#include "mozilla/StaticPrefs_dom.h"
|
#include "mozilla/StaticPrefs_dom.h"
|
||||||
|
|
@ -1636,6 +1639,53 @@ nsIContentHandle* nsHtml5TreeBuilder::getDocumentFragmentForTemplate(
|
||||||
return fragHandle;
|
return fragHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nsHtml5TreeBuilder::setDocumentFragmentForTemplate(
|
||||||
|
nsIContentHandle* aTemplate, nsIContentHandle* aFragment) {
|
||||||
|
if (mBuilder) {
|
||||||
|
nsHtml5TreeOperation::SetDocumentFragmentForTemplate(
|
||||||
|
static_cast<nsIContent*>(aTemplate),
|
||||||
|
static_cast<nsIContent*>(aFragment));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(mozilla::fallible);
|
||||||
|
if (MOZ_UNLIKELY(!treeOp)) {
|
||||||
|
MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
opSetDocumentFragmentForTemplate operation(aTemplate, aFragment);
|
||||||
|
treeOp->Init(mozilla::AsVariant(operation));
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIContentHandle* nsHtml5TreeBuilder::getShadowRootFromHost(
|
||||||
|
nsIContentHandle* aHost, nsIContentHandle* aTemplateNode,
|
||||||
|
nsHtml5String aShadowRootMode, bool aShadowRootDelegatesFocus) {
|
||||||
|
mozilla::dom::ShadowRootMode mode;
|
||||||
|
if (aShadowRootMode.LowerCaseEqualsASCII("open")) {
|
||||||
|
mode = mozilla::dom::ShadowRootMode::Open;
|
||||||
|
} else if (aShadowRootMode.LowerCaseEqualsASCII("closed")) {
|
||||||
|
mode = mozilla::dom::ShadowRootMode::Closed;
|
||||||
|
} else {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mBuilder) {
|
||||||
|
return nsContentUtils::AttachDeclarativeShadowRoot(
|
||||||
|
static_cast<nsIContent*>(aHost), mode, aShadowRootDelegatesFocus);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(mozilla::fallible);
|
||||||
|
if (MOZ_UNLIKELY(!treeOp)) {
|
||||||
|
MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
nsIContentHandle* fragHandle = AllocateContentHandle();
|
||||||
|
opGetShadowRootFromHost operation(aHost, fragHandle, aTemplateNode, mode,
|
||||||
|
aShadowRootDelegatesFocus);
|
||||||
|
treeOp->Init(mozilla::AsVariant(operation));
|
||||||
|
return fragHandle;
|
||||||
|
}
|
||||||
|
|
||||||
nsIContentHandle* nsHtml5TreeBuilder::getFormPointerForContext(
|
nsIContentHandle* nsHtml5TreeBuilder::getFormPointerForContext(
|
||||||
nsIContentHandle* aContext) {
|
nsIContentHandle* aContext) {
|
||||||
MOZ_ASSERT(mBuilder, "Must have builder.");
|
MOZ_ASSERT(mBuilder, "Must have builder.");
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,13 @@ bool mActive;
|
||||||
void documentMode(nsHtml5DocumentMode m);
|
void documentMode(nsHtml5DocumentMode m);
|
||||||
|
|
||||||
nsIContentHandle* getDocumentFragmentForTemplate(nsIContentHandle* aTemplate);
|
nsIContentHandle* getDocumentFragmentForTemplate(nsIContentHandle* aTemplate);
|
||||||
|
void setDocumentFragmentForTemplate(nsIContentHandle* aTemplate,
|
||||||
|
nsIContentHandle* aFragment);
|
||||||
|
|
||||||
|
nsIContentHandle* getShadowRootFromHost(nsIContentHandle* aHost,
|
||||||
|
nsIContentHandle* aTemplateNode,
|
||||||
|
nsHtml5String aShadowRootMode,
|
||||||
|
bool aShadowRootDelegatesFocus);
|
||||||
|
|
||||||
nsIContentHandle* getFormPointerForContext(nsIContentHandle* aContext);
|
nsIContentHandle* getFormPointerForContext(nsIContentHandle* aContext);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
#include "mozilla/dom/Comment.h"
|
#include "mozilla/dom/Comment.h"
|
||||||
#include "mozilla/dom/CustomElementRegistry.h"
|
#include "mozilla/dom/CustomElementRegistry.h"
|
||||||
#include "mozilla/dom/DocGroup.h"
|
#include "mozilla/dom/DocGroup.h"
|
||||||
|
#include "mozilla/dom/DocumentFragment.h"
|
||||||
#include "mozilla/dom/DocumentType.h"
|
#include "mozilla/dom/DocumentType.h"
|
||||||
#include "mozilla/dom/Element.h"
|
#include "mozilla/dom/Element.h"
|
||||||
#include "mozilla/dom/LinkStyle.h"
|
#include "mozilla/dom/LinkStyle.h"
|
||||||
|
|
@ -18,12 +19,14 @@
|
||||||
#include "mozilla/dom/HTMLImageElement.h"
|
#include "mozilla/dom/HTMLImageElement.h"
|
||||||
#include "mozilla/dom/HTMLTemplateElement.h"
|
#include "mozilla/dom/HTMLTemplateElement.h"
|
||||||
#include "mozilla/dom/MutationObservers.h"
|
#include "mozilla/dom/MutationObservers.h"
|
||||||
|
#include "mozilla/dom/ShadowRoot.h"
|
||||||
#include "mozilla/dom/Text.h"
|
#include "mozilla/dom/Text.h"
|
||||||
#include "nsAttrName.h"
|
#include "nsAttrName.h"
|
||||||
#include "nsContentCreatorFunctions.h"
|
#include "nsContentCreatorFunctions.h"
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
#include "nsDocElementCreatedNotificationRunner.h"
|
#include "nsDocElementCreatedNotificationRunner.h"
|
||||||
#include "nsEscape.h"
|
#include "nsEscape.h"
|
||||||
|
#include "nsGenericHTMLElement.h"
|
||||||
#include "nsHtml5AutoPauseUpdate.h"
|
#include "nsHtml5AutoPauseUpdate.h"
|
||||||
#include "nsHtml5DocumentMode.h"
|
#include "nsHtml5DocumentMode.h"
|
||||||
#include "nsHtml5HtmlAttributes.h"
|
#include "nsHtml5HtmlAttributes.h"
|
||||||
|
|
@ -135,6 +138,10 @@ nsHtml5TreeOperation::~nsHtml5TreeOperation() {
|
||||||
|
|
||||||
void operator()(const opGetDocumentFragmentForTemplate& aOperation) {}
|
void operator()(const opGetDocumentFragmentForTemplate& aOperation) {}
|
||||||
|
|
||||||
|
void operator()(const opSetDocumentFragmentForTemplate& aOperation) {}
|
||||||
|
|
||||||
|
void operator()(const opGetShadowRootFromHost& aOperation) {}
|
||||||
|
|
||||||
void operator()(const opGetFosterParent& aOperation) {}
|
void operator()(const opGetFosterParent& aOperation) {}
|
||||||
|
|
||||||
void operator()(const opMarkAsBroken& aOperation) {}
|
void operator()(const opMarkAsBroken& aOperation) {}
|
||||||
|
|
@ -694,6 +701,12 @@ nsIContent* nsHtml5TreeOperation::GetDocumentFragmentForTemplate(
|
||||||
return tempElem->Content();
|
return tempElem->Content();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nsHtml5TreeOperation::SetDocumentFragmentForTemplate(
|
||||||
|
nsIContent* aNode, nsIContent* aDocumentFragment) {
|
||||||
|
auto* tempElem = static_cast<HTMLTemplateElement*>(aNode);
|
||||||
|
tempElem->SetContent(static_cast<DocumentFragment*>(aDocumentFragment));
|
||||||
|
}
|
||||||
|
|
||||||
nsIContent* nsHtml5TreeOperation::GetFosterParent(nsIContent* aTable,
|
nsIContent* nsHtml5TreeOperation::GetFosterParent(nsIContent* aTable,
|
||||||
nsIContent* aStackParent) {
|
nsIContent* aStackParent) {
|
||||||
nsIContent* tableParent = aTable->GetParent();
|
nsIContent* tableParent = aTable->GetParent();
|
||||||
|
|
@ -894,6 +907,31 @@ nsresult nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult operator()(const opSetDocumentFragmentForTemplate& aOperation) {
|
||||||
|
SetDocumentFragmentForTemplate(*aOperation.mTemplate,
|
||||||
|
*aOperation.mFragment);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult operator()(const opGetShadowRootFromHost& aOperation) {
|
||||||
|
nsIContent* root = nsContentUtils::AttachDeclarativeShadowRoot(
|
||||||
|
*aOperation.mHost, aOperation.mShadowRootMode,
|
||||||
|
aOperation.mShadowRootDelegatesFocus);
|
||||||
|
if (root) {
|
||||||
|
*aOperation.mFragHandle = root;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We failed to attach a new shadow root, so instead attach a template
|
||||||
|
// element and return its content.
|
||||||
|
nsHtml5TreeOperation::Append(*aOperation.mTemplateNode, *aOperation.mHost,
|
||||||
|
mBuilder);
|
||||||
|
*aOperation.mFragHandle =
|
||||||
|
static_cast<HTMLTemplateElement*>(*aOperation.mTemplateNode)
|
||||||
|
->Content();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult operator()(const opGetFosterParent& aOperation) {
|
nsresult operator()(const opGetFosterParent& aOperation) {
|
||||||
nsIContent* table = *(aOperation.mTable);
|
nsIContent* table = *(aOperation.mTable);
|
||||||
nsIContent* stackParent = *(aOperation.mStackParent);
|
nsIContent* stackParent = *(aOperation.mStackParent);
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
#include "nsHtml5DocumentMode.h"
|
#include "nsHtml5DocumentMode.h"
|
||||||
#include "nsHtml5HtmlAttributes.h"
|
#include "nsHtml5HtmlAttributes.h"
|
||||||
#include "mozilla/dom/FromParser.h"
|
#include "mozilla/dom/FromParser.h"
|
||||||
|
#include "mozilla/dom/ShadowRootBinding.h"
|
||||||
#include "mozilla/NotNull.h"
|
#include "mozilla/NotNull.h"
|
||||||
#include "mozilla/Variant.h"
|
#include "mozilla/Variant.h"
|
||||||
#include "nsCharsetSource.h"
|
#include "nsCharsetSource.h"
|
||||||
|
|
@ -264,6 +265,37 @@ struct opGetDocumentFragmentForTemplate {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct opSetDocumentFragmentForTemplate {
|
||||||
|
nsIContent** mTemplate;
|
||||||
|
nsIContent** mFragment;
|
||||||
|
|
||||||
|
explicit opSetDocumentFragmentForTemplate(nsIContentHandle* aTemplate,
|
||||||
|
nsIContentHandle* aFragment) {
|
||||||
|
mTemplate = static_cast<nsIContent**>(aTemplate);
|
||||||
|
mFragment = static_cast<nsIContent**>(aFragment);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct opGetShadowRootFromHost {
|
||||||
|
nsIContent** mHost;
|
||||||
|
nsIContent** mFragHandle;
|
||||||
|
nsIContent** mTemplateNode;
|
||||||
|
mozilla::dom::ShadowRootMode mShadowRootMode;
|
||||||
|
bool mShadowRootDelegatesFocus;
|
||||||
|
|
||||||
|
explicit opGetShadowRootFromHost(nsIContentHandle* aHost,
|
||||||
|
nsIContentHandle* aFragHandle,
|
||||||
|
nsIContentHandle* aTemplateNode,
|
||||||
|
mozilla::dom::ShadowRootMode aShadowRootMode,
|
||||||
|
bool aShadowRootDelegatesFocus) {
|
||||||
|
mHost = static_cast<nsIContent**>(aHost);
|
||||||
|
mFragHandle = static_cast<nsIContent**>(aFragHandle);
|
||||||
|
mTemplateNode = static_cast<nsIContent**>(aTemplateNode);
|
||||||
|
mShadowRootMode = aShadowRootMode;
|
||||||
|
mShadowRootDelegatesFocus = aShadowRootDelegatesFocus;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct opGetFosterParent {
|
struct opGetFosterParent {
|
||||||
nsIContent** mTable;
|
nsIContent** mTable;
|
||||||
nsIContent** mStackParent;
|
nsIContent** mStackParent;
|
||||||
|
|
@ -492,7 +524,8 @@ typedef mozilla::Variant<
|
||||||
opCreateHTMLElement, opCreateSVGElement, opCreateMathMLElement,
|
opCreateHTMLElement, opCreateSVGElement, opCreateMathMLElement,
|
||||||
opSetFormElement, opAppendText, opFosterParentText, opAppendComment,
|
opSetFormElement, opAppendText, opFosterParentText, opAppendComment,
|
||||||
opAppendCommentToDocument, opAppendDoctypeToDocument,
|
opAppendCommentToDocument, opAppendDoctypeToDocument,
|
||||||
opGetDocumentFragmentForTemplate, opGetFosterParent,
|
opGetDocumentFragmentForTemplate, opSetDocumentFragmentForTemplate,
|
||||||
|
opGetShadowRootFromHost, opGetFosterParent,
|
||||||
// Gecko-specific on-pop ops
|
// Gecko-specific on-pop ops
|
||||||
opMarkAsBroken, opRunScriptThatMayDocumentWriteOrBlock,
|
opMarkAsBroken, opRunScriptThatMayDocumentWriteOrBlock,
|
||||||
opRunScriptThatCannotDocumentWriteOrBlock, opPreventScriptExecution,
|
opRunScriptThatCannotDocumentWriteOrBlock, opPreventScriptExecution,
|
||||||
|
|
@ -587,6 +620,8 @@ class nsHtml5TreeOperation final {
|
||||||
nsHtml5DocumentBuilder* aBuilder);
|
nsHtml5DocumentBuilder* aBuilder);
|
||||||
|
|
||||||
static nsIContent* GetDocumentFragmentForTemplate(nsIContent* aNode);
|
static nsIContent* GetDocumentFragmentForTemplate(nsIContent* aNode);
|
||||||
|
static void SetDocumentFragmentForTemplate(nsIContent* aNode,
|
||||||
|
nsIContent* aDocumentFragment);
|
||||||
|
|
||||||
static nsIContent* GetFosterParent(nsIContent* aTable,
|
static nsIContent* GetFosterParent(nsIContent* aTable,
|
||||||
nsIContent* aStackParent);
|
nsIContent* aStackParent);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue