📄 xsltprocessor.cpp
字号:
/* * This file is part of the XSL implementation. * * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple, Inc. All rights reserved. * Copyright (C) 2005, 2006 Alexey Proskuryakov <ap@webkit.org> * * 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., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */#include "config.h"#if ENABLE(XSLT)#include "XSLTProcessor.h"#include "CString.h"#include "Console.h"#include "DOMImplementation.h"#include "DOMWindow.h"#include "DocLoader.h"#include "DocumentFragment.h"#include "Frame.h"#include "FrameLoader.h"#include "FrameView.h"#include "HTMLDocument.h"#include "HTMLTokenizer.h" // for parseHTMLDocumentFragment#include "Page.h"#include "ResourceError.h"#include "ResourceHandle.h"#include "ResourceRequest.h"#include "ResourceResponse.h"#include "Text.h"#include "TextResourceDecoder.h"#include "XMLTokenizer.h"#include "XSLTExtensions.h"#include "XSLTUnicodeSort.h"#include "loader.h"#include "markup.h"#include <libxslt/imports.h>#include <libxslt/variables.h>#include <libxslt/xsltutils.h>#include <wtf/Assertions.h>#include <wtf/Platform.h>#include <wtf/Vector.h>#if PLATFORM(MAC)#include "SoftLinking.h"#endif#if PLATFORM(MAC)SOFT_LINK_LIBRARY(libxslt);SOFT_LINK(libxslt, xsltFreeStylesheet, void, (xsltStylesheetPtr sheet), (sheet))SOFT_LINK(libxslt, xsltFreeTransformContext, void, (xsltTransformContextPtr ctxt), (ctxt))SOFT_LINK(libxslt, xsltNewTransformContext, xsltTransformContextPtr, (xsltStylesheetPtr style, xmlDocPtr doc), (style, doc))SOFT_LINK(libxslt, xsltApplyStylesheetUser, xmlDocPtr, (xsltStylesheetPtr style, xmlDocPtr doc, const char** params, const char* output, FILE* profile, xsltTransformContextPtr userCtxt), (style, doc, params, output, profile, userCtxt))SOFT_LINK(libxslt, xsltQuoteUserParams, int, (xsltTransformContextPtr ctxt, const char** params), (ctxt, params))SOFT_LINK(libxslt, xsltSetCtxtSortFunc, void, (xsltTransformContextPtr ctxt, xsltSortFunc handler), (ctxt, handler))SOFT_LINK(libxslt, xsltSetLoaderFunc, void, (xsltDocLoaderFunc f), (f))SOFT_LINK(libxslt, xsltSaveResultTo, int, (xmlOutputBufferPtr buf, xmlDocPtr result, xsltStylesheetPtr style), (buf, result, style))SOFT_LINK(libxslt, xsltNextImport, xsltStylesheetPtr, (xsltStylesheetPtr style), (style))#endifnamespace WebCore {void XSLTProcessor::genericErrorFunc(void*, const char*, ...){ // It would be nice to do something with this error message.} void XSLTProcessor::parseErrorFunc(void* userData, xmlError* error){ Console* console = static_cast<Console*>(userData); if (!console) return; MessageLevel level; switch (error->level) { case XML_ERR_NONE: level = TipMessageLevel; break; case XML_ERR_WARNING: level = WarningMessageLevel; break; case XML_ERR_ERROR: case XML_ERR_FATAL: default: level = ErrorMessageLevel; break; } console->addMessage(XMLMessageSource, level, error->message, error->line, error->file);}// FIXME: There seems to be no way to control the ctxt pointer for loading here, thus we have globals.static XSLTProcessor* globalProcessor = 0;static DocLoader* globalDocLoader = 0;static xmlDocPtr docLoaderFunc(const xmlChar* uri, xmlDictPtr, int options, void* ctxt, xsltLoadType type){ if (!globalProcessor) return 0; switch (type) { case XSLT_LOAD_DOCUMENT: { xsltTransformContextPtr context = (xsltTransformContextPtr)ctxt; xmlChar* base = xmlNodeGetBase(context->document->doc, context->node); KURL url(KURL(reinterpret_cast<const char*>(base)), reinterpret_cast<const char*>(uri)); xmlFree(base); ResourceError error; ResourceResponse response; Vector<char> data; bool requestAllowed = globalDocLoader->frame() && globalDocLoader->doc()->securityOrigin()->canRequest(url); if (requestAllowed) { globalDocLoader->frame()->loader()->loadResourceSynchronously(url, error, response, data); requestAllowed = globalDocLoader->doc()->securityOrigin()->canRequest(response.url()); } if (!requestAllowed) { data.clear(); globalDocLoader->printAccessDeniedMessage(url); } Console* console = 0; if (Frame* frame = globalProcessor->xslStylesheet()->ownerDocument()->frame()) console = frame->domWindow()->console(); xmlSetStructuredErrorFunc(console, XSLTProcessor::parseErrorFunc); xmlSetGenericErrorFunc(console, XSLTProcessor::genericErrorFunc); // We don't specify an encoding here. Neither Gecko nor WinIE respects // the encoding specified in the HTTP headers. xmlDocPtr doc = xmlReadMemory(data.data(), data.size(), (const char*)uri, 0, options); xmlSetStructuredErrorFunc(0, 0); xmlSetGenericErrorFunc(0, 0); return doc; } case XSLT_LOAD_STYLESHEET: return globalProcessor->xslStylesheet()->locateStylesheetSubResource(((xsltStylesheetPtr)ctxt)->doc, uri); default: break; } return 0;}static inline void setXSLTLoadCallBack(xsltDocLoaderFunc func, XSLTProcessor* processor, DocLoader* loader){ xsltSetLoaderFunc(func); globalProcessor = processor; globalDocLoader = loader;}static int writeToVector(void* context, const char* buffer, int len){ Vector<UChar>& resultOutput = *static_cast<Vector<UChar>*>(context); String decodedChunk = String::fromUTF8(buffer, len); resultOutput.append(decodedChunk.characters(), decodedChunk.length()); return len;}static bool saveResultToString(xmlDocPtr resultDoc, xsltStylesheetPtr sheet, String& resultString){ xmlOutputBufferPtr outputBuf = xmlAllocOutputBuffer(0); if (!outputBuf) return false; Vector<UChar> resultVector; outputBuf->context = &resultVector; outputBuf->writecallback = writeToVector; int retval = xsltSaveResultTo(outputBuf, resultDoc, sheet); xmlOutputBufferClose(outputBuf); if (retval < 0) return false; // Workaround for <http://bugzilla.gnome.org/show_bug.cgi?id=495668>: libxslt appends an extra line feed to the result. if (resultVector.size() > 0 && resultVector[resultVector.size() - 1] == '\n') resultVector.removeLast(); resultString = String::adopt(resultVector); return true;}static inline void transformTextStringToXHTMLDocumentString(String& text){ // Modify the output so that it is a well-formed XHTML document with a <pre> tag enclosing the text. text.replace('&', "&"); text.replace('<', "<"); text = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n" "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n" "<head><title/></head>\n" "<body>\n" "<pre>" + text + "</pre>\n" "</body>\n" "</html>\n";}static const char** xsltParamArrayFromParameterMap(XSLTProcessor::ParameterMap& parameters){ if (parameters.isEmpty()) return 0; const char** parameterArray = (const char**)fastMalloc(((parameters.size() * 2) + 1) * sizeof(char*)); XSLTProcessor::ParameterMap::iterator end = parameters.end(); unsigned index = 0; for (XSLTProcessor::ParameterMap::iterator it = parameters.begin(); it != end; ++it) { parameterArray[index++] = strdup(it->first.utf8().data()); parameterArray[index++] = strdup(it->second.utf8().data()); } parameterArray[index] = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -