Changeset 224146 in webkit
- Timestamp:
- Oct 28, 2017 2:17:59 AM (7 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r224142 r224146 1 2017-10-28 Ryosuke Niwa <rniwa@webkit.org> 2 3 Style::Scope::flushPendingUpdate() can replace the entire document in XSLTProcessor::createDocumentFromSource 4 https://bugs.webkit.org/show_bug.cgi?id=178715 5 <rdar://problem/35144665> 6 7 Reviewed by Brent Fulgham. 8 9 Apply XLS tranforms when a 0s timer fires or the document finishes parsing or loading whichever comes first 10 instead of in the middle of collecting a list of stylesheets. 11 12 * dom/Document.cpp: 13 (WebCore::Document::Document): Initialize the newly added timer. 14 (WebCore::Document::implicitClose): Apply any pending XSLT before we fire load events since some of the event 15 handlers may be expecting to see the document after XSLT had been applied. 16 (WebCore::Document::scheduleToApplyXSLTransforms): Added. 17 (WebCore::Document::applyPendingXSLTransformsNowIfScheduled): Added. 18 (WebCore::Document::applyPendingXSLTransformsTimerFired): Added. Moved the logic to apply XSL transforms from 19 Style::Scope::collectActiveStyleSheets, and merged applyXSLTransform into this function. 20 (WebCore::Document::applyXSLTransform): Deleted. 21 (WebCore::Document::finishedParsing): Apply XSLT right before updating the style. This is where used to apply 22 inline XSLT and it happens much earlier than implicitClose. 23 (WebCore::Document::suspendScheduledTasks): Suspend the XSLT timer. 24 (WebCore::Document::resumeScheduledTasks): Reschedule the XSLT timer if m_hasPendingXSLTransforms is set. 25 * dom/Document.h: 26 * dom/ProcessingInstruction.cpp: 27 (WebCore::ProcessingInstruction::checkStyleSheet): Schedule XSLT in the document instead of flushing pending 28 stylesheets, which would have synchronously applied XSLT. We can't apply XSLT synchronously here because this 29 function can be called from a non-script-resilient call stack. 30 (WebCore::ProcessingInstruction::sheetLoaded): Ditto. 31 * style/StyleScope.cpp: 32 (WebCore::Style::Scope::collectXSLTransforms): Added. 33 (WebCore::Style::Scope::collectActiveStyleSheets): Removed the code to apply XSLT. Skip ProcessingInstructions 34 that applies XSLT. Also use RefPtr<StyleSheet> instead of a raw pointer to store StyleSheet. 35 * style/StyleScope.h: 36 * xml/parser/XMLDocumentParserLibxml2.cpp: 37 (WebCore::XMLDocumentParser::doEnd): Apply any pending XSLTs synchronously here as the comment suggests. 38 1 39 2017-10-27 Devin Rousso <webkit@devinrousso.com> 2 40 -
trunk/Source/WebCore/dom/Document.cpp
r224131 r224146 481 481 , m_scriptRunner(std::make_unique<ScriptRunner>(*this)) 482 482 , m_moduleLoader(std::make_unique<ScriptModuleLoader>(*this)) 483 #if ENABLE(XSLT) 484 , m_applyPendingXSLTransformsTimer(*this, &Document::applyPendingXSLTransformsTimerFired) 485 #endif 483 486 , m_xmlVersion(ASCIILiteral("1.0")) 484 487 , m_constantPropertyMap(std::make_unique<ConstantPropertyMap>(*this)) … … 2740 2743 RefPtr<Frame> f = frame(); 2741 2744 if (f) { 2745 #if ENABLE(XSLT) 2746 // Apply XSL transforms before load events so that event handlers can access the transformed DOM tree. 2747 applyPendingXSLTransformsNowIfScheduled(); 2748 #endif 2749 2742 2750 if (auto* documentLoader = loader()) 2743 2751 documentLoader->startIconLoading(); … … 5066 5074 #if ENABLE(XSLT) 5067 5075 5068 void Document::applyXSLTransform(ProcessingInstruction* pi) 5069 { 5070 RefPtr<XSLTProcessor> processor = XSLTProcessor::create(); 5071 processor->setXSLStyleSheet(downcast<XSLStyleSheet>(pi->sheet())); 5072 String resultMIMEType; 5073 String newSource; 5074 String resultEncoding; 5075 if (!processor->transformToString(*this, resultMIMEType, newSource, resultEncoding)) 5076 return; 5077 // FIXME: If the transform failed we should probably report an error (like Mozilla does). 5078 Frame* ownerFrame = frame(); 5079 processor->createDocumentFromSource(newSource, resultEncoding, resultMIMEType, this, ownerFrame); 5076 void Document::scheduleToApplyXSLTransforms() 5077 { 5078 m_hasPendingXSLTransforms = true; 5079 if (!m_applyPendingXSLTransformsTimer.isActive()) 5080 m_applyPendingXSLTransformsTimer.startOneShot(0_s); 5081 } 5082 5083 void Document::applyPendingXSLTransformsNowIfScheduled() 5084 { 5085 if (!m_hasPendingXSLTransforms) 5086 return; 5087 m_applyPendingXSLTransformsTimer.stop(); 5088 applyPendingXSLTransformsTimerFired(); 5089 } 5090 5091 void Document::applyPendingXSLTransformsTimerFired() 5092 { 5093 if (parsing()) 5094 return; 5095 5096 m_hasPendingXSLTransforms = false; 5097 ASSERT(NoEventDispatchAssertion::isEventAllowedInMainThread()); 5098 for (auto& processingInstruction : styleScope().collectXSLTransforms()) { 5099 ASSERT(processingInstruction->isXSL()); 5100 5101 // Don't apply XSL transforms to already transformed documents -- <rdar://problem/4132806> 5102 if (transformSourceDocument() || !processingInstruction->sheet()) 5103 return; 5104 5105 auto processor = XSLTProcessor::create(); 5106 processor->setXSLStyleSheet(downcast<XSLStyleSheet>(processingInstruction->sheet())); 5107 String resultMIMEType; 5108 String newSource; 5109 String resultEncoding; 5110 if (!processor->transformToString(*this, resultMIMEType, newSource, resultEncoding)) 5111 continue; 5112 // FIXME: If the transform failed we should probably report an error (like Mozilla does). 5113 processor->createDocumentFromSource(newSource, resultEncoding, resultMIMEType, this, frame()); 5114 } 5080 5115 } 5081 5116 … … 5259 5294 setParsing(false); 5260 5295 5296 Ref<Document> protectedThis(*this); 5297 5261 5298 if (!m_documentTiming.domContentLoadedEventStart) 5262 5299 m_documentTiming.domContentLoadedEventStart = MonotonicTime::now(); … … 5268 5305 5269 5306 if (RefPtr<Frame> frame = this->frame()) { 5307 #if ENABLE(XSLT) 5308 applyPendingXSLTransformsNowIfScheduled(); 5309 #endif 5310 5270 5311 // FrameLoader::finishedParsing() might end up calling Document::implicitClose() if all 5271 5312 // resource loads are complete. HTMLObjectElements can start loading their resources from … … 5708 5749 m_pendingTasksTimer.stop(); 5709 5750 5751 #if ENABLE(XSLT) 5752 m_applyPendingXSLTransformsTimer.stop(); 5753 #endif 5754 5710 5755 // Deferring loading and suspending parser is necessary when we need to prevent re-entrant JavaScript execution 5711 5756 // (e.g. while displaying an alert). … … 5727 5772 if (reason == ActiveDOMObject::WillDeferLoading && m_parser) 5728 5773 m_parser->resumeScheduledTasks(); 5774 5775 #if ENABLE(XSLT) 5776 if (m_hasPendingXSLTransforms) 5777 m_applyPendingXSLTransformsTimer.startOneShot(0_s); 5778 #endif 5779 5729 5780 if (!m_pendingTasks.isEmpty()) 5730 5781 m_pendingTasksTimer.startOneShot(0_s); -
trunk/Source/WebCore/dom/Document.h
r224116 r224146 953 953 954 954 #if ENABLE(XSLT) 955 void applyXSLTransform(ProcessingInstruction* pi); 955 void scheduleToApplyXSLTransforms(); 956 void applyPendingXSLTransformsNowIfScheduled(); 956 957 RefPtr<Document> transformSourceDocument() { return m_transformSourceDocument; } 957 958 void setTransformSourceDocument(Document* doc) { m_transformSourceDocument = doc; } … … 1568 1569 1569 1570 #if ENABLE(XSLT) 1571 void applyPendingXSLTransformsTimerFired(); 1572 1570 1573 std::unique_ptr<TransformSource> m_transformSource; 1571 1574 RefPtr<Document> m_transformSourceDocument; 1575 Timer m_applyPendingXSLTransformsTimer; 1576 bool m_hasPendingXSLTransforms { false }; 1572 1577 #endif 1573 1578 -
trunk/Source/WebCore/dom/ProcessingInstruction.cpp
r224116 r224146 127 127 m_sheet = XSLStyleSheet::createEmbedded(this, finalURL); 128 128 m_loading = false; 129 document().scheduleToApplyXSLTransforms(); 129 130 } 130 131 #endif … … 180 181 #if ENABLE(XSLT) 181 182 if (m_isXSL) 182 document().s tyleScope().flushPendingUpdate();183 document().scheduleToApplyXSLTransforms(); 183 184 #endif 184 185 } … … 203 204 #if ENABLE(XSLT) 204 205 if (m_isXSL) 205 document().s tyleScope().flushPendingUpdate();206 document().scheduleToApplyXSLTransforms(); 206 207 #endif 207 208 return true; -
trunk/Source/WebCore/style/StyleScope.cpp
r224116 r224146 291 291 } 292 292 293 #if ENABLE(XSLT) 294 // FIXME: <https://webkit.org/b/178830> Remove XSLT relaed code from Style::Scope. 295 Vector<Ref<ProcessingInstruction>> Scope::collectXSLTransforms() 296 { 297 Vector<Ref<ProcessingInstruction>> processingInstructions; 298 for (auto& node : m_styleSheetCandidateNodes) { 299 if (is<ProcessingInstruction>(*node) && downcast<ProcessingInstruction>(*node).isXSL()) 300 processingInstructions.append(downcast<ProcessingInstruction>(*node)); 301 } 302 return processingInstructions; 303 } 304 #endif 305 293 306 void Scope::collectActiveStyleSheets(Vector<RefPtr<StyleSheet>>& sheets) 294 307 { … … 297 310 298 311 for (auto& node : m_styleSheetCandidateNodes) { 299 StyleSheet* sheet = nullptr;312 RefPtr<StyleSheet> sheet; 300 313 if (is<ProcessingInstruction>(*node)) { 301 // Processing instruction (XML documents only). 314 if (!downcast<ProcessingInstruction>(*node).isCSS()) 315 continue; 302 316 // We don't support linking to embedded CSS stylesheets, see <https://bugs.webkit.org/show_bug.cgi?id=49281> for discussion. 303 ProcessingInstruction& pi = downcast<ProcessingInstruction>(*node); 304 sheet = pi.sheet(); 305 #if ENABLE(XSLT) 306 // Don't apply XSL transforms to already transformed documents -- <rdar://problem/4132806> 307 if (pi.isXSL() && !m_document.transformSourceDocument()) { 308 // Don't apply XSL transforms until loading is finished. 309 if (!m_document.parsing()) 310 m_document.applyXSLTransform(&pi); 311 return; 312 } 313 #endif 317 sheet = downcast<ProcessingInstruction>(*node).sheet(); 314 318 } else if (is<HTMLLinkElement>(*node) || is<HTMLStyleElement>(*node) || is<SVGStyleElement>(*node)) { 315 319 Element& element = downcast<Element>(*node); … … 365 369 } 366 370 if (sheet) 367 sheets.append( sheet);371 sheets.append(WTFMove(sheet)); 368 372 } 369 373 } -
trunk/Source/WebCore/style/StyleScope.h
r224116 r224146 109 109 void flushPendingUpdate(); 110 110 111 #if ENABLE(XSLT) 112 Vector<Ref<ProcessingInstruction>> collectXSLTransforms(); 113 #endif 114 111 115 StyleResolver& resolver(); 112 116 StyleResolver* resolverIfExists(); -
trunk/Source/WebCore/xml/parser/XMLDocumentParserLibxml2.cpp
r224116 r224146 1334 1334 1335 1335 document()->setParsing(false); // Make the document think it's done, so it will apply XSL stylesheets. 1336 document()-> styleScope().didChangeActiveStyleSheetCandidates();1336 document()->applyPendingXSLTransformsNowIfScheduled(); 1337 1337 1338 1338 // styleResolverChanged() call can detach the parser and null out its document.
Note: See TracChangeset
for help on using the changeset viewer.