Make XSLT imports/includes work. This code has to be turned off until the newer...
authorhyatt <hyatt@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 19 Aug 2004 22:50:30 +0000 (22:50 +0000)
committerhyatt <hyatt@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 19 Aug 2004 22:50:30 +0000 (22:50 +0000)
available.

        Reviewed by kocienda

        * khtml/css/css_ruleimpl.cpp:
        (CSSImportRuleImpl::init):
        * khtml/xml/dom_docimpl.cpp:
        (DocumentImpl::DocumentImpl):
        (DocumentImpl::~DocumentImpl):
        (DocumentImpl::applyXSLTransform):
        * khtml/xml/dom_docimpl.h:
        (DOM::DocumentImpl::setTransformSource):
        (DOM::DocumentImpl::transformSource):
        * khtml/xml/dom_xmlimpl.cpp:
        (DOM::ProcessingInstructionImpl::checkStyleSheet):
        * khtml/xml/xml_tokenizer.cpp:
        (khtml::matchFunc):
        (khtml::openFunc):
        (khtml::readFunc):
        (khtml::writeFunc):
        (khtml::createQStringParser):
        (khtml::XMLTokenizer::setTransformSource):
        * khtml/xsl/xsl_stylesheetimpl.cpp:
        (DOM::XSLStyleSheetImpl::XSLStyleSheetImpl):
        (DOM::XSLStyleSheetImpl::~XSLStyleSheetImpl):
        (DOM::XSLStyleSheetImpl::isLoading):
        (DOM::XSLStyleSheetImpl::clearDocuments):
        (DOM::XSLStyleSheetImpl::parseString):
        (DOM::XSLStyleSheetImpl::loadChildSheets):
        (DOM::XSLStyleSheetImpl::loadChildSheet):
        (DOM::XSLImportRuleImpl::parentStyleSheet):
        (DOM::XSLStyleSheetImpl::compileStyleSheet):
        (DOM::XSLStyleSheetImpl::locateStylesheetSubResource):
        (DOM::XSLImportRuleImpl::XSLImportRuleImpl):
        (DOM::XSLImportRuleImpl::~XSLImportRuleImpl):
        (DOM::XSLImportRuleImpl::setStyleSheet):
        (DOM::XSLImportRuleImpl::isLoading):
        (DOM::XSLImportRuleImpl::loadSheet):
        * khtml/xsl/xsl_stylesheetimpl.h:
        (DOM::XSLStyleSheetImpl::setOwnerDocument):
        (DOM::XSLStyleSheetImpl::setDocument):
        (DOM::XSLStyleSheetImpl::markAsProcessed):
        (DOM::XSLStyleSheetImpl::processed):
        (DOM::XSLImportRuleImpl::href):
        (DOM::XSLImportRuleImpl::styleSheet):
        (DOM::XSLImportRuleImpl::isImportRule):
        * khtml/xsl/xslt_processorimpl.cpp:
        (DOM::m_sourceDocument):
        (DOM::stylesheetLoadFunc):
        (DOM::XSLTProcessorImpl::transformDocument):
        * khtml/xsl/xslt_processorimpl.h:

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

WebCore/ChangeLog-2005-08-23
WebCore/khtml/css/css_ruleimpl.cpp
WebCore/khtml/xml/dom_docimpl.cpp
WebCore/khtml/xml/dom_docimpl.h
WebCore/khtml/xml/dom_xmlimpl.cpp
WebCore/khtml/xml/xml_tokenizer.cpp
WebCore/khtml/xsl/xsl_stylesheetimpl.cpp
WebCore/khtml/xsl/xsl_stylesheetimpl.h
WebCore/khtml/xsl/xslt_processorimpl.cpp
WebCore/khtml/xsl/xslt_processorimpl.h

