WebCore/xml/XSLTProcessor.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) 2004, 2005, 2006, 2007, 2008 Apple, Inc. All rights reserved.
       
     5  * Copyright (C) 2005, 2006 Alexey Proskuryakov <ap@webkit.org>
       
     6  *
       
     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
       
    19  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
       
    20  * Boston, MA 02110-1301, USA.
       
    21  */
       
    22 
       
    23 #include "config.h"
       
    24 
       
    25 #if ENABLE(XSLT)
       
    26 
       
    27 #include "XSLTProcessor.h"
       
    28 
       
    29 #include "DOMImplementation.h"
       
    30 #include "DocLoader.h"
       
    31 #include "DocumentFragment.h"
       
    32 #include "Frame.h"
       
    33 #include "FrameLoader.h"
       
    34 #include "FrameView.h"
       
    35 #include "HTMLDocument.h"
       
    36 #include "Page.h"
       
    37 #include "Text.h"
       
    38 #include "TextResourceDecoder.h"
       
    39 #include "loader.h"
       
    40 #include "markup.h"
       
    41 
       
    42 #include <wtf/Assertions.h>
       
    43 #include <wtf/Vector.h>
       
    44 
       
    45 namespace WebCore {
       
    46 
       
    47 static inline void transformTextStringToXHTMLDocumentString(String& text)
       
    48 {
       
    49     // Modify the output so that it is a well-formed XHTML document with a <pre> tag enclosing the text.
       
    50     text.replace('&', "&amp;");
       
    51     text.replace('<', "&lt;");
       
    52     text = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
       
    53         "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n"
       
    54         "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n"
       
    55         "<head><title/></head>\n"
       
    56         "<body>\n"
       
    57         "<pre>" + text + "</pre>\n"
       
    58         "</body>\n"
       
    59         "</html>\n";
       
    60 }
       
    61 
       
    62 PassRefPtr<Document> XSLTProcessor::createDocumentFromSource(const String& sourceString,
       
    63     const String& sourceEncoding, const String& sourceMIMEType, Node* sourceNode, Frame* frame)
       
    64 {
       
    65     RefPtr<Document> ownerDocument = sourceNode->document();
       
    66     bool sourceIsDocument = (sourceNode == ownerDocument.get());
       
    67     String documentSource = sourceString;
       
    68 
       
    69     RefPtr<Document> result;
       
    70     if (sourceMIMEType == "text/plain") {
       
    71         result = Document::create(frame, sourceIsDocument ? ownerDocument->url() : KURL());
       
    72         transformTextStringToXHTMLDocumentString(documentSource);
       
    73     } else
       
    74         result = DOMImplementation::createDocument(sourceMIMEType, frame, sourceIsDocument ? ownerDocument->url() : KURL(), false);
       
    75 
       
    76     // Before parsing, we need to save & detach the old document and get the new document
       
    77     // in place. We have to do this only if we're rendering the result document.
       
    78     if (frame) {
       
    79         if (FrameView* view = frame->view())
       
    80             view->clear();
       
    81         result->setTransformSourceDocument(frame->document());
       
    82         frame->setDocument(result);
       
    83     }
       
    84 
       
    85     result->open();
       
    86 
       
    87     RefPtr<TextResourceDecoder> decoder = TextResourceDecoder::create(sourceMIMEType);
       
    88     decoder->setEncoding(sourceEncoding.isEmpty() ? UTF8Encoding() : TextEncoding(sourceEncoding), TextResourceDecoder::EncodingFromXMLHeader);
       
    89     result->setDecoder(decoder.release());
       
    90 
       
    91     result->write(documentSource);
       
    92     result->finishParsing();
       
    93     result->close();
       
    94 
       
    95     return result.release();
       
    96 }
       
    97 
       
    98 static inline RefPtr<DocumentFragment> createFragmentFromSource(const String& sourceString, const String& sourceMIMEType, Document* outputDoc)
       
    99 {
       
   100     RefPtr<DocumentFragment> fragment = outputDoc->createDocumentFragment();
       
   101 
       
   102     if (sourceMIMEType == "text/html")
       
   103         fragment->parseHTML(sourceString);
       
   104     else if (sourceMIMEType == "text/plain")
       
   105         fragment->legacyParserAddChild(Text::create(outputDoc, sourceString));
       
   106     else {
       
   107         bool successfulParse = fragment->parseXML(sourceString, outputDoc->documentElement());
       
   108         if (!successfulParse)
       
   109             return 0;
       
   110     }
       
   111 
       
   112     // FIXME: Do we need to mess with URLs here?
       
   113 
       
   114     return fragment;
       
   115 }
       
   116 
       
   117 PassRefPtr<Document> XSLTProcessor::transformToDocument(Node* sourceNode)
       
   118 {
       
   119     String resultMIMEType;
       
   120     String resultString;
       
   121     String resultEncoding;
       
   122     if (!transformToString(sourceNode, resultMIMEType, resultString, resultEncoding))
       
   123         return 0;
       
   124     return createDocumentFromSource(resultString, resultEncoding, resultMIMEType, sourceNode, 0);
       
   125 }
       
   126 
       
   127 PassRefPtr<DocumentFragment> XSLTProcessor::transformToFragment(Node* sourceNode, Document* outputDoc)
       
   128 {
       
   129     String resultMIMEType;
       
   130     String resultString;
       
   131     String resultEncoding;
       
   132 
       
   133     // If the output document is HTML, default to HTML method.
       
   134     if (outputDoc->isHTMLDocument())
       
   135         resultMIMEType = "text/html";
       
   136 
       
   137     if (!transformToString(sourceNode, resultMIMEType, resultString, resultEncoding))
       
   138         return 0;
       
   139     return createFragmentFromSource(resultString, resultMIMEType, outputDoc);
       
   140 }
       
   141 
       
   142 void XSLTProcessor::setParameter(const String& /*namespaceURI*/, const String& localName, const String& value)
       
   143 {
       
   144     // FIXME: namespace support?
       
   145     // should make a QualifiedName here but we'd have to expose the impl
       
   146     m_parameters.set(localName, value);
       
   147 }
       
   148 
       
   149 String XSLTProcessor::getParameter(const String& /*namespaceURI*/, const String& localName) const
       
   150 {
       
   151     // FIXME: namespace support?
       
   152     // should make a QualifiedName here but we'd have to expose the impl
       
   153     return m_parameters.get(localName);
       
   154 }
       
   155 
       
   156 void XSLTProcessor::removeParameter(const String& /*namespaceURI*/, const String& localName)
       
   157 {
       
   158     // FIXME: namespace support?
       
   159     m_parameters.remove(localName);
       
   160 }
       
   161 
       
   162 void XSLTProcessor::reset()
       
   163 {
       
   164     m_stylesheet.clear();
       
   165     m_stylesheetRootNode.clear();
       
   166     m_parameters.clear();
       
   167 }
       
   168 
       
   169 } // namespace WebCore
       
   170 
       
   171 #endif // ENABLE(XSLT)