Land initial support for XSLT using xml-stylesheet PIs.
authorhyatt <hyatt@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 17 Aug 2004 01:54:55 +0000 (01:54 +0000)
committerhyatt <hyatt@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 17 Aug 2004 01:54:55 +0000 (01:54 +0000)
        * WebCore.pbproj/project.pbxproj:
        * khtml/khtml_part.cpp:
        (KHTMLPart::replaceDocImpl):
        * khtml/khtml_part.h:
        * khtml/khtmlview.h:
        * khtml/xml/dom_docimpl.cpp:
        (DocumentImpl::DocumentImpl):
        (DocumentImpl::~DocumentImpl):
        (DocumentImpl::recalcStyleSelector):
        (DocumentImpl::applyXSLTransform):
        (DocumentImpl::setTransformSourceDocument):
        * khtml/xml/dom_docimpl.h:
        (DOM::DocumentImpl::setTransformSource):
        (DOM::DocumentImpl::transformSource):
        (DOM::DocumentImpl::transformSourceDocument):
        * khtml/xml/dom_xmlimpl.cpp:
        (DOM::ProcessingInstructionImpl::checkStyleSheet):
        * khtml/xml/dom_xmlimpl.h:
        (DOM::ProcessingInstructionImpl::isXSL):
        * khtml/xml/xml_tokenizer.cpp:
        (khtml::matchFunc):
        (khtml::openFunc):
        (khtml::createQStringParser):
        (khtml::XMLTokenizer::processingInstruction):
        (khtml::XMLTokenizer::finish):
        (khtml::XMLTokenizer::setTransformSource):
        * khtml/xml/xml_tokenizer.h:
        (khtml::Tokenizer::setTransformSource):
        * khtml/xml/xsl_stylesheetimpl.cpp: Removed.
        * khtml/xml/xsl_stylesheetimpl.h: Removed.
        * khtml/xsl/xsl_stylesheetimpl.cpp: Added.
        (DOM::XSLStyleSheetImpl::XSLStyleSheetImpl):
        (DOM::XSLStyleSheetImpl::~XSLStyleSheetImpl):
        (DOM::XSLStyleSheetImpl::isLoading):
        (DOM::XSLStyleSheetImpl::checkLoaded):
        (DOM::XSLStyleSheetImpl::docLoader):
        (DOM::XSLStyleSheetImpl::parseString):
        * khtml/xsl/xsl_stylesheetimpl.h: Added.
        (DOM::XSLStyleSheetImpl::isXSLStyleSheet):
        (DOM::XSLStyleSheetImpl::type):
        (DOM::XSLStyleSheetImpl::ownerDocument):
        (DOM::XSLStyleSheetImpl::document):
        (DOM::XSLStyleSheetImpl::clearDocument):
        * khtml/xsl/xslt_processorimpl.cpp: Added.
        (DOM::m_sourceDocument):
        (DOM::XSLTProcessorImpl::~XSLTProcessorImpl):
        (DOM::XSLTProcessorImpl::transformDocument):
        (DOM::bufferWrite):
        (DOM::XSLTProcessorImpl::addToResult):
        (DOM::XSLTProcessorImpl::documentFromXMLDocPtr):
        * khtml/xsl/xslt_processorimpl.h: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@7266 268f45cc-cd09-0410-ab3c-d52691b4dbfc

15 files changed:
WebCore/ChangeLog-2005-08-23
WebCore/WebCore.pbproj/project.pbxproj
WebCore/khtml/khtml_part.cpp
WebCore/khtml/khtml_part.h
WebCore/khtml/khtmlview.h
WebCore/khtml/xml/dom_docimpl.cpp
WebCore/khtml/xml/dom_docimpl.h
WebCore/khtml/xml/dom_xmlimpl.cpp
WebCore/khtml/xml/dom_xmlimpl.h
WebCore/khtml/xml/xml_tokenizer.cpp
WebCore/khtml/xml/xml_tokenizer.h
WebCore/khtml/xsl/xsl_stylesheetimpl.cpp [moved from WebCore/khtml/xml/xsl_stylesheetimpl.cpp with 74% similarity]
WebCore/khtml/xsl/xsl_stylesheetimpl.h [moved from WebCore/khtml/xml/xsl_stylesheetimpl.h with 83% similarity]
WebCore/khtml/xsl/xslt_processorimpl.cpp [new file with mode: 0644]
WebCore/khtml/xsl/xslt_processorimpl.h [new file with mode: 0644]

