Bumping gaia.json for 1 gaia revision(s) a=gaia-bump
[gecko.git] / parser / html / nsParserUtils.cpp
blobe49e2fce504232192862f8a1d3c56f56c48661e5
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "nsString.h"
7 #include "nsIComponentManager.h"
8 #include "nsCOMPtr.h"
9 #include "nsXPCOM.h"
10 #include "nsISupportsPrimitives.h"
11 #include "nsXPIDLString.h"
12 #include "nsScriptLoader.h"
13 #include "nsEscape.h"
14 #include "nsIParser.h"
15 #include "nsIDTD.h"
16 #include "nsNetCID.h"
17 #include "nsNetUtil.h"
18 #include "nsParserCIID.h"
19 #include "nsContentUtils.h"
20 #include "nsIContentSink.h"
21 #include "nsIDocumentEncoder.h"
22 #include "nsIDOMDocumentFragment.h"
23 #include "nsIFragmentContentSink.h"
24 #include "nsIDOMDocument.h"
25 #include "nsIDOMNodeList.h"
26 #include "nsIDOMNode.h"
27 #include "nsIDOMElement.h"
28 #include "nsIDocument.h"
29 #include "nsIContent.h"
30 #include "nsAttrName.h"
31 #include "nsHTMLParts.h"
32 #include "nsContentCID.h"
33 #include "nsIScriptableUnescapeHTML.h"
34 #include "nsParserUtils.h"
35 #include "nsAutoPtr.h"
36 #include "nsTreeSanitizer.h"
37 #include "nsHtml5Module.h"
38 #include "mozilla/dom/DocumentFragment.h"
40 #define XHTML_DIV_TAG "div xmlns=\"http://www.w3.org/1999/xhtml\""
42 using namespace mozilla::dom;
44 NS_IMPL_ISUPPORTS(nsParserUtils,
45 nsIScriptableUnescapeHTML,
46 nsIParserUtils)
48 NS_IMETHODIMP
49 nsParserUtils::ConvertToPlainText(const nsAString& aFromStr,
50 uint32_t aFlags,
51 uint32_t aWrapCol,
52 nsAString& aToStr)
54 return nsContentUtils::ConvertToPlainText(aFromStr,
55 aToStr,
56 aFlags,
57 aWrapCol);
60 NS_IMETHODIMP
61 nsParserUtils::Unescape(const nsAString& aFromStr,
62 nsAString& aToStr)
64 return nsContentUtils::ConvertToPlainText(aFromStr,
65 aToStr,
66 nsIDocumentEncoder::OutputSelectionOnly |
67 nsIDocumentEncoder::OutputAbsoluteLinks,
68 0);
71 NS_IMETHODIMP
72 nsParserUtils::Sanitize(const nsAString& aFromStr,
73 uint32_t aFlags,
74 nsAString& aToStr)
76 nsCOMPtr<nsIURI> uri;
77 NS_NewURI(getter_AddRefs(uri), "about:blank");
78 nsCOMPtr<nsIPrincipal> principal =
79 do_CreateInstance("@mozilla.org/nullprincipal;1");
80 nsCOMPtr<nsIDOMDocument> domDocument;
81 nsresult rv = NS_NewDOMDocument(getter_AddRefs(domDocument),
82 EmptyString(),
83 EmptyString(),
84 nullptr,
85 uri,
86 uri,
87 principal,
88 true,
89 nullptr,
90 DocumentFlavorHTML);
91 NS_ENSURE_SUCCESS(rv, rv);
93 nsCOMPtr<nsIDocument> document = do_QueryInterface(domDocument);
94 rv = nsContentUtils::ParseDocumentHTML(aFromStr, document, false);
95 NS_ENSURE_SUCCESS(rv, rv);
97 nsTreeSanitizer sanitizer(aFlags);
98 sanitizer.Sanitize(document);
100 nsCOMPtr<nsIDocumentEncoder> encoder =
101 do_CreateInstance(NS_DOC_ENCODER_CONTRACTID_BASE "text/html");
103 encoder->NativeInit(document,
104 NS_LITERAL_STRING("text/html"),
105 nsIDocumentEncoder::OutputDontRewriteEncodingDeclaration |
106 nsIDocumentEncoder::OutputNoScriptContent |
107 nsIDocumentEncoder::OutputEncodeBasicEntities |
108 nsIDocumentEncoder::OutputLFLineBreak |
109 nsIDocumentEncoder::OutputRaw);
111 return encoder->EncodeToString(aToStr);
114 NS_IMETHODIMP
115 nsParserUtils::ParseFragment(const nsAString& aFragment,
116 bool aIsXML,
117 nsIURI* aBaseURI,
118 nsIDOMElement* aContextElement,
119 nsIDOMDocumentFragment** aReturn)
121 return nsParserUtils::ParseFragment(aFragment,
123 aIsXML,
124 aBaseURI,
125 aContextElement,
126 aReturn);
129 NS_IMETHODIMP
130 nsParserUtils::ParseFragment(const nsAString& aFragment,
131 uint32_t aFlags,
132 bool aIsXML,
133 nsIURI* aBaseURI,
134 nsIDOMElement* aContextElement,
135 nsIDOMDocumentFragment** aReturn)
137 NS_ENSURE_ARG(aContextElement);
138 *aReturn = nullptr;
140 nsCOMPtr<nsIDocument> document;
141 nsCOMPtr<nsIDOMDocument> domDocument;
142 nsCOMPtr<nsIDOMNode> contextNode;
143 contextNode = do_QueryInterface(aContextElement);
144 contextNode->GetOwnerDocument(getter_AddRefs(domDocument));
145 document = do_QueryInterface(domDocument);
146 NS_ENSURE_TRUE(document, NS_ERROR_NOT_AVAILABLE);
148 nsAutoScriptBlockerSuppressNodeRemoved autoBlocker;
150 // stop scripts
151 nsRefPtr<nsScriptLoader> loader;
152 bool scripts_enabled = false;
153 if (document) {
154 loader = document->ScriptLoader();
155 scripts_enabled = loader->GetEnabled();
157 if (scripts_enabled) {
158 loader->SetEnabled(false);
161 // Wrap things in a div or body for parsing, but it won't show up in
162 // the fragment.
163 nsAutoTArray<nsString, 2> tagStack;
164 nsAutoCString base, spec;
165 if (aIsXML) {
166 // XHTML
167 if (aBaseURI) {
168 base.AppendLiteral(XHTML_DIV_TAG);
169 base.AppendLiteral(" xml:base=\"");
170 aBaseURI->GetSpec(spec);
171 // nsEscapeHTML is good enough, because we only need to get
172 // quotes, ampersands, and angle brackets
173 char* escapedSpec = nsEscapeHTML(spec.get());
174 if (escapedSpec)
175 base += escapedSpec;
176 NS_Free(escapedSpec);
177 base.Append('"');
178 tagStack.AppendElement(NS_ConvertUTF8toUTF16(base));
179 } else {
180 tagStack.AppendElement(NS_LITERAL_STRING(XHTML_DIV_TAG));
184 nsresult rv = NS_OK;
185 nsCOMPtr<nsIContent> fragment;
186 if (aIsXML) {
187 rv = nsContentUtils::ParseFragmentXML(aFragment,
188 document,
189 tagStack,
190 true,
191 aReturn);
192 fragment = do_QueryInterface(*aReturn);
193 } else {
194 NS_ADDREF(*aReturn = new DocumentFragment(document->NodeInfoManager()));
195 fragment = do_QueryInterface(*aReturn);
196 rv = nsContentUtils::ParseFragmentHTML(aFragment,
197 fragment,
198 nsGkAtoms::body,
199 kNameSpaceID_XHTML,
200 false,
201 true);
202 // Now, set the base URI on all subtree roots.
203 if (aBaseURI) {
204 aBaseURI->GetSpec(spec);
205 nsAutoString spec16;
206 CopyUTF8toUTF16(spec, spec16);
207 nsIContent* node = fragment->GetFirstChild();
208 while (node) {
209 if (node->IsElement()) {
210 node->SetAttr(kNameSpaceID_XML,
211 nsGkAtoms::base,
212 nsGkAtoms::xml,
213 spec16,
214 false);
216 node = node->GetNextSibling();
220 if (fragment) {
221 nsTreeSanitizer sanitizer(aFlags);
222 sanitizer.Sanitize(fragment);
225 if (scripts_enabled) {
226 loader->SetEnabled(true);
229 return rv;