blob: db6f9ac678abe3f8ec2abe09b95648ede5132650 [file] [log] [blame]
darin@apple.com640fa302008-02-15 05:03:55 +00001/*
darinb9481ed2006-03-20 02:57:59 +00002 * This file is part of the XSL implementation.
3 *
darin@apple.com640fa302008-02-15 05:03:55 +00004 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple, Inc. All rights reserved.
ap247ccf02006-12-25 18:37:20 +00005 * Copyright (C) 2005, 2006 Alexey Proskuryakov <ap@webkit.org>
darinb9481ed2006-03-20 02:57:59 +00006 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB. If not, write to
ddkilzerc8eccec2007-09-26 02:29:57 +000019 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
darinb9481ed2006-03-20 02:57:59 +000021 */
22
23#include "config.h"
24
mjsd2948ef2007-02-26 19:29:04 +000025#if ENABLE(XSLT)
darinb9481ed2006-03-20 02:57:59 +000026
darin91298e52006-06-12 01:10:17 +000027#include "XSLTProcessor.h"
28
darin6f2a3ef2006-04-05 21:19:57 +000029#include "DOMImplementation.h"
abarth@webkit.org17d66c62010-09-08 10:26:02 +000030#include "CachedResourceLoader.h"
tsepez@chromium.org36568252011-12-23 10:40:25 +000031#include "ContentSecurityPolicy.h"
darin36d11362006-04-11 16:30:21 +000032#include "DocumentFragment.h"
darinb9481ed2006-03-20 02:57:59 +000033#include "Frame.h"
darinc370e7e2006-11-08 05:52:27 +000034#include "FrameLoader.h"
darin647be152006-11-05 22:02:23 +000035#include "FrameView.h"
eric@webkit.org71353462010-08-23 23:49:09 +000036#include "HTMLBodyElement.h"
darin6f2a3ef2006-04-05 21:19:57 +000037#include "HTMLDocument.h"
ap276970c2007-10-29 17:02:51 +000038#include "Page.h"
abarth@webkit.org51ad70c2011-11-18 00:20:41 +000039#include "SecurityOrigin.h"
andersca@apple.coma57d5552014-12-22 23:42:30 +000040#include "SecurityOriginPolicy.h"
weinigf18aae32006-08-03 21:55:57 +000041#include "Text.h"
weinig54a89ffb2007-01-08 17:50:01 +000042#include "TextResourceDecoder.h"
cdumez@apple.comd7e206f2016-01-25 01:11:35 +000043#include "XMLDocument.h"
darin6f2a3ef2006-04-05 21:19:57 +000044#include "markup.h"
abarth@webkit.org26dfd172010-06-22 23:43:59 +000045
weinigf18aae32006-08-03 21:55:57 +000046#include <wtf/Assertions.h>
weinigf18aae32006-08-03 21:55:57 +000047#include <wtf/Vector.h>
kdeckere6b16072007-09-27 23:18:24 +000048
darinb9481ed2006-03-20 02:57:59 +000049namespace WebCore {
50
ap276970c2007-10-29 17:02:51 +000051static inline void transformTextStringToXHTMLDocumentString(String& text)
darinb9481ed2006-03-20 02:57:59 +000052{
53 // Modify the output so that it is a well-formed XHTML document with a <pre> tag enclosing the text.
commit-queue@webkit.orgbf6f7fa2012-11-07 09:43:05 +000054 text.replaceWithLiteral('&', "&amp;");
55 text.replaceWithLiteral('<', "&lt;");
darinb9481ed2006-03-20 02:57:59 +000056 text = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
57 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n"
58 "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n"
59 "<head><title/></head>\n"
60 "<body>\n"
61 "<pre>" + text + "</pre>\n"
62 "</body>\n"
63 "</html>\n";
64}
65
ap@apple.com1fe90892010-11-10 21:12:39 +000066XSLTProcessor::~XSLTProcessor()
67{
68 // Stylesheet shouldn't outlive its root node.
69 ASSERT(!m_stylesheetRootNode || !m_stylesheet || m_stylesheet->hasOneRef());
70}
71
akling@apple.comf3266b92015-08-09 08:11:32 +000072Ref<Document> XSLTProcessor::createDocumentFromSource(const String& sourceString,
ap276970c2007-10-29 17:02:51 +000073 const String& sourceEncoding, const String& sourceMIMEType, Node* sourceNode, Frame* frame)
darinb9481ed2006-03-20 02:57:59 +000074{
akling@apple.com55cde012013-10-05 00:35:12 +000075 Ref<Document> ownerDocument(sourceNode->document());
76 bool sourceIsDocument = (sourceNode == &ownerDocument.get());
darinb3547a32006-09-06 04:40:44 +000077 String documentSource = sourceString;
darinb9481ed2006-03-20 02:57:59 +000078
79 RefPtr<Document> result;
mjs22f8a1a2007-04-29 07:33:46 +000080 if (sourceMIMEType == "text/plain") {
cdumez@apple.comd7e206f2016-01-25 01:11:35 +000081 result = XMLDocument::createXHTML(frame, sourceIsDocument ? ownerDocument->url() : URL());
mjs22f8a1a2007-04-29 07:33:46 +000082 transformTextStringToXHTMLDocumentString(documentSource);
kmccullough@apple.com83edbdb2008-02-01 01:53:55 +000083 } else
andersca@apple.com003f4662014-02-17 23:53:29 +000084 result = DOMImplementation::createDocument(sourceMIMEType, frame, sourceIsDocument ? ownerDocument->url() : URL());
hausmann@webkit.org34a3f962009-09-28 14:36:24 +000085
darinb9481ed2006-03-20 02:57:59 +000086 // Before parsing, we need to save & detach the old document and get the new document
87 // in place. We have to do this only if we're rendering the result document.
mjs22f8a1a2007-04-29 07:33:46 +000088 if (frame) {
89 if (FrameView* view = frame->view())
90 view->clear();
commit-queue@webkit.org20bc0832011-10-07 23:00:04 +000091
92 if (Document* oldDocument = frame->document()) {
93 result->setTransformSourceDocument(oldDocument);
abarth@webkit.org23ea90a2012-08-14 19:47:59 +000094 result->takeDOMWindowFrom(oldDocument);
andersca@apple.coma57d5552014-12-22 23:42:30 +000095 result->setSecurityOriginPolicy(oldDocument->securityOriginPolicy());
commit-queue@webkit.org20bc0832011-10-07 23:00:04 +000096 result->setCookieURL(oldDocument->cookieURL());
tsepez@chromium.org6181ccb2011-12-22 10:39:40 +000097 result->setFirstPartyForCookies(oldDocument->firstPartyForCookies());
tsepez@chromium.org36568252011-12-23 10:40:25 +000098 result->contentSecurityPolicy()->copyStateFrom(oldDocument->contentSecurityPolicy());
commit-queue@webkit.org20bc0832011-10-07 23:00:04 +000099 }
100
akling@apple.com6fbca0f2014-12-17 19:39:16 +0000101 frame->setDocument(result.copyRef());
darinb9481ed2006-03-20 02:57:59 +0000102 }
hausmann@webkit.org34a3f962009-09-28 14:36:24 +0000103
darin@apple.com642f5002008-06-07 22:51:37 +0000104 RefPtr<TextResourceDecoder> decoder = TextResourceDecoder::create(sourceMIMEType);
darin5b2cbe12006-10-30 00:57:20 +0000105 decoder->setEncoding(sourceEncoding.isEmpty() ? UTF8Encoding() : TextEncoding(sourceEncoding), TextResourceDecoder::EncodingFromXMLHeader);
gyuyoung.kim@webkit.org2db3c5d2016-01-25 06:13:09 +0000106 result->setDecoder(WTFMove(decoder));
hausmann@webkit.org34a3f962009-09-28 14:36:24 +0000107
paroga@webkit.orgdb657842011-01-12 01:26:04 +0000108 result->setContent(documentSource);
ggarend9f8cfd2007-07-10 16:25:40 +0000109
akling@apple.comf3266b92015-08-09 08:11:32 +0000110 return result.releaseNonNull();
darinb9481ed2006-03-20 02:57:59 +0000111}
112
gyuyoung.kim@webkit.org9559e5d2015-09-15 06:00:54 +0000113RefPtr<Document> XSLTProcessor::transformToDocument(Node* sourceNode)
darinb9481ed2006-03-20 02:57:59 +0000114{
commit-queue@webkit.org57193312012-09-06 09:17:10 +0000115 if (!sourceNode)
gyuyoung.kim@webkit.org9559e5d2015-09-15 06:00:54 +0000116 return nullptr;
commit-queue@webkit.org57193312012-09-06 09:17:10 +0000117
ap276970c2007-10-29 17:02:51 +0000118 String resultMIMEType;
119 String resultString;
120 String resultEncoding;
weinig@apple.com65ea5f32013-10-06 19:18:54 +0000121 if (!transformToString(*sourceNode, resultMIMEType, resultString, resultEncoding))
gyuyoung.kim@webkit.org9559e5d2015-09-15 06:00:54 +0000122 return nullptr;
mjs22f8a1a2007-04-29 07:33:46 +0000123 return createDocumentFromSource(resultString, resultEncoding, resultMIMEType, sourceNode, 0);
darinb9481ed2006-03-20 02:57:59 +0000124}
125
gyuyoung.kim@webkit.org9559e5d2015-09-15 06:00:54 +0000126RefPtr<DocumentFragment> XSLTProcessor::transformToFragment(Node* sourceNode, Document* outputDoc)
darinb9481ed2006-03-20 02:57:59 +0000127{
commit-queue@webkit.org57193312012-09-06 09:17:10 +0000128 if (!sourceNode || !outputDoc)
gyuyoung.kim@webkit.org9559e5d2015-09-15 06:00:54 +0000129 return nullptr;
commit-queue@webkit.org57193312012-09-06 09:17:10 +0000130
ap276970c2007-10-29 17:02:51 +0000131 String resultMIMEType;
132 String resultString;
133 String resultEncoding;
apfef47982006-11-28 05:33:18 +0000134
135 // If the output document is HTML, default to HTML method.
136 if (outputDoc->isHTMLDocument())
137 resultMIMEType = "text/html";
hausmann@webkit.org34a3f962009-09-28 14:36:24 +0000138
weinig@apple.com65ea5f32013-10-06 19:18:54 +0000139 if (!transformToString(*sourceNode, resultMIMEType, resultString, resultEncoding))
gyuyoung.kim@webkit.org9559e5d2015-09-15 06:00:54 +0000140 return nullptr;
rniwa@webkit.org3976f1b2012-05-24 21:15:17 +0000141 return createFragmentForTransformToFragment(resultString, resultMIMEType, outputDoc);
darinb9481ed2006-03-20 02:57:59 +0000142}
143
darin@apple.com98a7ac62009-01-05 17:26:53 +0000144void XSLTProcessor::setParameter(const String& /*namespaceURI*/, const String& localName, const String& value)
darinb9481ed2006-03-20 02:57:59 +0000145{
146 // FIXME: namespace support?
147 // should make a QualifiedName here but we'd have to expose the impl
148 m_parameters.set(localName, value);
149}
150
darin@apple.com98a7ac62009-01-05 17:26:53 +0000151String XSLTProcessor::getParameter(const String& /*namespaceURI*/, const String& localName) const
darinb9481ed2006-03-20 02:57:59 +0000152{
153 // FIXME: namespace support?
154 // should make a QualifiedName here but we'd have to expose the impl
155 return m_parameters.get(localName);
156}
157
darin@apple.com98a7ac62009-01-05 17:26:53 +0000158void XSLTProcessor::removeParameter(const String& /*namespaceURI*/, const String& localName)
darinb9481ed2006-03-20 02:57:59 +0000159{
160 // FIXME: namespace support?
161 m_parameters.remove(localName);
162}
163
hausmann@webkit.org34a3f962009-09-28 14:36:24 +0000164void XSLTProcessor::reset()
165{
cdumez@apple.comd839ea12015-07-04 19:42:18 +0000166 m_stylesheet = nullptr;
167 m_stylesheetRootNode = nullptr;
hausmann@webkit.org34a3f962009-09-28 14:36:24 +0000168 m_parameters.clear();
169}
170
weinigf18aae32006-08-03 21:55:57 +0000171} // namespace WebCore
darinb9481ed2006-03-20 02:57:59 +0000172
mjsd2948ef2007-02-26 19:29:04 +0000173#endif // ENABLE(XSLT)