Backed out changeset 2450366cf7ca (bug 1891629) for causing win msix mochitest failures
[gecko.git] / dom / base / DOMImplementation.cpp
blobcc4d3d3da885d6331d21b7a1eca3a074066f1033
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/. */
7 #include "mozilla/dom/DOMImplementation.h"
9 #include "mozilla/ContentEvents.h"
10 #include "mozilla/dom/DOMImplementationBinding.h"
11 #include "nsContentCreatorFunctions.h"
12 #include "nsContentUtils.h"
13 #include "mozilla/dom/Document.h"
14 #include "mozilla/dom/DocumentType.h"
15 #include "nsTextNode.h"
17 namespace mozilla::dom {
19 // QueryInterface implementation for DOMImplementation
20 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMImplementation)
21 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
22 NS_INTERFACE_MAP_ENTRY(nsISupports)
23 NS_INTERFACE_MAP_END
25 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DOMImplementation, mOwner)
27 NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMImplementation)
28 NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMImplementation)
30 DOMImplementation::DOMImplementation(Document* aOwner,
31 nsIGlobalObject* aScriptObject,
32 nsIURI* aDocumentURI, nsIURI* aBaseURI)
33 : mOwner(aOwner),
34 mScriptObject(do_GetWeakReference(aScriptObject)),
35 mDocumentURI(aDocumentURI),
36 mBaseURI(aBaseURI) {
37 MOZ_ASSERT(aOwner);
40 DOMImplementation::~DOMImplementation() = default;
42 JSObject* DOMImplementation::WrapObject(JSContext* aCx,
43 JS::Handle<JSObject*> aGivenProto) {
44 return DOMImplementation_Binding::Wrap(aCx, this, aGivenProto);
47 already_AddRefed<DocumentType> DOMImplementation::CreateDocumentType(
48 const nsAString& aQualifiedName, const nsAString& aPublicId,
49 const nsAString& aSystemId, ErrorResult& aRv) {
50 if (!mOwner) {
51 aRv.Throw(NS_ERROR_UNEXPECTED);
52 return nullptr;
55 aRv = nsContentUtils::CheckQName(aQualifiedName);
56 if (aRv.Failed()) {
57 return nullptr;
60 RefPtr<nsAtom> name = NS_Atomize(aQualifiedName);
61 if (!name) {
62 aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
63 return nullptr;
66 // Indicate that there is no internal subset (not just an empty one)
67 RefPtr<DocumentType> docType = NS_NewDOMDocumentType(
68 mOwner->NodeInfoManager(), name, aPublicId, aSystemId, VoidString());
69 return docType.forget();
72 nsresult DOMImplementation::CreateDocument(const nsAString& aNamespaceURI,
73 const nsAString& aQualifiedName,
74 DocumentType* aDoctype,
75 Document** aDocument) {
76 *aDocument = nullptr;
78 nsresult rv;
79 if (!aQualifiedName.IsEmpty()) {
80 const nsString& qName = PromiseFlatString(aQualifiedName);
81 const char16_t* colon;
82 rv = nsContentUtils::CheckQName(qName, true, &colon);
83 NS_ENSURE_SUCCESS(rv, rv);
85 if (colon && (DOMStringIsNull(aNamespaceURI) ||
86 (Substring(qName.get(), colon).EqualsLiteral("xml") &&
87 !aNamespaceURI.EqualsLiteral(
88 "http://www.w3.org/XML/1998/namespace")))) {
89 return NS_ERROR_DOM_NAMESPACE_ERR;
93 nsCOMPtr<nsIGlobalObject> scriptHandlingObject =
94 do_QueryReferent(mScriptObject);
96 NS_ENSURE_STATE(!mScriptObject || scriptHandlingObject);
98 nsCOMPtr<Document> doc;
100 rv = NS_NewDOMDocument(getter_AddRefs(doc), aNamespaceURI, aQualifiedName,
101 aDoctype, mDocumentURI, mBaseURI,
102 mOwner->NodePrincipal(), true, scriptHandlingObject,
103 DocumentFlavorXML);
104 NS_ENSURE_SUCCESS(rv, rv);
106 // When DOMImplementation's createDocument method is invoked with
107 // namespace set to HTML Namespace use the registry of the associated
108 // document to the new instance.
110 if (aNamespaceURI.EqualsLiteral("http://www.w3.org/1999/xhtml")) {
111 doc->SetContentType("application/xhtml+xml"_ns);
112 } else if (aNamespaceURI.EqualsLiteral("http://www.w3.org/2000/svg")) {
113 doc->SetContentType("image/svg+xml"_ns);
114 } else {
115 doc->SetContentType("application/xml"_ns);
118 doc->SetReadyStateInternal(Document::READYSTATE_COMPLETE);
120 doc.forget(aDocument);
121 return NS_OK;
124 already_AddRefed<Document> DOMImplementation::CreateDocument(
125 const nsAString& aNamespaceURI, const nsAString& aQualifiedName,
126 DocumentType* aDoctype, ErrorResult& aRv) {
127 nsCOMPtr<Document> document;
128 aRv = CreateDocument(aNamespaceURI, aQualifiedName, aDoctype,
129 getter_AddRefs(document));
130 return document.forget();
133 nsresult DOMImplementation::CreateHTMLDocument(const nsAString& aTitle,
134 Document** aDocument) {
135 *aDocument = nullptr;
137 NS_ENSURE_STATE(mOwner);
139 // Indicate that there is no internal subset (not just an empty one)
140 RefPtr<DocumentType> doctype =
141 NS_NewDOMDocumentType(mOwner->NodeInfoManager(),
142 nsGkAtoms::html, // aName
143 u""_ns, // aPublicId
144 u""_ns, // aSystemId
145 VoidString()); // aInternalSubset
147 nsCOMPtr<nsIGlobalObject> scriptHandlingObject =
148 do_QueryReferent(mScriptObject);
150 NS_ENSURE_STATE(!mScriptObject || scriptHandlingObject);
152 nsCOMPtr<Document> doc;
153 nsresult rv =
154 NS_NewDOMDocument(getter_AddRefs(doc), u""_ns, u""_ns, doctype,
155 mDocumentURI, mBaseURI, mOwner->NodePrincipal(), true,
156 scriptHandlingObject, DocumentFlavorLegacyGuess);
157 NS_ENSURE_SUCCESS(rv, rv);
159 ErrorResult error;
160 nsCOMPtr<Element> root =
161 doc->CreateElem(u"html"_ns, nullptr, kNameSpaceID_XHTML);
162 doc->AppendChildTo(root, false, error);
163 if (error.Failed()) {
164 return error.StealNSResult();
167 nsCOMPtr<Element> head =
168 doc->CreateElem(u"head"_ns, nullptr, kNameSpaceID_XHTML);
169 root->AppendChildTo(head, false, error);
170 if (error.Failed()) {
171 return error.StealNSResult();
174 if (!DOMStringIsNull(aTitle)) {
175 nsCOMPtr<Element> title =
176 doc->CreateElem(u"title"_ns, nullptr, kNameSpaceID_XHTML);
177 head->AppendChildTo(title, false, error);
178 if (error.Failed()) {
179 return error.StealNSResult();
182 RefPtr<nsTextNode> titleText =
183 new (doc->NodeInfoManager()) nsTextNode(doc->NodeInfoManager());
184 rv = titleText->SetText(aTitle, false);
185 NS_ENSURE_SUCCESS(rv, rv);
186 title->AppendChildTo(titleText, false, error);
187 if (error.Failed()) {
188 return error.StealNSResult();
192 nsCOMPtr<Element> body =
193 doc->CreateElem(u"body"_ns, nullptr, kNameSpaceID_XHTML);
194 root->AppendChildTo(body, false, error);
195 if (error.Failed()) {
196 return error.StealNSResult();
199 doc->SetReadyStateInternal(Document::READYSTATE_COMPLETE);
201 doc.forget(aDocument);
202 return NS_OK;
205 already_AddRefed<Document> DOMImplementation::CreateHTMLDocument(
206 const Optional<nsAString>& aTitle, ErrorResult& aRv) {
207 nsCOMPtr<Document> document;
208 aRv = CreateHTMLDocument(aTitle.WasPassed() ? aTitle.Value() : VoidString(),
209 getter_AddRefs(document));
210 return document.forget();
213 } // namespace mozilla::dom