Line data Source code
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/DOMImplementation.h"
8 :
9 : #include "mozilla/ContentEvents.h"
10 : #include "mozilla/dom/DOMImplementationBinding.h"
11 : #include "nsContentCreatorFunctions.h"
12 : #include "nsContentUtils.h"
13 : #include "nsDOMClassInfoID.h"
14 : #include "nsIDOMDocument.h"
15 : #include "DocumentType.h"
16 : #include "nsTextNode.h"
17 :
18 : namespace mozilla {
19 : namespace dom {
20 :
21 : // QueryInterface implementation for DOMImplementation
22 0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMImplementation)
23 0 : NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
24 0 : NS_INTERFACE_MAP_ENTRY(nsIDOMDOMImplementation)
25 0 : NS_INTERFACE_MAP_ENTRY(nsISupports)
26 0 : NS_INTERFACE_MAP_END
27 :
28 0 : NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DOMImplementation, mOwner)
29 :
30 0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMImplementation)
31 0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMImplementation)
32 :
33 : JSObject*
34 0 : DOMImplementation::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
35 : {
36 0 : return DOMImplementationBinding::Wrap(aCx, this, aGivenProto);
37 : }
38 :
39 : NS_IMETHODIMP
40 0 : DOMImplementation::HasFeature(const nsAString& aFeature,
41 : const nsAString& aVersion,
42 : bool* aReturn)
43 : {
44 0 : *aReturn = true;
45 0 : return NS_OK;
46 : }
47 :
48 : already_AddRefed<DocumentType>
49 0 : DOMImplementation::CreateDocumentType(const nsAString& aQualifiedName,
50 : const nsAString& aPublicId,
51 : const nsAString& aSystemId,
52 : ErrorResult& aRv)
53 : {
54 0 : if (!mOwner) {
55 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
56 0 : return nullptr;
57 : }
58 :
59 0 : aRv = nsContentUtils::CheckQName(aQualifiedName);
60 0 : if (aRv.Failed()) {
61 0 : return nullptr;
62 : }
63 :
64 0 : nsCOMPtr<nsIAtom> name = NS_Atomize(aQualifiedName);
65 0 : if (!name) {
66 0 : aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
67 0 : return nullptr;
68 : }
69 :
70 : // Indicate that there is no internal subset (not just an empty one)
71 : RefPtr<DocumentType> docType =
72 0 : NS_NewDOMDocumentType(mOwner->NodeInfoManager(), name, aPublicId,
73 0 : aSystemId, NullString(), aRv);
74 0 : return docType.forget();
75 : }
76 :
77 : NS_IMETHODIMP
78 0 : DOMImplementation::CreateDocumentType(const nsAString& aQualifiedName,
79 : const nsAString& aPublicId,
80 : const nsAString& aSystemId,
81 : nsIDOMDocumentType** aReturn)
82 : {
83 0 : ErrorResult rv;
84 0 : *aReturn =
85 0 : CreateDocumentType(aQualifiedName, aPublicId, aSystemId, rv).take();
86 0 : return rv.StealNSResult();
87 : }
88 :
89 : nsresult
90 0 : DOMImplementation::CreateDocument(const nsAString& aNamespaceURI,
91 : const nsAString& aQualifiedName,
92 : nsIDOMDocumentType* aDoctype,
93 : nsIDocument** aDocument,
94 : nsIDOMDocument** aDOMDocument)
95 : {
96 0 : *aDocument = nullptr;
97 0 : *aDOMDocument = nullptr;
98 :
99 : nsresult rv;
100 0 : if (!aQualifiedName.IsEmpty()) {
101 0 : const nsString& qName = PromiseFlatString(aQualifiedName);
102 : const char16_t *colon;
103 0 : rv = nsContentUtils::CheckQName(qName, true, &colon);
104 0 : NS_ENSURE_SUCCESS(rv, rv);
105 :
106 0 : if (colon &&
107 0 : (DOMStringIsNull(aNamespaceURI) ||
108 0 : (Substring(qName.get(), colon).EqualsLiteral("xml") &&
109 0 : !aNamespaceURI.EqualsLiteral("http://www.w3.org/XML/1998/namespace")))) {
110 0 : return NS_ERROR_DOM_NAMESPACE_ERR;
111 : }
112 : }
113 :
114 : nsCOMPtr<nsIGlobalObject> scriptHandlingObject =
115 0 : do_QueryReferent(mScriptObject);
116 :
117 0 : NS_ENSURE_STATE(!mScriptObject || scriptHandlingObject);
118 :
119 0 : nsCOMPtr<nsIDOMDocument> document;
120 :
121 0 : rv = NS_NewDOMDocument(getter_AddRefs(document),
122 : aNamespaceURI, aQualifiedName, aDoctype,
123 : mDocumentURI, mBaseURI,
124 0 : mOwner->NodePrincipal(),
125 : true, scriptHandlingObject,
126 0 : DocumentFlavorLegacyGuess);
127 0 : NS_ENSURE_SUCCESS(rv, rv);
128 :
129 : // When DOMImplementation's createDocument method is invoked with
130 : // namespace set to HTML Namespace use the registry of the associated
131 : // document to the new instance.
132 0 : nsCOMPtr<nsIDocument> doc = do_QueryInterface(document);
133 :
134 0 : if (aNamespaceURI.EqualsLiteral("http://www.w3.org/1999/xhtml")) {
135 0 : doc->SetContentType(NS_LITERAL_STRING("application/xhtml+xml"));
136 0 : } else if (aNamespaceURI.EqualsLiteral("http://www.w3.org/2000/svg")) {
137 0 : doc->SetContentType(NS_LITERAL_STRING("image/svg+xml"));
138 : } else {
139 0 : doc->SetContentType(NS_LITERAL_STRING("application/xml"));
140 : }
141 :
142 0 : doc->SetReadyStateInternal(nsIDocument::READYSTATE_COMPLETE);
143 :
144 0 : doc.forget(aDocument);
145 0 : document.forget(aDOMDocument);
146 0 : return NS_OK;
147 : }
148 :
149 : already_AddRefed<nsIDocument>
150 0 : DOMImplementation::CreateDocument(const nsAString& aNamespaceURI,
151 : const nsAString& aQualifiedName,
152 : nsIDOMDocumentType* aDoctype,
153 : ErrorResult& aRv)
154 : {
155 0 : nsCOMPtr<nsIDocument> document;
156 0 : nsCOMPtr<nsIDOMDocument> domDocument;
157 0 : aRv = CreateDocument(aNamespaceURI, aQualifiedName, aDoctype,
158 0 : getter_AddRefs(document), getter_AddRefs(domDocument));
159 0 : return document.forget();
160 : }
161 :
162 : NS_IMETHODIMP
163 0 : DOMImplementation::CreateDocument(const nsAString& aNamespaceURI,
164 : const nsAString& aQualifiedName,
165 : nsIDOMDocumentType* aDoctype,
166 : nsIDOMDocument** aReturn)
167 : {
168 0 : nsCOMPtr<nsIDocument> document;
169 0 : return CreateDocument(aNamespaceURI, aQualifiedName, aDoctype,
170 0 : getter_AddRefs(document), aReturn);
171 : }
172 :
173 : nsresult
174 0 : DOMImplementation::CreateHTMLDocument(const nsAString& aTitle,
175 : nsIDocument** aDocument,
176 : nsIDOMDocument** aDOMDocument)
177 : {
178 0 : *aDocument = nullptr;
179 0 : *aDOMDocument = nullptr;
180 :
181 0 : NS_ENSURE_STATE(mOwner);
182 :
183 0 : nsCOMPtr<nsIDOMDocumentType> doctype;
184 : // Indicate that there is no internal subset (not just an empty one)
185 0 : nsresult rv = NS_NewDOMDocumentType(getter_AddRefs(doctype),
186 : mOwner->NodeInfoManager(),
187 : nsGkAtoms::html, // aName
188 0 : EmptyString(), // aPublicId
189 0 : EmptyString(), // aSystemId
190 0 : NullString()); // aInternalSubset
191 0 : NS_ENSURE_SUCCESS(rv, rv);
192 :
193 :
194 : nsCOMPtr<nsIGlobalObject> scriptHandlingObject =
195 0 : do_QueryReferent(mScriptObject);
196 :
197 0 : NS_ENSURE_STATE(!mScriptObject || scriptHandlingObject);
198 :
199 0 : nsCOMPtr<nsIDOMDocument> document;
200 0 : rv = NS_NewDOMDocument(getter_AddRefs(document),
201 0 : EmptyString(), EmptyString(),
202 : doctype, mDocumentURI, mBaseURI,
203 0 : mOwner->NodePrincipal(),
204 : true, scriptHandlingObject,
205 0 : DocumentFlavorLegacyGuess);
206 0 : NS_ENSURE_SUCCESS(rv, rv);
207 0 : nsCOMPtr<nsIDocument> doc = do_QueryInterface(document);
208 :
209 0 : nsCOMPtr<Element> root = doc->CreateElem(NS_LITERAL_STRING("html"), nullptr,
210 0 : kNameSpaceID_XHTML);
211 0 : rv = doc->AppendChildTo(root, false);
212 0 : NS_ENSURE_SUCCESS(rv, rv);
213 :
214 0 : nsCOMPtr<Element> head = doc->CreateElem(NS_LITERAL_STRING("head"), nullptr,
215 0 : kNameSpaceID_XHTML);
216 0 : rv = root->AppendChildTo(head, false);
217 0 : NS_ENSURE_SUCCESS(rv, rv);
218 :
219 0 : if (!DOMStringIsNull(aTitle)) {
220 0 : nsCOMPtr<Element> title = doc->CreateElem(NS_LITERAL_STRING("title"),
221 0 : nullptr, kNameSpaceID_XHTML);
222 0 : rv = head->AppendChildTo(title, false);
223 0 : NS_ENSURE_SUCCESS(rv, rv);
224 :
225 0 : RefPtr<nsTextNode> titleText = new nsTextNode(doc->NodeInfoManager());
226 0 : rv = titleText->SetText(aTitle, false);
227 0 : NS_ENSURE_SUCCESS(rv, rv);
228 0 : rv = title->AppendChildTo(titleText, false);
229 0 : NS_ENSURE_SUCCESS(rv, rv);
230 : }
231 :
232 0 : nsCOMPtr<Element> body = doc->CreateElem(NS_LITERAL_STRING("body"), nullptr,
233 0 : kNameSpaceID_XHTML);
234 0 : rv = root->AppendChildTo(body, false);
235 0 : NS_ENSURE_SUCCESS(rv, rv);
236 :
237 0 : doc->SetReadyStateInternal(nsIDocument::READYSTATE_COMPLETE);
238 :
239 0 : doc.forget(aDocument);
240 0 : document.forget(aDOMDocument);
241 0 : return NS_OK;
242 : }
243 :
244 : already_AddRefed<nsIDocument>
245 0 : DOMImplementation::CreateHTMLDocument(const Optional<nsAString>& aTitle,
246 : ErrorResult& aRv)
247 : {
248 0 : nsCOMPtr<nsIDocument> document;
249 0 : nsCOMPtr<nsIDOMDocument> domDocument;
250 0 : aRv = CreateHTMLDocument(aTitle.WasPassed() ? aTitle.Value()
251 0 : : NullString(),
252 0 : getter_AddRefs(document),
253 0 : getter_AddRefs(domDocument));
254 0 : return document.forget();
255 : }
256 :
257 : NS_IMETHODIMP
258 0 : DOMImplementation::CreateHTMLDocument(const nsAString& aTitle,
259 : nsIDOMDocument** aReturn)
260 : {
261 0 : nsCOMPtr<nsIDocument> document;
262 0 : return CreateHTMLDocument(aTitle, getter_AddRefs(document), aReturn);
263 : }
264 :
265 : } // namespace dom
266 : } // namespace mozilla
|