HTMLTemplateElement.cpp (4723B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "mozilla/dom/HTMLTemplateElement.h" 8 9 #include "mozilla/dom/Document.h" 10 #include "mozilla/dom/HTMLTemplateElementBinding.h" 11 #include "mozilla/dom/NameSpaceConstants.h" 12 #include "mozilla/dom/ShadowRootBinding.h" 13 #include "nsAtom.h" 14 #include "nsGenericHTMLElement.h" 15 #include "nsGkAtoms.h" 16 #include "nsStyleConsts.h" 17 18 NS_IMPL_NS_NEW_HTML_ELEMENT(Template) 19 20 namespace mozilla::dom { 21 22 static constexpr nsAttrValue::EnumTableEntry kShadowRootModeTable[] = { 23 {"open", ShadowRootMode::Open}, 24 {"closed", ShadowRootMode::Closed}, 25 }; 26 27 HTMLTemplateElement::HTMLTemplateElement( 28 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo) 29 : nsGenericHTMLElement(std::move(aNodeInfo)) { 30 SetHasWeirdParserInsertionMode(); 31 32 Document* contentsOwner = OwnerDoc()->GetTemplateContentsOwner(); 33 if (!contentsOwner) { 34 MOZ_CRASH("There should always be a template contents owner."); 35 } 36 37 mContent = contentsOwner->CreateDocumentFragment(); 38 mContent->SetHost(this); 39 } 40 41 HTMLTemplateElement::~HTMLTemplateElement() { 42 if (mContent && mContent->GetHost() == this) { 43 mContent->SetHost(nullptr); 44 } 45 } 46 47 NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(HTMLTemplateElement, 48 nsGenericHTMLElement) 49 50 NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLTemplateElement) 51 52 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLTemplateElement, 53 nsGenericHTMLElement) 54 if (tmp->mContent) { 55 if (tmp->mContent->GetHost() == tmp) { 56 tmp->mContent->SetHost(nullptr); 57 } 58 tmp->mContent = nullptr; 59 } 60 NS_IMPL_CYCLE_COLLECTION_UNLINK_END 61 62 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLTemplateElement, 63 nsGenericHTMLElement) 64 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mContent) 65 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END 66 67 NS_IMPL_ELEMENT_CLONE(HTMLTemplateElement) 68 69 JSObject* HTMLTemplateElement::WrapNode(JSContext* aCx, 70 JS::Handle<JSObject*> aGivenProto) { 71 return HTMLTemplateElement_Binding::Wrap(aCx, this, aGivenProto); 72 } 73 74 void HTMLTemplateElement::AfterSetAttr(int32_t aNamespaceID, nsAtom* aName, 75 const nsAttrValue* aValue, 76 const nsAttrValue* aOldValue, 77 nsIPrincipal* aMaybeScriptedPrincipal, 78 bool aNotify) { 79 if (aNamespaceID == kNameSpaceID_None && aName == nsGkAtoms::shadowrootmode && 80 aValue && aValue->Type() == nsAttrValue::ValueType::eEnum && 81 !mShadowRootMode.isSome()) { 82 mShadowRootMode.emplace( 83 static_cast<ShadowRootMode>(aValue->GetEnumValue())); 84 } 85 86 nsGenericHTMLElement::AfterSetAttr(aNamespaceID, aName, aValue, aOldValue, 87 aMaybeScriptedPrincipal, aNotify); 88 } 89 90 bool HTMLTemplateElement::ParseAttribute(int32_t aNamespaceID, 91 nsAtom* aAttribute, 92 const nsAString& aValue, 93 nsIPrincipal* aMaybeScriptedPrincipal, 94 nsAttrValue& aResult) { 95 if (aNamespaceID == kNameSpaceID_None && 96 aAttribute == nsGkAtoms::shadowrootmode) { 97 return aResult.ParseEnumValue(aValue, kShadowRootModeTable, false, nullptr); 98 } 99 return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue, 100 aMaybeScriptedPrincipal, aResult); 101 } 102 103 void HTMLTemplateElement::SetHTML(const nsAString& aHTML, 104 const SetHTMLOptions& aOptions, 105 ErrorResult& aError) { 106 RefPtr<DocumentFragment> content = mContent; 107 nsContentUtils::SetHTML(content, this, aHTML, aOptions, aError); 108 } 109 110 void HTMLTemplateElement::SetHTMLUnsafe(const TrustedHTMLOrString& aHTML, 111 const SetHTMLUnsafeOptions& aOptions, 112 nsIPrincipal* aSubjectPrincipal, 113 ErrorResult& aError) { 114 RefPtr<DocumentFragment> content = mContent; 115 nsContentUtils::SetHTMLUnsafe(content, this, aHTML, aOptions, 116 false /*aIsShadowRoot*/, aSubjectPrincipal, 117 aError); 118 } 119 120 } // namespace mozilla::dom