index 2c261fc..a08c3fc 100644 (file)
@@ -1,3 +1,58 @@
+2004-08-19  David Hyatt  <hyatt@apple.com>
+
+       Make XSLT imports/includes work.  This code has to be turned off until the newer version of libxslt is
+       available.
+       
+        Reviewed by kocienda
+
+        * khtml/css/css_ruleimpl.cpp:
+        (CSSImportRuleImpl::init):
+        * khtml/xml/dom_docimpl.cpp:
+        (DocumentImpl::DocumentImpl):
+        (DocumentImpl::~DocumentImpl):
+        (DocumentImpl::applyXSLTransform):
+        * khtml/xml/dom_docimpl.h:
+        (DOM::DocumentImpl::setTransformSource):
+        (DOM::DocumentImpl::transformSource):
+        * khtml/xml/dom_xmlimpl.cpp:
+        (DOM::ProcessingInstructionImpl::checkStyleSheet):
+        * khtml/xml/xml_tokenizer.cpp:
+        (khtml::matchFunc):
+        (khtml::openFunc):
+        (khtml::readFunc):
+        (khtml::writeFunc):
+        (khtml::createQStringParser):
+        (khtml::XMLTokenizer::setTransformSource):
+        * khtml/xsl/xsl_stylesheetimpl.cpp:
+        (DOM::XSLStyleSheetImpl::XSLStyleSheetImpl):
+        (DOM::XSLStyleSheetImpl::~XSLStyleSheetImpl):
+        (DOM::XSLStyleSheetImpl::isLoading):
+        (DOM::XSLStyleSheetImpl::clearDocuments):
+        (DOM::XSLStyleSheetImpl::parseString):
+        (DOM::XSLStyleSheetImpl::loadChildSheets):
+        (DOM::XSLStyleSheetImpl::loadChildSheet):
+        (DOM::XSLImportRuleImpl::parentStyleSheet):
+        (DOM::XSLStyleSheetImpl::compileStyleSheet):
+        (DOM::XSLStyleSheetImpl::locateStylesheetSubResource):
+        (DOM::XSLImportRuleImpl::XSLImportRuleImpl):
+        (DOM::XSLImportRuleImpl::~XSLImportRuleImpl):
+        (DOM::XSLImportRuleImpl::setStyleSheet):
+        (DOM::XSLImportRuleImpl::isLoading):
+        (DOM::XSLImportRuleImpl::loadSheet):
+        * khtml/xsl/xsl_stylesheetimpl.h:
+        (DOM::XSLStyleSheetImpl::setOwnerDocument):
+        (DOM::XSLStyleSheetImpl::setDocument):
+        (DOM::XSLStyleSheetImpl::markAsProcessed):
+        (DOM::XSLStyleSheetImpl::processed):
+        (DOM::XSLImportRuleImpl::href):
+        (DOM::XSLImportRuleImpl::styleSheet):
+        (DOM::XSLImportRuleImpl::isImportRule):
+        * khtml/xsl/xslt_processorimpl.cpp:
+        (DOM::m_sourceDocument):
+        (DOM::stylesheetLoadFunc):
+        (DOM::XSLTProcessorImpl::transformDocument):
+        * khtml/xsl/xslt_processorimpl.h:
+
 === Safari-158 ===
 
 2004-08-18  Trey Matteson  <trey@apple.com>
index 918cb34..8912a30 100644 (file)
@@ -195,7 +195,7 @@ void CSSImportRuleImpl::init()
       // loaded (even if our subresources haven't), so if we have stylesheet after
       // checking the cache, then we've clearly loaded. -dwh
       if (!m_styleSheet)
-      m_loading = true;
+          m_loading = true;
     }
 }
 
index e0b053b..dd27757 100644 (file)
@@ -252,6 +252,7 @@ DocumentImpl::DocumentImpl(DOMImplementationImpl *_implementation, KHTMLView *v)
       , m_bindingManager(new XBLBindingManager(this))
 #endif
 #ifdef KHTML_XSLT
+    , m_transformSource(NULL)
     , m_transformSourceDocument(0)
 #endif
 #if APPLE_CHANGES