index 567fa45..05042f7 100644 (file)
@@ -1,3 +1,59 @@
+2004-08-16  David Hyatt  <hyatt@apple.com>
+
+       Land initial support for XSLT using xml-stylesheet PIs.
+       
+        * WebCore.pbproj/project.pbxproj:
+        * khtml/khtml_part.cpp:
+        (KHTMLPart::replaceDocImpl):
+        * khtml/khtml_part.h:
+        * khtml/khtmlview.h:
+        * khtml/xml/dom_docimpl.cpp:
+        (DocumentImpl::DocumentImpl):
+        (DocumentImpl::~DocumentImpl):
+        (DocumentImpl::recalcStyleSelector):
+        (DocumentImpl::applyXSLTransform):
+        (DocumentImpl::setTransformSourceDocument):
+        * khtml/xml/dom_docimpl.h:
+        (DOM::DocumentImpl::setTransformSource):
+        (DOM::DocumentImpl::transformSource):
+        (DOM::DocumentImpl::transformSourceDocument):
+        * khtml/xml/dom_xmlimpl.cpp:
+        (DOM::ProcessingInstructionImpl::checkStyleSheet):
+        * khtml/xml/dom_xmlimpl.h:
+        (DOM::ProcessingInstructionImpl::isXSL):
+        * khtml/xml/xml_tokenizer.cpp:
+        (khtml::matchFunc):
+        (khtml::openFunc):
+        (khtml::createQStringParser):
+        (khtml::XMLTokenizer::processingInstruction):
+        (khtml::XMLTokenizer::finish):
+        (khtml::XMLTokenizer::setTransformSource):
+        * khtml/xml/xml_tokenizer.h:
+        (khtml::Tokenizer::setTransformSource):
+        * khtml/xml/xsl_stylesheetimpl.cpp: Removed.
+        * khtml/xml/xsl_stylesheetimpl.h: Removed.
+        * khtml/xsl/xsl_stylesheetimpl.cpp: Added.
+        (DOM::XSLStyleSheetImpl::XSLStyleSheetImpl):
+        (DOM::XSLStyleSheetImpl::~XSLStyleSheetImpl):
+        (DOM::XSLStyleSheetImpl::isLoading):
+        (DOM::XSLStyleSheetImpl::checkLoaded):
+        (DOM::XSLStyleSheetImpl::docLoader):
+        (DOM::XSLStyleSheetImpl::parseString):
+        * khtml/xsl/xsl_stylesheetimpl.h: Added.
+        (DOM::XSLStyleSheetImpl::isXSLStyleSheet):
+        (DOM::XSLStyleSheetImpl::type):
+        (DOM::XSLStyleSheetImpl::ownerDocument):
+        (DOM::XSLStyleSheetImpl::document):
+        (DOM::XSLStyleSheetImpl::clearDocument):
+        * khtml/xsl/xslt_processorimpl.cpp: Added.
+        (DOM::m_sourceDocument):
+        (DOM::XSLTProcessorImpl::~XSLTProcessorImpl):
+        (DOM::XSLTProcessorImpl::transformDocument):
+        (DOM::bufferWrite):
+        (DOM::XSLTProcessorImpl::addToResult):
+        (DOM::XSLTProcessorImpl::documentFromXMLDocPtr):
+        * khtml/xsl/xslt_processorimpl.h: Added.
+
 2004-08-16  Maciej Stachowiak  <mjs@apple.com>
 
         Fix build.
index 7d96433..6f4e25c 100644 (file)
@@ -15,7 +15,7 @@
                                GCC_OPTIMIZATION_LEVEL = 0;
                                INSTALL_PATH = "@executable_path/../Frameworks";
                                OPTIMIZATION_CFLAGS = "-O0";
-                               OTHER_LDFLAGS = "-seg1addr $(LOCAL_SEG1_ADDR)";
+                               OTHER_LDFLAGS = "-seg1addr $(LOCAL_SEG1_ADDR) $(COMMON_LDFLAGS)";
                                SECTORDER_FLAGS = "";
                                ZERO_LINK = YES;
                        };
@@ -26,7 +26,7 @@
                        buildSettings = {
                                COPY_PHASE_STRIP = YES;
                                INSTALL_PATH = "@executable_path/../Frameworks";
-                               OTHER_LDFLAGS = "-seg1addr $(LOCAL_SEG1_ADDR)";
+                               OTHER_LDFLAGS = "-seg1addr $(LOCAL_SEG1_ADDR) $(COMMON_LDFLAGS)";
                                SECTORDER_FLAGS = "";
                        };
                        isa = PBXBuildStyle;
                                0867D6A0FE84028FC02AAC07,
                        );
                        buildSettings = {
+                               COMMON_LDFLAGS = "\"`if [ -f /usr/lib/libxslt.1.dylib ]; then echo \\\"-lxslt.1\\\"; else echo \\\"-lxml2\\\"; fi`\"";
                                COPY_PHASE_STRIP = NO;
                                DEBUG_CFLAGS = "-DNDEBUG";
                                DYLIB_COMPATIBILITY_VERSION = 1;
                                FRAMEWORK_SEARCH_PATHS = "\"${DSTROOT}\" \"${MERGE_DIR}/$(SYSTEM_LIBRARY_DIR)/Frameworks/WebKit.framework/Frameworks\" \"$(SYSTEM_LIBRARY_DIR)/Frameworks/WebKit.framework/Frameworks\"";
                                FRAMEWORK_VERSION = A;
                                GCC_TREAT_WARNINGS_AS_ERRORS = YES;
-                               HEADER_SEARCH_PATHS = "ForwardingHeaders /usr/include/libxml2";
+                               HEADER_SEARCH_PATHS = "ForwardingHeaders /usr/include/libxslt /usr/include/libxml2";
                                INSTALL_PATH = /System/Library/Frameworks/WebKit.framework/Versions/A/Frameworks;
                                LIBRARY_SEARCH_PATHS = "";
                                LOCAL_SEG1_ADDR = 0x9000000;
                                BE02D4E8066F908A0076809F,
                                93D1FEF7067EBF89009CE68A,
                                9348900606C00363007E7ACE,
-                               BC9D580706C185A4001E893C,
+                               BC06F24E06D18A7E004A6FA3,
+                               BC06F25006D18A7E004A6FA3,
                        );
                        isa = PBXHeadersBuildPhase;
                        runOnlyForDeploymentPostprocessing = 0;
                                2D90660E0665D937006B6F1A,
                                BE02F485066E1C550013A9F6,
                                BE02D4E9066F908A0076809F,
