OLD | NEW |
---|---|
(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 : public V8AbstractEventListener { | |
haraken
2014/11/19 09:01:36
Add final
tasak
2014/11/19 09:23:03
Done.
| |
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(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.
| |
34 ScriptState::Scope scope(scriptState()); | |
35 | |
36 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.
| |
37 // Processing instruction (XML documents only). | |
38 // We don't support linking to embedded CSS stylesheets, | |
39 // see <https://bugs.webkit.org/show_bug.cgi?id=49281> for discussion. | |
40 // Don't apply XSL transforms to already transformed documents. | |
41 if (DocumentXSLT::hasTransformSourceDocument(document)) | |
42 return; | |
43 | |
44 ProcessingInstruction* pi = DocumentXSLT::findXSLStyleSheet(document); | |
45 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.
| |
46 return; | |
47 DocumentXSLT::applyXSLTransform(document, pi); | |
48 } | |
49 | |
50 static PassRefPtr<DOMContentLoadedListener> create(ScriptState* scriptState, ProcessingInstruction* pi) | |
51 { | |
52 return adoptRef(new DOMContentLoadedListener(scriptState, pi)); | |
53 } | |
54 | |
55 private: | |
56 DOMContentLoadedListener(ScriptState* scriptState, ProcessingInstruction* pi ) | |
57 : V8AbstractEventListener(false, scriptState) | |
58 , m_processingInstruction(pi) | |
59 { | |
60 } | |
61 | |
62 virtual v8::Local<v8::Value> callListenerFunction(v8::Handle<v8::Value> jsev ent, Event*) | |
63 { | |
64 ASSERT_NOT_REACHED(); | |
65 return v8::Local<v8::Value>(); | |
66 } | |
67 | |
68 RefPtrWillBePersistent<ProcessingInstruction> m_processingInstruction; | |
69 }; | |
70 | |
71 DocumentXSLT::DocumentXSLT() | |
72 : m_transformSourceDocument(nullptr) | |
73 { | |
74 } | |
75 | |
76 PassRefPtr<EventListener> DocumentXSLT::addDOMContentLoadedListenerForXSLT(Docum ent& document, ProcessingInstruction* pi) | |
77 { | |
78 if (!RuntimeEnabledFeatures::xsltEnabled()) | |
79 return nullptr; | |
80 | |
81 if (!document.frame()) | |
82 return nullptr; | |
83 | |
84 ScriptState* scriptState = ScriptState::forMainWorld(document.frame()); | |
85 RefPtr<EventListener> listener = DOMContentLoadedListener::create(scriptStat e, pi); | |
86 document.addEventListener(EventTypeNames::DOMContentLoaded, listener, false) ; | |
87 return listener; | |
haraken
2014/11/19 09:01:36
listener.release()
tasak
2014/11/19 09:23:03
Done.
| |
88 } | |
89 | |
90 void DocumentXSLT::applyXSLTransform(Document& document, ProcessingInstruction* pi) | |
91 { | |
92 ASSERT(!pi->isLoading()); | |
93 UseCounter::count(document, UseCounter::XSLProcessingInstruction); | |
94 RefPtrWillBeRawPtr<XSLTProcessor> processor = XSLTProcessor::create(document ); | |
95 processor->setXSLStyleSheet(toXSLStyleSheet(pi->sheet())); | |
96 String resultMIMEType; | |
97 String newSource; | |
98 String resultEncoding; | |
99 document.setParsingState(Document::Parsing); | |
100 if (!processor->transformToString(&document, resultMIMEType, newSource, resu ltEncoding)) { | |
101 document.setParsingState(Document::FinishedParsing); | |
102 return; | |
103 } | |
104 // FIXME: If the transform failed we should probably report an error (like M ozilla does). | |
105 LocalFrame* ownerFrame = document.frame(); | |
106 processor->createDocumentFromSource(newSource, resultEncoding, resultMIMETyp e, &document, ownerFrame); | |
107 InspectorInstrumentation::frameDocumentUpdated(ownerFrame); | |
108 document.setParsingState(Document::FinishedParsing); | |
109 } | |
110 | |
111 ProcessingInstruction* DocumentXSLT::findXSLStyleSheet(Document& document) | |
112 { | |
113 for (Node* node = document.firstChild(); node; node = node->nextSibling()) { | |
114 if (node->nodeType() != Node::PROCESSING_INSTRUCTION_NODE) | |
115 continue; | |
116 | |
117 ProcessingInstruction* pi = toProcessingInstruction(node); | |
118 if (pi->isXSL()) | |
119 return pi; | |
120 } | |
121 return 0; | |
122 } | |
123 | |
124 void DocumentXSLT::sheetLoaded(Document& document, ProcessingInstruction* pi) | |
125 { | |
126 if (!RuntimeEnabledFeatures::xsltEnabled()) | |
127 return; | |
128 | |
129 if (document.parsing() || pi->isLoading()) | |
130 return; | |
131 | |
132 if (DocumentXSLT::hasTransformSourceDocument(document)) | |
133 return; | |
134 | |
135 ProcessingInstruction* firstPi = findXSLStyleSheet(document); | |
136 ASSERT(firstPi); | |
137 if (firstPi != pi) | |
138 return; | |
139 applyXSLTransform(document, pi); | |
140 } | |
141 | |
142 const char* DocumentXSLT::supplementName() | |
143 { | |
144 return "DocumentXSLT"; | |
145 } | |
146 | |
147 bool DocumentXSLT::hasTransformSourceDocument(Document& document) | |
148 { | |
149 return static_cast<DocumentXSLT*>(DocumentSupplement::from(document, supplem entName())); | |
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
| |
150 } | |
151 | |
152 | |
153 DocumentXSLT& DocumentXSLT::from(DocumentSupplementable& document) | |
154 { | |
155 DocumentXSLT* supplement = static_cast<DocumentXSLT*>(DocumentSupplement::fr om(document, supplementName())); | |
156 if (!supplement) { | |
157 supplement = new DocumentXSLT(); | |
158 DocumentSupplement::provideTo(document, supplementName(), adoptPtrWillBe Noop(supplement)); | |
159 } | |
160 return *supplement; | |
161 } | |
162 | |
163 void DocumentXSLT::trace(Visitor* visitor) | |
164 { | |
165 visitor->trace(m_transformSourceDocument); | |
166 DocumentSupplement::trace(visitor); | |
167 } | |
168 | |
169 } // namespace blink | |
OLD | NEW |