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