-                               BC9D580606C185A4001E893C,
                                BE1A407206CA8A33005B28CF,
+                               BC06F24D06D18A7E004A6FA3,
+                               BC06F24F06D18A7E004A6FA3,
                        );
                        isa = PBXSourcesBuildPhase;
                        runOnlyForDeploymentPostprocessing = 0;
 //BC2
 //BC3
 //BC4
+               BC06F24406D18A35004A6FA3 = {
+                       children = (
+                               BC06F24906D18A7E004A6FA3,
+                               BC06F24A06D18A7E004A6FA3,
+                               BC06F24B06D18A7E004A6FA3,
+                               BC06F24C06D18A7E004A6FA3,
+                       );
+                       isa = PBXGroup;
+                       name = xsl;
+                       path = khtml;
+                       refType = 2;
+                       sourceTree = SOURCE_ROOT;
+               };
+               BC06F24906D18A7E004A6FA3 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.cpp.cpp;
+                       name = xsl_stylesheetimpl.cpp;
+                       path = xsl/xsl_stylesheetimpl.cpp;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               BC06F24A06D18A7E004A6FA3 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = xsl_stylesheetimpl.h;
+                       path = xsl/xsl_stylesheetimpl.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               BC06F24B06D18A7E004A6FA3 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.cpp.cpp;
+                       name = xslt_processorimpl.cpp;
+                       path = xsl/xslt_processorimpl.cpp;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               BC06F24C06D18A7E004A6FA3 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = xslt_processorimpl.h;
+                       path = xsl/xslt_processorimpl.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               BC06F24D06D18A7E004A6FA3 = {
+                       fileRef = BC06F24906D18A7E004A6FA3;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               BC06F24E06D18A7E004A6FA3 = {
+                       fileRef = BC06F24A06D18A7E004A6FA3;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               BC06F24F06D18A7E004A6FA3 = {
+                       fileRef = BC06F24B06D18A7E004A6FA3;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               BC06F25006D18A7E004A6FA3 = {
+                       fileRef = BC06F24C06D18A7E004A6FA3;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
                BC32C2EC048BF95C00A8000B = {
                        fileEncoding = 30;
                        isa = PBXFileReference;
                        settings = {
                        };
                };
-               BC9D580406C185A4001E893C = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.cpp.cpp;
-                       path = xsl_stylesheetimpl.cpp;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               BC9D580506C185A4001E893C = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = xsl_stylesheetimpl.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               BC9D580606C185A4001E893C = {
-                       fileRef = BC9D580406C185A4001E893C;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               BC9D580706C185A4001E893C = {
-                       fileRef = BC9D580506C185A4001E893C;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
                BCBDB0370597B36E00B83B92 = {
                        fileEncoding = 30;
                        isa = PBXFileReference;
                                F523D2F302DE443B018635CA,
                                BC41978B059293BE0016347F,
                                F523D32402DE4478018635CA,
+                               BC06F24406D18A35004A6FA3,
                                F523D15202DE42AD018635CA,
                                F523D15102DE42AD018635CA,
                                F523D15402DE42AD018635CA,
                                BC7FDE3205C1D9AB0070A902,
                                F523D30902DE4476018635CA,
                                F523D30A02DE4476018635CA,
-                               BC9D580406C185A4001E893C,
-                               BC9D580506C185A4001E893C,
                        );
                        isa = PBXGroup;
                        path = xml;
                        buildSettings = {
                                GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
                                INSTALL_PATH = "@executable_path/../Frameworks";
-                               OTHER_LDFLAGS = "-seg1addr $(LOCAL_SEG1_ADDR)";
+                               OTHER_LDFLAGS = "-seg1addr $(LOCAL_SEG1_ADDR) $(COMMON_LDFLAGS)";
                                SECTORDER_FLAGS = "";
                        };
                        isa = PBXBuildStyle;
index b02eabd..4b66a8f 100644 (file)
@@ -1098,6 +1098,19 @@ DOM::DocumentImpl *KHTMLPart::xmlDocImpl() const
     return 0;
 }
 
+void KHTMLPart::replaceDocImpl(DocumentImpl* newDoc)
+{
+    if (d) {
+        if (d->m_doc) {
+            d->m_doc->detach();
+            d->m_doc->deref();
+        }
+        d->m_doc = newDoc;
+        if (newDoc)
+            newDoc->ref();
+    }
+}
+
 /*bool KHTMLPart::isSSLInUse() const
 {
   return d->m_ssl_in_use;
index b0170c5..0d5211d 100644 (file)
@@ -1239,6 +1239,7 @@ private:
 #endif
   DOM::HTMLDocumentImpl *docImpl() const;
   DOM::DocumentImpl *xmlDocImpl() const;
+  void replaceDocImpl(DOM::DocumentImpl* newDoc);
 #if APPLE_CHANGES
   private:
 #endif
index 2c2d900..48cb3da 100644 (file)
@@ -166,12 +166,12 @@ public:
     void resetScrollBars();
 #endif
 
+     void clear();
+
 signals:
         void cleared();
     
 protected:
-        void clear();
-    
 #if APPLE_CHANGES
 public:
         void clearPart();
index 7012063..b7dbbba 100644 (file)
 
 #include <kio/job.h>
 
+#ifdef KHTML_XSLT
+#include "xsl_stylesheetimpl.h"
+#include "xslt_processorimpl.h"
+#endif
+
 #ifndef KHTML_NO_XBL
 #include "xbl/xbl_binding_manager.h"
 using XBL::XBLBindingManager;
@@ -246,6 +251,9 @@ DocumentImpl::DocumentImpl(DOMImplementationImpl *_implementation, KHTMLView *v)
 #ifndef KHTML_NO_XBL
       , m_bindingManager(new XBLBindingManager(this))
 #endif
+#ifdef KHTML_XSLT
+    , m_transformSourceDocument(0)
+#endif
 #if APPLE_CHANGES
     , m_finishedParsing(this, SIGNAL(finishedParsing()))
     , m_inPageCache(false), m_savedRenderer(0)
@@ -381,6 +389,11 @@ DocumentImpl::~DocumentImpl()
         m_renderArena = 0;
     }
 
+#ifdef KHTML_XSLT
+    if (m_transformSourceDocument)
+        m_transformSourceDocument->deref();
+#endif
+
 #ifndef KHTML_NO_XBL
     delete m_bindingManager;
 #endif
@@ -2175,6 +2188,12 @@ void DocumentImpl::recalcStyleSelector()
             // Processing instruction (XML documents only)
             ProcessingInstructionImpl* pi = static_cast<ProcessingInstructionImpl*>(n);
             sheet = pi->sheet();
+#ifdef KHTML_XSLT
+            if (pi->isXSL()) {
+                applyXSLTransform(pi);
+                return;
+            }
+#endif
             if (!sheet && !pi->localHref().isEmpty())
             {
                 // Processing instruction with reference to an element in this document - e.g.
@@ -2978,10 +2997,16 @@ void DocumentImpl::removeMarker(NodeImpl *node, DocumentMarker target)
             }
         }
     }
+}
 
-    // repaint the affected node
-    if (docDirty && node->renderer())
-        node->renderer()->repaint();
+QValueList<DocumentMarker> DocumentImpl::markersForNode(NodeImpl *node)
+{
+    QValueList <DocumentMarker> *markers = m_markers.find(node);
+    if (markers) {
+        return *markers;
+    } else {
+        return QValueList <DocumentMarker> ();
+    }
 }
 
 void DocumentImpl::removeAllMarkers(NodeImpl *node, ulong startOffset, long length)
@@ -3029,16 +3054,31 @@ void DocumentImpl::shiftMarkers(NodeImpl *node, ulong startOffset, long delta)
         node->renderer()->repaint();
 }
 
-QValueList<DocumentMarker> DocumentImpl::markersForNode(NodeImpl *node)
+#ifdef KHTML_XSLT
+void DocumentImpl::applyXSLTransform(ProcessingInstructionImpl* pi)
 {
-    QValueList <DocumentMarker> *markers = m_markers.find(node);
-    if (markers) {
-        return *markers;
-    } else {
-        return QValueList <DocumentMarker> ();
-    }
+    // Ref ourselves to keep from being destroyed.
+    XSLTProcessorImpl processor(static_cast<XSLStyleSheetImpl*>(pi->sheet()), this, !pi->localHref().isEmpty());
+    DocumentImpl* result = processor.transformDocument(this);
+    if (result)
+        // Cache the source document.
+        result->setTransformSourceDocument(this);
+
+    // FIXME: If the transform failed we should probably report an error (like Mozilla does) in this
+    // case.
 }
 
+void DocumentImpl::setTransformSourceDocument(DocumentImpl* doc)
+{ 
+    if (m_transformSourceDocument)
+        m_transformSourceDocument->deref(); 
+    m_transformSourceDocument = doc;
+    if (doc)
+        doc->ref();
+}
+
+#endif
+
 // ----------------------------------------------------------------------------
 
 DocumentFragmentImpl::DocumentFragmentImpl(DocumentPtr *doc) : NodeBaseImpl(doc)
index 1c8d0f2..cb509ab 100644 (file)
@@ -115,7 +115,10 @@ namespace DOM {
     class StyleSheetListImpl;
     class TextImpl;
     class TreeWalkerImpl;
-    
+#ifdef KHTML_XSLT
+    class XSLStyleSheetImpl;
+#endif
+
     // A range of a node within a document that is "marked", such as being misspelled
     struct DocumentMarker
     {
@@ -554,6 +557,14 @@ public:
     void shiftMarkers(NodeImpl *node, ulong startOffset, long delta);
     QValueList<DocumentMarker> markersForNode(NodeImpl *node);
 
+#ifdef KHTML_XSLT
+    void applyXSLTransform(ProcessingInstructionImpl* pi);
+    void setTransformSource(const QString& xmlSource) { m_transformSource = xmlSource; }
+    const QString& transformSource() { return m_transformSource; }
+    DocumentImpl* transformSourceDocument() { return m_transformSourceDocument; }
+    void setTransformSourceDocument(DocumentImpl* doc);
+#endif
+
 #ifndef KHTML_NO_XBL
     // XBL methods
     XBL::XBLBindingManager* bindingManager() const { return m_bindingManager; }
@@ -662,6 +673,11 @@ protected:
     QTime m_startTime;
     bool m_overMinimumLayoutThreshold;
     
+#ifdef KHTML_XSLT
+    QString m_transformSource;
+    DocumentImpl* m_transformSourceDocument;
+#endif
+
 #ifndef KHTML_NO_XBL
     XBL::XBLBindingManager* m_bindingManager; // The access point through which documents and elements communicate with XBL.
 #endif
index 8220694..260d4c6 100644 (file)
@@ -401,7 +401,7 @@ bool ProcessingInstructionImpl::childTypeAllowed( unsigned short /*type*/ )
     return false;
 }
 
-void ProcessingInstructionImpl::checkStyleSheet()
+bool ProcessingInstructionImpl::checkStyleSheet()
 {
     if (m_target && DOMString(m_target) == "xml-stylesheet") {
         // see http://www.w3.org/TR/xml-stylesheet/
@@ -411,7 +411,7 @@ void ProcessingInstructionImpl::checkStyleSheet()
         bool attrsOk;
         const QMap<QString, QString> attrs = parseAttributes(m_data, attrsOk);
         if (!attrsOk)
-            return;
+            return true;
         QMap<QString, QString>::ConstIterator i = attrs.find("type");
         QString type;
         if (i != attrs.end())
@@ -425,7 +425,12 @@ void ProcessingInstructionImpl::checkStyleSheet()
 #else
         if (!isCSS)
 #endif
-            return;
+            return true;
+
+#ifdef KHTML_XSLT
+        if (m_isXSL)
+            getDocument()->tokenizer()->setTransformSource(getDocument());
+#endif
 
         i = attrs.find("href");
         QString href;
@@ -442,6 +447,9 @@ void ProcessingInstructionImpl::checkStyleSheet()
                 m_localHref = newLocalHref.implementation();
                 if (m_localHref)
                     m_localHref->ref();
+#ifdef KHTML_XSLT
+                return !m_isXSL;
+#endif
             }
             else
             {
@@ -459,11 +467,16 @@ void ProcessingInstructionImpl::checkStyleSheet()
                     m_cachedSheet = getDocument()->docLoader()->requestStyleSheet(getDocument()->completeURL(href), QString::null);
                    if (m_cachedSheet)
                        m_cachedSheet->ref( this );
+#ifdef KHTML_XSLT
+                    return !m_isXSL;
+#endif
                }
             }
 
         }
     }
+    
+    return true;
 }
 
 StyleSheetImpl* ProcessingInstructionImpl::sheet() const