@@ -390,6 +391,7 @@ DocumentImpl::~DocumentImpl()
     }
 
 #ifdef KHTML_XSLT
+    xmlFreeDoc((xmlDocPtr)m_transformSource);
     if (m_transformSourceDocument)
         m_transformSourceDocument->deref();
 #endif
@@ -3062,7 +3064,7 @@ void DocumentImpl::shiftMarkers(NodeImpl *node, ulong startOffset, long delta)
 void DocumentImpl::applyXSLTransform(ProcessingInstructionImpl* pi)
 {
     // Ref ourselves to keep from being destroyed.
-    XSLTProcessorImpl processor(static_cast<XSLStyleSheetImpl*>(pi->sheet()), this, !pi->localHref().isEmpty());
+    XSLTProcessorImpl processor(static_cast<XSLStyleSheetImpl*>(pi->sheet()), this);
     DocumentImpl* result = processor.transformDocument(this);
     if (result)
         // Cache the source document.
index cb509ab..a444b77 100644 (file)
@@ -559,8 +559,8 @@ public:
 
 #ifdef KHTML_XSLT
     void applyXSLTransform(ProcessingInstructionImpl* pi);
-    void setTransformSource(const QString& xmlSource) { m_transformSource = xmlSource; }
-    const QString& transformSource() { return m_transformSource; }
+    void setTransformSource(void* doc) { m_transformSource = doc; }
+    const void* transformSource() { return m_transformSource; }
     DocumentImpl* transformSourceDocument() { return m_transformSourceDocument; }
     void setTransformSourceDocument(DocumentImpl* doc);
 #endif
@@ -674,7 +674,7 @@ protected:
     bool m_overMinimumLayoutThreshold;
     
 #ifdef KHTML_XSLT
-    QString m_transformSource;
+    void* m_transformSource;
     DocumentImpl* m_transformSourceDocument;
 #endif
 
index 260d4c6..79cb2cf 100644 (file)
@@ -448,6 +448,18 @@ bool ProcessingInstructionImpl::checkStyleSheet()
                 if (m_localHref)
                     m_localHref->ref();
 #ifdef KHTML_XSLT
+                // We need to make a synthetic XSLStyleSheetImpl that is embedded.  It needs to be able
+                // to kick off import/include loads that can hang off some parent sheet.
+                if (m_isXSL) {
+                    if (m_sheet)
+                        m_sheet->deref();
+                    XSLStyleSheetImpl* localSheet = new XSLStyleSheetImpl(this, m_localHref, true);
+                    localSheet->setDocument((xmlDocPtr)getDocument()->transformSource());
+                    localSheet->ref();
+                    localSheet->loadChildSheets();
+                    m_sheet = localSheet;
+                    m_loading = false;
+                }                    
                 return !m_isXSL;
 #endif
             }
index 0dc9e50..e87a460 100644 (file)
@@ -196,13 +196,27 @@ private:
 
 // --------------------------------
 
-static int matchFunc(const char* URI)
+static int globalDescriptor = 0;
+
+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 void* openFunc(const char * uri) {
+    return &globalDescriptor;
+}
+
+static int readFunc(void* context, char* buffer, int len)
+{
+    // Always just do 0-byte reads
+    return 0;
+}
+
+static int writeFunc(void* context, const char* buffer, int len)
+{
+    // Always just do 0-byte writes
+    return 0;
 }
 
 static xmlParserCtxtPtr createQStringParser(xmlSAXHandlerPtr handlers, void *userData, const char* uri = NULL)
