1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is Robert Sayre.
18 : * Portions created by the Initial Developer are Copyright (C) 2006
19 : * the Initial Developer. All Rights Reserved.
20 : *
21 : * Contributor(s):
22 : *
23 : * Alternatively, the contents of this file may be used under the terms of
24 : * either the GNU General Public License Version 2 or later (the "GPL"), or
25 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26 : * in which case the provisions of the GPL or the LGPL are applicable instead
27 : * of those above. If you wish to allow use of your version of this file only
28 : * under the terms of either the GPL or the LGPL, and not to allow others to
29 : * use your version of this file under the terms of the MPL, indicate your
30 : * decision by deleting the provisions above and replace them with the notice
31 : * and other provisions required by the GPL or the LGPL. If you do not delete
32 : * the provisions above, a recipient may use your version of this file under
33 : * the terms of any one of the MPL, the GPL or the LGPL.
34 : *
35 : * ***** END LICENSE BLOCK ***** */
36 :
37 : #include "nsString.h"
38 : #include "nsIComponentManager.h"
39 : #include "nsCOMPtr.h"
40 : #include "nsXPCOM.h"
41 : #include "nsISupportsPrimitives.h"
42 : #include "nsXPIDLString.h"
43 : #include "nsScriptLoader.h"
44 : #include "nsEscape.h"
45 : #include "nsIParser.h"
46 : #include "nsIDTD.h"
47 : #include "nsNetCID.h"
48 : #include "nsNetUtil.h"
49 : #include "nsParserCIID.h"
50 : #include "nsContentUtils.h"
51 : #include "nsIContentSink.h"
52 : #include "nsIDocumentEncoder.h"
53 : #include "nsIDOMDocumentFragment.h"
54 : #include "nsIFragmentContentSink.h"
55 : #include "nsIDOMDocument.h"
56 : #include "nsIDOMNodeList.h"
57 : #include "nsIDOMNode.h"
58 : #include "nsIDOMElement.h"
59 : #include "nsIDocument.h"
60 : #include "nsIContent.h"
61 : #include "nsAttrName.h"
62 : #include "nsHTMLParts.h"
63 : #include "nsContentCID.h"
64 : #include "nsIScriptableUnescapeHTML.h"
65 : #include "nsParserUtils.h"
66 : #include "nsAutoPtr.h"
67 : #include "nsTreeSanitizer.h"
68 : #include "nsHtml5Module.h"
69 :
70 : #define XHTML_DIV_TAG "div xmlns=\"http://www.w3.org/1999/xhtml\""
71 :
72 4448 : NS_IMPL_ISUPPORTS2(nsParserUtils,
73 : nsIScriptableUnescapeHTML,
74 : nsIParserUtils)
75 :
76 : static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID);
77 :
78 :
79 :
80 : NS_IMETHODIMP
81 4 : nsParserUtils::ConvertToPlainText(const nsAString & aFromStr,
82 : PRUint32 aFlags,
83 : PRUint32 aWrapCol,
84 : nsAString & aToStr)
85 : {
86 : return nsContentUtils::ConvertToPlainText(aFromStr,
87 : aToStr,
88 : aFlags,
89 4 : aWrapCol);
90 : }
91 :
92 : NS_IMETHODIMP
93 14 : nsParserUtils::Unescape(const nsAString & aFromStr,
94 : nsAString & aToStr)
95 : {
96 : return nsContentUtils::ConvertToPlainText(aFromStr,
97 : aToStr,
98 : nsIDocumentEncoder::OutputSelectionOnly |
99 : nsIDocumentEncoder::OutputAbsoluteLinks,
100 14 : 0);
101 : }
102 :
103 : // The feed version of nsContentUtils::CreateContextualFragment It
104 : // creates a fragment, but doesn't go to all the effort to preserve
105 : // context like innerHTML does, because feed DOMs shouldn't have that.
106 : NS_IMETHODIMP
107 1 : nsParserUtils::ParseFragment(const nsAString &aFragment,
108 : bool aIsXML,
109 : nsIURI* aBaseURI,
110 : nsIDOMElement* aContextElement,
111 : nsIDOMDocumentFragment** aReturn)
112 : {
113 1 : NS_ENSURE_ARG(aContextElement);
114 1 : *aReturn = nsnull;
115 :
116 : nsresult rv;
117 2 : nsCOMPtr<nsIParser> parser = do_CreateInstance(kCParserCID, &rv);
118 1 : NS_ENSURE_SUCCESS(rv, rv);
119 :
120 2 : nsCOMPtr<nsIDocument> document;
121 2 : nsCOMPtr<nsIDOMDocument> domDocument;
122 2 : nsCOMPtr<nsIDOMNode> contextNode;
123 1 : contextNode = do_QueryInterface(aContextElement);
124 1 : contextNode->GetOwnerDocument(getter_AddRefs(domDocument));
125 1 : document = do_QueryInterface(domDocument);
126 1 : NS_ENSURE_TRUE(document, NS_ERROR_NOT_AVAILABLE);
127 :
128 : // stop scripts
129 2 : nsRefPtr<nsScriptLoader> loader;
130 1 : bool scripts_enabled = false;
131 1 : if (document) {
132 1 : loader = document->ScriptLoader();
133 1 : scripts_enabled = loader->GetEnabled();
134 : }
135 1 : if (scripts_enabled) {
136 0 : loader->SetEnabled(false);
137 : }
138 :
139 : // Wrap things in a div or body for parsing, but it won't show up in
140 : // the fragment.
141 2 : nsAutoTArray<nsString, 2> tagStack;
142 2 : nsCAutoString base, spec;
143 1 : if (aIsXML) {
144 : // XHTML
145 1 : if (aBaseURI) {
146 1 : base.Append(NS_LITERAL_CSTRING(XHTML_DIV_TAG));
147 1 : base.Append(NS_LITERAL_CSTRING(" xml:base=\""));
148 1 : aBaseURI->GetSpec(spec);
149 : // nsEscapeHTML is good enough, because we only need to get
150 : // quotes, ampersands, and angle brackets
151 1 : char* escapedSpec = nsEscapeHTML(spec.get());
152 1 : if (escapedSpec)
153 1 : base += escapedSpec;
154 1 : NS_Free(escapedSpec);
155 1 : base.Append(NS_LITERAL_CSTRING("\""));
156 1 : tagStack.AppendElement(NS_ConvertUTF8toUTF16(base));
157 : } else {
158 0 : tagStack.AppendElement(NS_LITERAL_STRING(XHTML_DIV_TAG));
159 : }
160 : }
161 :
162 1 : if (NS_SUCCEEDED(rv)) {
163 2 : nsCOMPtr<nsIContent> fragment;
164 1 : if (aIsXML) {
165 : rv = nsContentUtils::ParseFragmentXML(aFragment,
166 : document,
167 : tagStack,
168 : true,
169 1 : aReturn);
170 1 : fragment = do_QueryInterface(*aReturn);
171 : } else {
172 : NS_NewDocumentFragment(aReturn,
173 0 : document->NodeInfoManager());
174 0 : fragment = do_QueryInterface(*aReturn);
175 : rv = nsContentUtils::ParseFragmentHTML(aFragment,
176 : fragment,
177 : nsGkAtoms::body,
178 : kNameSpaceID_XHTML,
179 : false,
180 0 : true);
181 : // Now, set the base URI on all subtree roots.
182 0 : if (aBaseURI) {
183 0 : aBaseURI->GetSpec(spec);
184 0 : nsAutoString spec16;
185 0 : CopyUTF8toUTF16(spec, spec16);
186 0 : nsIContent* node = fragment->GetFirstChild();
187 0 : while (node) {
188 0 : if (node->IsElement()) {
189 : node->SetAttr(kNameSpaceID_XML,
190 : nsGkAtoms::base,
191 : nsGkAtoms::xml,
192 : spec16,
193 0 : false);
194 : }
195 0 : node = node->GetNextSibling();
196 : }
197 : }
198 : }
199 1 : if (fragment) {
200 1 : nsTreeSanitizer sanitizer(false, false);
201 1 : sanitizer.Sanitize(fragment);
202 : }
203 : }
204 :
205 1 : if (scripts_enabled)
206 0 : loader->SetEnabled(true);
207 :
208 1 : return rv;
209 : }
|