index 6a0e8a3..3124485 100644 (file)
@@ -151,12 +151,16 @@ public:
     virtual DOMString localHref() const;
     virtual bool childTypeAllowed( unsigned short type );
     StyleSheetImpl *sheet() const;
-    void checkStyleSheet();
+    bool checkStyleSheet();
     virtual void setStyleSheet(const DOM::DOMString &url, const DOM::DOMString &sheet);
     virtual void setStyleSheet(CSSStyleSheetImpl* sheet);
     bool isLoading() const;
     void sheetLoaded();
 
+#ifdef KHTML_XSLT
+    bool isXSL() const { return m_isXSL; }
+#endif
+
     virtual DOMString toString() const;
     
 #if APPLE_CHANGES
index ef7aa1a..0dc9e50 100644 (file)
@@ -137,6 +137,10 @@ public:
     virtual void setOnHold(bool onHold);
     virtual bool isWaitingForScripts();
 
+#ifdef KHTML_XSLT
+    void setTransformSource(DocumentImpl* doc);
+#endif
+
     // from CachedObjectClient
     virtual void notifyFinished(CachedObject *finishedObj);
 
@@ -178,7 +182,8 @@ private:
 
     bool m_sawError;
     bool m_parserStopped;
-
+    bool m_sawXSLTransform;
+    
     int m_errorCount;
     int m_lastErrorLine;
     int m_lastErrorColumn;