@@ -210,8 +224,8 @@ static xmlParserCtxtPtr createQStringParser(xmlSAXHandlerPtr handlers, void *use
     static bool didInit = false;
     if (!didInit) {
         xmlInitParser();
-        xmlRegisterInputCallbacks(matchFunc, openFunc, NULL, NULL);
-        xmlRegisterOutputCallbacks(matchFunc, openFunc, NULL, NULL);
+        xmlRegisterInputCallbacks(matchFunc, openFunc, readFunc, NULL);
+        xmlRegisterOutputCallbacks(matchFunc, openFunc, writeFunc, NULL);
         didInit = true;
     }
 
@@ -695,7 +709,18 @@ bool XMLTokenizer::isWaitingForScripts()
 #ifdef KHTML_XSLT
 void XMLTokenizer::setTransformSource(DocumentImpl* doc)
 {
-    doc->setTransformSource(m_xmlCode);
+    // Time to spin up a new parse and save the xmlDocPtr.
+    // Parse in a single chunk into an xmlDocPtr
+    // FIXME: Hook up error handlers so that a failure to parse the main document results in
+    // good error messages.
+    const QChar BOM(0xFEFF);
+    const unsigned char BOMHighByte = *reinterpret_cast<const unsigned char *>(&BOM);
+    xmlDocPtr sourceDoc = xmlReadMemory(reinterpret_cast<const char *>(m_xmlCode.unicode()),
+                                        m_xmlCode.length() * sizeof(QChar),
+                                        doc->URL().ascii(),
+                                        BOMHighByte == 0xFF ? "UTF-16LE" : "UTF-16BE", 
+                                        XML_PARSE_NOCDATA|XML_PARSE_DTDATTR|XML_PARSE_NOENT);
+    doc->setTransformSource(sourceDoc);
 }
 #endif
 
index 7ee33b3..80b43da 100644 (file)
 
 #include <kdebug.h>
 
+#include <libxslt/xsltutils.h>
+#include <libxml/uri.h>
+
+#define IS_BLANK_NODE(n)                                                \
+    (((n)->type == XML_TEXT_NODE) && (xsltIsBlank((n)->content)))
+
 using namespace khtml;
 using namespace DOM;
 
 namespace DOM {
     
-XSLStyleSheetImpl::XSLStyleSheetImpl(XSLStyleSheetImpl *parentSheet, DOMString href)
-    : StyleSheetImpl(parentSheet, href)
+XSLStyleSheetImpl::XSLStyleSheetImpl(XSLImportRuleImpl *parentRule, DOMString href)
+    : StyleSheetImpl(parentRule, href)
 {
     m_lstChildren = new QPtrList<StyleBaseImpl>;
-    m_ownerDocument = parentSheet ? parentSheet->ownerDocument() : 0;
-    parentSheet->append(this);
+    m_ownerDocument = 0;
+    m_processed = false; // Child sheets get marked as processed when the libxslt engine has finally seen them.
 }
 
-XSLStyleSheetImpl::XSLStyleSheetImpl(NodeImpl *parentNode, DOMString href)
+XSLStyleSheetImpl::XSLStyleSheetImpl(NodeImpl *parentNode, DOMString href,  bool embedded)
     : StyleSheetImpl(parentNode, href)
 {
     m_lstChildren = new QPtrList<StyleBaseImpl>;
     m_ownerDocument = parentNode->getDocument();
+    m_embedded = embedded;
+    m_processed = true; // The root sheet starts off processed.
 }
 
 XSLStyleSheetImpl::~XSLStyleSheetImpl()
 {
-    xmlFreeDoc(m_stylesheetDoc);
+    if (!m_embedded)
+        xmlFreeDoc(m_stylesheetDoc);
 }
 
 bool XSLStyleSheetImpl::isLoading()
 {
-    StyleBaseImpl* sheet;
-    for (sheet = m_lstChildren->first(); sheet; sheet = m_lstChildren->next()) {
-        if (sheet->isXSLStyleSheet()) {
-            XSLStyleSheetImpl* import = static_cast<XSLStyleSheetImpl*>(import);
+    for (StyleBaseImpl* rule = m_lstChildren->first(); rule; rule = m_lstChildren->next()) {
+        if (rule->isImportRule()) {
+            XSLImportRuleImpl* import = static_cast<XSLImportRuleImpl*>(rule);
             if (import->isLoading())
                 return true;
         }
@@ -79,6 +87,18 @@ void XSLStyleSheetImpl::checkLoaded()
         m_parentNode->sheetLoaded();
 }
 
+void XSLStyleSheetImpl::clearDocuments()
+{
+    m_stylesheetDoc = 0;
+    for (StyleBaseImpl* rule = m_lstChildren->first(); rule; rule = m_lstChildren->next()) {
+        if (rule->isImportRule()) {
+            XSLImportRuleImpl* import = static_cast<XSLImportRuleImpl*>(rule);
+            if (import->styleSheet())
+                import->styleSheet()->clearDocuments();
+        }
+    }
+}
+
 khtml::DocLoader* XSLStyleSheetImpl::docLoader()
 {
     if (!m_ownerDocument)
@@ -96,8 +116,194 @@ bool XSLStyleSheetImpl::parseString(const DOMString &string, bool strict)
                                     m_ownerDocument->URL().ascii(),
                                     BOMHighByte == 0xFF ? "UTF-16LE" : "UTF-16BE", 
                                     XML_PARSE_NOCDATA|XML_PARSE_DTDATTR|XML_PARSE_NOENT);
+    loadChildSheets();
     return m_stylesheetDoc;
 }
 
+void XSLStyleSheetImpl::loadChildSheets()
+{
+    if (!m_stylesheetDoc)
+        return;
+    
+    xmlNodePtr stylesheetRoot = m_stylesheetDoc->children;
+    if (m_embedded) {
+        // We have to locate (by ID) the appropriate embedded stylesheet element, so that we can walk the 
+        // import/include list.
+        xmlAttrPtr idNode = xmlGetID(m_stylesheetDoc, (const xmlChar*)(const char*)(href().string().utf8()));
+        if (idNode == NULL)
+            return;
+        stylesheetRoot = idNode->parent;
+    } else {
+        // FIXME: Need to handle an external URI with a # in it.  This is a pretty minor edge case, so we'll deal
+        // with it later.
+    }
+    
+    if (stylesheetRoot) {
+        // Walk the children of the root element and look for import/include elements.
+        // Imports must occur first.
+        xmlNodePtr curr = stylesheetRoot->children;
+        while (curr) {
+            if (IS_BLANK_NODE(curr)) {
+                curr = curr->next;
+                continue;
+            }
+            if (IS_XSLT_ELEM(curr) && IS_XSLT_NAME(curr, "import")) {
+                xmlChar* uriRef = xsltGetNsProp(curr, (const xmlChar *)"href", XSLT_NAMESPACE);
+                QString buff = QString::fromUtf8((const char*)uriRef);
+                loadChildSheet(buff);
+            } else
+                break;
+            curr = curr->next;
+        }
+
+        // Now handle includes.
+        while (curr) {
+            if (IS_XSLT_ELEM(curr) && IS_XSLT_NAME(curr, "include")) {
+                xmlChar* uriRef = xsltGetNsProp(curr, (const xmlChar *)"href", XSLT_NAMESPACE);
+                QString buff = QString::fromUtf8((const char*)uriRef);
+                loadChildSheet(buff);
+            }
+            curr = curr->next;
+        }
+    }
+}
+
+void XSLStyleSheetImpl::loadChildSheet(const QString& href)
+{
+    XSLImportRuleImpl* childRule = new XSLImportRuleImpl(this, href);
+    m_lstChildren->append(childRule);
+    childRule->loadSheet();
+}
+
+XSLStyleSheetImpl* XSLImportRuleImpl::parentStyleSheet() const
+{
+    return (m_parent && m_parent->isXSLStyleSheet()) ? static_cast<XSLStyleSheetImpl*>(m_parent) : 0;
+}
+
+xsltStylesheetPtr XSLStyleSheetImpl::compileStyleSheet()
+{
+    // FIXME: Hook up error reporting for the stylesheet compilation process.
+    if (m_embedded)
+        return xsltLoadStylesheetPI(m_stylesheetDoc);
+    else
+        return xsltParseStylesheetDoc(m_stylesheetDoc);
+}
+
+xmlDocPtr XSLStyleSheetImpl::locateStylesheetSubResource(xmlDocPtr parentDoc, const xmlChar* uri)
+{
+    bool matchedParent = (parentDoc == m_stylesheetDoc);
+    for (StyleBaseImpl* rule = m_lstChildren->first(); rule; rule = m_lstChildren->next()) {
+        if (rule->isImportRule()) {
+            XSLImportRuleImpl* import = static_cast<XSLImportRuleImpl*>(rule);
+            XSLStyleSheetImpl* child = import->styleSheet();
+            if (!child) continue;
+            if (matchedParent) {
+                if (child->processed()) continue; // libxslt has been given this sheet already.
+                
+                // Check the URI of the child stylesheet against the doc URI.
+                // In order to ensure that libxml canonicalized both URLs, we get the original href
+                // string from the import rule and canonicalize it using libxml before comparing it
+                // with the URI argument.
+                QCString importHref = import->href().string().utf8();
+                xmlChar* base = xmlNodeGetBase(parentDoc, (xmlNodePtr)parentDoc);
+                xmlChar* childURI = xmlBuildURI((const xmlChar*)(const char*)importHref, base);
+                if (xmlStrEqual(uri, childURI)) {
+                    child->markAsProcessed();
+                    return child->document();
+                }
+            }
+            else {
+                xmlDocPtr result = import->styleSheet()->locateStylesheetSubResource(parentDoc, uri);
+                if (result)
+                    return result;
+            }
+        }
+    }
+    
+    return NULL;
+}
+
+// ----------------------------------------------------------------------------------------------
+
+XSLImportRuleImpl::XSLImportRuleImpl(StyleBaseImpl* parent, const DOMString &href)
+: StyleBaseImpl(parent)
+{
+    m_strHref = href;
+    m_styleSheet = 0;
+    m_cachedSheet = 0;
+    m_loading = false;
+}
+
+XSLImportRuleImpl::~XSLImportRuleImpl()
+{
+    if (m_styleSheet) {
+        m_styleSheet->setParent(0);
+        m_styleSheet->deref();
+    }
+    
+    if (m_cachedSheet)
+        m_cachedSheet->deref(this);
+}
+
+void XSLImportRuleImpl::setStyleSheet(const DOMString& url, const DOMString& sheet)
+{
+    if (m_styleSheet) {
+        m_styleSheet->setParent(0);
+        m_styleSheet->deref();
+    }
+    m_styleSheet = new XSLStyleSheetImpl(this, url);
+    m_styleSheet->ref();
+    
+    XSLStyleSheetImpl* parent = parentStyleSheet();
+    if (parent)
+        m_styleSheet->setOwnerDocument(parent->ownerDocument());
+
+    m_styleSheet->parseString(sheet);
+    m_loading = false;
+    
+    checkLoaded();
+}
+
+bool XSLImportRuleImpl::isLoading()
+{
+    return (m_loading || (m_styleSheet && m_styleSheet->isLoading()));
+}
+
+void XSLImportRuleImpl::loadSheet()
+{
+    DocLoader* docLoader = 0;
+    StyleBaseImpl* root = this;
+    StyleBaseImpl* parent;
+    while ((parent = root->parent()))
+       root = parent;
+    if (root->isXSLStyleSheet())
+       docLoader = static_cast<XSLStyleSheetImpl*>(root)->docLoader();
+    
+    DOMString absHref = m_strHref;
+    XSLStyleSheetImpl* parentSheet = parentStyleSheet();
+    if (!parentSheet->href().isNull())
+        // use parent styleheet's URL as the base URL
+        absHref = KURL(parentSheet->href().string(),m_strHref.string()).url();
+    
+    // Check for a cycle in our import chain.  If we encounter a stylesheet
+    // in our parent chain with the same URL, then just bail.
+    for (parent = static_cast<StyleBaseImpl*>(this)->parent(); parent; parent = parent->parent())
+        if (absHref == parent->baseURL())
+            return;
+    
+    m_cachedSheet = docLoader->requestXSLStyleSheet(absHref);
+    
+    if (m_cachedSheet) {
+        m_cachedSheet->ref(this);
+        
+        // If the imported sheet is in the cache, then setStyleSheet gets called,
+        // and the sheet even gets parsed (via parseString).  In this case we have
+        // loaded (even if our subresources haven't), so if we have a stylesheet after
+        // checking the cache, then we've clearly loaded.
+        if (!m_styleSheet)
+            m_loading = true;
+    }
+}
+
 }
 #endif
index 1a956d8..d20a450 100644 (file)
@@ -25,6 +25,7 @@
 #ifdef KHTML_XSLT
 
 #include "css/css_stylesheetimpl.h"
+#include "misc/loader.h"
 
 #include <libxml/parser.h>
 #include <libxml/parserInternals.h>
 
 namespace DOM {
 
+class XSLImportRuleImpl;
+    
 class XSLStyleSheetImpl : public StyleSheetImpl
 {
 public:
-    XSLStyleSheetImpl(DOM::NodeImpl *parentNode, DOM::DOMString href = DOMString());
-    XSLStyleSheetImpl(XSLStyleSheetImpl *parentSheet, DOM::DOMString href = DOMString());
+    XSLStyleSheetImpl(DOM::NodeImpl *parentNode, DOM::DOMString href = DOMString(), bool embedded = false);
+    XSLStyleSheetImpl(XSLImportRuleImpl* parentImport, DOM::DOMString href = DOMString());
     ~XSLStyleSheetImpl();
     
     virtual bool isXSLStyleSheet() const { return true; }
+
     virtual DOM::DOMString type() const { return "text/xml"; }
 
     virtual bool parseString(const DOMString &string, bool strict = true);
     
     virtual bool isLoading();
     virtual void checkLoaded();
-    
+
+    void loadChildSheets();
+    void loadChildSheet(const QString& href);
+
+    xsltStylesheetPtr compileStyleSheet();
+
     khtml::DocLoader *docLoader();
+
     DocumentImpl* ownerDocument() { return m_ownerDocument; }
+    void setOwnerDocument(DocumentImpl* doc) { m_ownerDocument = doc; }
 
     xmlDocPtr document() { return m_stylesheetDoc; }
-    void clearDocument() { m_stylesheetDoc = 0; }
+    void setDocument(xmlDocPtr doc) { m_stylesheetDoc = doc; }
+
+    void clearDocuments();
+
+    xmlDocPtr locateStylesheetSubResource(xmlDocPtr parentDoc, const xmlChar* uri);
+    
+    void markAsProcessed() { m_processed = true; }
+    bool processed() const { return m_processed; }
 
 protected:
     DocumentImpl* m_ownerDocument;
     xmlDocPtr m_stylesheetDoc;
+    bool m_embedded;
+    bool m_processed;
+};
+
+class XSLImportRuleImpl : public khtml::CachedObjectClient, public StyleBaseImpl
+{
+public:
+    XSLImportRuleImpl( StyleBaseImpl *parent, const DOM::DOMString &href);
+    virtual ~XSLImportRuleImpl();
+    
+    DOM::DOMString href() const { return m_strHref; }
+    XSLStyleSheetImpl* styleSheet() const { return m_styleSheet; }
+    
+    virtual bool isImportRule() { return true; }
+    XSLStyleSheetImpl* parentStyleSheet() const;
+    
+    // from CachedObjectClient
+    virtual void setStyleSheet(const DOM::DOMString &url, const DOM::DOMString &sheet);
+    
+    bool isLoading();
+    void loadSheet();
+    
+protected:
+    DOMString m_strHref;
+    XSLStyleSheetImpl* m_styleSheet;
+    khtml::CachedXSLStyleSheet* m_cachedSheet;
+    bool m_loading;
 };
 
 }
index 9f7283e..089af76 100644 (file)
@@ -29,6 +29,7 @@
 #include "khtml_part.h"
 
 #include <libxslt/xsltutils.h>
+#include <libxslt/documents.h>
 #include <libxslt/imports.h>
 
 using namespace khtml;
@@ -36,14 +37,13 @@ using namespace DOM;
 
 namespace DOM {
     
-XSLTProcessorImpl::XSLTProcessorImpl(XSLStyleSheetImpl* sheet, DocumentImpl* source, bool embedded)
+XSLTProcessorImpl::XSLTProcessorImpl(XSLStyleSheetImpl* sheet, DocumentImpl* source)
 :m_stylesheet(sheet), m_sourceDocument(source)
 {
     if (m_stylesheet)
         m_stylesheet->ref();
     if (m_sourceDocument)
         m_sourceDocument->ref();
-    m_embedded = embedded;
 }
 
 XSLTProcessorImpl::~XSLTProcessorImpl()
@@ -54,36 +54,51 @@ XSLTProcessorImpl::~XSLTProcessorImpl()
         m_sourceDocument->deref();
 }
 
+#ifdef NOT_YET_READY
+static XSLStyleSheetImpl* globalSheet = 0;
+static xmlDocPtr stylesheetLoadFunc(const xmlChar* uri,
+                                    xmlDictPtr dict,
+                                    int options,
+                                    void* ctxt,
+                                    xsltLoadType type)
+{
+    if (type != XSLT_LOAD_STYLESHEET)
+        return NULL; // FIXME: Add support for XSLT_LOAD_DOCUMENT for the document() function.
+    
+    if (!globalSheet)
+        return NULL;
+    return globalSheet->locateStylesheetSubResource(((xsltStylesheetPtr)ctxt)->doc, uri);
+}
+#endif
+
 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();
-    }
+    if (!m_stylesheet || !m_stylesheet->document()) return 0;
+        
+#ifdef NOT_YET_READY
+    globalSheet = m_stylesheet;
+    xsltSetLoaderFunc(stylesheetLoadFunc);
+#endif
 
-    // 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);
+    xsltStylesheetPtr sheet = m_stylesheet->compileStyleSheet();
+
+#ifdef NOT_YET_READY
+    globalSheet = 0;
+    xsltSetLoaderFunc(0);
+#endif
 
+    if (!sheet) return 0;
+    m_stylesheet->clearDocuments();
+  
+    // Get the parsed source document.
+    xmlDocPtr sourceDoc = (xmlDocPtr)doc->transformSource();
     xmlDocPtr resultDoc = xsltApplyStylesheet(sheet, sourceDoc, NULL);
     DocumentImpl* result = documentFromXMLDocPtr(resultDoc, sheet);
     xsltFreeStylesheet(sheet);
-    xmlFreeDoc(sourceDoc);
     return result;
 }
 
index 0ec9914..4498d89 100644 (file)
@@ -41,7 +41,7 @@ class XSLTProcessorImpl
 {
 public:
     // Constructors
-    XSLTProcessorImpl(XSLStyleSheetImpl* stylesheet, DocumentImpl* source, bool embedded = false);
+    XSLTProcessorImpl(XSLStyleSheetImpl* stylesheet, DocumentImpl* source);
     ~XSLTProcessorImpl();
     
     // Method for transforming a source document into a result document.
@@ -57,7 +57,6 @@ protected:
     XSLStyleSheetImpl* m_stylesheet;
     QString m_resultOutput;
     DocumentImpl* m_sourceDocument;
-    bool m_embedded;
 };
 
 }