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

Side by Side Diff: Source/core/xml/DocumentXSLT.cpp

Issue 730003002: Refactoring XSLT (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Fixed ASSERT crashes when xsltEnabled() returns false 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 unified diff | Download patch
« no previous file with comments | « Source/core/xml/DocumentXSLT.h ('k') | Source/core/xml/XSLTProcessor.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "config.h"
6 #include "core/xml/DocumentXSLT.h"
7
8 #include "bindings/core/v8/DOMWrapperWorld.h"
9 #include "bindings/core/v8/ScriptState.h"
10 #include "bindings/core/v8/V8AbstractEventListener.h"
11 #include "bindings/core/v8/V8Binding.h"
12 #include "core/dom/Document.h"
13 #include "core/dom/Node.h"
14 #include "core/dom/ProcessingInstruction.h"
15 #include "core/events/Event.h"
16 #include "core/events/EventListener.h"
17 #include "core/frame/UseCounter.h"
18 #include "core/inspector/InspectorInstrumentation.h"
19 #include "core/xml/XSLStyleSheet.h"
20 #include "core/xml/XSLTProcessor.h"
21
22 namespace blink {
23
24 class DOMContentLoadedListener final : public V8AbstractEventListener {
25 public:
26 virtual bool operator==(const EventListener&)
27 {
28 return true;
29 }
30
31 virtual void handleEvent(ExecutionContext* context, Event* event)
32 {
33 ASSERT(RuntimeEnabledFeatures::xsltEnabled());
34 ASSERT(event->type() == "DOMContentLoaded");
35 ScriptState::Scope scope(scriptState());
36
37 Document& document = *toDocument(context);
38 ASSERT(!document.parsing());
39
40 // Processing instruction (XML documents only).
41 // We don't support linking to embedded CSS stylesheets,
42 // see <https://bugs.webkit.org/show_bug.cgi?id=49281> for discussion.
43 // Don't apply XSL transforms to already transformed documents.
44 if (DocumentXSLT::hasTransformSourceDocument(document))
45 return;
46
47 ProcessingInstruction* pi = DocumentXSLT::findXSLStyleSheet(document);
48 if (!pi || pi != m_processingInstruction || pi->isLoading())
49 return;
50 DocumentXSLT::applyXSLTransform(document, pi);
51 }
52
53 static PassRefPtr<DOMContentLoadedListener> create(ScriptState* scriptState, ProcessingInstruction* pi)
54 {
55 return adoptRef(new DOMContentLoadedListener(scriptState, pi));
56 }
57
58 private:
59 DOMContentLoadedListener(ScriptState* scriptState, ProcessingInstruction* pi )
60 : V8AbstractEventListener(false, scriptState)
61 , m_processingInstruction(pi)
62 {
63 }
64
65 virtual v8::Local<v8::Value> callListenerFunction(v8::Handle<v8::Value> jsev ent, Event*)
66 {
67 ASSERT_NOT_REACHED();
68 return v8::Local<v8::Value>();
69 }
70
71 RefPtrWillBePersistent<ProcessingInstruction> m_processingInstruction;
72 };
73
74 DocumentXSLT::DocumentXSLT()
75 : m_transformSourceDocument(nullptr)
76 {
77 }
78
79 void DocumentXSLT::applyXSLTransform(Document& document, ProcessingInstruction* pi)
80 {
81 ASSERT(!pi->isLoading());
82 UseCounter::count(document, UseCounter::XSLProcessingInstruction);
83 RefPtrWillBeRawPtr<XSLTProcessor> processor = XSLTProcessor::create(document );
84 processor->setXSLStyleSheet(toXSLStyleSheet(pi->sheet()));
85 String resultMIMEType;
86 String newSource;
87 String resultEncoding;
88 document.setParsingState(Document::Parsing);
89 if (!processor->transformToString(&document, resultMIMEType, newSource, resu ltEncoding)) {
90 document.setParsingState(Document::FinishedParsing);
91 return;
92 }
93 // FIXME: If the transform failed we should probably report an error (like M ozilla does).
94 LocalFrame* ownerFrame = document.frame();
95 processor->createDocumentFromSource(newSource, resultEncoding, resultMIMETyp e, &document, ownerFrame);
96 InspectorInstrumentation::frameDocumentUpdated(ownerFrame);
97 document.setParsingState(Document::FinishedParsing);
98 }
99
100 ProcessingInstruction* DocumentXSLT::findXSLStyleSheet(Document& document)
101 {
102 for (Node* node = document.firstChild(); node; node = node->nextSibling()) {
103 if (node->nodeType() != Node::PROCESSING_INSTRUCTION_NODE)
104 continue;
105
106 ProcessingInstruction* pi = toProcessingInstruction(node);
107 if (pi->isXSL())
108 return pi;
109 }
110 return 0;
111 }
112
113 bool DocumentXSLT::processingInstructionInsertedIntoDocument(Document& document, ProcessingInstruction* pi)
114 {
115 if (!pi->isXSL())
116 return false;
117
118 if (!RuntimeEnabledFeatures::xsltEnabled() || !document.frame())
119 return true;
120
121 ScriptState* scriptState = ScriptState::forMainWorld(document.frame());
122 RefPtr<EventListener> listener = DOMContentLoadedListener::create(scriptStat e, pi);
123 document.addEventListener(EventTypeNames::DOMContentLoaded, listener, false) ;
124 ASSERT(!pi->eventListenerForXSLT());
125 pi->setEventListenerForXSLT(listener);
126 return true;
127 }
128
129 bool DocumentXSLT::processingInstructionRemovedFromDocument(Document& document, ProcessingInstruction* pi)
130 {
131 if (!pi->isXSL())
132 return false;
133
134 if (!pi->eventListenerForXSLT())
135 return true;
136
137 ASSERT(RuntimeEnabledFeatures::xsltEnabled());
138 document.removeEventListener(EventTypeNames::DOMContentLoaded, pi->eventList enerForXSLT(), false);
139 pi->clearEventListenerForXSLT();
140 return true;
141 }
142
143 bool DocumentXSLT::sheetLoaded(Document& document, ProcessingInstruction* pi)
144 {
145 if (!pi->isXSL())
146 return false;
147
148 if (RuntimeEnabledFeatures::xsltEnabled() && !document.parsing() && !pi->isL oading()
149 && !DocumentXSLT::hasTransformSourceDocument(document)) {
150 if (findXSLStyleSheet(document) == pi)
151 applyXSLTransform(document, pi);
152 }
153 return true;
154 }
155
156 const char* DocumentXSLT::supplementName()
157 {
158 return "DocumentXSLT";
159 }
160
161 bool DocumentXSLT::hasTransformSourceDocument(Document& document)
162 {
163 return static_cast<DocumentXSLT*>(DocumentSupplement::from(document, supplem entName()));
164 }
165
166
167 DocumentXSLT& DocumentXSLT::from(DocumentSupplementable& document)
168 {
169 DocumentXSLT* supplement = static_cast<DocumentXSLT*>(DocumentSupplement::fr om(document, supplementName()));
170 if (!supplement) {
171 supplement = new DocumentXSLT();
172 DocumentSupplement::provideTo(document, supplementName(), adoptPtrWillBe Noop(supplement));
173 }
174 return *supplement;
175 }
176
177 void DocumentXSLT::trace(Visitor* visitor)
178 {
179 visitor->trace(m_transformSourceDocument);
180 DocumentSupplement::trace(visitor);
181 }
182
183 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/xml/DocumentXSLT.h ('k') | Source/core/xml/XSLTProcessor.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698