@@ -191,15 +196,26 @@ private:
 
 // --------------------------------
 
-static xmlParserCtxtPtr createQStringParser(xmlSAXHandlerPtr handlers, void *userData)
+static int matchFunc(const char* URI)
+{
+    return 1; // Match everything.
+}
+
+static void* openFunc(const char * URI) {
+    return NULL; // Don't ever allow the open.
+}
+
+static xmlParserCtxtPtr createQStringParser(xmlSAXHandlerPtr handlers, void *userData, const char* uri = NULL)
 {
     static bool didInit = false;
     if (!didInit) {
         xmlInitParser();
+        xmlRegisterInputCallbacks(matchFunc, openFunc, NULL, NULL);
+        xmlRegisterOutputCallbacks(matchFunc, openFunc, NULL, NULL);
         didInit = true;
     }
 
-    xmlParserCtxtPtr parser = xmlCreatePushParserCtxt(handlers, userData, NULL, 0, NULL);
+    xmlParserCtxtPtr parser = xmlCreatePushParserCtxt(handlers, userData, NULL, 0, uri);
     const QChar BOM(0xFEFF);
     const unsigned char BOMHighByte = *reinterpret_cast<const unsigned char *>(&BOM);
     xmlSwitchEncoding(parser, BOMHighByte == 0xFF ? XML_CHAR_ENCODING_UTF16LE : XML_CHAR_ENCODING_UTF16BE);
@@ -431,7 +447,10 @@ void XMLTokenizer::processingInstruction(const xmlChar *target, const xmlChar *d
     m_currentNode->addChild(pi);
     // don't load stylesheets for standalone documents
     if (m_doc->document()->part()) {
-       pi->checkStyleSheet();
+       m_sawXSLTransform = !pi->checkStyleSheet();
+        if (m_sawXSLTransform)
+            // Stop the SAX parser.
+            stopParsing();
     }
 }
 
@@ -540,7 +559,8 @@ void XMLTokenizer::finish()
     sax.warning = warningHandler;
     m_parserStopped = false;
     m_sawError = false;
-    m_context = createQStringParser(&sax, this);
+    m_sawXSLTransform = false;
+    m_context = createQStringParser(&sax, this, m_doc->document()->URL().ascii());
     parseQString(m_context, m_xmlCode);
     xmlFreeParserCtxt(m_context);
     m_context = NULL;
@@ -672,6 +692,13 @@ bool XMLTokenizer::isWaitingForScripts()
     return m_cachedScript != 0;
 }
 
