Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1226)

Unified Diff: Source/core/xml/DocumentXSLT.cpp

Issue 730003002: Refactoring XSLT (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Fixed oilpan build Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: Source/core/xml/DocumentXSLT.cpp
diff --git a/Source/core/xml/DocumentXSLT.cpp b/Source/core/xml/DocumentXSLT.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b81cf148ef7d2a4215baf5ab2eb1ff46eacbc611
--- /dev/null
+++ b/Source/core/xml/DocumentXSLT.cpp
@@ -0,0 +1,169 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/xml/DocumentXSLT.h"
+
+#include "bindings/core/v8/DOMWrapperWorld.h"
+#include "bindings/core/v8/ScriptState.h"
+#include "bindings/core/v8/V8AbstractEventListener.h"
+#include "bindings/core/v8/V8Binding.h"
+#include "core/dom/Document.h"
+#include "core/dom/Node.h"
+#include "core/dom/ProcessingInstruction.h"
+#include "core/events/Event.h"
+#include "core/events/EventListener.h"
+#include "core/frame/UseCounter.h"
+#include "core/inspector/InspectorInstrumentation.h"
+#include "core/xml/XSLStyleSheet.h"
+#include "core/xml/XSLTProcessor.h"
+
+namespace blink {
+
+class DOMContentLoadedListener : public V8AbstractEventListener {
haraken 2014/11/19 09:01:36 Add final
tasak 2014/11/19 09:23:03 Done.
+public:
+ virtual bool operator==(const EventListener&)
+ {
+ return true;
+ }
+
+ virtual void handleEvent(ExecutionContext* context, Event* event)
+ {
+ ASSERT(event->type() == "DOMContentLoaded");
haraken 2014/11/19 09:01:36 Don't you need: if (!RuntimeEnabledFeatures::xs
tasak 2014/11/19 09:23:03 If disabled, we don't add this listener.
haraken 2014/11/19 09:33:59 Can we add an ASSERT?
tasak 2014/11/19 11:12:35 Done.
+ ScriptState::Scope scope(scriptState());
+
+ Document& document = *toDocument(context);
haraken 2014/11/19 09:01:35 Don't you need: if (document.parsing()) ret
tasak 2014/11/19 09:23:03 I think, in DOMContentLoaded, document has been al
haraken 2014/11/19 09:33:59 Can we add an ASSERT?
tasak 2014/11/19 11:12:35 Done.
+ // Processing instruction (XML documents only).
+ // We don't support linking to embedded CSS stylesheets,
+ // see <https://bugs.webkit.org/show_bug.cgi?id=49281> for discussion.
+ // Don't apply XSL transforms to already transformed documents.
+ if (DocumentXSLT::hasTransformSourceDocument(document))
+ return;
+
+ ProcessingInstruction* pi = DocumentXSLT::findXSLStyleSheet(document);
+ if (!pi || pi != m_processingInstruction.get() || pi->isLoading())
haraken 2014/11/19 09:01:35 .get() won't be needed.
tasak 2014/11/19 09:23:03 Done.
+ return;
+ DocumentXSLT::applyXSLTransform(document, pi);
+ }
+
+ static PassRefPtr<DOMContentLoadedListener> create(ScriptState* scriptState, ProcessingInstruction* pi)
+ {
+ return adoptRef(new DOMContentLoadedListener(scriptState, pi));
+ }
+
+private:
+ DOMContentLoadedListener(ScriptState* scriptState, ProcessingInstruction* pi)
+ : V8AbstractEventListener(false, scriptState)
+ , m_processingInstruction(pi)
+ {
+ }
+
+ virtual v8::Local<v8::Value> callListenerFunction(v8::Handle<v8::Value> jsevent, Event*)
+ {
+ ASSERT_NOT_REACHED();
+ return v8::Local<v8::Value>();
+ }
+
+ RefPtrWillBePersistent<ProcessingInstruction> m_processingInstruction;
+};
+
+DocumentXSLT::DocumentXSLT()
+ : m_transformSourceDocument(nullptr)
+{
+}
+
+PassRefPtr<EventListener> DocumentXSLT::addDOMContentLoadedListenerForXSLT(Document& document, ProcessingInstruction* pi)
+{
+ if (!RuntimeEnabledFeatures::xsltEnabled())
+ return nullptr;
+
+ if (!document.frame())
+ return nullptr;
+
+ ScriptState* scriptState = ScriptState::forMainWorld(document.frame());
+ RefPtr<EventListener> listener = DOMContentLoadedListener::create(scriptState, pi);
+ document.addEventListener(EventTypeNames::DOMContentLoaded, listener, false);
+ return listener;
haraken 2014/11/19 09:01:36 listener.release()
tasak 2014/11/19 09:23:03 Done.
+}
+
+void DocumentXSLT::applyXSLTransform(Document& document, ProcessingInstruction* pi)
+{
+ ASSERT(!pi->isLoading());
+ UseCounter::count(document, UseCounter::XSLProcessingInstruction);
+ RefPtrWillBeRawPtr<XSLTProcessor> processor = XSLTProcessor::create(document);
+ processor->setXSLStyleSheet(toXSLStyleSheet(pi->sheet()));
+ String resultMIMEType;
+ String newSource;
+ String resultEncoding;
+ document.setParsingState(Document::Parsing);
+ if (!processor->transformToString(&document, resultMIMEType, newSource, resultEncoding)) {
+ document.setParsingState(Document::FinishedParsing);
+ return;
+ }
+ // FIXME: If the transform failed we should probably report an error (like Mozilla does).
+ LocalFrame* ownerFrame = document.frame();
+ processor->createDocumentFromSource(newSource, resultEncoding, resultMIMEType, &document, ownerFrame);
+ InspectorInstrumentation::frameDocumentUpdated(ownerFrame);
+ document.setParsingState(Document::FinishedParsing);
+}
+
+ProcessingInstruction* DocumentXSLT::findXSLStyleSheet(Document& document)
+{
+ for (Node* node = document.firstChild(); node; node = node->nextSibling()) {
+ if (node->nodeType() != Node::PROCESSING_INSTRUCTION_NODE)
+ continue;
+
+ ProcessingInstruction* pi = toProcessingInstruction(node);
+ if (pi->isXSL())
+ return pi;
+ }
+ return 0;
+}
+
+void DocumentXSLT::sheetLoaded(Document& document, ProcessingInstruction* pi)
+{
+ if (!RuntimeEnabledFeatures::xsltEnabled())
+ return;
+
+ if (document.parsing() || pi->isLoading())
+ return;
+
+ if (DocumentXSLT::hasTransformSourceDocument(document))
+ return;
+
+ ProcessingInstruction* firstPi = findXSLStyleSheet(document);
+ ASSERT(firstPi);
+ if (firstPi != pi)
+ return;
+ applyXSLTransform(document, pi);
+}
+
+const char* DocumentXSLT::supplementName()
+{
+ return "DocumentXSLT";
+}
+
+bool DocumentXSLT::hasTransformSourceDocument(Document& document)
+{
+ return static_cast<DocumentXSLT*>(DocumentSupplement::from(document, supplementName()));
haraken 2014/11/19 09:01:35 What happens if there is a DocumentXSLT instance b
tasak 2014/11/19 09:23:03 Only XSLTProcessor uses DocumentXSLT::from and use
+}
+
+
+DocumentXSLT& DocumentXSLT::from(DocumentSupplementable& document)
+{
+ DocumentXSLT* supplement = static_cast<DocumentXSLT*>(DocumentSupplement::from(document, supplementName()));
+ if (!supplement) {
+ supplement = new DocumentXSLT();
+ DocumentSupplement::provideTo(document, supplementName(), adoptPtrWillBeNoop(supplement));
+ }
+ return *supplement;
+}
+
+void DocumentXSLT::trace(Visitor* visitor)
+{
+ visitor->trace(m_transformSourceDocument);
+ DocumentSupplement::trace(visitor);
+}
+
+} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698