xslt_processorimpl.cpp [plain text]
#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/documents.h>
#include <libxslt/imports.h>
using namespace khtml;
using namespace DOM;
namespace DOM {
XSLTProcessorImpl::XSLTProcessorImpl(XSLStyleSheetImpl* sheet, DocumentImpl* source)
:m_stylesheet(sheet), m_sourceDocument(source)
{
if (m_stylesheet)
m_stylesheet->ref();
if (m_sourceDocument)
m_sourceDocument->ref();
}
XSLTProcessorImpl::~XSLTProcessorImpl()
{
if (m_stylesheet)
m_stylesheet->deref();
if (m_sourceDocument)
m_sourceDocument->deref();
}
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;
if (!globalSheet)
return NULL;
return globalSheet->locateStylesheetSubResource(((xsltStylesheetPtr)ctxt)->doc, uri);
}
DocumentImpl* XSLTProcessorImpl::transformDocument(DocumentImpl* doc)
{
m_resultOutput = "";
if (!m_stylesheet || !m_stylesheet->document()) return 0;
globalSheet = m_stylesheet;
xsltSetLoaderFunc(stylesheetLoadFunc);
xsltStylesheetPtr sheet = m_stylesheet->compileStyleSheet();
globalSheet = 0;
xsltSetLoaderFunc(0);
if (!sheet) return 0;
m_stylesheet->clearDocuments();
xmlDocPtr sourceDoc = (xmlDocPtr)doc->transformSource();
xmlDocPtr resultDoc = xsltApplyStylesheet(sheet, sourceDoc, NULL);
DocumentImpl* result = documentFromXMLDocPtr(resultDoc, sheet);
xsltFreeStylesheet(sheet);
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)
{
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;
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()); result->docLoader()->setShowAnimations(m_sourceDocument->docLoader()->showAnimations());
result->setTransformSourceDocument(m_sourceDocument);
if (xmlStrEqual(method, (const xmlChar*)"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;
}
if (view) {
view->clear();
view->part()->replaceDocImpl(result);
}
result->open();
result->determineParseMode(m_resultOutput); result->write(m_resultOutput);
result->finishParsing();
if (view)
view->part()->checkCompleted();
else
result->close(); }
return result;
}
}
#endif