+#ifdef KHTML_XSLT
+void XMLTokenizer::setTransformSource(DocumentImpl* doc)
+{
+    doc->setTransformSource(m_xmlCode);
+}
+#endif
+
 Tokenizer *newXMLTokenizer(DocumentPtr *d, KHTMLView *v)
 {
     return new XMLTokenizer(d, v);
index 013afd8..1493a18 100644 (file)
@@ -36,6 +36,7 @@ class KHTMLView;
 
 namespace DOM {
     class DocumentPtr;
+    class DocumentImpl;
     class NodeImpl;
 };
 
@@ -57,6 +58,10 @@ public:
     virtual void setOnHold(bool onHold) = 0;
     virtual bool isWaitingForScripts() = 0;
 
+#ifdef KHTML_XSLT
+    virtual void setTransformSource(DOM::DocumentImpl* doc) {};
+#endif
+    
 signals:
     void finishedParsing();
 
similarity index 74%
rename from WebCore/khtml/xml/xsl_stylesheetimpl.cpp
rename to WebCore/khtml/xsl/xsl_stylesheetimpl.cpp
index d1fe0b2..7ee33b3 100644 (file)
@@ -40,7 +40,7 @@ XSLStyleSheetImpl::XSLStyleSheetImpl(XSLStyleSheetImpl *parentSheet, DOMString h
     : StyleSheetImpl(parentSheet, href)
 {
     m_lstChildren = new QPtrList<StyleBaseImpl>;
-    m_doc = parentSheet ? parentSheet->doc() : 0;
+    m_ownerDocument = parentSheet ? parentSheet->ownerDocument() : 0;
     parentSheet->append(this);
 }
 
@@ -48,11 +48,12 @@ XSLStyleSheetImpl::XSLStyleSheetImpl(NodeImpl *parentNode, DOMString href)
     : StyleSheetImpl(parentNode, href)
 {
     m_lstChildren = new QPtrList<StyleBaseImpl>;
-    m_doc = parentNode->getDocument();
+    m_ownerDocument = parentNode->getDocument();
 }
 
 XSLStyleSheetImpl::~XSLStyleSheetImpl()
 {
+    xmlFreeDoc(m_stylesheetDoc);
 }
 
 bool XSLStyleSheetImpl::isLoading()
@@ -80,14 +81,22 @@ void XSLStyleSheetImpl::checkLoaded()
 
 khtml::DocLoader* XSLStyleSheetImpl::docLoader()
 {
-    if (!m_doc)
+    if (!m_ownerDocument)
         return 0;
-    return m_doc->docLoader();
+    return m_ownerDocument->docLoader();
 }
 
 bool XSLStyleSheetImpl::parseString(const DOMString &string, bool strict)
 {
-    return false;
+    // Parse in a single chunk into an xmlDocPtr
+    const QChar BOM(0xFEFF);
+    const unsigned char BOMHighByte = *reinterpret_cast<const unsigned char *>(&BOM);
+    m_stylesheetDoc = xmlReadMemory(reinterpret_cast<const char *>(string.unicode()),
+                                    string.length() * sizeof(QChar),
+                                    m_ownerDocument->URL().ascii(),
+                                    BOMHighByte == 0xFF ? "UTF-16LE" : "UTF-16BE", 
+                                    XML_PARSE_NOCDATA|XML_PARSE_DTDATTR|XML_PARSE_NOENT);
+    return m_stylesheetDoc;
 }
 
 }
similarity index 83%
rename from WebCore/khtml/xml/xsl_stylesheetimpl.h
rename to WebCore/khtml/xsl/xsl_stylesheetimpl.h
index 1aaad38..1a956d8 100644 (file)
 
 #include "css/css_stylesheetimpl.h"
 
+#include <libxml/parser.h>
+#include <libxml/parserInternals.h>
+
+#include <libxslt/transform.h>
+
 namespace DOM {
 
 class XSLStyleSheetImpl : public StyleSheetImpl
@@ -44,10 +49,14 @@ public:
     virtual void checkLoaded();
     
     khtml::DocLoader *docLoader();
-    DocumentImpl *doc() { return m_doc; }
+    DocumentImpl* ownerDocument() { return m_ownerDocument; }
+
+    xmlDocPtr document() { return m_stylesheetDoc; }
+    void clearDocument() { m_stylesheetDoc = 0; }
 
 protected:
-    DocumentImpl *m_doc;
+    DocumentImpl* m_ownerDocument;
+    xmlDocPtr m_stylesheetDoc;
 };
 
 }
