Changeset 223999 in webkit
- Timestamp:
- Oct 25, 2017 5:30:03 PM (6 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r223998 r223999 1 2017-10-25 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 * dom/Document.h: 24 * dom/ProcessingInstruction.cpp: 25 (WebCore::ProcessingInstruction::checkStyleSheet): Schedule XSLT in the document instead of flushing pending 26 stylesheets, which would have synchronously applied XSLT. We can't apply XSLT synchronously here because this 27 function can be called from a non-script-resilient call stack. 28 (WebCore::ProcessingInstruction::sheetLoaded): Ditto. 29 * style/StyleScope.cpp: 30 (WebCore::Style::Scope::collectXSLTransforms): Added. 31 (WebCore::Style::Scope::collectActiveStyleSheets): Removed the code to apply XSLT. Skip ProcessingInstructions 32 that applies XSLT. Also use RefPtr<StyleSheet> instead of a raw pointer to store StyleSheet. 33 * style/StyleScope.h: 34 * xml/parser/XMLDocumentParserLibxml2.cpp: 35 (WebCore::XMLDocumentParser::doEnd): Apply any pending XSLTs synchronously here as the comment suggests. 36 1 37 2017-10-25 Devin Rousso <webkit@devinrousso.com> 2 38 -
trunk/Source/WebCore/dom/Document.cpp
r223929 r223999 470 470 , m_scriptRunner(std::make_unique<ScriptRunner>(*this)) 471 471 , m_moduleLoader(std::make_unique<ScriptModuleLoader>(*this)) 472 , m_applyPendingXSLTransformsTimer(*this, &Document::applyPendingXSLTransformsTimerFired) 472 473 , m_xmlVersion(ASCIILiteral("1.0")) 473 474 , m_constantPropertyMap(std::make_unique<ConstantPropertyMap>(*this)) … … 2726 2727 RefPtr<Frame> f = frame(); 2727 2728 if (f) { 2729 // Apply XSL transforms before load events so that event handlers can access the transformed DOM tree. 2730 applyPendingXSLTransformsNowIfScheduled(); 2731 2728 2732 if (auto* documentLoader = loader()) 2729 2733 documentLoader->startIconLoading(); … … 5051 5055 #if ENABLE(XSLT) 5052 5056 5053 void Document::applyXSLTransform(ProcessingInstruction* pi) 5054 { 5055 RefPtr<XSLTProcessor> processor = XSLTProcessor::create(); 5056 processor->setXSLStyleSheet(downcast<XSLStyleSheet>(pi->sheet())); 5057 String resultMIMEType; 5058 String newSource; 5059 String resultEncoding; 5060 if (!processor->transformToString(*this, resultMIMEType, newSource, resultEncoding)) 5061 return; 5062 // FIXME: If the transform failed we should probably report an error (like Mozilla does). 5063 Frame* ownerFrame = frame(); 5064 processor->createDocumentFromSource(newSource, resultEncoding, resultMIMEType, this, ownerFrame); 5057 void Document::scheduleToApplyXSLTransforms() 5058 { 5059 if (!m_applyPendingXSLTransformsTimer.isActive()) 5060 m_applyPendingXSLTransformsTimer.startOneShot(0_s); 5061 } 5062 5063 void Document::applyPendingXSLTransformsNowIfScheduled() 5064 { 5065 if (!m_applyPendingXSLTransformsTimer.isActive()) 5066 return; 5067 m_applyPendingXSLTransformsTimer.stop(); 5068 applyPendingXSLTransformsTimerFired(); 5069 } 5070 5071 void Document::applyPendingXSLTransformsTimerFired() 5072 { 5073 if (parsing()) 5074 return; 5075 5076 ASSERT(NoEventDispatchAssertion::isEventAllowedInMainThread()); 5077 for (auto& processingInstruction : styleScope().collectXSLTransforms()) { 5078 ASSERT(processingInstruction->isXSL()); 5079 5080 // Don't apply XSL transforms to already transformed documents -- <rdar://problem/4132806> 5081 if (transformSourceDocument() || !processingInstruction->sheet()) 5082 return; 5083 5084 auto processor = XSLTProcessor::create(); 5085 processor->setXSLStyleSheet(downcast<XSLStyleSheet>(processingInstruction->sheet())); 5086 String resultMIMEType; 5087 String newSource; 5088 String resultEncoding; 5089 if (!processor->transformToString(*this, resultMIMEType, newSource, resultEncoding)) 5090 continue; 5091 // FIXME: If the transform failed we should probably report an error (like Mozilla does). 5092 processor->createDocumentFromSource(newSource, resultEncoding, resultMIMEType, this, frame()); 5093 } 5065 5094 } 5066 5095 … … 5244 5273 setParsing(false); 5245 5274 5275 Ref<Document> protectedThis(*this); 5276 5246 5277 if (!m_documentTiming.domContentLoadedEventStart) 5247 5278 m_documentTiming.domContentLoadedEventStart = MonotonicTime::now(); … … 5253 5284 5254 5285 if (RefPtr<Frame> frame = this->frame()) { 5286 applyPendingXSLTransformsNowIfScheduled(); 5287 5255 5288 // FrameLoader::finishedParsing() might end up calling Document::implicitClose() if all 5256 5289 // resource loads are complete. HTMLObjectElements can start loading their resources from -
trunk/Source/WebCore/dom/Document.h
r223929 r223999 945 945 946 946 #if ENABLE(XSLT) 947 void applyXSLTransform(ProcessingInstruction* pi); 947 void scheduleToApplyXSLTransforms(); 948 void applyPendingXSLTransformsNowIfScheduled(); 948 949 RefPtr<Document> transformSourceDocument() { return m_transformSourceDocument; } 949 950 void setTransformSourceDocument(Document* doc) { m_transformSourceDocument = doc; } … … 1559 1560 1560 1561 #if ENABLE(XSLT) 1562 void applyPendingXSLTransformsTimerFired(); 1563 1561 1564 std::unique_ptr<TransformSource> m_transformSource; 1562 1565 RefPtr<Document> m_transformSourceDocument; 1566 Timer m_applyPendingXSLTransformsTimer; 1563 1567 #endif 1564 1568 -
trunk/Source/WebCore/dom/ProcessingInstruction.cpp
r223802 r223999 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
r223047 r223999 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
r218793 r223999 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
r223728 r223999 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.