OLD | NEW |
1 /* | 1 /* |
2 * This file is part of the XSL implementation. | 2 * This file is part of the XSL implementation. |
3 * | 3 * |
4 * Copyright (C) 2004, 2005, 2006, 2008, 2012 Apple Inc. All rights reserved. | 4 * Copyright (C) 2004, 2005, 2006, 2008, 2012 Apple Inc. All rights reserved. |
5 * | 5 * |
6 * This library is free software; you can redistribute it and/or | 6 * This library is free software; you can redistribute it and/or |
7 * modify it under the terms of the GNU Library General Public | 7 * modify it under the terms of the GNU Library General Public |
8 * License as published by the Free Software Foundation; either | 8 * License as published by the Free Software Foundation; either |
9 * version 2 of the License, or (at your option) any later version. | 9 * version 2 of the License, or (at your option) any later version. |
10 * | 10 * |
(...skipping 14 matching lines...) Expand all Loading... |
25 #include "core/dom/Document.h" | 25 #include "core/dom/Document.h" |
26 #include "core/dom/Node.h" | 26 #include "core/dom/Node.h" |
27 #include "core/dom/TransformSource.h" | 27 #include "core/dom/TransformSource.h" |
28 #include "core/frame/FrameHost.h" | 28 #include "core/frame/FrameHost.h" |
29 #include "core/frame/LocalFrame.h" | 29 #include "core/frame/LocalFrame.h" |
30 #include "core/xml/XSLImportRule.h" | 30 #include "core/xml/XSLImportRule.h" |
31 #include "core/xml/XSLTProcessor.h" | 31 #include "core/xml/XSLTProcessor.h" |
32 #include "core/xml/parser/XMLDocumentParserScope.h" | 32 #include "core/xml/parser/XMLDocumentParserScope.h" |
33 #include "core/xml/parser/XMLParserInput.h" | 33 #include "core/xml/parser/XMLParserInput.h" |
34 #include "wtf/text/CString.h" | 34 #include "wtf/text/CString.h" |
35 | |
36 #include <libxml/uri.h> | 35 #include <libxml/uri.h> |
37 #include <libxslt/xsltutils.h> | 36 #include <libxslt/xsltutils.h> |
38 | 37 |
39 namespace WebCore { | 38 namespace WebCore { |
40 | 39 |
41 XSLStyleSheet::XSLStyleSheet(XSLImportRule* parentRule, const String& originalUR
L, const KURL& finalURL) | 40 XSLStyleSheet::XSLStyleSheet(XSLImportRule* parentRule, const String& originalUR
L, const KURL& finalURL) |
42 : m_ownerNode(nullptr) | 41 : m_ownerNode(nullptr) |
43 , m_originalURL(originalURL) | 42 , m_originalURL(originalURL) |
44 , m_finalURL(finalURL) | 43 , m_finalURL(finalURL) |
45 , m_isDisabled(false) | 44 , m_isDisabled(false) |
46 , m_embedded(false) | 45 , m_embedded(false) |
47 , m_processed(false) // Child sheets get marked as processed when the libxsl
t engine has finally seen them. | 46 // Child sheets get marked as processed when the libxslt engine has finally |
| 47 // seen them. |
| 48 , m_processed(false) |
48 , m_stylesheetDoc(0) | 49 , m_stylesheetDoc(0) |
49 , m_stylesheetDocTaken(false) | 50 , m_stylesheetDocTaken(false) |
50 , m_compilationFailed(false) | 51 , m_compilationFailed(false) |
51 , m_parentStyleSheet(parentRule ? parentRule->parentStyleSheet() : 0) | 52 , m_parentStyleSheet(parentRule ? parentRule->parentStyleSheet() : 0) |
52 { | 53 { |
53 } | 54 } |
54 | 55 |
55 XSLStyleSheet::XSLStyleSheet(Node* parentNode, const String& originalURL, const
KURL& finalURL, bool embedded) | 56 XSLStyleSheet::XSLStyleSheet(Node* parentNode, const String& originalURL, const
KURL& finalURL, bool embedded) |
56 : m_ownerNode(parentNode) | 57 : m_ownerNode(parentNode) |
57 , m_originalURL(originalURL) | 58 , m_originalURL(originalURL) |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
109 m_stylesheetDoc = 0; | 110 m_stylesheetDoc = 0; |
110 for (unsigned i = 0; i < m_children.size(); ++i) { | 111 for (unsigned i = 0; i < m_children.size(); ++i) { |
111 XSLImportRule* import = m_children.at(i).get(); | 112 XSLImportRule* import = m_children.at(i).get(); |
112 if (import->styleSheet()) | 113 if (import->styleSheet()) |
113 import->styleSheet()->clearDocuments(); | 114 import->styleSheet()->clearDocuments(); |
114 } | 115 } |
115 } | 116 } |
116 | 117 |
117 ResourceFetcher* XSLStyleSheet::fetcher() | 118 ResourceFetcher* XSLStyleSheet::fetcher() |
118 { | 119 { |
119 Document* document = ownerDocument(); | 120 if (Document* document = ownerDocument()) |
120 if (!document) | 121 return document->fetcher(); |
121 return 0; | 122 return 0; |
122 return document->fetcher(); | |
123 } | 123 } |
124 | 124 |
125 bool XSLStyleSheet::parseString(const String& source) | 125 bool XSLStyleSheet::parseString(const String& source) |
126 { | 126 { |
127 // Parse in a single chunk into an xmlDocPtr | 127 // Parse in a single chunk into an xmlDocPtr |
128 if (!m_stylesheetDocTaken) | 128 if (!m_stylesheetDocTaken) |
129 xmlFreeDoc(m_stylesheetDoc); | 129 xmlFreeDoc(m_stylesheetDoc); |
130 m_stylesheetDocTaken = false; | 130 m_stylesheetDocTaken = false; |
131 | 131 |
132 FrameConsole* console = 0; | 132 FrameConsole* console = 0; |
133 LocalFrame* frame = ownerDocument()->frame(); | 133 if (LocalFrame* frame = ownerDocument()->frame()) |
134 if (frame) | |
135 console = &frame->console(); | 134 console = &frame->console(); |
136 | 135 |
137 XMLDocumentParserScope scope(fetcher(), XSLTProcessor::genericErrorFunc, XSL
TProcessor::parseErrorFunc, console); | 136 XMLDocumentParserScope scope(fetcher(), XSLTProcessor::genericErrorFunc, XSL
TProcessor::parseErrorFunc, console); |
138 XMLParserInput input(source); | 137 XMLParserInput input(source); |
139 | 138 |
140 xmlParserCtxtPtr ctxt = xmlCreateMemoryParserCtxt(input.data(), input.size()
); | 139 xmlParserCtxtPtr ctxt = xmlCreateMemoryParserCtxt(input.data(), input.size()
); |
141 if (!ctxt) | 140 if (!ctxt) |
142 return 0; | 141 return 0; |
143 | 142 |
144 if (m_parentStyleSheet) { | 143 if (m_parentStyleSheet) { |
(...skipping 17 matching lines...) Expand all Loading... |
162 return m_stylesheetDoc; | 161 return m_stylesheetDoc; |
163 } | 162 } |
164 | 163 |
165 void XSLStyleSheet::loadChildSheets() | 164 void XSLStyleSheet::loadChildSheets() |
166 { | 165 { |
167 if (!document()) | 166 if (!document()) |
168 return; | 167 return; |
169 | 168 |
170 xmlNodePtr stylesheetRoot = document()->children; | 169 xmlNodePtr stylesheetRoot = document()->children; |
171 | 170 |
172 // Top level children may include other things such as DTD nodes, we ignore
those. | 171 // Top level children may include other things such as DTD nodes, we ignore |
| 172 // those. |
173 while (stylesheetRoot && stylesheetRoot->type != XML_ELEMENT_NODE) | 173 while (stylesheetRoot && stylesheetRoot->type != XML_ELEMENT_NODE) |
174 stylesheetRoot = stylesheetRoot->next; | 174 stylesheetRoot = stylesheetRoot->next; |
175 | 175 |
176 if (m_embedded) { | 176 if (m_embedded) { |
177 // We have to locate (by ID) the appropriate embedded stylesheet element
, so that we can walk the | 177 // We have to locate (by ID) the appropriate embedded stylesheet |
178 // import/include list. | 178 // element, so that we can walk the import/include list. |
179 xmlAttrPtr idNode = xmlGetID(document(), (const xmlChar*)(finalURL().str
ing().utf8().data())); | 179 xmlAttrPtr idNode = xmlGetID(document(), (const xmlChar*)(finalURL().str
ing().utf8().data())); |
180 if (!idNode) | 180 if (!idNode) |
181 return; | 181 return; |
182 stylesheetRoot = idNode->parent; | 182 stylesheetRoot = idNode->parent; |
183 } else { | 183 } else { |
184 // FIXME: Need to handle an external URI with a # in it. This is a pret
ty minor edge case, so we'll deal | 184 // FIXME: Need to handle an external URI with a # in it. This is a |
185 // with it later. | 185 // pretty minor edge case, so we'll deal with it later. |
186 } | 186 } |
187 | 187 |
188 if (stylesheetRoot) { | 188 if (stylesheetRoot) { |
189 // Walk the children of the root element and look for import/include ele
ments. | 189 // Walk the children of the root element and look for import/include |
190 // Imports must occur first. | 190 // elements. Imports must occur first. |
191 xmlNodePtr curr = stylesheetRoot->children; | 191 xmlNodePtr curr = stylesheetRoot->children; |
192 while (curr) { | 192 while (curr) { |
193 if (curr->type != XML_ELEMENT_NODE) { | 193 if (curr->type != XML_ELEMENT_NODE) { |
194 curr = curr->next; | 194 curr = curr->next; |
195 continue; | 195 continue; |
196 } | 196 } |
197 if (IS_XSLT_ELEM(curr) && IS_XSLT_NAME(curr, "import")) { | 197 if (IS_XSLT_ELEM(curr) && IS_XSLT_NAME(curr, "import")) { |
198 xmlChar* uriRef = xsltGetNsProp(curr, (const xmlChar*)"href", XS
LT_NAMESPACE); | 198 xmlChar* uriRef = xsltGetNsProp(curr, (const xmlChar*)"href", XS
LT_NAMESPACE); |
199 loadChildSheet(String::fromUTF8((const char*)uriRef)); | 199 loadChildSheet(String::fromUTF8((const char*)uriRef)); |
200 xmlFree(uriRef); | 200 xmlFree(uriRef); |
201 } else | 201 } else { |
202 break; | 202 break; |
| 203 } |
203 curr = curr->next; | 204 curr = curr->next; |
204 } | 205 } |
205 | 206 |
206 // Now handle includes. | 207 // Now handle includes. |
207 while (curr) { | 208 while (curr) { |
208 if (curr->type == XML_ELEMENT_NODE && IS_XSLT_ELEM(curr) && IS_XSLT_
NAME(curr, "include")) { | 209 if (curr->type == XML_ELEMENT_NODE && IS_XSLT_ELEM(curr) && IS_XSLT_
NAME(curr, "include")) { |
209 xmlChar* uriRef = xsltGetNsProp(curr, (const xmlChar*)"href", XS
LT_NAMESPACE); | 210 xmlChar* uriRef = xsltGetNsProp(curr, (const xmlChar*)"href", XS
LT_NAMESPACE); |
210 loadChildSheet(String::fromUTF8((const char*)uriRef)); | 211 loadChildSheet(String::fromUTF8((const char*)uriRef)); |
211 xmlFree(uriRef); | 212 xmlFree(uriRef); |
212 } | 213 } |
213 curr = curr->next; | 214 curr = curr->next; |
214 } | 215 } |
215 } | 216 } |
216 } | 217 } |
217 | 218 |
218 void XSLStyleSheet::loadChildSheet(const String& href) | 219 void XSLStyleSheet::loadChildSheet(const String& href) |
219 { | 220 { |
220 OwnPtrWillBeRawPtr<XSLImportRule> childRule = XSLImportRule::create(this, hr
ef); | 221 OwnPtrWillBeRawPtr<XSLImportRule> childRule = XSLImportRule::create(this, hr
ef); |
221 XSLImportRule* c = childRule.get(); | 222 XSLImportRule* c = childRule.get(); |
222 m_children.append(childRule.release()); | 223 m_children.append(childRule.release()); |
223 c->loadSheet(); | 224 c->loadSheet(); |
224 } | 225 } |
225 | 226 |
226 xsltStylesheetPtr XSLStyleSheet::compileStyleSheet() | 227 xsltStylesheetPtr XSLStyleSheet::compileStyleSheet() |
227 { | 228 { |
228 // FIXME: Hook up error reporting for the stylesheet compilation process. | 229 // FIXME: Hook up error reporting for the stylesheet compilation process. |
229 if (m_embedded) | 230 if (m_embedded) |
230 return xsltLoadStylesheetPI(document()); | 231 return xsltLoadStylesheetPI(document()); |
231 | 232 |
232 // Certain libxslt versions are corrupting the xmlDoc on compilation failure
s - | 233 // Certain libxslt versions are corrupting the xmlDoc on compilation |
233 // hence attempting to recompile after a failure is unsafe. | 234 // failures - hence attempting to recompile after a failure is unsafe. |
234 if (m_compilationFailed) | 235 if (m_compilationFailed) |
235 return 0; | 236 return 0; |
236 | 237 |
237 // xsltParseStylesheetDoc makes the document part of the stylesheet | 238 // xsltParseStylesheetDoc makes the document part of the stylesheet |
238 // so we have to release our pointer to it. | 239 // so we have to release our pointer to it. |
239 ASSERT(!m_stylesheetDocTaken); | 240 ASSERT(!m_stylesheetDocTaken); |
240 xsltStylesheetPtr result = xsltParseStylesheetDoc(m_stylesheetDoc); | 241 xsltStylesheetPtr result = xsltParseStylesheetDoc(m_stylesheetDoc); |
241 if (result) | 242 if (result) |
242 m_stylesheetDocTaken = true; | 243 m_stylesheetDocTaken = true; |
243 else | 244 else |
(...skipping 22 matching lines...) Expand all Loading... |
266 for (unsigned i = 0; i < m_children.size(); ++i) { | 267 for (unsigned i = 0; i < m_children.size(); ++i) { |
267 XSLImportRule* import = m_children.at(i).get(); | 268 XSLImportRule* import = m_children.at(i).get(); |
268 XSLStyleSheet* child = import->styleSheet(); | 269 XSLStyleSheet* child = import->styleSheet(); |
269 if (!child) | 270 if (!child) |
270 continue; | 271 continue; |
271 if (matchedParent) { | 272 if (matchedParent) { |
272 if (child->processed()) | 273 if (child->processed()) |
273 continue; // libxslt has been given this sheet already. | 274 continue; // libxslt has been given this sheet already. |
274 | 275 |
275 // Check the URI of the child stylesheet against the doc URI. | 276 // Check the URI of the child stylesheet against the doc URI. |
276 // In order to ensure that libxml canonicalized both URLs, we get th
e original href | 277 // In order to ensure that libxml canonicalized both URLs, we get |
277 // string from the import rule and canonicalize it using libxml befo
re comparing it | 278 // the original href string from the import rule and canonicalize it |
278 // with the URI argument. | 279 // using libxml before comparing it with the URI argument. |
279 CString importHref = import->href().utf8(); | 280 CString importHref = import->href().utf8(); |
280 xmlChar* base = xmlNodeGetBase(parentDoc, (xmlNodePtr)parentDoc); | 281 xmlChar* base = xmlNodeGetBase(parentDoc, (xmlNodePtr)parentDoc); |
281 xmlChar* childURI = xmlBuildURI((const xmlChar*)importHref.data(), b
ase); | 282 xmlChar* childURI = xmlBuildURI((const xmlChar*)importHref.data(), b
ase); |
282 bool equalURIs = xmlStrEqual(uri, childURI); | 283 bool equalURIs = xmlStrEqual(uri, childURI); |
283 xmlFree(base); | 284 xmlFree(base); |
284 xmlFree(childURI); | 285 xmlFree(childURI); |
285 if (equalURIs) { | 286 if (equalURIs) { |
286 child->markAsProcessed(); | 287 child->markAsProcessed(); |
287 return child->document(); | 288 return child->document(); |
288 } | 289 } |
(...skipping 17 matching lines...) Expand all Loading... |
306 | 307 |
307 void XSLStyleSheet::trace(Visitor* visitor) | 308 void XSLStyleSheet::trace(Visitor* visitor) |
308 { | 309 { |
309 visitor->trace(m_ownerNode); | 310 visitor->trace(m_ownerNode); |
310 visitor->trace(m_children); | 311 visitor->trace(m_children); |
311 visitor->trace(m_parentStyleSheet); | 312 visitor->trace(m_parentStyleSheet); |
312 StyleSheet::trace(visitor); | 313 StyleSheet::trace(visitor); |
313 } | 314 } |
314 | 315 |
315 } // namespace WebCore | 316 } // namespace WebCore |
OLD | NEW |