Bug 1861467 - [wpt-sync] Update web-platform-tests to eedf737ce39c512d0ca3471f988972e...
[gecko.git] / dom / serializers / nsDOMSerializer.cpp
blob98d92e64cef15b6737c4be9a04e96d1f1e755b22
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 "nsDOMSerializer.h"
9 #include "mozilla/Encoding.h"
10 #include "mozilla/dom/Document.h"
11 #include "nsIDocumentEncoder.h"
12 #include "nsComponentManagerUtils.h"
13 #include "nsContentCID.h"
14 #include "nsContentUtils.h"
15 #include "nsError.h"
16 #include "nsINode.h"
18 using namespace mozilla;
20 nsDOMSerializer::nsDOMSerializer() = default;
22 static already_AddRefed<nsIDocumentEncoder> SetUpEncoder(
23 nsINode& aRoot, const nsAString& aCharset, ErrorResult& aRv) {
24 nsCOMPtr<nsIDocumentEncoder> encoder =
25 do_createDocumentEncoder("application/xhtml+xml");
26 if (!encoder) {
27 aRv.Throw(NS_ERROR_FAILURE);
28 return nullptr;
31 dom::Document* doc = aRoot.OwnerDoc();
32 bool entireDocument = (doc == &aRoot);
34 // This method will fail if no document
35 nsresult rv = encoder->NativeInit(
36 doc, u"application/xhtml+xml"_ns,
37 nsIDocumentEncoder::OutputRaw |
38 nsIDocumentEncoder::OutputDontRewriteEncodingDeclaration);
40 if (NS_FAILED(rv)) {
41 aRv.Throw(rv);
42 return nullptr;
45 NS_ConvertUTF16toUTF8 charset(aCharset);
46 if (charset.IsEmpty()) {
47 doc->GetDocumentCharacterSet()->Name(charset);
49 rv = encoder->SetCharset(charset);
50 if (NS_FAILED(rv)) {
51 aRv.Throw(rv);
52 return nullptr;
55 // If we are working on the entire document we do not need to
56 // specify which part to serialize
57 if (!entireDocument) {
58 rv = encoder->SetNode(&aRoot);
61 if (NS_FAILED(rv)) {
62 aRv.Throw(rv);
63 return nullptr;
66 return encoder.forget();
69 void nsDOMSerializer::SerializeToString(nsINode& aRoot, nsAString& aStr,
70 ErrorResult& aRv) {
71 aStr.Truncate();
73 if (!nsContentUtils::CanCallerAccess(&aRoot)) {
74 aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
75 return;
78 nsCOMPtr<nsIDocumentEncoder> encoder = SetUpEncoder(aRoot, u""_ns, aRv);
79 if (aRv.Failed()) {
80 return;
83 nsresult rv = encoder->EncodeToString(aStr);
84 if (NS_FAILED(rv)) {
85 aRv.Throw(rv);
89 void nsDOMSerializer::SerializeToStream(nsINode& aRoot,
90 nsIOutputStream* aStream,
91 const nsAString& aCharset,
92 ErrorResult& aRv) {
93 if (NS_WARN_IF(!aStream)) {
94 aRv.Throw(NS_ERROR_INVALID_ARG);
95 return;
98 // The charset arg can be empty, in which case we get the document's
99 // charset and use that when serializing.
101 // No point doing a CanCallerAccess check, because we can only be
102 // called by system JS or C++.
103 nsCOMPtr<nsIDocumentEncoder> encoder = SetUpEncoder(aRoot, aCharset, aRv);
104 if (aRv.Failed()) {
105 return;
108 nsresult rv = encoder->EncodeToStream(aStream);
109 if (NS_FAILED(rv)) {
110 aRv.Throw(rv);