1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "mozilla/dom/DOMImplementation.h"
7 #include "mozilla/ContentEvents.h"
8 #include "mozilla/dom/DOMImplementationBinding.h"
9 #include "nsContentCreatorFunctions.h"
10 #include "nsContentUtils.h"
11 #include "nsDOMClassInfoID.h"
12 #include "nsIDOMDocument.h"
13 #include "DocumentType.h"
14 #include "nsTextNode.h"
19 // QueryInterface implementation for DOMImplementation
20 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMImplementation
)
21 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
22 NS_INTERFACE_MAP_ENTRY(nsIDOMDOMImplementation
)
23 NS_INTERFACE_MAP_ENTRY(nsISupports
)
26 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DOMImplementation
, mOwner
)
28 NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMImplementation
)
29 NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMImplementation
)
32 DOMImplementation::WrapObject(JSContext
* aCx
)
34 return DOMImplementationBinding::Wrap(aCx
, this);
38 DOMImplementation::HasFeature(const nsAString
& aFeature
,
39 const nsAString
& aVersion
)
41 return nsContentUtils::InternalIsSupported(
42 static_cast<nsIDOMDOMImplementation
*>(this),
47 DOMImplementation::HasFeature(const nsAString
& aFeature
,
48 const nsAString
& aVersion
,
51 *aReturn
= HasFeature(aFeature
, aVersion
);
55 already_AddRefed
<DocumentType
>
56 DOMImplementation::CreateDocumentType(const nsAString
& aQualifiedName
,
57 const nsAString
& aPublicId
,
58 const nsAString
& aSystemId
,
62 aRv
.Throw(NS_ERROR_UNEXPECTED
);
66 aRv
= nsContentUtils::CheckQName(aQualifiedName
);
71 nsCOMPtr
<nsIAtom
> name
= do_GetAtom(aQualifiedName
);
73 aRv
.Throw(NS_ERROR_OUT_OF_MEMORY
);
77 // Indicate that there is no internal subset (not just an empty one)
78 nsRefPtr
<DocumentType
> docType
=
79 NS_NewDOMDocumentType(mOwner
->NodeInfoManager(), name
, aPublicId
,
80 aSystemId
, NullString(), aRv
);
81 return docType
.forget();
85 DOMImplementation::CreateDocumentType(const nsAString
& aQualifiedName
,
86 const nsAString
& aPublicId
,
87 const nsAString
& aSystemId
,
88 nsIDOMDocumentType
** aReturn
)
92 CreateDocumentType(aQualifiedName
, aPublicId
, aSystemId
, rv
).take();
93 return rv
.ErrorCode();
97 DOMImplementation::CreateDocument(const nsAString
& aNamespaceURI
,
98 const nsAString
& aQualifiedName
,
99 nsIDOMDocumentType
* aDoctype
,
100 nsIDocument
** aDocument
,
101 nsIDOMDocument
** aDOMDocument
)
103 *aDocument
= nullptr;
104 *aDOMDocument
= nullptr;
107 if (!aQualifiedName
.IsEmpty()) {
108 const nsAFlatString
& qName
= PromiseFlatString(aQualifiedName
);
109 const char16_t
*colon
;
110 rv
= nsContentUtils::CheckQName(qName
, true, &colon
);
111 NS_ENSURE_SUCCESS(rv
, rv
);
114 (DOMStringIsNull(aNamespaceURI
) ||
115 (Substring(qName
.get(), colon
).EqualsLiteral("xml") &&
116 !aNamespaceURI
.EqualsLiteral("http://www.w3.org/XML/1998/namespace")))) {
117 return NS_ERROR_DOM_NAMESPACE_ERR
;
121 nsCOMPtr
<nsIGlobalObject
> scriptHandlingObject
=
122 do_QueryReferent(mScriptObject
);
124 NS_ENSURE_STATE(!mScriptObject
|| scriptHandlingObject
);
126 nsCOMPtr
<nsIDOMDocument
> document
;
128 rv
= NS_NewDOMDocument(getter_AddRefs(document
),
129 aNamespaceURI
, aQualifiedName
, aDoctype
,
130 mDocumentURI
, mBaseURI
,
131 mOwner
->NodePrincipal(),
132 true, scriptHandlingObject
,
133 DocumentFlavorLegacyGuess
);
134 NS_ENSURE_SUCCESS(rv
, rv
);
136 // When DOMImplementation's createDocument method is invoked with
137 // namespace set to HTML Namespace use the registry of the associated
138 // document to the new instance.
139 nsCOMPtr
<nsIDocument
> doc
= do_QueryInterface(document
);
140 if (aNamespaceURI
.EqualsLiteral("http://www.w3.org/1999/xhtml")) {
141 doc
->UseRegistryFromDocument(mOwner
);
144 doc
->SetReadyStateInternal(nsIDocument::READYSTATE_COMPLETE
);
146 doc
.forget(aDocument
);
147 document
.forget(aDOMDocument
);
151 already_AddRefed
<nsIDocument
>
152 DOMImplementation::CreateDocument(const nsAString
& aNamespaceURI
,
153 const nsAString
& aQualifiedName
,
154 nsIDOMDocumentType
* aDoctype
,
157 nsCOMPtr
<nsIDocument
> document
;
158 nsCOMPtr
<nsIDOMDocument
> domDocument
;
159 aRv
= CreateDocument(aNamespaceURI
, aQualifiedName
, aDoctype
,
160 getter_AddRefs(document
), getter_AddRefs(domDocument
));
161 return document
.forget();
165 DOMImplementation::CreateDocument(const nsAString
& aNamespaceURI
,
166 const nsAString
& aQualifiedName
,
167 nsIDOMDocumentType
* aDoctype
,
168 nsIDOMDocument
** aReturn
)
170 nsCOMPtr
<nsIDocument
> document
;
171 return CreateDocument(aNamespaceURI
, aQualifiedName
, aDoctype
,
172 getter_AddRefs(document
), aReturn
);
176 DOMImplementation::CreateHTMLDocument(const nsAString
& aTitle
,
177 nsIDocument
** aDocument
,
178 nsIDOMDocument
** aDOMDocument
)
180 *aDocument
= nullptr;
181 *aDOMDocument
= nullptr;
183 NS_ENSURE_STATE(mOwner
);
185 nsCOMPtr
<nsIDOMDocumentType
> doctype
;
186 // Indicate that there is no internal subset (not just an empty one)
187 nsresult rv
= NS_NewDOMDocumentType(getter_AddRefs(doctype
),
188 mOwner
->NodeInfoManager(),
189 nsGkAtoms::html
, // aName
190 EmptyString(), // aPublicId
191 EmptyString(), // aSystemId
192 NullString()); // aInternalSubset
193 NS_ENSURE_SUCCESS(rv
, rv
);
196 nsCOMPtr
<nsIGlobalObject
> scriptHandlingObject
=
197 do_QueryReferent(mScriptObject
);
199 NS_ENSURE_STATE(!mScriptObject
|| scriptHandlingObject
);
201 nsCOMPtr
<nsIDOMDocument
> document
;
202 rv
= NS_NewDOMDocument(getter_AddRefs(document
),
203 EmptyString(), EmptyString(),
204 doctype
, mDocumentURI
, mBaseURI
,
205 mOwner
->NodePrincipal(),
206 true, scriptHandlingObject
,
207 DocumentFlavorLegacyGuess
);
208 NS_ENSURE_SUCCESS(rv
, rv
);
209 nsCOMPtr
<nsIDocument
> doc
= do_QueryInterface(document
);
211 nsCOMPtr
<nsIContent
> root
;
212 rv
= doc
->CreateElem(NS_LITERAL_STRING("html"), nullptr, kNameSpaceID_XHTML
,
213 getter_AddRefs(root
));
214 NS_ENSURE_SUCCESS(rv
, rv
);
215 rv
= doc
->AppendChildTo(root
, false);
216 NS_ENSURE_SUCCESS(rv
, rv
);
218 nsCOMPtr
<nsIContent
> head
;
219 rv
= doc
->CreateElem(NS_LITERAL_STRING("head"), nullptr, kNameSpaceID_XHTML
,
220 getter_AddRefs(head
));
221 NS_ENSURE_SUCCESS(rv
, rv
);
222 rv
= root
->AppendChildTo(head
, false);
223 NS_ENSURE_SUCCESS(rv
, rv
);
225 if (!DOMStringIsNull(aTitle
)) {
226 nsCOMPtr
<nsIContent
> title
;
227 rv
= doc
->CreateElem(NS_LITERAL_STRING("title"), nullptr,
228 kNameSpaceID_XHTML
, getter_AddRefs(title
));
229 NS_ENSURE_SUCCESS(rv
, rv
);
230 rv
= head
->AppendChildTo(title
, false);
231 NS_ENSURE_SUCCESS(rv
, rv
);
233 nsRefPtr
<nsTextNode
> titleText
= new nsTextNode(doc
->NodeInfoManager());
234 rv
= titleText
->SetText(aTitle
, false);
235 NS_ENSURE_SUCCESS(rv
, rv
);
236 rv
= title
->AppendChildTo(titleText
, false);
237 NS_ENSURE_SUCCESS(rv
, rv
);
240 nsCOMPtr
<nsIContent
> body
;
241 rv
= doc
->CreateElem(NS_LITERAL_STRING("body"), nullptr, kNameSpaceID_XHTML
,
242 getter_AddRefs(body
));
243 NS_ENSURE_SUCCESS(rv
, rv
);
244 rv
= root
->AppendChildTo(body
, false);
245 NS_ENSURE_SUCCESS(rv
, rv
);
247 // When the createHTMLDocument method is invoked,
248 // use the registry of the associated document to the new instance.
249 doc
->UseRegistryFromDocument(mOwner
);
251 doc
->SetReadyStateInternal(nsIDocument::READYSTATE_COMPLETE
);
253 doc
.forget(aDocument
);
254 document
.forget(aDOMDocument
);
258 already_AddRefed
<nsIDocument
>
259 DOMImplementation::CreateHTMLDocument(const Optional
<nsAString
>& aTitle
,
262 nsCOMPtr
<nsIDocument
> document
;
263 nsCOMPtr
<nsIDOMDocument
> domDocument
;
264 aRv
= CreateHTMLDocument(aTitle
.WasPassed() ? aTitle
.Value()
266 getter_AddRefs(document
),
267 getter_AddRefs(domDocument
));
268 return document
.forget();
272 DOMImplementation::CreateHTMLDocument(const nsAString
& aTitle
,
273 nsIDOMDocument
** aReturn
)
275 nsCOMPtr
<nsIDocument
> document
;
276 return CreateHTMLDocument(aTitle
, getter_AddRefs(document
), aReturn
);
280 } // namespace mozilla