diff -r 000000000000 -r 6474c204b198 content/base/src/DOMImplementation.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/content/base/src/DOMImplementation.cpp Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,280 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/dom/DOMImplementation.h" + +#include "mozilla/ContentEvents.h" +#include "mozilla/dom/DOMImplementationBinding.h" +#include "nsContentCreatorFunctions.h" +#include "nsContentUtils.h" +#include "nsDOMClassInfoID.h" +#include "nsIDOMDocument.h" +#include "DocumentType.h" +#include "nsTextNode.h" + +namespace mozilla { +namespace dom { + +// QueryInterface implementation for DOMImplementation +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMImplementation) + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY + NS_INTERFACE_MAP_ENTRY(nsIDOMDOMImplementation) + NS_INTERFACE_MAP_ENTRY(nsISupports) +NS_INTERFACE_MAP_END + +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(DOMImplementation, mOwner) + +NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMImplementation) +NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMImplementation) + +JSObject* +DOMImplementation::WrapObject(JSContext* aCx) +{ + return DOMImplementationBinding::Wrap(aCx, this); +} + +bool +DOMImplementation::HasFeature(const nsAString& aFeature, + const nsAString& aVersion) +{ + return nsContentUtils::InternalIsSupported( + static_cast(this), + aFeature, aVersion); +} + +NS_IMETHODIMP +DOMImplementation::HasFeature(const nsAString& aFeature, + const nsAString& aVersion, + bool* aReturn) +{ + *aReturn = HasFeature(aFeature, aVersion); + return NS_OK; +} + +already_AddRefed +DOMImplementation::CreateDocumentType(const nsAString& aQualifiedName, + const nsAString& aPublicId, + const nsAString& aSystemId, + ErrorResult& aRv) +{ + if (!mOwner) { + aRv.Throw(NS_ERROR_UNEXPECTED); + return nullptr; + } + + aRv = nsContentUtils::CheckQName(aQualifiedName); + if (aRv.Failed()) { + return nullptr; + } + + nsCOMPtr name = do_GetAtom(aQualifiedName); + if (!name) { + aRv.Throw(NS_ERROR_OUT_OF_MEMORY); + return nullptr; + } + + // Indicate that there is no internal subset (not just an empty one) + nsRefPtr docType = + NS_NewDOMDocumentType(mOwner->NodeInfoManager(), name, aPublicId, + aSystemId, NullString(), aRv); + return docType.forget(); +} + +NS_IMETHODIMP +DOMImplementation::CreateDocumentType(const nsAString& aQualifiedName, + const nsAString& aPublicId, + const nsAString& aSystemId, + nsIDOMDocumentType** aReturn) +{ + ErrorResult rv; + *aReturn = + CreateDocumentType(aQualifiedName, aPublicId, aSystemId, rv).take(); + return rv.ErrorCode(); +} + +nsresult +DOMImplementation::CreateDocument(const nsAString& aNamespaceURI, + const nsAString& aQualifiedName, + nsIDOMDocumentType* aDoctype, + nsIDocument** aDocument, + nsIDOMDocument** aDOMDocument) +{ + *aDocument = nullptr; + *aDOMDocument = nullptr; + + nsresult rv; + if (!aQualifiedName.IsEmpty()) { + const nsAFlatString& qName = PromiseFlatString(aQualifiedName); + const char16_t *colon; + rv = nsContentUtils::CheckQName(qName, true, &colon); + NS_ENSURE_SUCCESS(rv, rv); + + if (colon && + (DOMStringIsNull(aNamespaceURI) || + (Substring(qName.get(), colon).EqualsLiteral("xml") && + !aNamespaceURI.EqualsLiteral("http://www.w3.org/XML/1998/namespace")))) { + return NS_ERROR_DOM_NAMESPACE_ERR; + } + } + + nsCOMPtr scriptHandlingObject = + do_QueryReferent(mScriptObject); + + NS_ENSURE_STATE(!mScriptObject || scriptHandlingObject); + + nsCOMPtr document; + + rv = NS_NewDOMDocument(getter_AddRefs(document), + aNamespaceURI, aQualifiedName, aDoctype, + mDocumentURI, mBaseURI, + mOwner->NodePrincipal(), + true, scriptHandlingObject, + DocumentFlavorLegacyGuess); + NS_ENSURE_SUCCESS(rv, rv); + + // When DOMImplementation's createDocument method is invoked with + // namespace set to HTML Namespace use the registry of the associated + // document to the new instance. + nsCOMPtr doc = do_QueryInterface(document); + if (aNamespaceURI.EqualsLiteral("http://www.w3.org/1999/xhtml")) { + doc->UseRegistryFromDocument(mOwner); + } + + doc->SetReadyStateInternal(nsIDocument::READYSTATE_COMPLETE); + + doc.forget(aDocument); + document.forget(aDOMDocument); + return NS_OK; +} + +already_AddRefed +DOMImplementation::CreateDocument(const nsAString& aNamespaceURI, + const nsAString& aQualifiedName, + nsIDOMDocumentType* aDoctype, + ErrorResult& aRv) +{ + nsCOMPtr document; + nsCOMPtr domDocument; + aRv = CreateDocument(aNamespaceURI, aQualifiedName, aDoctype, + getter_AddRefs(document), getter_AddRefs(domDocument)); + return document.forget(); +} + +NS_IMETHODIMP +DOMImplementation::CreateDocument(const nsAString& aNamespaceURI, + const nsAString& aQualifiedName, + nsIDOMDocumentType* aDoctype, + nsIDOMDocument** aReturn) +{ + nsCOMPtr document; + return CreateDocument(aNamespaceURI, aQualifiedName, aDoctype, + getter_AddRefs(document), aReturn); +} + +nsresult +DOMImplementation::CreateHTMLDocument(const nsAString& aTitle, + nsIDocument** aDocument, + nsIDOMDocument** aDOMDocument) +{ + *aDocument = nullptr; + *aDOMDocument = nullptr; + + NS_ENSURE_STATE(mOwner); + + nsCOMPtr doctype; + // Indicate that there is no internal subset (not just an empty one) + nsresult rv = NS_NewDOMDocumentType(getter_AddRefs(doctype), + mOwner->NodeInfoManager(), + nsGkAtoms::html, // aName + EmptyString(), // aPublicId + EmptyString(), // aSystemId + NullString()); // aInternalSubset + NS_ENSURE_SUCCESS(rv, rv); + + + nsCOMPtr scriptHandlingObject = + do_QueryReferent(mScriptObject); + + NS_ENSURE_STATE(!mScriptObject || scriptHandlingObject); + + nsCOMPtr document; + rv = NS_NewDOMDocument(getter_AddRefs(document), + EmptyString(), EmptyString(), + doctype, mDocumentURI, mBaseURI, + mOwner->NodePrincipal(), + true, scriptHandlingObject, + DocumentFlavorLegacyGuess); + NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr doc = do_QueryInterface(document); + + nsCOMPtr root; + rv = doc->CreateElem(NS_LITERAL_STRING("html"), nullptr, kNameSpaceID_XHTML, + getter_AddRefs(root)); + NS_ENSURE_SUCCESS(rv, rv); + rv = doc->AppendChildTo(root, false); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr head; + rv = doc->CreateElem(NS_LITERAL_STRING("head"), nullptr, kNameSpaceID_XHTML, + getter_AddRefs(head)); + NS_ENSURE_SUCCESS(rv, rv); + rv = root->AppendChildTo(head, false); + NS_ENSURE_SUCCESS(rv, rv); + + if (!DOMStringIsNull(aTitle)) { + nsCOMPtr title; + rv = doc->CreateElem(NS_LITERAL_STRING("title"), nullptr, + kNameSpaceID_XHTML, getter_AddRefs(title)); + NS_ENSURE_SUCCESS(rv, rv); + rv = head->AppendChildTo(title, false); + NS_ENSURE_SUCCESS(rv, rv); + + nsRefPtr titleText = new nsTextNode(doc->NodeInfoManager()); + rv = titleText->SetText(aTitle, false); + NS_ENSURE_SUCCESS(rv, rv); + rv = title->AppendChildTo(titleText, false); + NS_ENSURE_SUCCESS(rv, rv); + } + + nsCOMPtr body; + rv = doc->CreateElem(NS_LITERAL_STRING("body"), nullptr, kNameSpaceID_XHTML, + getter_AddRefs(body)); + NS_ENSURE_SUCCESS(rv, rv); + rv = root->AppendChildTo(body, false); + NS_ENSURE_SUCCESS(rv, rv); + + // When the createHTMLDocument method is invoked, + // use the registry of the associated document to the new instance. + doc->UseRegistryFromDocument(mOwner); + + doc->SetReadyStateInternal(nsIDocument::READYSTATE_COMPLETE); + + doc.forget(aDocument); + document.forget(aDOMDocument); + return NS_OK; +} + +already_AddRefed +DOMImplementation::CreateHTMLDocument(const Optional& aTitle, + ErrorResult& aRv) +{ + nsCOMPtr document; + nsCOMPtr domDocument; + aRv = CreateHTMLDocument(aTitle.WasPassed() ? aTitle.Value() + : NullString(), + getter_AddRefs(document), + getter_AddRefs(domDocument)); + return document.forget(); +} + +NS_IMETHODIMP +DOMImplementation::CreateHTMLDocument(const nsAString& aTitle, + nsIDOMDocument** aReturn) +{ + nsCOMPtr document; + return CreateHTMLDocument(aTitle, getter_AddRefs(document), aReturn); +} + +} // namespace dom +} // namespace mozilla