diff --git a/WebCore/khtml/xsl/xslt_processorimpl.cpp b/WebCore/khtml/xsl/xslt_processorimpl.cpp
new file mode 100644 (file)
index 0000000..9f7283e
--- /dev/null
@@ -0,0 +1,162 @@
+/**
+ * This file is part of the XSL implementation.
+ *
+ * Copyright (C) 2004 Apple Computer, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef KHTML_XSLT
+
+#include "xslt_processorimpl.h"
+#include "xsl_stylesheetimpl.h"
+#include "html_documentimpl.h"
+#include "loader.h"
+#include "khtmlview.h"
+#include "khtml_part.h"
+
+#include <libxslt/xsltutils.h>
+#include <libxslt/imports.h>
+
+using namespace khtml;
+using namespace DOM;
+
+namespace DOM {
+    
+XSLTProcessorImpl::XSLTProcessorImpl(XSLStyleSheetImpl* sheet, DocumentImpl* source, bool embedded)
+:m_stylesheet(sheet), m_sourceDocument(source)
+{
+    if (m_stylesheet)
+        m_stylesheet->ref();
+    if (m_sourceDocument)
+        m_sourceDocument->ref();
+    m_embedded = embedded;
+}
+
+XSLTProcessorImpl::~XSLTProcessorImpl()
+{
+    if (m_stylesheet)
+        m_stylesheet->deref();
+    if (m_sourceDocument)
+        m_sourceDocument->deref();
+}
+
+DocumentImpl* XSLTProcessorImpl::transformDocument(DocumentImpl* doc)
+{
+    // FIXME: Right now we assume |doc| is unparsed, but if it has been parsed we will need to serialize it
+    // and then feed that resulting source to libxslt.
+    m_resultOutput = "";
+
+    xsltStylesheetPtr sheet = NULL;
+    if (!m_embedded) {
+        if (!m_stylesheet || !m_stylesheet->document()) return 0;
+        sheet = xsltParseStylesheetDoc(m_stylesheet->document());
+        if (!sheet) return 0;
+        m_stylesheet->clearDocument();
+    }
+
+    // Parse in a single chunk into an xmlDocPtr
+    const QChar BOM(0xFEFF);
+    const unsigned char BOMHighByte = *reinterpret_cast<const unsigned char *>(&BOM);
+    xmlDocPtr sourceDoc = xmlReadMemory(reinterpret_cast<const char *>(doc->transformSource().unicode()),
+                  doc->transformSource().length() * sizeof(QChar),
+                  doc->URL().ascii(),
+                  BOMHighByte == 0xFF ? "UTF-16LE" : "UTF-16BE", 
+                  XML_PARSE_NOCDATA|XML_PARSE_DTDATTR|XML_PARSE_NOENT);
+    if (m_embedded)
+        // Attempt to obtain the stylesheet from within our parsed source document.
+        sheet = xsltLoadStylesheetPI(sourceDoc);
+
+    xmlDocPtr resultDoc = xsltApplyStylesheet(sheet, sourceDoc, NULL);
+    DocumentImpl* result = documentFromXMLDocPtr(resultDoc, sheet);
+    xsltFreeStylesheet(sheet);
+    xmlFreeDoc(sourceDoc);
+    return result;
+}
+
+static int bufferWrite(void* context, const char* buffer, int len)
+{
+    static_cast<XSLTProcessorImpl*>(context)->addToResult(buffer, len);
+    return len;
+}
+
+void XSLTProcessorImpl::addToResult(const char* buffer, int len)
+{
+    m_resultOutput += QString(buffer, len);
+}
+
+DocumentImpl* XSLTProcessorImpl::documentFromXMLDocPtr(xmlDocPtr resultDoc, xsltStylesheetPtr sheet)
+{
+    // FIXME: For now we serialize and then reparse.  It might be more optimal to write a DOM
+    // converter.
+    if (!resultDoc || !sheet) return 0;
+    DocumentImpl* result = 0;
+    xmlOutputBufferPtr outputBuf = xmlAllocOutputBuffer(NULL);
+    if (outputBuf) {
+        outputBuf->context = this;
+        outputBuf->writecallback = bufferWrite;
+        
+        if (xsltSaveResultTo(outputBuf, resultDoc, sheet) < 0)
+            return 0;
+        
+        // There are three types of output we need to be able to deal with:
+        // HTML (create an HTML document), XML (create an XML document), and text (wrap in a <pre> and
+        // make an XML document).
+        KHTMLView* view = m_sourceDocument->view();
+        const xmlChar* method;
+        XSLT_GET_IMPORT_PTR(method, sheet, method);
+        if (method == NULL && resultDoc->type == XML_HTML_DOCUMENT_NODE)
+            method = (const xmlChar*)"html";
+        if (xmlStrEqual(method, (const xmlChar*)"html"))
+            result = m_sourceDocument->implementation()->createHTMLDocument(view);
+        else
+            result = m_sourceDocument->implementation()->createDocument(view);
+        result->attach();
+        result->setURL(m_sourceDocument->URL());
+        result->setBaseURL(m_sourceDocument->baseURL());
+        result->setDecoder(m_sourceDocument->decoder()); // FIXME: Should just be UTF-16.
+        result->docLoader()->setShowAnimations(m_sourceDocument->docLoader()->showAnimations());
+        
+        if (xmlStrEqual(method, (const xmlChar*)"text")) {
+            // Modify the output so that it is a well-formed XHTML document with a <pre> tag enclosing
+            // the text.
+            QString beforeString("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/strict.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n<body>\n<pre>\n<![CDATA[");
+            QString afterString("]]>\n</pre>\n</body>\n</html>\n");
+            m_resultOutput = beforeString + m_resultOutput + afterString;
+        }
+        
+        // Before parsing, we need to detach the old document completely and get the new document
+        // in place.  We have to do this only if we're rendering the result document.
+        if (view) {
+            view->clear();
+            view->part()->replaceDocImpl(result);
+        }
+        
+        result->open();
+        result->determineParseMode(m_resultOutput); // Make sure we parse in the correct mode.
+        result->write(m_resultOutput);
+        result->finishParsing();
+        if (view)
+            view->part()->checkCompleted();
+        else
+            result->close(); // FIXME: Even viewless docs can load subresources. onload will fire too early.
+                             // This is probably a bug in XMLHttpRequestObjects as well.
+    }
+    return result;
+}
+
+}
+#endif
diff --git a/WebCore/khtml/xsl/xslt_processorimpl.h b/WebCore/khtml/xsl/xslt_processorimpl.h
new file mode 100644 (file)
index 0000000..0ec9914
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * This file is part of the XSL implementation.
+ *
+ * Copyright (C) 2004 Apple Computer, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _xslt_processorimpl_h_
+#define _xslt_processorimpl_h_
+
+#ifdef KHTML_XSLT
+
+#include <libxml/parser.h>
+#include <libxml/parserInternals.h>
+
+#include <libxslt/transform.h>
+
+#include <qstring.h>
+
+namespace DOM {
+
+class XSLStyleSheetImpl;
+class DocumentImpl;
+    
+class XSLTProcessorImpl
+{
+public:
+    // Constructors
+    XSLTProcessorImpl(XSLStyleSheetImpl* stylesheet, DocumentImpl* source, bool embedded = false);
+    ~XSLTProcessorImpl();
+    
+    // Method for transforming a source document into a result document.
+    DocumentImpl* transformDocument(DocumentImpl* sourceDoc);
+
+    // Convert a libxml doc ptr to a KHTML DOM Document
+    DocumentImpl* documentFromXMLDocPtr(xmlDocPtr resultDoc, xsltStylesheetPtr sheet);
+    
+    // Helpers
+    void addToResult(const char* buffer, int len);
+    
+protected:
+    XSLStyleSheetImpl* m_stylesheet;
+    QString m_resultOutput;
+    DocumentImpl* m_sourceDocument;
+    bool m_embedded;
+};
+
+}
+#endif
+#endif