2 * This file is part of the XSL implementation.
4 * Copyright (C) 2009 Jakub Wieczorek <faw217@gmail.com>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
26 #include "XSLTProcessor.h"
29 #include "DOMWindow.h"
31 #include "TransformSource.h"
34 #include <wtf/Assertions.h>
35 #include <wtf/Vector.h>
37 #include <qabstractmessagehandler.h>
38 #include <qabstracturiresolver.h>
40 #include <qsourcelocation.h>
41 #include <qxmlquery.h>
45 class XSLTMessageHandler : public QAbstractMessageHandler {
48 XSLTMessageHandler(Document* document = 0);
49 virtual void handleMessage(QtMsgType type, const QString& description,
50 const QUrl& identifier, const QSourceLocation& sourceLocation);
56 XSLTMessageHandler::XSLTMessageHandler(Document* document)
57 : QAbstractMessageHandler()
58 , m_document(document)
62 void XSLTMessageHandler::handleMessage(QtMsgType type, const QString& description,
63 const QUrl&, const QSourceLocation& sourceLocation)
65 if (!m_document->frame())
71 level = TipMessageLevel;
74 level = WarningMessageLevel;
78 level = ErrorMessageLevel;
81 level = LogMessageLevel;
85 Console* console = m_document->frame()->domWindow()->console();
86 console->addMessage(XMLMessageSource, LogMessageType, level, description,
87 sourceLocation.line(), sourceLocation.uri().toString());
90 class XSLTUriResolver : public QAbstractUriResolver {
93 XSLTUriResolver(Document* document);
94 virtual QUrl resolve(const QUrl& relative, const QUrl& baseURI) const;
100 XSLTUriResolver::XSLTUriResolver(Document* document)
101 : QAbstractUriResolver()
102 , m_document(document)
106 QUrl XSLTUriResolver::resolve(const QUrl& relative, const QUrl& baseURI) const
108 QUrl url = baseURI.resolved(relative);
110 if (!m_document->frame() || !m_document->securityOrigin()->canRequest(url))
115 bool XSLTProcessor::transformToString(Node* sourceNode, String&, String& resultString, String&)
117 bool success = false;
119 RefPtr<XSLStyleSheet> stylesheet = m_stylesheet;
120 if (!stylesheet && m_stylesheetRootNode) {
121 Node* node = m_stylesheetRootNode.get();
122 stylesheet = XSLStyleSheet::createForXSLTProcessor(node->parentNode() ? node->parentNode() : node,
123 node->document()->url().string(),
124 node->document()->url()); // FIXME: Should we use baseURL here?
126 // According to Mozilla documentation, the node must be a Document node, an xsl:stylesheet or xsl:transform element.
127 // But we just use text content regardless of node type.
128 stylesheet->parseString(createMarkup(node));
131 if (!stylesheet || stylesheet->sheetString().isEmpty())
134 RefPtr<Document> ownerDocument = sourceNode->document();
135 bool sourceIsDocument = (sourceNode == ownerDocument.get());
137 QXmlQuery query(QXmlQuery::XSLT20);
139 XSLTMessageHandler messageHandler(ownerDocument.get());
140 XSLTUriResolver uriResolver(ownerDocument.get());
141 query.setMessageHandler(&messageHandler);
143 XSLTProcessor::ParameterMap::iterator end = m_parameters.end();
144 for (XSLTProcessor::ParameterMap::iterator it = m_parameters.begin(); it != end; ++it)
145 query.bindVariable(QString(it->first), QXmlItem(QVariant(it->second)));
148 if (sourceIsDocument && ownerDocument->transformSource())
149 source = ownerDocument->transformSource()->platformSource();
150 if (!sourceIsDocument || source.isEmpty())
151 source = createMarkup(sourceNode);
154 QBuffer styleSheetBuffer;
155 QBuffer outputBuffer;
157 inputBuffer.setData(source.toUtf8());
158 styleSheetBuffer.setData(QString(stylesheet->sheetString()).toUtf8());
160 inputBuffer.open(QIODevice::ReadOnly);
161 styleSheetBuffer.open(QIODevice::ReadOnly);
162 outputBuffer.open(QIODevice::ReadWrite);
164 query.setFocus(&inputBuffer);
165 query.setQuery(&styleSheetBuffer, QUrl(stylesheet->href()));
167 query.setUriResolver(&uriResolver);
169 success = query.evaluateTo(&outputBuffer);
170 outputBuffer.reset();
171 resultString = QString::fromUtf8(outputBuffer.readAll()).trimmed();
174 m_stylesheet->clearDocuments();
181 } // namespace WebCore
183 #endif // ENABLE(XSLT)