WebCore/xml/XSLTProcessorQt.cpp
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 /*
       
     2  * This file is part of the XSL implementation.
       
     3  *
       
     4  * Copyright (C) 2009 Jakub Wieczorek <faw217@gmail.com>
       
     5  *
       
     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.
       
    10  *
       
    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.
       
    15  *
       
    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.
       
    20  */
       
    21 
       
    22 #include "config.h"
       
    23 
       
    24 #if ENABLE(XSLT)
       
    25 
       
    26 #include "XSLTProcessor.h"
       
    27 
       
    28 #include "Console.h"
       
    29 #include "DOMWindow.h"
       
    30 #include "Frame.h"
       
    31 #include "TransformSource.h"
       
    32 #include "loader.h"
       
    33 #include "markup.h"
       
    34 #include <wtf/Assertions.h>
       
    35 #include <wtf/Vector.h>
       
    36 
       
    37 #include <qabstractmessagehandler.h>
       
    38 #include <qabstracturiresolver.h>
       
    39 #include <qbuffer.h>
       
    40 #include <qsourcelocation.h>
       
    41 #include <qxmlquery.h>
       
    42 
       
    43 namespace WebCore {
       
    44 
       
    45 class XSLTMessageHandler : public QAbstractMessageHandler {
       
    46 
       
    47 public:
       
    48     XSLTMessageHandler(Document* document = 0);
       
    49     virtual void handleMessage(QtMsgType type, const QString& description,
       
    50                                const QUrl& identifier, const QSourceLocation& sourceLocation);
       
    51 
       
    52 private:
       
    53     Document* m_document;
       
    54 };
       
    55 
       
    56 XSLTMessageHandler::XSLTMessageHandler(Document* document)
       
    57     : QAbstractMessageHandler()
       
    58     , m_document(document)
       
    59 {
       
    60 }
       
    61 
       
    62 void XSLTMessageHandler::handleMessage(QtMsgType type, const QString& description,
       
    63                                        const QUrl&, const QSourceLocation& sourceLocation)
       
    64 {
       
    65     if (!m_document->frame())
       
    66         return;
       
    67 
       
    68     MessageLevel level;
       
    69     switch (type) {
       
    70     case QtDebugMsg:
       
    71         level = TipMessageLevel;
       
    72         break;
       
    73     case QtWarningMsg:
       
    74         level = WarningMessageLevel;
       
    75         break;
       
    76     case QtCriticalMsg:
       
    77     case QtFatalMsg:
       
    78         level = ErrorMessageLevel;
       
    79         break;
       
    80     default:
       
    81         level = LogMessageLevel;
       
    82         break;
       
    83     }
       
    84 
       
    85     Console* console = m_document->frame()->domWindow()->console();
       
    86     console->addMessage(XMLMessageSource, LogMessageType, level, description,
       
    87                         sourceLocation.line(), sourceLocation.uri().toString());
       
    88 }
       
    89 
       
    90 class XSLTUriResolver : public QAbstractUriResolver {
       
    91 
       
    92 public:
       
    93     XSLTUriResolver(Document* document);
       
    94     virtual QUrl resolve(const QUrl& relative, const QUrl& baseURI) const;
       
    95 
       
    96 private:
       
    97     Document* m_document;
       
    98 };
       
    99 
       
   100 XSLTUriResolver::XSLTUriResolver(Document* document)
       
   101     : QAbstractUriResolver()
       
   102     , m_document(document)
       
   103 {
       
   104 }
       
   105 
       
   106 QUrl XSLTUriResolver::resolve(const QUrl& relative, const QUrl& baseURI) const
       
   107 {
       
   108     QUrl url = baseURI.resolved(relative);
       
   109 
       
   110     if (!m_document->frame() || !m_document->securityOrigin()->canRequest(url))
       
   111         return QUrl();
       
   112     return url;
       
   113 }
       
   114 
       
   115 bool XSLTProcessor::transformToString(Node* sourceNode, String&, String& resultString, String&)
       
   116 {
       
   117     bool success = false;
       
   118 
       
   119     RefPtr<XSLStyleSheet> stylesheet = m_stylesheet;
       
   120     if (!stylesheet && m_stylesheetRootNode) {
       
   121         Node* node = m_stylesheetRootNode.get();
       
   122         stylesheet = XSLStyleSheet::create(node->parent() ? node->parent() : node,
       
   123             node->document()->url().string(),
       
   124             node->document()->url()); // FIXME: Should we use baseURL here?
       
   125         stylesheet->parseString(createMarkup(node));
       
   126     }
       
   127 
       
   128     if (!stylesheet || stylesheet->sheetString().isEmpty())
       
   129         return success;
       
   130 
       
   131     RefPtr<Document> ownerDocument = sourceNode->document();
       
   132     bool sourceIsDocument = (sourceNode == ownerDocument.get());
       
   133 
       
   134     QXmlQuery query(QXmlQuery::XSLT20);
       
   135 
       
   136     XSLTMessageHandler messageHandler(ownerDocument.get());
       
   137     XSLTUriResolver uriResolver(ownerDocument.get());
       
   138     query.setMessageHandler(&messageHandler);
       
   139 
       
   140     XSLTProcessor::ParameterMap::iterator end = m_parameters.end();
       
   141     for (XSLTProcessor::ParameterMap::iterator it = m_parameters.begin(); it != end; ++it)
       
   142         query.bindVariable(QString(it->first), QXmlItem(QVariant(it->second)));
       
   143 
       
   144     QString source;
       
   145     if (sourceIsDocument && ownerDocument->transformSource())
       
   146         source = ownerDocument->transformSource()->platformSource();
       
   147     if (!sourceIsDocument || source.isEmpty())
       
   148         source = createMarkup(sourceNode);
       
   149 
       
   150     QBuffer inputBuffer;
       
   151     QBuffer styleSheetBuffer;
       
   152     QBuffer outputBuffer;
       
   153 
       
   154     inputBuffer.setData(source.toUtf8());
       
   155     styleSheetBuffer.setData(QString(stylesheet->sheetString()).toUtf8());
       
   156 
       
   157     inputBuffer.open(QIODevice::ReadOnly);
       
   158     styleSheetBuffer.open(QIODevice::ReadOnly);
       
   159     outputBuffer.open(QIODevice::ReadWrite);
       
   160 
       
   161     query.setFocus(&inputBuffer);
       
   162     query.setQuery(&styleSheetBuffer, QUrl(stylesheet->href()));
       
   163 
       
   164     query.setUriResolver(&uriResolver);
       
   165 
       
   166     success = query.evaluateTo(&outputBuffer);
       
   167     outputBuffer.reset();
       
   168     resultString = QString::fromUtf8(outputBuffer.readAll()).trimmed();
       
   169 
       
   170     if (m_stylesheet) {
       
   171         m_stylesheet->clearDocuments();
       
   172         m_stylesheet = 0;
       
   173     }
       
   174 
       
   175     return success;
       
   176 }
       
   177 
       
   178 } // namespace WebCore
       
   179 
       
   180 #endif // ENABLE(XSLT)