XMLStylesheetProcessingInstruction.cpp (5121B)
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 "XMLStylesheetProcessingInstruction.h" 8 9 #include "mozilla/dom/Document.h" 10 #include "mozilla/dom/FetchPriority.h" 11 #include "mozilla/dom/ReferrerInfo.h" 12 #include "nsContentUtils.h" 13 #include "nsNetUtil.h" 14 15 namespace mozilla::dom { 16 17 // nsISupports implementation 18 19 NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0( 20 XMLStylesheetProcessingInstruction, ProcessingInstruction) 21 22 NS_IMPL_CYCLE_COLLECTION_CLASS(XMLStylesheetProcessingInstruction) 23 24 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED( 25 XMLStylesheetProcessingInstruction, ProcessingInstruction) 26 tmp->LinkStyle::Traverse(cb); 27 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END 28 29 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED( 30 XMLStylesheetProcessingInstruction, ProcessingInstruction) 31 tmp->LinkStyle::Unlink(); 32 NS_IMPL_CYCLE_COLLECTION_UNLINK_END 33 34 XMLStylesheetProcessingInstruction::~XMLStylesheetProcessingInstruction() = 35 default; 36 37 // nsIContent 38 39 nsresult XMLStylesheetProcessingInstruction::BindToTree(BindContext& aContext, 40 nsINode& aParent) { 41 nsresult rv = ProcessingInstruction::BindToTree(aContext, aParent); 42 NS_ENSURE_SUCCESS(rv, rv); 43 44 void (XMLStylesheetProcessingInstruction::*update)() = 45 &XMLStylesheetProcessingInstruction::UpdateStyleSheetInternal; 46 nsContentUtils::AddScriptRunner(NewRunnableMethod( 47 "dom::XMLStylesheetProcessingInstruction::BindToTree", this, update)); 48 49 return rv; 50 } 51 52 void XMLStylesheetProcessingInstruction::UnbindFromTree( 53 UnbindContext& aContext) { 54 nsCOMPtr<Document> oldDoc = GetUncomposedDoc(); 55 56 ProcessingInstruction::UnbindFromTree(aContext); 57 (void)UpdateStyleSheetInternal(oldDoc, nullptr); 58 } 59 60 // nsINode 61 62 void XMLStylesheetProcessingInstruction::SetNodeValueInternal( 63 const nsAString& aNodeValue, ErrorResult& aError, 64 MutationEffectOnScript aMutationEffectOnScript) { 65 CharacterData::SetNodeValueInternal(aNodeValue, aError, 66 aMutationEffectOnScript); 67 if (!aError.Failed()) { 68 (void)UpdateStyleSheetInternal(nullptr, nullptr, ForceUpdate::Yes); 69 } 70 } 71 72 // LinkStyle 73 74 void XMLStylesheetProcessingInstruction::GetCharset(nsAString& aCharset) { 75 if (!GetAttrValue(nsGkAtoms::charset, aCharset)) { 76 aCharset.Truncate(); 77 } 78 } 79 80 void XMLStylesheetProcessingInstruction::OverrideBaseURI(nsIURI* aNewBaseURI) { 81 mOverriddenBaseURI = aNewBaseURI; 82 } 83 84 Maybe<LinkStyle::SheetInfo> 85 XMLStylesheetProcessingInstruction::GetStyleSheetInfo() { 86 // xml-stylesheet PI is special only in prolog 87 if (!nsContentUtils::InProlog(this)) { 88 return Nothing(); 89 } 90 91 nsAutoString href; 92 if (!GetAttrValue(nsGkAtoms::href, href)) { 93 return Nothing(); 94 } 95 96 nsAutoString data; 97 GetData(data); 98 99 nsAutoString title; 100 nsContentUtils::GetPseudoAttributeValue(data, nsGkAtoms::title, title); 101 102 nsAutoString alternateAttr; 103 nsContentUtils::GetPseudoAttributeValue(data, nsGkAtoms::alternate, 104 alternateAttr); 105 106 bool alternate = alternateAttr.EqualsLiteral("yes"); 107 if (alternate && title.IsEmpty()) { 108 // alternates must have title 109 return Nothing(); 110 } 111 112 nsAutoString media; 113 nsContentUtils::GetPseudoAttributeValue(data, nsGkAtoms::media, media); 114 115 // Make sure the type handling here matches 116 // nsXMLContentSink::HandleProcessingInstruction 117 nsAutoString type; 118 nsContentUtils::GetPseudoAttributeValue(data, nsGkAtoms::type, type); 119 120 nsAutoString mimeType, notUsed; 121 nsContentUtils::SplitMimeType(type, mimeType, notUsed); 122 if (!mimeType.IsEmpty() && !mimeType.LowerCaseEqualsLiteral("text/css")) { 123 return Nothing(); 124 } 125 126 Document* doc = OwnerDoc(); 127 nsIURI* baseURL = 128 mOverriddenBaseURI ? mOverriddenBaseURI.get() : doc->GetDocBaseURI(); 129 auto encoding = doc->GetDocumentCharacterSet(); 130 nsCOMPtr<nsIURI> uri; 131 NS_NewURI(getter_AddRefs(uri), href, encoding, baseURL); 132 133 return Some(SheetInfo{ 134 *doc, 135 this, 136 uri.forget(), 137 nullptr, 138 MakeAndAddRef<ReferrerInfo>(*doc), 139 CORS_NONE, 140 title, 141 media, 142 /* integrity = */ u""_ns, 143 /* nonce = */ u""_ns, 144 alternate ? HasAlternateRel::Yes : HasAlternateRel::No, 145 IsInline::No, 146 IsExplicitlyEnabled::No, 147 FetchPriority::Auto, 148 }); 149 } 150 151 already_AddRefed<CharacterData> 152 XMLStylesheetProcessingInstruction::CloneDataNode( 153 mozilla::dom::NodeInfo* aNodeInfo, bool aCloneText) const { 154 nsAutoString data; 155 GetData(data); 156 RefPtr<mozilla::dom::NodeInfo> ni = aNodeInfo; 157 auto* nim = ni->NodeInfoManager(); 158 auto* doc = ni->GetDocument(); 159 RefPtr<XMLStylesheetProcessingInstruction> it = do_AddRef( 160 new (nim) XMLStylesheetProcessingInstruction(ni.forget(), data)); 161 MaybeStartCopyStyleSheetTo(it.get(), doc); 162 return it.forget(); 163 } 164 165 } // namespace mozilla::dom