<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[194691] trunk/Source/WebCore</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/194691">194691</a></dd>
<dt>Author</dt> <dd>antti@apple.com</dd>
<dt>Date</dt> <dd>2016-01-07 00:16:49 -0800 (Thu, 07 Jan 2016)</dd>
</dl>
<h3>Log Message</h3>
<pre>Factor free standing tree style resolve functions into a class
https://bugs.webkit.org/show_bug.cgi?id=152786
Reviewed by Simon Fraser.
Factor the free standing tree style resolve functions into a class that can keep state.
Style::TreeResolver instances resolve a single tree scope. It is instantiated for resolving
the document style and then recursively for each encountered shadow tree.
This will enable new features and optimizations later.
* dom/Document.cpp:
(WebCore::Document::recalcStyle):
Move the root style computation code back to Document. It fits better here and avoid some
awkwardness with style resolver construction order.
* style/StyleResolveTree.cpp:
(WebCore::Style::TreeResolver::TreeResolver):
TreeResolver knows the current tree context and the StyleResolver to use for it.
Switch the functions to use these instead of recomputing them repeatedly.
(WebCore::Style::shouldCreateRenderer):
(WebCore::Style::TreeResolver::styleForElement):
(WebCore::Style::moveToFlowThreadIfNeeded):
(WebCore::Style::TreeResolver::createRenderer):
(WebCore::Style::updateTextRendererAfterContentChange):
(WebCore::Style::TreeResolver::createRenderTreeForChildren):
(WebCore::Style::TreeResolver::createRenderTreeForShadowRoot):
(WebCore::Style::needsPseudoElement):
(WebCore::Style::TreeResolver::createRenderTreeForBeforeOrAfterPseudoElement):
(WebCore::Style::TreeResolver::createRenderTreeForSlotAssignees):
(WebCore::Style::TreeResolver::createRenderTreeRecursively):
Rename to reduce the use of confusing "attach" terminology.
(WebCore::Style::pseudoStyleCacheIsInvalid):
(WebCore::Style::TreeResolver::resolveLocally):
(WebCore::Style::resolveTextNode):
(WebCore::Style::TreeResolver::resolveChildAtShadowBoundary):
(WebCore::Style::TreeResolver::resolveShadowTree):
(WebCore::Style::TreeResolver::resolveBeforeOrAfterPseudoElement):
(WebCore::Style::TreeResolver::resolveChildren):
(WebCore::Style::TreeResolver::resolveSlotAssignees):
(WebCore::Style::TreeResolver::resolveRecursively):
(WebCore::Style::TreeResolver::resolve):
(WebCore::Style::detachRenderTree):
(WebCore::Style::styleForElement): Deleted.
(WebCore::Style::createRendererIfNeeded): Deleted.
(WebCore::Style::attachChildren): Deleted.
(WebCore::Style::attachShadowRoot): Deleted.
(WebCore::Style::attachBeforeOrAfterPseudoElementIfNeeded): Deleted.
(WebCore::Style::attachSlotAssignees): Deleted.
(WebCore::Style::attachRenderTree): Deleted.
(WebCore::Style::resolveLocal): Deleted.
(WebCore::Style::resolveChildAtShadowBoundary): Deleted.
(WebCore::Style::resolveShadowTree): Deleted.
(WebCore::Style::updateBeforeOrAfterPseudoElement): Deleted.
(WebCore::Style::resolveChildren): Deleted.
(WebCore::Style::resolveSlotAssignees): Deleted.
(WebCore::Style::resolveTree): Deleted.
* style/StyleResolveTree.h:</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreCMakeListstxt">trunk/Source/WebCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCorevcxprojWebCorevcxproj">trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCoredomCharacterDatacpp">trunk/Source/WebCore/dom/CharacterData.cpp</a></li>
<li><a href="#trunkSourceWebCoredomContainerNodecpp">trunk/Source/WebCore/dom/ContainerNode.cpp</a></li>
<li><a href="#trunkSourceWebCoredomDocumentcpp">trunk/Source/WebCore/dom/Document.cpp</a></li>
<li><a href="#trunkSourceWebCoredomElementcpp">trunk/Source/WebCore/dom/Element.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLFormControlElementcpp">trunk/Source/WebCore/html/HTMLFormControlElement.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLFrameOwnerElementcpp">trunk/Source/WebCore/html/HTMLFrameOwnerElement.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLPlugInImageElementcpp">trunk/Source/WebCore/html/HTMLPlugInImageElement.cpp</a></li>
<li><a href="#trunkSourceWebCoremathmlMathMLSelectElementcpp">trunk/Source/WebCore/mathml/MathMLSelectElement.cpp</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebCorestyleStyleTreeResolvercpp">trunk/Source/WebCore/style/StyleTreeResolver.cpp</a></li>
<li><a href="#trunkSourceWebCorestyleStyleTreeResolverh">trunk/Source/WebCore/style/StyleTreeResolver.h</a></li>
</ul>
<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkSourceWebCorestyleStyleResolveTreecpp">trunk/Source/WebCore/style/StyleResolveTree.cpp</a></li>
<li><a href="#trunkSourceWebCorestyleStyleResolveTreeh">trunk/Source/WebCore/style/StyleResolveTree.h</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/CMakeLists.txt (194690 => 194691)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/CMakeLists.txt        2016-01-07 08:14:39 UTC (rev 194690)
+++ trunk/Source/WebCore/CMakeLists.txt        2016-01-07 08:16:49 UTC (rev 194691)
</span><span class="lines">@@ -2605,7 +2605,7 @@
</span><span class="cx"> style/StyleChange.cpp
</span><span class="cx"> style/StyleFontSizeFunctions.cpp
</span><span class="cx"> style/StyleResolveForDocument.cpp
</span><del>- style/StyleResolveTree.cpp
</del><ins>+ style/StyleTreeResolver.cpp
</ins><span class="cx">
</span><span class="cx"> svg/SVGAElement.cpp
</span><span class="cx"> svg/SVGAltGlyphDefElement.cpp
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (194690 => 194691)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-01-07 08:14:39 UTC (rev 194690)
+++ trunk/Source/WebCore/ChangeLog        2016-01-07 08:16:49 UTC (rev 194691)
</span><span class="lines">@@ -1,3 +1,69 @@
</span><ins>+2016-01-06 Antti Koivisto <antti@apple.com>
+
+ Factor free standing tree style resolve functions into a class
+ https://bugs.webkit.org/show_bug.cgi?id=152786
+
+ Reviewed by Simon Fraser.
+
+ Factor the free standing tree style resolve functions into a class that can keep state.
+ Style::TreeResolver instances resolve a single tree scope. It is instantiated for resolving
+ the document style and then recursively for each encountered shadow tree.
+
+ This will enable new features and optimizations later.
+
+ * dom/Document.cpp:
+ (WebCore::Document::recalcStyle):
+
+ Move the root style computation code back to Document. It fits better here and avoid some
+ awkwardness with style resolver construction order.
+
+ * style/StyleResolveTree.cpp:
+ (WebCore::Style::TreeResolver::TreeResolver):
+
+ TreeResolver knows the current tree context and the StyleResolver to use for it.
+ Switch the functions to use these instead of recomputing them repeatedly.
+
+ (WebCore::Style::shouldCreateRenderer):
+ (WebCore::Style::TreeResolver::styleForElement):
+ (WebCore::Style::moveToFlowThreadIfNeeded):
+ (WebCore::Style::TreeResolver::createRenderer):
+ (WebCore::Style::updateTextRendererAfterContentChange):
+ (WebCore::Style::TreeResolver::createRenderTreeForChildren):
+ (WebCore::Style::TreeResolver::createRenderTreeForShadowRoot):
+ (WebCore::Style::needsPseudoElement):
+ (WebCore::Style::TreeResolver::createRenderTreeForBeforeOrAfterPseudoElement):
+ (WebCore::Style::TreeResolver::createRenderTreeForSlotAssignees):
+ (WebCore::Style::TreeResolver::createRenderTreeRecursively):
+
+ Rename to reduce the use of confusing "attach" terminology.
+
+ (WebCore::Style::pseudoStyleCacheIsInvalid):
+ (WebCore::Style::TreeResolver::resolveLocally):
+ (WebCore::Style::resolveTextNode):
+ (WebCore::Style::TreeResolver::resolveChildAtShadowBoundary):
+ (WebCore::Style::TreeResolver::resolveShadowTree):
+ (WebCore::Style::TreeResolver::resolveBeforeOrAfterPseudoElement):
+ (WebCore::Style::TreeResolver::resolveChildren):
+ (WebCore::Style::TreeResolver::resolveSlotAssignees):
+ (WebCore::Style::TreeResolver::resolveRecursively):
+ (WebCore::Style::TreeResolver::resolve):
+ (WebCore::Style::detachRenderTree):
+ (WebCore::Style::styleForElement): Deleted.
+ (WebCore::Style::createRendererIfNeeded): Deleted.
+ (WebCore::Style::attachChildren): Deleted.
+ (WebCore::Style::attachShadowRoot): Deleted.
+ (WebCore::Style::attachBeforeOrAfterPseudoElementIfNeeded): Deleted.
+ (WebCore::Style::attachSlotAssignees): Deleted.
+ (WebCore::Style::attachRenderTree): Deleted.
+ (WebCore::Style::resolveLocal): Deleted.
+ (WebCore::Style::resolveChildAtShadowBoundary): Deleted.
+ (WebCore::Style::resolveShadowTree): Deleted.
+ (WebCore::Style::updateBeforeOrAfterPseudoElement): Deleted.
+ (WebCore::Style::resolveChildren): Deleted.
+ (WebCore::Style::resolveSlotAssignees): Deleted.
+ (WebCore::Style::resolveTree): Deleted.
+ * style/StyleResolveTree.h:
+
</ins><span class="cx"> 2016-01-07 Doug Russell <d_russell@apple.com>
</span><span class="cx">
</span><span class="cx"> AX: AXObjectCacheMac is passing WebCore enum values directly to VoiceOver
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorevcxprojWebCorevcxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj (194690 => 194691)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj        2016-01-07 08:14:39 UTC (rev 194690)
+++ trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj        2016-01-07 08:16:49 UTC (rev 194691)
</span><span class="lines">@@ -19202,7 +19202,7 @@
</span><span class="cx"> <ClCompile Include="..\style\StyleChange.cpp" />
</span><span class="cx"> <ClCompile Include="..\style\StyleFontSizeFunctions.cpp" />
</span><span class="cx"> <ClCompile Include="..\style\StyleResolveForDocument.cpp" />
</span><del>- <ClCompile Include="..\style\StyleResolveTree.cpp" />
</del><ins>+ <ClCompile Include="..\style\StyleTreeResolver.cpp" />
</ins><span class="cx"> <ClCompile Include="..\bridge\jsc\BridgeJSC.cpp" />
</span><span class="cx"> <ClCompile Include="..\bridge\c\c_class.cpp" />
</span><span class="cx"> <ClCompile Include="..\bridge\c\c_instance.cpp" />
</span><span class="lines">@@ -22766,7 +22766,7 @@
</span><span class="cx"> <ClInclude Include="..\style\StyleChange.h" />
</span><span class="cx"> <ClInclude Include="..\style\StyleFontSizeFunctions.h" />
</span><span class="cx"> <ClInclude Include="..\style\StyleResolveForDocument.h" />
</span><del>- <ClInclude Include="..\style\StyleResolveTree.h" />
</del><ins>+ <ClInclude Include="..\style\StyleTreeResolver.h" />
</ins><span class="cx"> <ClInclude Include="..\bridge\Bridge.h" />
</span><span class="cx"> <ClInclude Include="..\bridge\jsc\BridgeJSC.h" />
</span><span class="cx"> <ClInclude Include="..\bridge\c\c_class.h" />
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (194690 => 194691)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-01-07 08:14:39 UTC (rev 194690)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-01-07 08:16:49 UTC (rev 194691)
</span><span class="lines">@@ -6579,8 +6579,8 @@
</span><span class="cx">                 E4D58EBB17B8F12800CBDCA8 /* ElementTraversal.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D58EBA17B8F12800CBDCA8 /* ElementTraversal.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 E4D988B417BFD1F60084FB88 /* TextNodeTraversal.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D988B317BFD1F60084FB88 /* TextNodeTraversal.h */; };
</span><span class="cx">                 E4D988B617BFEB210084FB88 /* TextNodeTraversal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4D988B517BFEB210084FB88 /* TextNodeTraversal.cpp */; };
</span><del>-                E4DEAA1717A93DC3000E0430 /* StyleResolveTree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4DEAA1517A93DC3000E0430 /* StyleResolveTree.cpp */; };
-                E4DEAA1817A93DC3000E0430 /* StyleResolveTree.h in Headers */ = {isa = PBXBuildFile; fileRef = E4DEAA1617A93DC3000E0430 /* StyleResolveTree.h */; settings = {ATTRIBUTES = (Private, ); }; };
</del><ins>+                E4DEAA1717A93DC3000E0430 /* StyleTreeResolver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4DEAA1517A93DC3000E0430 /* StyleTreeResolver.cpp */; };
+                E4DEAA1817A93DC3000E0430 /* StyleTreeResolver.h in Headers */ = {isa = PBXBuildFile; fileRef = E4DEAA1617A93DC3000E0430 /* StyleTreeResolver.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 E4E39AFB1330EFA8003AB274 /* LegacyTileLayerPool.h in Headers */ = {isa = PBXBuildFile; fileRef = E4E39AFA1330EFA8003AB274 /* LegacyTileLayerPool.h */; };
</span><span class="cx">                 E4E39AFD1330EFC6003AB274 /* LegacyTileLayerPool.mm in Sources */ = {isa = PBXBuildFile; fileRef = E4E39AFC1330EFC5003AB274 /* LegacyTileLayerPool.mm */; };
</span><span class="cx">                 E4E9B1191810916F003ACCDF /* SimpleLineLayoutResolver.h in Headers */ = {isa = PBXBuildFile; fileRef = E4E9B1181810916F003ACCDF /* SimpleLineLayoutResolver.h */; };
</span><span class="lines">@@ -14496,8 +14496,8 @@
</span><span class="cx">                 E4D58EBA17B8F12800CBDCA8 /* ElementTraversal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ElementTraversal.h; sourceTree = "<group>"; };
</span><span class="cx">                 E4D988B317BFD1F60084FB88 /* TextNodeTraversal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextNodeTraversal.h; sourceTree = "<group>"; };
</span><span class="cx">                 E4D988B517BFEB210084FB88 /* TextNodeTraversal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextNodeTraversal.cpp; sourceTree = "<group>"; };
</span><del>-                E4DEAA1517A93DC3000E0430 /* StyleResolveTree.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleResolveTree.cpp; sourceTree = "<group>"; };
-                E4DEAA1617A93DC3000E0430 /* StyleResolveTree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleResolveTree.h; sourceTree = "<group>"; };
</del><ins>+                E4DEAA1517A93DC3000E0430 /* StyleTreeResolver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleTreeResolver.cpp; sourceTree = "<group>"; };
+                E4DEAA1617A93DC3000E0430 /* StyleTreeResolver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleTreeResolver.h; sourceTree = "<group>"; };
</ins><span class="cx">                 E4E39AFA1330EFA8003AB274 /* LegacyTileLayerPool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LegacyTileLayerPool.h; sourceTree = "<group>"; };
</span><span class="cx">                 E4E39AFC1330EFC5003AB274 /* LegacyTileLayerPool.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = LegacyTileLayerPool.mm; sourceTree = "<group>"; };
</span><span class="cx">                 E4E9B1181810916F003ACCDF /* SimpleLineLayoutResolver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimpleLineLayoutResolver.h; sourceTree = "<group>"; };
</span><span class="lines">@@ -23120,8 +23120,8 @@
</span><span class="cx">                                 E4D58EB717B4ED8900CBDCA8 /* StyleFontSizeFunctions.h */,
</span><span class="cx">                                 E4D58EB217B4DBDC00CBDCA8 /* StyleResolveForDocument.cpp */,
</span><span class="cx">                                 E4D58EB317B4DBDC00CBDCA8 /* StyleResolveForDocument.h */,
</span><del>-                                E4DEAA1517A93DC3000E0430 /* StyleResolveTree.cpp */,
-                                E4DEAA1617A93DC3000E0430 /* StyleResolveTree.h */,
</del><ins>+                                E4DEAA1517A93DC3000E0430 /* StyleTreeResolver.cpp */,
+                                E4DEAA1617A93DC3000E0430 /* StyleTreeResolver.h */,
</ins><span class="cx">                         );
</span><span class="cx">                         path = style;
</span><span class="cx">                         sourceTree = "<group>";
</span><span class="lines">@@ -27508,7 +27508,7 @@
</span><span class="cx">                                 BC2272870E82E70700E7F975 /* StyleReflection.h in Headers */,
</span><span class="cx">                                 E4D58EB517B4DBDC00CBDCA8 /* StyleResolveForDocument.h in Headers */,
</span><span class="cx">                                 E139866415478474001E3F65 /* StyleResolver.h in Headers */,
</span><del>-                                E4DEAA1817A93DC3000E0430 /* StyleResolveTree.h in Headers */,
</del><ins>+                                E4DEAA1817A93DC3000E0430 /* StyleTreeResolver.h in Headers */,
</ins><span class="cx">                                 E4BBED4D14FCDBA1003F0B98 /* StyleRule.h in Headers */,
</span><span class="cx">                                 E4946EAF156E64DD00D3297F /* StyleRuleImport.h in Headers */,
</span><span class="cx">                                 F47A5E3E195B8C8A00483100 /* StyleScrollSnapPoints.h in Headers */,
</span><span class="lines">@@ -31039,7 +31039,7 @@
</span><span class="cx">                                 BC2272BC0E82EAAE00E7F975 /* StyleRareNonInheritedData.cpp in Sources */,
</span><span class="cx">                                 E4D58EB417B4DBDC00CBDCA8 /* StyleResolveForDocument.cpp in Sources */,
</span><span class="cx">                                 E139866315478474001E3F65 /* StyleResolver.cpp in Sources */,
</span><del>-                                E4DEAA1717A93DC3000E0430 /* StyleResolveTree.cpp in Sources */,
</del><ins>+                                E4DEAA1717A93DC3000E0430 /* StyleTreeResolver.cpp in Sources */,
</ins><span class="cx">                                 E4BBED4C14FCDBA1003F0B98 /* StyleRule.cpp in Sources */,
</span><span class="cx">                                 E4946EAE156E64DD00D3297F /* StyleRuleImport.cpp in Sources */,
</span><span class="cx">                                 F47A5E3F195B8E4800483100 /* StyleScrollSnapPoints.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCoredomCharacterDatacpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/CharacterData.cpp (194690 => 194691)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/CharacterData.cpp        2016-01-07 08:14:39 UTC (rev 194690)
+++ trunk/Source/WebCore/dom/CharacterData.cpp        2016-01-07 08:16:49 UTC (rev 194691)
</span><span class="lines">@@ -32,7 +32,7 @@
</span><span class="cx"> #include "ProcessingInstruction.h"
</span><span class="cx"> #include "RenderText.h"
</span><span class="cx"> #include "StyleInheritedData.h"
</span><del>-#include "StyleResolveTree.h"
</del><ins>+#include "StyleTreeResolver.h"
</ins><span class="cx"> #include "TextBreakIterator.h"
</span><span class="cx"> #include <wtf/Ref.h>
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCoredomContainerNodecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/ContainerNode.cpp (194690 => 194691)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/ContainerNode.cpp        2016-01-07 08:14:39 UTC (rev 194690)
+++ trunk/Source/WebCore/dom/ContainerNode.cpp        2016-01-07 08:16:49 UTC (rev 194691)
</span><span class="lines">@@ -54,7 +54,7 @@
</span><span class="cx"> #include "SVGElement.h"
</span><span class="cx"> #include "SVGNames.h"
</span><span class="cx"> #include "SelectorQuery.h"
</span><del>-#include "StyleResolveTree.h"
</del><ins>+#include "StyleTreeResolver.h"
</ins><span class="cx"> #include "TemplateContentDocumentFragment.h"
</span><span class="cx"> #include <algorithm>
</span><span class="cx"> #include <wtf/CurrentTime.h>
</span></span></pre></div>
<a id="trunkSourceWebCoredomDocumentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Document.cpp (194690 => 194691)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Document.cpp        2016-01-07 08:14:39 UTC (rev 194690)
+++ trunk/Source/WebCore/dom/Document.cpp        2016-01-07 08:16:49 UTC (rev 194691)
</span><span class="lines">@@ -154,10 +154,11 @@
</span><span class="cx"> #include "ShadowRoot.h"
</span><span class="cx"> #include "StorageEvent.h"
</span><span class="cx"> #include "StyleProperties.h"
</span><del>-#include "StyleResolveTree.h"
</del><ins>+#include "StyleResolveForDocument.h"
</ins><span class="cx"> #include "StyleResolver.h"
</span><span class="cx"> #include "StyleSheetContents.h"
</span><span class="cx"> #include "StyleSheetList.h"
</span><ins>+#include "StyleTreeResolver.h"
</ins><span class="cx"> #include "SubresourceLoader.h"
</span><span class="cx"> #include "TextEvent.h"
</span><span class="cx"> #include "TextNodeTraversal.h"
</span><span class="lines">@@ -1851,9 +1852,23 @@
</span><span class="cx"> if (change == Style::Force) {
</span><span class="cx"> // This may get set again during style resolve.
</span><span class="cx"> m_hasNodesWithPlaceholderStyle = false;
</span><ins>+
+ auto documentStyle = Style::resolveForDocument(*this);
+
+ // Inserting the pictograph font at the end of the font fallback list is done by the
+ // font selector, so set a font selector if needed.
+ if (Settings* settings = this->settings()) {
+ if (settings->fontFallbackPrefersPictographs())
+ documentStyle.get().fontCascade().update(&fontSelector());
+ }
+
+ auto documentChange = Style::determineChange(documentStyle.get(), m_renderView->style());
+ if (documentChange != Style::NoChange)
+ renderView()->setStyle(WTFMove(documentStyle));
</ins><span class="cx"> }
</span><span class="cx">
</span><del>- Style::resolveTree(*this, change);
</del><ins>+ Style::TreeResolver resolver(*this);
+ resolver.resolve(change);
</ins><span class="cx">
</span><span class="cx"> updatedCompositingLayers = frameView.updateCompositingLayersAfterStyleChange();
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCoredomElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Element.cpp (194690 => 194691)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Element.cpp        2016-01-07 08:14:39 UTC (rev 194690)
+++ trunk/Source/WebCore/dom/Element.cpp        2016-01-07 08:16:49 UTC (rev 194691)
</span><span class="lines">@@ -77,8 +77,8 @@
</span><span class="cx"> #include "SelectorQuery.h"
</span><span class="cx"> #include "Settings.h"
</span><span class="cx"> #include "StyleProperties.h"
</span><del>-#include "StyleResolveTree.h"
</del><span class="cx"> #include "StyleResolver.h"
</span><ins>+#include "StyleTreeResolver.h"
</ins><span class="cx"> #include "TextIterator.h"
</span><span class="cx"> #include "VoidCallback.h"
</span><span class="cx"> #include "WheelEvent.h"
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLFormControlElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLFormControlElement.cpp (194690 => 194691)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLFormControlElement.cpp        2016-01-07 08:14:39 UTC (rev 194690)
+++ trunk/Source/WebCore/html/HTMLFormControlElement.cpp        2016-01-07 08:16:49 UTC (rev 194691)
</span><span class="lines">@@ -38,7 +38,7 @@
</span><span class="cx"> #include "HTMLTextAreaElement.h"
</span><span class="cx"> #include "RenderBox.h"
</span><span class="cx"> #include "RenderTheme.h"
</span><del>-#include "StyleResolveTree.h"
</del><ins>+#include "StyleTreeResolver.h"
</ins><span class="cx"> #include "ValidationMessage.h"
</span><span class="cx"> #include <wtf/NeverDestroyed.h>
</span><span class="cx"> #include <wtf/Ref.h>
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLFrameOwnerElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLFrameOwnerElement.cpp (194690 => 194691)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLFrameOwnerElement.cpp        2016-01-07 08:14:39 UTC (rev 194690)
+++ trunk/Source/WebCore/html/HTMLFrameOwnerElement.cpp        2016-01-07 08:16:49 UTC (rev 194691)
</span><span class="lines">@@ -28,7 +28,7 @@
</span><span class="cx"> #include "RenderWidget.h"
</span><span class="cx"> #include "ShadowRoot.h"
</span><span class="cx"> #include "SVGDocument.h"
</span><del>-#include "StyleResolveTree.h"
</del><ins>+#include "StyleTreeResolver.h"
</ins><span class="cx"> #include <wtf/Ref.h>
</span><span class="cx">
</span><span class="cx"> namespace WebCore {
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLPlugInImageElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLPlugInImageElement.cpp (194690 => 194691)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLPlugInImageElement.cpp        2016-01-07 08:14:39 UTC (rev 194690)
+++ trunk/Source/WebCore/html/HTMLPlugInImageElement.cpp        2016-01-07 08:16:49 UTC (rev 194691)
</span><span class="lines">@@ -48,8 +48,8 @@
</span><span class="cx"> #include "SecurityOrigin.h"
</span><span class="cx"> #include "Settings.h"
</span><span class="cx"> #include "ShadowRoot.h"
</span><del>-#include "StyleResolveTree.h"
</del><span class="cx"> #include "StyleResolver.h"
</span><ins>+#include "StyleTreeResolver.h"
</ins><span class="cx"> #include "SubframeLoader.h"
</span><span class="cx"> #include "TypedElementDescendantIterator.h"
</span><span class="cx"> #include <JavaScriptCore/APICast.h>
</span></span></pre></div>
<a id="trunkSourceWebCoremathmlMathMLSelectElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/mathml/MathMLSelectElement.cpp (194690 => 194691)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/mathml/MathMLSelectElement.cpp        2016-01-07 08:14:39 UTC (rev 194690)
+++ trunk/Source/WebCore/mathml/MathMLSelectElement.cpp        2016-01-07 08:16:49 UTC (rev 194691)
</span><span class="lines">@@ -35,7 +35,7 @@
</span><span class="cx"> #include "RenderMathMLRow.h"
</span><span class="cx"> #include "SVGElement.h"
</span><span class="cx"> #include "SVGNames.h"
</span><del>-#include "StyleResolveTree.h"
</del><ins>+#include "StyleTreeResolver.h"
</ins><span class="cx">
</span><span class="cx"> namespace WebCore {
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCorestyleStyleResolveTreecpp"></a>
<div class="delfile"><h4>Deleted: trunk/Source/WebCore/style/StyleResolveTree.cpp (194690 => 194691)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/style/StyleResolveTree.cpp        2016-01-07 08:14:39 UTC (rev 194690)
+++ trunk/Source/WebCore/style/StyleResolveTree.cpp        2016-01-07 08:16:49 UTC (rev 194691)
</span><span class="lines">@@ -1,920 +0,0 @@
</span><del>-/*
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * (C) 1999 Antti Koivisto (koivisto@kde.org)
- * (C) 2001 Peter Kelly (pmk@post.com)
- * (C) 2001 Dirk Mueller (mueller@kde.org)
- * (C) 2007 David Smith (catfish.man@gmail.com)
- * Copyright (C) 2004-2010, 2012-2014 Apple Inc. All rights reserved.
- * (C) 2007 Eric Seidel (eric@webkit.org)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-#include "StyleResolveTree.h"
-
-#include "AXObjectCache.h"
-#include "AnimationController.h"
-#include "AuthorStyleSheets.h"
-#include "CSSFontSelector.h"
-#include "ComposedTreeAncestorIterator.h"
-#include "ComposedTreeIterator.h"
-#include "ElementIterator.h"
-#include "ElementRareData.h"
-#include "FlowThreadController.h"
-#include "HTMLSlotElement.h"
-#include "InspectorInstrumentation.h"
-#include "LoaderStrategy.h"
-#include "MainFrame.h"
-#include "NodeRenderStyle.h"
-#include "NodeTraversal.h"
-#include "PlatformStrategies.h"
-#include "RenderFullScreen.h"
-#include "RenderNamedFlowThread.h"
-#include "RenderText.h"
-#include "RenderTreePosition.h"
-#include "RenderWidget.h"
-#include "Settings.h"
-#include "ShadowRoot.h"
-#include "StyleResolveForDocument.h"
-#include "StyleResolver.h"
-#include "Text.h"
-
-#if PLATFORM(IOS)
-#include "CSSFontSelector.h"
-#include "WKContentObservation.h"
-#endif
-
-namespace WebCore {
-
-namespace Style {
-
-enum DetachType { NormalDetach, ReattachDetach };
-
-static void attachRenderTree(Element&, RenderStyle& inheritedStyle, RenderTreePosition&, PassRefPtr<RenderStyle>);
-static void attachTextRenderer(Text&, RenderTreePosition&);
-static void detachRenderTree(Element&, DetachType);
-static void resolveTextNode(Text&, RenderTreePosition&);
-static void resolveTree(Element&, RenderStyle& inheritedStyle, RenderTreePosition&, Change);
-
-static bool shouldCreateRenderer(const Element& element, const RenderElement& parentRenderer)
-{
- if (!element.document().shouldCreateRenderers())
- return false;
- if (!parentRenderer.canHaveChildren() && !(element.isPseudoElement() && parentRenderer.canHaveGeneratedChildren()))
- return false;
- if (parentRenderer.element() && !parentRenderer.element()->childShouldCreateRenderer(element))
- return false;
- return true;
-}
-
-static Ref<RenderStyle> styleForElement(Element& element, RenderStyle& inheritedStyle)
-{
- if (element.hasCustomStyleResolveCallbacks()) {
- if (RefPtr<RenderStyle> style = element.customStyleForRenderer(inheritedStyle))
- return style.releaseNonNull();
- }
- return element.resolveStyle(&inheritedStyle);
-}
-
-#if ENABLE(CSS_REGIONS)
-static RenderNamedFlowThread* moveToFlowThreadIfNeeded(Element& element, const RenderStyle& style)
-{
- if (!element.shouldMoveToFlowThread(style))
- return 0;
-
- FlowThreadController& flowThreadController = element.document().renderView()->flowThreadController();
- RenderNamedFlowThread& parentFlowRenderer = flowThreadController.ensureRenderFlowThreadWithName(style.flowThread());
- flowThreadController.registerNamedFlowContentElement(element, parentFlowRenderer);
- return &parentFlowRenderer;
-}
-#endif
-
-static void createRendererIfNeeded(Element& element, RenderStyle& inheritedStyle, RenderTreePosition& renderTreePosition, PassRefPtr<RenderStyle> resolvedStyle)
-{
- ASSERT(!element.renderer());
-
- RefPtr<RenderStyle> style = resolvedStyle;
-
- if (!shouldCreateRenderer(element, renderTreePosition.parent()))
- return;
-
- if (!style)
- style = styleForElement(element, inheritedStyle);
-
- RenderNamedFlowThread* parentFlowRenderer = 0;
-#if ENABLE(CSS_REGIONS)
- parentFlowRenderer = moveToFlowThreadIfNeeded(element, *style);
-#endif
-
- if (!element.rendererIsNeeded(*style))
- return;
-
- renderTreePosition.computeNextSibling(element);
-
- RenderTreePosition insertionPosition = parentFlowRenderer
- ? RenderTreePosition(*parentFlowRenderer, parentFlowRenderer->nextRendererForElement(element))
- : renderTreePosition;
-
- RenderElement* newRenderer = element.createElementRenderer(style.releaseNonNull(), insertionPosition).leakPtr();
- if (!newRenderer)
- return;
- if (!insertionPosition.canInsert(*newRenderer)) {
- newRenderer->destroy();
- return;
- }
-
- // Make sure the RenderObject already knows it is going to be added to a RenderFlowThread before we set the style
- // for the first time. Otherwise code using inRenderFlowThread() in the styleWillChange and styleDidChange will fail.
- newRenderer->setFlowThreadState(insertionPosition.parent().flowThreadState());
-
- // Code below updateAnimations() can depend on Element::renderer() already being set.
- element.setRenderer(newRenderer);
-
- // FIXME: There's probably a better way to factor this.
- // This just does what setAnimatedStyle() does, except with setStyleInternal() instead of setStyle().
- Ref<RenderStyle> animatedStyle = newRenderer->style();
- newRenderer->animation().updateAnimations(*newRenderer, animatedStyle, animatedStyle);
- newRenderer->setStyleInternal(WTFMove(animatedStyle));
-
- newRenderer->initializeStyle();
-
-#if ENABLE(FULLSCREEN_API)
- Document& document = element.document();
- if (document.webkitIsFullScreen() && document.webkitCurrentFullScreenElement() == &element) {
- newRenderer = RenderFullScreen::wrapRenderer(newRenderer, &insertionPosition.parent(), document);
- if (!newRenderer)
- return;
- }
-#endif
- // Note: Adding newRenderer instead of renderer(). renderer() may be a child of newRenderer.
- insertionPosition.insert(*newRenderer);
-}
-
-static void invalidateWhitespaceOnlyTextSiblingsAfterAttachIfNeeded(Node& current)
-{
- // FIXME: This needs to traverse in composed tree order.
-
- // This function finds sibling text renderers where the results of textRendererIsNeeded may have changed as a result of
- // the current node gaining or losing the renderer. This can only affect white space text nodes.
- for (Node* sibling = current.nextSibling(); sibling; sibling = sibling->nextSibling()) {
- if (sibling->needsStyleRecalc())
- return;
- if (is<Element>(*sibling)) {
- // Text renderers beyond rendered elements can't be affected.
- if (!sibling->renderer() || RenderTreePosition::isRendererReparented(*sibling->renderer()))
- continue;
- return;
- }
- if (!is<Text>(*sibling))
- continue;
- Text& textSibling = downcast<Text>(*sibling);
- if (!textSibling.containsOnlyWhitespace())
- continue;
- textSibling.setNeedsStyleRecalc();
- }
-}
-
-static bool textRendererIsNeeded(const Text& textNode, const RenderTreePosition& renderTreePosition)
-{
- const RenderElement& parentRenderer = renderTreePosition.parent();
- if (!parentRenderer.canHaveChildren())
- return false;
- if (parentRenderer.element() && !parentRenderer.element()->childShouldCreateRenderer(textNode))
- return false;
- if (textNode.isEditingText())
- return true;
- if (!textNode.length())
- return false;
- if (!textNode.containsOnlyWhitespace())
- return true;
- // This text node has nothing but white space. We may still need a renderer in some cases.
- if (parentRenderer.isTable() || parentRenderer.isTableRow() || parentRenderer.isTableSection() || parentRenderer.isRenderTableCol() || parentRenderer.isFrameSet())
- return false;
- if (parentRenderer.style().preserveNewline()) // pre/pre-wrap/pre-line always make renderers.
- return true;
-
- RenderObject* previousRenderer = renderTreePosition.previousSiblingRenderer(textNode);
- if (previousRenderer && previousRenderer->isBR()) // <span><br/> <br/></span>
- return false;
-
- if (parentRenderer.isRenderInline()) {
- // <span><div/> <div/></span>
- if (previousRenderer && !previousRenderer->isInline())
- return false;
- } else {
- if (parentRenderer.isRenderBlock() && !parentRenderer.childrenInline() && (!previousRenderer || !previousRenderer->isInline()))
- return false;
-
- RenderObject* first = parentRenderer.firstChild();
- while (first && first->isFloatingOrOutOfFlowPositioned())
- first = first->nextSibling();
- RenderObject* nextRenderer = renderTreePosition.nextSiblingRenderer(textNode);
- if (!first || nextRenderer == first) {
- // Whitespace at the start of a block just goes away. Don't even make a render object for this text.
- return false;
- }
- }
- return true;
-}
-
-static void createTextRendererIfNeeded(Text& textNode, RenderTreePosition& renderTreePosition)
-{
- ASSERT(!textNode.renderer());
-
- if (!textRendererIsNeeded(textNode, renderTreePosition))
- return;
-
- auto newRenderer = textNode.createTextRenderer(renderTreePosition.parent().style());
- ASSERT(newRenderer);
-
- renderTreePosition.computeNextSibling(textNode);
-
- if (!renderTreePosition.canInsert(*newRenderer))
- return;
-
- // Make sure the RenderObject already knows it is going to be added to a RenderFlowThread before we set the style
- // for the first time. Otherwise code using inRenderFlowThread() in the styleWillChange and styleDidChange will fail.
- newRenderer->setFlowThreadState(renderTreePosition.parent().flowThreadState());
-
- textNode.setRenderer(newRenderer.get());
- // Parent takes care of the animations, no need to call setAnimatableStyle.
- renderTreePosition.insert(*newRenderer.leakPtr());
-}
-
-void attachTextRenderer(Text& textNode, RenderTreePosition& renderTreePosition)
-{
- createTextRendererIfNeeded(textNode, renderTreePosition);
-
- textNode.clearNeedsStyleRecalc();
-}
-
-void detachTextRenderer(Text& textNode)
-{
- if (textNode.renderer())
- textNode.renderer()->destroyAndCleanupAnonymousWrappers();
- textNode.setRenderer(0);
-}
-
-void updateTextRendererAfterContentChange(Text& textNode, unsigned offsetOfReplacedData, unsigned lengthOfReplacedData)
-{
- auto* renderingParentNode = composedTreeAncestors(textNode).first();
- if (!renderingParentNode || !renderingParentNode->renderer())
- return;
-
- bool hadRenderer = textNode.renderer();
-
- RenderTreePosition renderTreePosition(*renderingParentNode->renderer());
- resolveTextNode(textNode, renderTreePosition);
-
- if (hadRenderer && textNode.renderer())
- textNode.renderer()->setTextWithOffset(textNode.data(), offsetOfReplacedData, lengthOfReplacedData);
-}
-
-static void attachChildren(ContainerNode& current, RenderStyle& inheritedStyle, RenderTreePosition& renderTreePosition)
-{
- for (Node* child = current.firstChild(); child; child = child->nextSibling()) {
- ASSERT((!child->renderer() || child->isNamedFlowContentNode()) || current.shadowRoot());
- if (child->renderer()) {
- renderTreePosition.invalidateNextSibling(*child->renderer());
- continue;
- }
- if (is<Text>(*child)) {
- attachTextRenderer(downcast<Text>(*child), renderTreePosition);
- continue;
- }
- if (is<Element>(*child))
- attachRenderTree(downcast<Element>(*child), inheritedStyle, renderTreePosition, nullptr);
- }
-}
-
-static void attachShadowRoot(ShadowRoot& shadowRoot)
-{
- ASSERT(shadowRoot.host());
- ASSERT(shadowRoot.host()->renderer());
-
- auto& renderer = *shadowRoot.host()->renderer();
- RenderTreePosition renderTreePosition(renderer);
- attachChildren(shadowRoot, renderer.style(), renderTreePosition);
-
- shadowRoot.clearNeedsStyleRecalc();
- shadowRoot.clearChildNeedsStyleRecalc();
-}
-
-static PseudoElement* beforeOrAfterPseudoElement(Element& current, PseudoId pseudoId)
-{
- ASSERT(pseudoId == BEFORE || pseudoId == AFTER);
- if (pseudoId == BEFORE)
- return current.beforePseudoElement();
- return current.afterPseudoElement();
-}
-
-static void setBeforeOrAfterPseudoElement(Element& current, Ref<PseudoElement>&& pseudoElement, PseudoId pseudoId)
-{
- ASSERT(pseudoId == BEFORE || pseudoId == AFTER);
- if (pseudoId == BEFORE) {
- current.setBeforePseudoElement(WTFMove(pseudoElement));
- return;
- }
- current.setAfterPseudoElement(WTFMove(pseudoElement));
-}
-
-static void clearBeforeOrAfterPseudoElement(Element& current, PseudoId pseudoId)
-{
- ASSERT(pseudoId == BEFORE || pseudoId == AFTER);
- if (pseudoId == BEFORE) {
- current.clearBeforePseudoElement();
- return;
- }
- current.clearAfterPseudoElement();
-}
-
-static void resetStyleForNonRenderedDescendants(Element& current)
-{
- ASSERT(!current.renderer());
- bool elementNeedingStyleRecalcAffectsNextSiblingElementStyle = false;
- for (auto& child : childrenOfType<Element>(current)) {
- ASSERT(!child.renderer());
- if (elementNeedingStyleRecalcAffectsNextSiblingElementStyle) {
- if (child.styleIsAffectedByPreviousSibling())
- child.setNeedsStyleRecalc();
- elementNeedingStyleRecalcAffectsNextSiblingElementStyle = child.affectsNextSiblingElementStyle();
- }
-
- if (child.needsStyleRecalc()) {
- child.resetComputedStyle();
- child.clearNeedsStyleRecalc();
- elementNeedingStyleRecalcAffectsNextSiblingElementStyle = child.affectsNextSiblingElementStyle();
- }
-
- if (child.childNeedsStyleRecalc()) {
- resetStyleForNonRenderedDescendants(child);
- child.clearChildNeedsStyleRecalc();
- }
- }
-}
-
-static bool needsPseudoElement(Element& current, PseudoId pseudoId)
-{
- if (!current.renderer() || !current.renderer()->canHaveGeneratedChildren())
- return false;
- if (current.isPseudoElement())
- return false;
- if (!pseudoElementRendererIsNeeded(current.renderer()->getCachedPseudoStyle(pseudoId)))
- return false;
- return true;
-}
-
-static void attachBeforeOrAfterPseudoElementIfNeeded(Element& current, PseudoId pseudoId, RenderTreePosition& renderTreePosition)
-{
- if (!needsPseudoElement(current, pseudoId))
- return;
- Ref<PseudoElement> pseudoElement = PseudoElement::create(current, pseudoId);
- InspectorInstrumentation::pseudoElementCreated(pseudoElement->document().page(), pseudoElement.get());
- setBeforeOrAfterPseudoElement(current, pseudoElement.copyRef(), pseudoId);
- attachRenderTree(pseudoElement.get(), *current.renderStyle(), renderTreePosition, nullptr);
-}
-
-#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
-static void attachSlotAssignees(HTMLSlotElement& slot, RenderStyle& inheritedStyle, RenderTreePosition& renderTreePosition)
-{
- if (auto* assignedNodes = slot.assignedNodes()) {
- for (auto* child : *assignedNodes) {
- if (is<Text>(*child))
- attachTextRenderer(downcast<Text>(*child), renderTreePosition);
- else if (is<Element>(*child))
- attachRenderTree(downcast<Element>(*child), inheritedStyle, renderTreePosition, nullptr);
- }
- } else
- attachChildren(slot, inheritedStyle, renderTreePosition);
-
- slot.clearNeedsStyleRecalc();
- slot.clearChildNeedsStyleRecalc();
-}
-#endif
-
-static void attachRenderTree(Element& current, RenderStyle& inheritedStyle, RenderTreePosition& renderTreePosition, PassRefPtr<RenderStyle> resolvedStyle)
-{
- PostResolutionCallbackDisabler callbackDisabler(current.document());
- WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
-
-#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
- if (is<HTMLSlotElement>(current)) {
- attachSlotAssignees(downcast<HTMLSlotElement>(current), inheritedStyle, renderTreePosition);
- return;
- }
-#endif
-
- if (current.hasCustomStyleResolveCallbacks())
- current.willAttachRenderers();
-
- createRendererIfNeeded(current, inheritedStyle, renderTreePosition, resolvedStyle);
-
- if (auto* renderer = current.renderer()) {
- StyleResolverParentPusher parentPusher(&current);
-
- RenderTreePosition childRenderTreePosition(*renderer);
- attachBeforeOrAfterPseudoElementIfNeeded(current, BEFORE, childRenderTreePosition);
-
- auto* shadowRoot = current.shadowRoot();
- if (shadowRoot) {
- parentPusher.push();
- attachShadowRoot(*shadowRoot);
- } else if (current.firstChild())
- parentPusher.push();
-
- bool skipChildren = shadowRoot;
- if (!skipChildren)
- attachChildren(current, renderer->style(), childRenderTreePosition);
-
- if (AXObjectCache* cache = current.document().axObjectCache())
- cache->updateCacheAfterNodeIsAttached(&current);
-
- attachBeforeOrAfterPseudoElementIfNeeded(current, AFTER, childRenderTreePosition);
-
- current.updateFocusAppearanceAfterAttachIfNeeded();
- } else
- resetStyleForNonRenderedDescendants(current);
-
- current.clearNeedsStyleRecalc();
- current.clearChildNeedsStyleRecalc();
-
- if (current.hasCustomStyleResolveCallbacks())
- current.didAttachRenderers();
-}
-
-static void detachChildren(ContainerNode& current, DetachType detachType)
-{
- for (Node* child = current.firstChild(); child; child = child->nextSibling()) {
- if (is<Text>(*child))
- detachTextRenderer(downcast<Text>(*child));
- else if (is<Element>(*child))
- detachRenderTree(downcast<Element>(*child), detachType);
- }
- current.clearChildNeedsStyleRecalc();
-}
-
-static void detachShadowRoot(ShadowRoot& shadowRoot, DetachType detachType)
-{
- detachChildren(shadowRoot, detachType);
-}
-
-#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
-static void detachSlotAssignees(HTMLSlotElement& slot, DetachType detachType)
-{
- ASSERT(!slot.renderer());
- if (auto* assignedNodes = slot.assignedNodes()) {
- for (auto* child : *assignedNodes) {
- if (is<Text>(*child))
- detachTextRenderer(downcast<Text>(*child));
- else if (is<Element>(*child))
- detachRenderTree(downcast<Element>(*child), detachType);
- }
- } else
- detachChildren(slot, detachType);
-
- slot.clearNeedsStyleRecalc();
- slot.clearChildNeedsStyleRecalc();
-}
-#endif
-
-static void detachRenderTree(Element& current, DetachType detachType)
-{
- WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
-
- if (current.hasCustomStyleResolveCallbacks())
- current.willDetachRenderers();
-
- current.clearStyleDerivedDataBeforeDetachingRenderer();
-
- // Do not remove the element's hovered and active status
- // if performing a reattach.
- if (detachType != ReattachDetach)
- current.clearHoverAndActiveStatusBeforeDetachingRenderer();
-
-#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
- if (is<HTMLSlotElement>(current))
- detachSlotAssignees(downcast<HTMLSlotElement>(current), detachType);
-#endif
- else if (ShadowRoot* shadowRoot = current.shadowRoot())
- detachShadowRoot(*shadowRoot, detachType);
-
- detachChildren(current, detachType);
-
- if (current.renderer())
- current.renderer()->destroyAndCleanupAnonymousWrappers();
- current.setRenderer(0);
-
- if (current.hasCustomStyleResolveCallbacks())
- current.didDetachRenderers();
-}
-
-static bool pseudoStyleCacheIsInvalid(RenderElement* renderer, RenderStyle* newStyle)
-{
- const RenderStyle& currentStyle = renderer->style();
-
- const PseudoStyleCache* pseudoStyleCache = currentStyle.cachedPseudoStyles();
- if (!pseudoStyleCache)
- return false;
-
- for (auto& cache : *pseudoStyleCache) {
- RefPtr<RenderStyle> newPseudoStyle;
- PseudoId pseudoId = cache->styleType();
- if (pseudoId == FIRST_LINE || pseudoId == FIRST_LINE_INHERITED)
- newPseudoStyle = renderer->uncachedFirstLineStyle(newStyle);
- else
- newPseudoStyle = renderer->getUncachedPseudoStyle(PseudoStyleRequest(pseudoId), newStyle, newStyle);
- if (!newPseudoStyle)
- return true;
- if (*newPseudoStyle != *cache) {
- if (pseudoId < FIRST_INTERNAL_PSEUDOID)
- newStyle->setHasPseudoStyle(pseudoId);
- newStyle->addCachedPseudoStyle(newPseudoStyle);
- if (pseudoId == FIRST_LINE || pseudoId == FIRST_LINE_INHERITED) {
- // FIXME: We should do an actual diff to determine whether a repaint vs. layout
- // is needed, but for now just assume a layout will be required. The diff code
- // in RenderObject::setStyle would need to be factored out so that it could be reused.
- renderer->setNeedsLayoutAndPrefWidthsRecalc();
- }
- return true;
- }
- }
- return false;
-}
-
-static Change resolveLocal(Element& current, RenderStyle& inheritedStyle, RenderTreePosition& renderTreePosition, Change inheritedChange)
-{
- Change localChange = Detach;
- RefPtr<RenderStyle> newStyle;
- RefPtr<RenderStyle> currentStyle = current.renderStyle();
-
- Document& document = current.document();
- if (currentStyle && current.styleChangeType() != ReconstructRenderTree) {
- Ref<RenderStyle> style(styleForElement(current, inheritedStyle));
- newStyle = style.ptr();
- localChange = determineChange(*currentStyle, style);
- }
- if (localChange == Detach) {
- if (current.renderer() || current.isNamedFlowContentNode())
- detachRenderTree(current, ReattachDetach);
- attachRenderTree(current, inheritedStyle, renderTreePosition, newStyle.release());
- invalidateWhitespaceOnlyTextSiblingsAfterAttachIfNeeded(current);
-
- return Detach;
- }
-
- if (RenderElement* renderer = current.renderer()) {
- if (localChange != NoChange || pseudoStyleCacheIsInvalid(renderer, newStyle.get()) || (inheritedChange == Force && renderer->requiresForcedStyleRecalcPropagation()) || current.styleChangeType() == SyntheticStyleChange)
- renderer->setAnimatableStyle(*newStyle, current.styleChangeType() == SyntheticStyleChange ? StyleDifferenceRecompositeLayer : StyleDifferenceEqual);
- else if (current.needsStyleRecalc()) {
- // Although no change occurred, we use the new style so that the cousin style sharing code won't get
- // fooled into believing this style is the same.
- renderer->setStyleInternal(*newStyle);
- }
- }
-
- // If "rem" units are used anywhere in the document, and if the document element's font size changes, then force font updating
- // all the way down the tree. This is simpler than having to maintain a cache of objects (and such font size changes should be rare anyway).
- if (document.authorStyleSheets().usesRemUnits() && document.documentElement() == &current && localChange != NoChange && currentStyle && newStyle && currentStyle->fontSize() != newStyle->fontSize()) {
- // Cached RenderStyles may depend on the re units.
- if (StyleResolver* styleResolver = document.styleResolverIfExists())
- styleResolver->invalidateMatchedPropertiesCache();
- return Force;
- }
- if (inheritedChange == Force)
- return Force;
- if (current.styleChangeType() >= FullStyleChange)
- return Force;
-
- return localChange;
-}
-
-void resolveTextNode(Text& text, RenderTreePosition& renderTreePosition)
-{
- text.clearNeedsStyleRecalc();
-
- bool hasRenderer = text.renderer();
- bool needsRenderer = textRendererIsNeeded(text, renderTreePosition);
- if (hasRenderer) {
- if (needsRenderer)
- return;
- detachTextRenderer(text);
- invalidateWhitespaceOnlyTextSiblingsAfterAttachIfNeeded(text);
- return;
- }
- if (!needsRenderer)
- return;
- attachTextRenderer(text, renderTreePosition);
- invalidateWhitespaceOnlyTextSiblingsAfterAttachIfNeeded(text);
-}
-
-static void resolveChildAtShadowBoundary(Node& child, RenderStyle& inheritedStyle, RenderTreePosition& renderTreePosition, Style::Change change)
-{
- if (auto* renderer = child.renderer())
- renderTreePosition.invalidateNextSibling(*renderer);
-
- if (is<Text>(child) && child.needsStyleRecalc()) {
- resolveTextNode(downcast<Text>(child), renderTreePosition);
- return;
- }
- if (is<Element>(child))
- resolveTree(downcast<Element>(child), inheritedStyle, renderTreePosition, change);
-}
-
-static void resolveShadowTree(ShadowRoot& shadowRoot, Element& host, Style::Change change)
-{
- ASSERT(shadowRoot.host() == &host);
- ASSERT(host.renderer());
- auto& inheritedStyle = host.renderer()->style();
- if (shadowRoot.styleChangeType() >= FullStyleChange)
- change = Force;
- RenderTreePosition renderTreePosition(*host.renderer());
- for (auto* child = shadowRoot.firstChild(); child; child = child->nextSibling())
- resolveChildAtShadowBoundary(*child, inheritedStyle, renderTreePosition, change);
-
- shadowRoot.clearNeedsStyleRecalc();
- shadowRoot.clearChildNeedsStyleRecalc();
-}
-
-static void updateBeforeOrAfterPseudoElement(Element& current, Change change, PseudoId pseudoId, RenderTreePosition& renderTreePosition)
-{
- ASSERT(current.renderer());
- if (PseudoElement* existingPseudoElement = beforeOrAfterPseudoElement(current, pseudoId)) {
- if (existingPseudoElement->renderer())
- renderTreePosition.invalidateNextSibling(*existingPseudoElement->renderer());
-
- if (needsPseudoElement(current, pseudoId))
- resolveTree(*existingPseudoElement, current.renderer()->style(), renderTreePosition, current.needsStyleRecalc() ? Force : change);
- else
- clearBeforeOrAfterPseudoElement(current, pseudoId);
- return;
- }
- attachBeforeOrAfterPseudoElementIfNeeded(current, pseudoId, renderTreePosition);
-}
-
-#if PLATFORM(IOS)
-static EVisibility elementImplicitVisibility(const Element* element)
-{
- RenderObject* renderer = element->renderer();
- if (!renderer)
- return VISIBLE;
-
- RenderStyle& style = renderer->style();
-
- Length width(style.width());
- Length height(style.height());
- if ((width.isFixed() && width.value() <= 0) || (height.isFixed() && height.value() <= 0))
- return HIDDEN;
-
- Length top(style.top());
- Length left(style.left());
- if (left.isFixed() && width.isFixed() && -left.value() >= width.value())
- return HIDDEN;
-
- if (top.isFixed() && height.isFixed() && -top.value() >= height.value())
- return HIDDEN;
- return VISIBLE;
-}
-
-class CheckForVisibilityChangeOnRecalcStyle {
-public:
- CheckForVisibilityChangeOnRecalcStyle(Element* element, RenderStyle* currentStyle)
- : m_element(element)
- , m_previousDisplay(currentStyle ? currentStyle->display() : NONE)
- , m_previousVisibility(currentStyle ? currentStyle->visibility() : HIDDEN)
- , m_previousImplicitVisibility(WKObservingContentChanges() && WKContentChange() != WKContentVisibilityChange ? elementImplicitVisibility(element) : VISIBLE)
- {
- }
- ~CheckForVisibilityChangeOnRecalcStyle()
- {
- if (!WKObservingContentChanges())
- return;
- if (m_element->isInUserAgentShadowTree())
- return;
- RenderStyle* style = m_element->renderStyle();
- if (!style)
- return;
- if ((m_previousDisplay == NONE && style->display() != NONE) || (m_previousVisibility == HIDDEN && style->visibility() != HIDDEN)
- || (m_previousImplicitVisibility == HIDDEN && elementImplicitVisibility(m_element.get()) == VISIBLE))
- WKSetObservedContentChange(WKContentVisibilityChange);
- }
-private:
- RefPtr<Element> m_element;
- EDisplay m_previousDisplay;
- EVisibility m_previousVisibility;
- EVisibility m_previousImplicitVisibility;
-};
-#endif // PLATFORM(IOS)
-
-static void resolveChildren(Element& current, RenderStyle& inheritedStyle, Change change, RenderTreePosition& childRenderTreePosition)
-{
- StyleResolverParentPusher parentPusher(&current);
-
- bool elementNeedingStyleRecalcAffectsNextSiblingElementStyle = false;
- for (Node* child = current.firstChild(); child; child = child->nextSibling()) {
- if (RenderObject* childRenderer = child->renderer())
- childRenderTreePosition.invalidateNextSibling(*childRenderer);
- if (is<Text>(*child) && child->needsStyleRecalc()) {
- resolveTextNode(downcast<Text>(*child), childRenderTreePosition);
- continue;
- }
- if (!is<Element>(*child))
- continue;
-
- Element& childElement = downcast<Element>(*child);
- if (elementNeedingStyleRecalcAffectsNextSiblingElementStyle) {
- if (childElement.styleIsAffectedByPreviousSibling())
- childElement.setNeedsStyleRecalc();
- elementNeedingStyleRecalcAffectsNextSiblingElementStyle = childElement.affectsNextSiblingElementStyle();
- } else if (childElement.needsStyleRecalc())
- elementNeedingStyleRecalcAffectsNextSiblingElementStyle = childElement.affectsNextSiblingElementStyle();
- if (change >= Inherit || childElement.childNeedsStyleRecalc() || childElement.needsStyleRecalc()) {
- parentPusher.push();
- resolveTree(childElement, inheritedStyle, childRenderTreePosition, change);
- }
- }
-}
-
-#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
-static void resolveSlotAssignees(HTMLSlotElement& slot, RenderStyle& inheritedStyle, RenderTreePosition& renderTreePosition, Change change)
-{
- if (auto* assignedNodes = slot.assignedNodes()) {
- for (auto* child : *assignedNodes)
- resolveChildAtShadowBoundary(*child, inheritedStyle, renderTreePosition, change);
- } else
- resolveChildren(slot, inheritedStyle, change, renderTreePosition);
-
- slot.clearNeedsStyleRecalc();
- slot.clearChildNeedsStyleRecalc();
-}
-#endif
-
-void resolveTree(Element& current, RenderStyle& inheritedStyle, RenderTreePosition& renderTreePosition, Change change)
-{
- ASSERT(change != Detach);
-
-#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
- if (is<HTMLSlotElement>(current)) {
- resolveSlotAssignees(downcast<HTMLSlotElement>(current), inheritedStyle, renderTreePosition, change);
- return;
- }
-#endif
-
- if (current.hasCustomStyleResolveCallbacks()) {
- if (!current.willRecalcStyle(change))
- return;
- }
-
-#if PLATFORM(IOS)
- CheckForVisibilityChangeOnRecalcStyle checkForVisibilityChange(&current, current.renderStyle());
-#endif
-
- if (change > NoChange || current.needsStyleRecalc())
- current.resetComputedStyle();
-
- if (change >= Inherit || current.needsStyleRecalc())
- change = resolveLocal(current, inheritedStyle, renderTreePosition, change);
-
- auto* renderer = current.renderer();
-
- if (change != Detach && renderer) {
- auto* shadowRoot = current.shadowRoot();
- if (shadowRoot && (change >= Inherit || shadowRoot->childNeedsStyleRecalc() || shadowRoot->needsStyleRecalc()))
- resolveShadowTree(*shadowRoot, current, change);
-
- RenderTreePosition childRenderTreePosition(*renderer);
- updateBeforeOrAfterPseudoElement(current, change, BEFORE, childRenderTreePosition);
-
- bool skipChildren = shadowRoot;
- if (!skipChildren)
- resolveChildren(current, renderer->style(), change, childRenderTreePosition);
-
- updateBeforeOrAfterPseudoElement(current, change, AFTER, childRenderTreePosition);
- }
- if (change != Detach && !renderer)
- resetStyleForNonRenderedDescendants(current);
-
- current.clearNeedsStyleRecalc();
- current.clearChildNeedsStyleRecalc();
-
- if (current.hasCustomStyleResolveCallbacks())
- current.didRecalcStyle(change);
-}
-
-void resolveTree(Document& document, Change change)
-{
- auto& renderView = *document.renderView();
-
- if (change == Force) {
- auto documentStyle = resolveForDocument(document);
-
- // Inserting the pictograph font at the end of the font fallback list is done by the
- // font selector, so set a font selector if needed.
- if (Settings* settings = document.settings()) {
- if (settings->fontFallbackPrefersPictographs())
- documentStyle.get().fontCascade().update(&document.fontSelector());
- }
-
- Style::Change documentChange = determineChange(documentStyle.get(), renderView.style());
- if (documentChange != NoChange)
- renderView.setStyle(WTFMove(documentStyle));
- }
-
- Element* documentElement = document.documentElement();
- if (!documentElement)
- return;
- if (change < Inherit && !documentElement->childNeedsStyleRecalc() && !documentElement->needsStyleRecalc())
- return;
-
- auto& styleResolved = document.ensureStyleResolver();
-
- // Pseudo element removal and similar may only work with these flags still set. Reset them after the style recalc.
- renderView.setUsesFirstLineRules(renderView.usesFirstLineRules() || styleResolved.usesFirstLineRules());
- renderView.setUsesFirstLetterRules(renderView.usesFirstLetterRules() || styleResolved.usesFirstLetterRules());
-
- RenderTreePosition renderTreePosition(renderView);
- resolveTree(*documentElement, *document.renderStyle(), renderTreePosition, change);
-
- renderView.setUsesFirstLineRules(styleResolved.usesFirstLineRules());
- renderView.setUsesFirstLetterRules(styleResolved.usesFirstLetterRules());
-}
-
-void detachRenderTree(Element& element)
-{
- detachRenderTree(element, NormalDetach);
-}
-
-static Vector<std::function<void ()>>& postResolutionCallbackQueue()
-{
- static NeverDestroyed<Vector<std::function<void ()>>> vector;
- return vector;
-}
-
-void queuePostResolutionCallback(std::function<void ()> callback)
-{
- postResolutionCallbackQueue().append(callback);
-}
-
-static void suspendMemoryCacheClientCalls(Document& document)
-{
- Page* page = document.page();
- if (!page || !page->areMemoryCacheClientCallsEnabled())
- return;
-
- page->setMemoryCacheClientCallsEnabled(false);
-
- RefPtr<MainFrame> protectedMainFrame = &page->mainFrame();
- postResolutionCallbackQueue().append([protectedMainFrame]{
- if (Page* page = protectedMainFrame->page())
- page->setMemoryCacheClientCallsEnabled(true);
- });
-}
-
-static unsigned resolutionNestingDepth;
-
-PostResolutionCallbackDisabler::PostResolutionCallbackDisabler(Document& document)
-{
- ++resolutionNestingDepth;
-
- if (resolutionNestingDepth == 1)
- platformStrategies()->loaderStrategy()->suspendPendingRequests();
-
- // FIXME: It's strange to build this into the disabler.
- suspendMemoryCacheClientCalls(document);
-}
-
-PostResolutionCallbackDisabler::~PostResolutionCallbackDisabler()
-{
- if (resolutionNestingDepth == 1) {
- // Get size each time through the loop because a callback can add more callbacks to the end of the queue.
- auto& queue = postResolutionCallbackQueue();
- for (size_t i = 0; i < queue.size(); ++i)
- queue[i]();
- queue.clear();
-
- platformStrategies()->loaderStrategy()->resumePendingRequests();
- }
-
- --resolutionNestingDepth;
-}
-
-bool postResolutionCallbacksAreSuspended()
-{
- return resolutionNestingDepth;
-}
-
-}
-}
</del></span></pre></div>
<a id="trunkSourceWebCorestyleStyleResolveTreeh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/WebCore/style/StyleResolveTree.h (194690 => 194691)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/style/StyleResolveTree.h        2016-01-07 08:14:39 UTC (rev 194690)
+++ trunk/Source/WebCore/style/StyleResolveTree.h        2016-01-07 08:16:49 UTC (rev 194691)
</span><span class="lines">@@ -1,62 +0,0 @@
</span><del>-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef StyleResolveTree_h
-#define StyleResolveTree_h
-
-#include "StyleChange.h"
-#include <functional>
-
-namespace WebCore {
-
-class Document;
-class Element;
-class RenderStyle;
-class Settings;
-class Text;
-
-namespace Style {
-
-void resolveTree(Document&, Change);
-
-void detachRenderTree(Element&);
-void detachTextRenderer(Text&);
-
-void updateTextRendererAfterContentChange(Text&, unsigned offsetOfReplacedData, unsigned lengthOfReplacedData);
-
-void queuePostResolutionCallback(std::function<void ()>);
-bool postResolutionCallbacksAreSuspended();
-
-class PostResolutionCallbackDisabler {
-public:
- explicit PostResolutionCallbackDisabler(Document&);
- ~PostResolutionCallbackDisabler();
-};
-
-}
-
-}
-
-#endif
</del></span></pre></div>
<a id="trunkSourceWebCorestyleStyleTreeResolvercppfromrev194584trunkSourceWebCorestyleStyleResolveTreecpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/style/StyleTreeResolver.cpp (from rev 194584, trunk/Source/WebCore/style/StyleResolveTree.cpp) (0 => 194691)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/style/StyleTreeResolver.cpp         (rev 0)
+++ trunk/Source/WebCore/style/StyleTreeResolver.cpp        2016-01-07 08:16:49 UTC (rev 194691)
</span><span class="lines">@@ -0,0 +1,917 @@
</span><ins>+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * (C) 2001 Peter Kelly (pmk@post.com)
+ * (C) 2001 Dirk Mueller (mueller@kde.org)
+ * (C) 2007 David Smith (catfish.man@gmail.com)
+ * Copyright (C) 2004-2010, 2012-2014 Apple Inc. All rights reserved.
+ * (C) 2007 Eric Seidel (eric@webkit.org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "StyleTreeResolver.h"
+
+#include "AXObjectCache.h"
+#include "AnimationController.h"
+#include "AuthorStyleSheets.h"
+#include "CSSFontSelector.h"
+#include "ComposedTreeAncestorIterator.h"
+#include "ComposedTreeIterator.h"
+#include "ElementIterator.h"
+#include "ElementRareData.h"
+#include "FlowThreadController.h"
+#include "HTMLSlotElement.h"
+#include "InspectorInstrumentation.h"
+#include "LoaderStrategy.h"
+#include "MainFrame.h"
+#include "NodeRenderStyle.h"
+#include "NodeTraversal.h"
+#include "PlatformStrategies.h"
+#include "RenderFullScreen.h"
+#include "RenderNamedFlowThread.h"
+#include "RenderText.h"
+#include "RenderTreePosition.h"
+#include "RenderWidget.h"
+#include "Settings.h"
+#include "ShadowRoot.h"
+#include "StyleResolver.h"
+#include "Text.h"
+
+#if PLATFORM(IOS)
+#include "WKContentObservation.h"
+#endif
+
+namespace WebCore {
+
+namespace Style {
+
+enum DetachType { NormalDetach, ReattachDetach };
+
+static void attachTextRenderer(Text&, RenderTreePosition&);
+static void detachRenderTree(Element&, DetachType);
+static void resolveTextNode(Text&, RenderTreePosition&);
+
+TreeResolver::TreeResolver(Document& document)
+ : m_document(document)
+ , m_styleResolver(document.ensureStyleResolver())
+{
+}
+
+TreeResolver::TreeResolver(ShadowRoot& shadowRoot, TreeResolver& shadowHostTreeResolver)
+ : m_document(shadowRoot.document())
+ , m_styleResolver(shadowRoot.styleResolver())
+ , m_shadowRoot(&shadowRoot)
+ , m_shadowHostTreeResolver(&shadowHostTreeResolver)
+{
+}
+
+static bool shouldCreateRenderer(const Element& element, const RenderElement& parentRenderer)
+{
+ if (!element.document().shouldCreateRenderers())
+ return false;
+ if (!parentRenderer.canHaveChildren() && !(element.isPseudoElement() && parentRenderer.canHaveGeneratedChildren()))
+ return false;
+ if (parentRenderer.element() && !parentRenderer.element()->childShouldCreateRenderer(element))
+ return false;
+ return true;
+}
+
+Ref<RenderStyle> TreeResolver::styleForElement(Element& element, RenderStyle& inheritedStyle)
+{
+ if (element.hasCustomStyleResolveCallbacks()) {
+ if (RefPtr<RenderStyle> style = element.customStyleForRenderer(inheritedStyle))
+ return style.releaseNonNull();
+ }
+ return m_styleResolver.styleForElement(&element, &inheritedStyle);
+}
+
+#if ENABLE(CSS_REGIONS)
+static RenderNamedFlowThread* moveToFlowThreadIfNeeded(Element& element, const RenderStyle& style)
+{
+ if (!element.shouldMoveToFlowThread(style))
+ return 0;
+
+ FlowThreadController& flowThreadController = element.document().renderView()->flowThreadController();
+ RenderNamedFlowThread& parentFlowRenderer = flowThreadController.ensureRenderFlowThreadWithName(style.flowThread());
+ flowThreadController.registerNamedFlowContentElement(element, parentFlowRenderer);
+ return &parentFlowRenderer;
+}
+#endif
+
+void TreeResolver::createRenderer(Element& element, RenderStyle& inheritedStyle, RenderTreePosition& renderTreePosition, RefPtr<RenderStyle>&& resolvedStyle)
+{
+ ASSERT(!element.renderer());
+
+ RefPtr<RenderStyle> style = resolvedStyle;
+
+ if (!shouldCreateRenderer(element, renderTreePosition.parent()))
+ return;
+
+ if (!style)
+ style = styleForElement(element, inheritedStyle);
+
+ RenderNamedFlowThread* parentFlowRenderer = 0;
+#if ENABLE(CSS_REGIONS)
+ parentFlowRenderer = moveToFlowThreadIfNeeded(element, *style);
+#endif
+
+ if (!element.rendererIsNeeded(*style))
+ return;
+
+ renderTreePosition.computeNextSibling(element);
+
+ RenderTreePosition insertionPosition = parentFlowRenderer
+ ? RenderTreePosition(*parentFlowRenderer, parentFlowRenderer->nextRendererForElement(element))
+ : renderTreePosition;
+
+ RenderElement* newRenderer = element.createElementRenderer(style.releaseNonNull(), insertionPosition).leakPtr();
+ if (!newRenderer)
+ return;
+ if (!insertionPosition.canInsert(*newRenderer)) {
+ newRenderer->destroy();
+ return;
+ }
+
+ // Make sure the RenderObject already knows it is going to be added to a RenderFlowThread before we set the style
+ // for the first time. Otherwise code using inRenderFlowThread() in the styleWillChange and styleDidChange will fail.
+ newRenderer->setFlowThreadState(insertionPosition.parent().flowThreadState());
+
+ // Code below updateAnimations() can depend on Element::renderer() already being set.
+ element.setRenderer(newRenderer);
+
+ // FIXME: There's probably a better way to factor this.
+ // This just does what setAnimatedStyle() does, except with setStyleInternal() instead of setStyle().
+ Ref<RenderStyle> animatedStyle = newRenderer->style();
+ newRenderer->animation().updateAnimations(*newRenderer, animatedStyle, animatedStyle);
+ newRenderer->setStyleInternal(WTFMove(animatedStyle));
+
+ newRenderer->initializeStyle();
+
+#if ENABLE(FULLSCREEN_API)
+ if (m_document.webkitIsFullScreen() && m_document.webkitCurrentFullScreenElement() == &element) {
+ newRenderer = RenderFullScreen::wrapRenderer(newRenderer, &insertionPosition.parent(), m_document);
+ if (!newRenderer)
+ return;
+ }
+#endif
+ // Note: Adding newRenderer instead of renderer(). renderer() may be a child of newRenderer.
+ insertionPosition.insert(*newRenderer);
+}
+
+static void invalidateWhitespaceOnlyTextSiblingsAfterAttachIfNeeded(Node& current)
+{
+ // FIXME: This needs to traverse in composed tree order.
+
+ // This function finds sibling text renderers where the results of textRendererIsNeeded may have changed as a result of
+ // the current node gaining or losing the renderer. This can only affect white space text nodes.
+ for (Node* sibling = current.nextSibling(); sibling; sibling = sibling->nextSibling()) {
+ if (sibling->needsStyleRecalc())
+ return;
+ if (is<Element>(*sibling)) {
+ // Text renderers beyond rendered elements can't be affected.
+ if (!sibling->renderer() || RenderTreePosition::isRendererReparented(*sibling->renderer()))
+ continue;
+ return;
+ }
+ if (!is<Text>(*sibling))
+ continue;
+ Text& textSibling = downcast<Text>(*sibling);
+ if (!textSibling.containsOnlyWhitespace())
+ continue;
+ textSibling.setNeedsStyleRecalc();
+ }
+}
+
+static bool textRendererIsNeeded(const Text& textNode, const RenderTreePosition& renderTreePosition)
+{
+ const RenderElement& parentRenderer = renderTreePosition.parent();
+ if (!parentRenderer.canHaveChildren())
+ return false;
+ if (parentRenderer.element() && !parentRenderer.element()->childShouldCreateRenderer(textNode))
+ return false;
+ if (textNode.isEditingText())
+ return true;
+ if (!textNode.length())
+ return false;
+ if (!textNode.containsOnlyWhitespace())
+ return true;
+ // This text node has nothing but white space. We may still need a renderer in some cases.
+ if (parentRenderer.isTable() || parentRenderer.isTableRow() || parentRenderer.isTableSection() || parentRenderer.isRenderTableCol() || parentRenderer.isFrameSet())
+ return false;
+ if (parentRenderer.style().preserveNewline()) // pre/pre-wrap/pre-line always make renderers.
+ return true;
+
+ RenderObject* previousRenderer = renderTreePosition.previousSiblingRenderer(textNode);
+ if (previousRenderer && previousRenderer->isBR()) // <span><br/> <br/></span>
+ return false;
+
+ if (parentRenderer.isRenderInline()) {
+ // <span><div/> <div/></span>
+ if (previousRenderer && !previousRenderer->isInline())
+ return false;
+ } else {
+ if (parentRenderer.isRenderBlock() && !parentRenderer.childrenInline() && (!previousRenderer || !previousRenderer->isInline()))
+ return false;
+
+ RenderObject* first = parentRenderer.firstChild();
+ while (first && first->isFloatingOrOutOfFlowPositioned())
+ first = first->nextSibling();
+ RenderObject* nextRenderer = renderTreePosition.nextSiblingRenderer(textNode);
+ if (!first || nextRenderer == first) {
+ // Whitespace at the start of a block just goes away. Don't even make a render object for this text.
+ return false;
+ }
+ }
+ return true;
+}
+
+static void createTextRendererIfNeeded(Text& textNode, RenderTreePosition& renderTreePosition)
+{
+ ASSERT(!textNode.renderer());
+
+ if (!textRendererIsNeeded(textNode, renderTreePosition))
+ return;
+
+ auto newRenderer = textNode.createTextRenderer(renderTreePosition.parent().style());
+ ASSERT(newRenderer);
+
+ renderTreePosition.computeNextSibling(textNode);
+
+ if (!renderTreePosition.canInsert(*newRenderer))
+ return;
+
+ // Make sure the RenderObject already knows it is going to be added to a RenderFlowThread before we set the style
+ // for the first time. Otherwise code using inRenderFlowThread() in the styleWillChange and styleDidChange will fail.
+ newRenderer->setFlowThreadState(renderTreePosition.parent().flowThreadState());
+
+ textNode.setRenderer(newRenderer.get());
+ // Parent takes care of the animations, no need to call setAnimatableStyle.
+ renderTreePosition.insert(*newRenderer.leakPtr());
+}
+
+void attachTextRenderer(Text& textNode, RenderTreePosition& renderTreePosition)
+{
+ createTextRendererIfNeeded(textNode, renderTreePosition);
+
+ textNode.clearNeedsStyleRecalc();
+}
+
+void detachTextRenderer(Text& textNode)
+{
+ if (textNode.renderer())
+ textNode.renderer()->destroyAndCleanupAnonymousWrappers();
+ textNode.setRenderer(0);
+}
+
+void updateTextRendererAfterContentChange(Text& textNode, unsigned offsetOfReplacedData, unsigned lengthOfReplacedData)
+{
+ auto* renderingParentNode = composedTreeAncestors(textNode).first();
+ if (!renderingParentNode || !renderingParentNode->renderer())
+ return;
+
+ bool hadRenderer = textNode.renderer();
+
+ RenderTreePosition renderTreePosition(*renderingParentNode->renderer());
+ resolveTextNode(textNode, renderTreePosition);
+
+ if (hadRenderer && textNode.renderer())
+ textNode.renderer()->setTextWithOffset(textNode.data(), offsetOfReplacedData, lengthOfReplacedData);
+}
+
+void TreeResolver::createRenderTreeForChildren(ContainerNode& current, RenderStyle& inheritedStyle, RenderTreePosition& renderTreePosition)
+{
+ for (Node* child = current.firstChild(); child; child = child->nextSibling()) {
+ ASSERT((!child->renderer() || child->isNamedFlowContentNode()) || current.shadowRoot());
+ if (child->renderer()) {
+ renderTreePosition.invalidateNextSibling(*child->renderer());
+ continue;
+ }
+ if (is<Text>(*child)) {
+ attachTextRenderer(downcast<Text>(*child), renderTreePosition);
+ continue;
+ }
+ if (is<Element>(*child))
+ createRenderTreeRecursively(downcast<Element>(*child), inheritedStyle, renderTreePosition, nullptr);
+ }
+}
+
+void TreeResolver::createRenderTreeForShadowRoot(ShadowRoot& shadowRoot)
+{
+ ASSERT(shadowRoot.host());
+ ASSERT(shadowRoot.host()->renderer());
+
+ TreeResolver shadowTreeResolver(shadowRoot, *this);
+
+ auto& renderer = *shadowRoot.host()->renderer();
+ RenderTreePosition renderTreePosition(renderer);
+ shadowTreeResolver.createRenderTreeForChildren(shadowRoot, renderer.style(), renderTreePosition);
+
+ shadowRoot.clearNeedsStyleRecalc();
+ shadowRoot.clearChildNeedsStyleRecalc();
+}
+
+static PseudoElement* beforeOrAfterPseudoElement(Element& current, PseudoId pseudoId)
+{
+ ASSERT(pseudoId == BEFORE || pseudoId == AFTER);
+ if (pseudoId == BEFORE)
+ return current.beforePseudoElement();
+ return current.afterPseudoElement();
+}
+
+static void setBeforeOrAfterPseudoElement(Element& current, Ref<PseudoElement>&& pseudoElement, PseudoId pseudoId)
+{
+ ASSERT(pseudoId == BEFORE || pseudoId == AFTER);
+ if (pseudoId == BEFORE) {
+ current.setBeforePseudoElement(WTFMove(pseudoElement));
+ return;
+ }
+ current.setAfterPseudoElement(WTFMove(pseudoElement));
+}
+
+static void clearBeforeOrAfterPseudoElement(Element& current, PseudoId pseudoId)
+{
+ ASSERT(pseudoId == BEFORE || pseudoId == AFTER);
+ if (pseudoId == BEFORE) {
+ current.clearBeforePseudoElement();
+ return;
+ }
+ current.clearAfterPseudoElement();
+}
+
+static void resetStyleForNonRenderedDescendants(Element& current)
+{
+ ASSERT(!current.renderer());
+ bool elementNeedingStyleRecalcAffectsNextSiblingElementStyle = false;
+ for (auto& child : childrenOfType<Element>(current)) {
+ ASSERT(!child.renderer());
+ if (elementNeedingStyleRecalcAffectsNextSiblingElementStyle) {
+ if (child.styleIsAffectedByPreviousSibling())
+ child.setNeedsStyleRecalc();
+ elementNeedingStyleRecalcAffectsNextSiblingElementStyle = child.affectsNextSiblingElementStyle();
+ }
+
+ if (child.needsStyleRecalc()) {
+ child.resetComputedStyle();
+ child.clearNeedsStyleRecalc();
+ elementNeedingStyleRecalcAffectsNextSiblingElementStyle = child.affectsNextSiblingElementStyle();
+ }
+
+ if (child.childNeedsStyleRecalc()) {
+ resetStyleForNonRenderedDescendants(child);
+ child.clearChildNeedsStyleRecalc();
+ }
+ }
+}
+
+static bool needsPseudoElement(Element& current, PseudoId pseudoId)
+{
+ if (!current.renderer() || !current.renderer()->canHaveGeneratedChildren())
+ return false;
+ if (current.isPseudoElement())
+ return false;
+ if (!pseudoElementRendererIsNeeded(current.renderer()->getCachedPseudoStyle(pseudoId)))
+ return false;
+ return true;
+}
+
+void TreeResolver::createRenderTreeForBeforeOrAfterPseudoElement(Element& current, PseudoId pseudoId, RenderTreePosition& renderTreePosition)
+{
+ if (!needsPseudoElement(current, pseudoId))
+ return;
+ Ref<PseudoElement> pseudoElement = PseudoElement::create(current, pseudoId);
+ InspectorInstrumentation::pseudoElementCreated(m_document.page(), pseudoElement.get());
+ setBeforeOrAfterPseudoElement(current, pseudoElement.copyRef(), pseudoId);
+ createRenderTreeRecursively(pseudoElement.get(), *current.renderStyle(), renderTreePosition, nullptr);
+}
+
+#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
+void TreeResolver::createRenderTreeForSlotAssignees(HTMLSlotElement& slot, RenderStyle& inheritedStyle, RenderTreePosition& renderTreePosition)
+{
+ if (auto* assignedNodes = slot.assignedNodes()) {
+ ASSERT(m_shadowHostTreeResolver);
+ for (auto* child : *assignedNodes) {
+ if (is<Text>(*child))
+ attachTextRenderer(downcast<Text>(*child), renderTreePosition);
+ else if (is<Element>(*child))
+ m_shadowHostTreeResolver->createRenderTreeRecursively(downcast<Element>(*child), inheritedStyle, renderTreePosition, nullptr);
+ }
+ } else
+ createRenderTreeForChildren(slot, inheritedStyle, renderTreePosition);
+
+ slot.clearNeedsStyleRecalc();
+ slot.clearChildNeedsStyleRecalc();
+}
+#endif
+
+void TreeResolver::createRenderTreeRecursively(Element& current, RenderStyle& inheritedStyle, RenderTreePosition& renderTreePosition, RefPtr<RenderStyle>&& resolvedStyle)
+{
+ PostResolutionCallbackDisabler callbackDisabler(m_document);
+ WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
+
+#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
+ if (is<HTMLSlotElement>(current)) {
+ createRenderTreeForSlotAssignees(downcast<HTMLSlotElement>(current), inheritedStyle, renderTreePosition);
+ return;
+ }
+#endif
+
+ if (current.hasCustomStyleResolveCallbacks())
+ current.willAttachRenderers();
+
+ createRenderer(current, inheritedStyle, renderTreePosition, WTFMove(resolvedStyle));
+
+ if (auto* renderer = current.renderer()) {
+ StyleResolverParentPusher parentPusher(&current);
+
+ RenderTreePosition childRenderTreePosition(*renderer);
+ createRenderTreeForBeforeOrAfterPseudoElement(current, BEFORE, childRenderTreePosition);
+
+ auto* shadowRoot = current.shadowRoot();
+ if (shadowRoot)
+ createRenderTreeForShadowRoot(*shadowRoot);
+ else if (current.firstChild())
+ parentPusher.push();
+
+ bool skipChildren = shadowRoot;
+ if (!skipChildren)
+ createRenderTreeForChildren(current, renderer->style(), childRenderTreePosition);
+
+ if (AXObjectCache* cache = m_document.axObjectCache())
+ cache->updateCacheAfterNodeIsAttached(&current);
+
+ createRenderTreeForBeforeOrAfterPseudoElement(current, AFTER, childRenderTreePosition);
+
+ current.updateFocusAppearanceAfterAttachIfNeeded();
+ } else
+ resetStyleForNonRenderedDescendants(current);
+
+ current.clearNeedsStyleRecalc();
+ current.clearChildNeedsStyleRecalc();
+
+ if (current.hasCustomStyleResolveCallbacks())
+ current.didAttachRenderers();
+}
+
+static void detachChildren(ContainerNode& current, DetachType detachType)
+{
+ for (Node* child = current.firstChild(); child; child = child->nextSibling()) {
+ if (is<Text>(*child))
+ detachTextRenderer(downcast<Text>(*child));
+ else if (is<Element>(*child))
+ detachRenderTree(downcast<Element>(*child), detachType);
+ }
+ current.clearChildNeedsStyleRecalc();
+}
+
+static void detachShadowRoot(ShadowRoot& shadowRoot, DetachType detachType)
+{
+ detachChildren(shadowRoot, detachType);
+}
+
+#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
+static void detachSlotAssignees(HTMLSlotElement& slot, DetachType detachType)
+{
+ ASSERT(!slot.renderer());
+ if (auto* assignedNodes = slot.assignedNodes()) {
+ for (auto* child : *assignedNodes) {
+ if (is<Text>(*child))
+ detachTextRenderer(downcast<Text>(*child));
+ else if (is<Element>(*child))
+ detachRenderTree(downcast<Element>(*child), detachType);
+ }
+ } else
+ detachChildren(slot, detachType);
+
+ slot.clearNeedsStyleRecalc();
+ slot.clearChildNeedsStyleRecalc();
+}
+#endif
+
+static void detachRenderTree(Element& current, DetachType detachType)
+{
+ WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
+
+ if (current.hasCustomStyleResolveCallbacks())
+ current.willDetachRenderers();
+
+ current.clearStyleDerivedDataBeforeDetachingRenderer();
+
+ // Do not remove the element's hovered and active status
+ // if performing a reattach.
+ if (detachType != ReattachDetach)
+ current.clearHoverAndActiveStatusBeforeDetachingRenderer();
+
+#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
+ if (is<HTMLSlotElement>(current))
+ detachSlotAssignees(downcast<HTMLSlotElement>(current), detachType);
+#endif
+ else if (ShadowRoot* shadowRoot = current.shadowRoot())
+ detachShadowRoot(*shadowRoot, detachType);
+
+ detachChildren(current, detachType);
+
+ if (current.renderer())
+ current.renderer()->destroyAndCleanupAnonymousWrappers();
+ current.setRenderer(0);
+
+ if (current.hasCustomStyleResolveCallbacks())
+ current.didDetachRenderers();
+}
+
+static bool pseudoStyleCacheIsInvalid(RenderElement* renderer, RenderStyle* newStyle)
+{
+ const RenderStyle& currentStyle = renderer->style();
+
+ const PseudoStyleCache* pseudoStyleCache = currentStyle.cachedPseudoStyles();
+ if (!pseudoStyleCache)
+ return false;
+
+ for (auto& cache : *pseudoStyleCache) {
+ RefPtr<RenderStyle> newPseudoStyle;
+ PseudoId pseudoId = cache->styleType();
+ if (pseudoId == FIRST_LINE || pseudoId == FIRST_LINE_INHERITED)
+ newPseudoStyle = renderer->uncachedFirstLineStyle(newStyle);
+ else
+ newPseudoStyle = renderer->getUncachedPseudoStyle(PseudoStyleRequest(pseudoId), newStyle, newStyle);
+ if (!newPseudoStyle)
+ return true;
+ if (*newPseudoStyle != *cache) {
+ if (pseudoId < FIRST_INTERNAL_PSEUDOID)
+ newStyle->setHasPseudoStyle(pseudoId);
+ newStyle->addCachedPseudoStyle(newPseudoStyle);
+ if (pseudoId == FIRST_LINE || pseudoId == FIRST_LINE_INHERITED) {
+ // FIXME: We should do an actual diff to determine whether a repaint vs. layout
+ // is needed, but for now just assume a layout will be required. The diff code
+ // in RenderObject::setStyle would need to be factored out so that it could be reused.
+ renderer->setNeedsLayoutAndPrefWidthsRecalc();
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+Change TreeResolver::resolveLocally(Element& current, RenderStyle& inheritedStyle, RenderTreePosition& renderTreePosition, Change inheritedChange)
+{
+ Change localChange = Detach;
+ RefPtr<RenderStyle> newStyle;
+ RefPtr<RenderStyle> currentStyle = current.renderStyle();
+
+ if (currentStyle && current.styleChangeType() != ReconstructRenderTree) {
+ Ref<RenderStyle> style(styleForElement(current, inheritedStyle));
+ newStyle = style.ptr();
+ localChange = determineChange(*currentStyle, style);
+ }
+ if (localChange == Detach) {
+ if (current.renderer() || current.isNamedFlowContentNode())
+ detachRenderTree(current, ReattachDetach);
+ createRenderTreeRecursively(current, inheritedStyle, renderTreePosition, newStyle.release());
+ invalidateWhitespaceOnlyTextSiblingsAfterAttachIfNeeded(current);
+
+ return Detach;
+ }
+
+ if (RenderElement* renderer = current.renderer()) {
+ if (localChange != NoChange || pseudoStyleCacheIsInvalid(renderer, newStyle.get()) || (inheritedChange == Force && renderer->requiresForcedStyleRecalcPropagation()) || current.styleChangeType() == SyntheticStyleChange)
+ renderer->setAnimatableStyle(*newStyle, current.styleChangeType() == SyntheticStyleChange ? StyleDifferenceRecompositeLayer : StyleDifferenceEqual);
+ else if (current.needsStyleRecalc()) {
+ // Although no change occurred, we use the new style so that the cousin style sharing code won't get
+ // fooled into believing this style is the same.
+ renderer->setStyleInternal(*newStyle);
+ }
+ }
+
+ // If "rem" units are used anywhere in the document, and if the document element's font size changes, then force font updating
+ // all the way down the tree. This is simpler than having to maintain a cache of objects (and such font size changes should be rare anyway).
+ if (m_document.authorStyleSheets().usesRemUnits() && m_document.documentElement() == &current && localChange != NoChange && currentStyle && newStyle && currentStyle->fontSize() != newStyle->fontSize()) {
+ // Cached RenderStyles may depend on the re units.
+ m_styleResolver.invalidateMatchedPropertiesCache();
+ return Force;
+ }
+ if (inheritedChange == Force)
+ return Force;
+ if (current.styleChangeType() >= FullStyleChange)
+ return Force;
+
+ return localChange;
+}
+
+void resolveTextNode(Text& text, RenderTreePosition& renderTreePosition)
+{
+ text.clearNeedsStyleRecalc();
+
+ bool hasRenderer = text.renderer();
+ bool needsRenderer = textRendererIsNeeded(text, renderTreePosition);
+ if (hasRenderer) {
+ if (needsRenderer)
+ return;
+ detachTextRenderer(text);
+ invalidateWhitespaceOnlyTextSiblingsAfterAttachIfNeeded(text);
+ return;
+ }
+ if (!needsRenderer)
+ return;
+ attachTextRenderer(text, renderTreePosition);
+ invalidateWhitespaceOnlyTextSiblingsAfterAttachIfNeeded(text);
+}
+
+void TreeResolver::resolveChildAtShadowBoundary(Node& child, RenderStyle& inheritedStyle, RenderTreePosition& renderTreePosition, Style::Change change)
+{
+ if (auto* renderer = child.renderer())
+ renderTreePosition.invalidateNextSibling(*renderer);
+
+ if (is<Text>(child) && child.needsStyleRecalc()) {
+ resolveTextNode(downcast<Text>(child), renderTreePosition);
+ return;
+ }
+ if (is<Element>(child))
+ resolveRecursively(downcast<Element>(child), inheritedStyle, renderTreePosition, change);
+}
+
+void TreeResolver::resolveShadowTree(Style::Change change, RenderStyle& inheritedStyle)
+{
+ ASSERT(m_shadowRoot);
+ auto& host = *m_shadowRoot->host();
+ ASSERT(host.renderer());
+ if (m_shadowRoot->styleChangeType() >= FullStyleChange)
+ change = Force;
+ RenderTreePosition renderTreePosition(*host.renderer());
+ for (auto* child = m_shadowRoot->firstChild(); child; child = child->nextSibling())
+ resolveChildAtShadowBoundary(*child, inheritedStyle, renderTreePosition, change);
+
+ m_shadowRoot->clearNeedsStyleRecalc();
+ m_shadowRoot->clearChildNeedsStyleRecalc();
+}
+
+void TreeResolver::resolveBeforeOrAfterPseudoElement(Element& current, Change change, PseudoId pseudoId, RenderTreePosition& renderTreePosition)
+{
+ ASSERT(current.renderer());
+ if (PseudoElement* existingPseudoElement = beforeOrAfterPseudoElement(current, pseudoId)) {
+ if (existingPseudoElement->renderer())
+ renderTreePosition.invalidateNextSibling(*existingPseudoElement->renderer());
+
+ if (needsPseudoElement(current, pseudoId))
+ resolveRecursively(*existingPseudoElement, current.renderer()->style(), renderTreePosition, current.needsStyleRecalc() ? Force : change);
+ else
+ clearBeforeOrAfterPseudoElement(current, pseudoId);
+ return;
+ }
+ createRenderTreeForBeforeOrAfterPseudoElement(current, pseudoId, renderTreePosition);
+}
+
+#if PLATFORM(IOS)
+static EVisibility elementImplicitVisibility(const Element* element)
+{
+ RenderObject* renderer = element->renderer();
+ if (!renderer)
+ return VISIBLE;
+
+ RenderStyle& style = renderer->style();
+
+ Length width(style.width());
+ Length height(style.height());
+ if ((width.isFixed() && width.value() <= 0) || (height.isFixed() && height.value() <= 0))
+ return HIDDEN;
+
+ Length top(style.top());
+ Length left(style.left());
+ if (left.isFixed() && width.isFixed() && -left.value() >= width.value())
+ return HIDDEN;
+
+ if (top.isFixed() && height.isFixed() && -top.value() >= height.value())
+ return HIDDEN;
+ return VISIBLE;
+}
+
+class CheckForVisibilityChangeOnRecalcStyle {
+public:
+ CheckForVisibilityChangeOnRecalcStyle(Element* element, RenderStyle* currentStyle)
+ : m_element(element)
+ , m_previousDisplay(currentStyle ? currentStyle->display() : NONE)
+ , m_previousVisibility(currentStyle ? currentStyle->visibility() : HIDDEN)
+ , m_previousImplicitVisibility(WKObservingContentChanges() && WKContentChange() != WKContentVisibilityChange ? elementImplicitVisibility(element) : VISIBLE)
+ {
+ }
+ ~CheckForVisibilityChangeOnRecalcStyle()
+ {
+ if (!WKObservingContentChanges())
+ return;
+ if (m_element->isInUserAgentShadowTree())
+ return;
+ RenderStyle* style = m_element->renderStyle();
+ if (!style)
+ return;
+ if ((m_previousDisplay == NONE && style->display() != NONE) || (m_previousVisibility == HIDDEN && style->visibility() != HIDDEN)
+ || (m_previousImplicitVisibility == HIDDEN && elementImplicitVisibility(m_element.get()) == VISIBLE))
+ WKSetObservedContentChange(WKContentVisibilityChange);
+ }
+private:
+ RefPtr<Element> m_element;
+ EDisplay m_previousDisplay;
+ EVisibility m_previousVisibility;
+ EVisibility m_previousImplicitVisibility;
+};
+#endif // PLATFORM(IOS)
+
+void TreeResolver::resolveChildren(Element& current, RenderStyle& inheritedStyle, Change change, RenderTreePosition& childRenderTreePosition)
+{
+ StyleResolverParentPusher parentPusher(&current);
+
+ bool elementNeedingStyleRecalcAffectsNextSiblingElementStyle = false;
+ for (Node* child = current.firstChild(); child; child = child->nextSibling()) {
+ if (RenderObject* childRenderer = child->renderer())
+ childRenderTreePosition.invalidateNextSibling(*childRenderer);
+ if (is<Text>(*child) && child->needsStyleRecalc()) {
+ resolveTextNode(downcast<Text>(*child), childRenderTreePosition);
+ continue;
+ }
+ if (!is<Element>(*child))
+ continue;
+
+ Element& childElement = downcast<Element>(*child);
+ if (elementNeedingStyleRecalcAffectsNextSiblingElementStyle) {
+ if (childElement.styleIsAffectedByPreviousSibling())
+ childElement.setNeedsStyleRecalc();
+ elementNeedingStyleRecalcAffectsNextSiblingElementStyle = childElement.affectsNextSiblingElementStyle();
+ } else if (childElement.needsStyleRecalc())
+ elementNeedingStyleRecalcAffectsNextSiblingElementStyle = childElement.affectsNextSiblingElementStyle();
+ if (change >= Inherit || childElement.childNeedsStyleRecalc() || childElement.needsStyleRecalc()) {
+ parentPusher.push();
+ resolveRecursively(childElement, inheritedStyle, childRenderTreePosition, change);
+ }
+ }
+}
+
+#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
+void TreeResolver::resolveSlotAssignees(HTMLSlotElement& slot, RenderStyle& inheritedStyle, RenderTreePosition& renderTreePosition, Change change)
+{
+ if (auto* assignedNodes = slot.assignedNodes()) {
+ ASSERT(m_shadowHostTreeResolver);
+ for (auto* child : *assignedNodes)
+ m_shadowHostTreeResolver->resolveChildAtShadowBoundary(*child, inheritedStyle, renderTreePosition, change);
+ } else
+ resolveChildren(slot, inheritedStyle, change, renderTreePosition);
+
+ slot.clearNeedsStyleRecalc();
+ slot.clearChildNeedsStyleRecalc();
+}
+#endif
+
+void TreeResolver::resolveRecursively(Element& current, RenderStyle& inheritedStyle, RenderTreePosition& renderTreePosition, Change change)
+{
+ ASSERT(change != Detach);
+
+#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
+ if (is<HTMLSlotElement>(current)) {
+ resolveSlotAssignees(downcast<HTMLSlotElement>(current), inheritedStyle, renderTreePosition, change);
+ return;
+ }
+#endif
+
+ if (current.hasCustomStyleResolveCallbacks()) {
+ if (!current.willRecalcStyle(change))
+ return;
+ }
+
+#if PLATFORM(IOS)
+ CheckForVisibilityChangeOnRecalcStyle checkForVisibilityChange(&current, current.renderStyle());
+#endif
+
+ if (change > NoChange || current.needsStyleRecalc())
+ current.resetComputedStyle();
+
+ if (change >= Inherit || current.needsStyleRecalc())
+ change = resolveLocally(current, inheritedStyle, renderTreePosition, change);
+
+ auto* renderer = current.renderer();
+
+ if (change != Detach && renderer) {
+ auto* shadowRoot = current.shadowRoot();
+ if (shadowRoot && (change >= Inherit || shadowRoot->childNeedsStyleRecalc() || shadowRoot->needsStyleRecalc())) {
+ TreeResolver shadowTreeResolver(*shadowRoot, *this);
+ shadowTreeResolver.resolveShadowTree(change, renderer->style());
+ }
+
+ RenderTreePosition childRenderTreePosition(*renderer);
+ resolveBeforeOrAfterPseudoElement(current, change, BEFORE, childRenderTreePosition);
+
+ bool skipChildren = shadowRoot;
+ if (!skipChildren)
+ resolveChildren(current, renderer->style(), change, childRenderTreePosition);
+
+ resolveBeforeOrAfterPseudoElement(current, change, AFTER, childRenderTreePosition);
+ }
+ if (change != Detach && !renderer)
+ resetStyleForNonRenderedDescendants(current);
+
+ current.clearNeedsStyleRecalc();
+ current.clearChildNeedsStyleRecalc();
+
+ if (current.hasCustomStyleResolveCallbacks())
+ current.didRecalcStyle(change);
+}
+
+void TreeResolver::resolve(Change change)
+{
+ ASSERT(!m_shadowRoot);
+
+ auto& renderView = *m_document.renderView();
+
+ Element* documentElement = m_document.documentElement();
+ if (!documentElement)
+ return;
+ if (change != Force && !documentElement->childNeedsStyleRecalc() && !documentElement->needsStyleRecalc())
+ return;
+
+ // Pseudo element removal and similar may only work with these flags still set. Reset them after the style recalc.
+ renderView.setUsesFirstLineRules(renderView.usesFirstLineRules() || m_styleResolver.usesFirstLineRules());
+ renderView.setUsesFirstLetterRules(renderView.usesFirstLetterRules() || m_styleResolver.usesFirstLetterRules());
+
+ RenderTreePosition renderTreePosition(renderView);
+ resolveRecursively(*documentElement, *m_document.renderStyle(), renderTreePosition, change);
+
+ renderView.setUsesFirstLineRules(m_styleResolver.usesFirstLineRules());
+ renderView.setUsesFirstLetterRules(m_styleResolver.usesFirstLetterRules());
+}
+
+void detachRenderTree(Element& element)
+{
+ detachRenderTree(element, NormalDetach);
+}
+
+static Vector<std::function<void ()>>& postResolutionCallbackQueue()
+{
+ static NeverDestroyed<Vector<std::function<void ()>>> vector;
+ return vector;
+}
+
+void queuePostResolutionCallback(std::function<void ()> callback)
+{
+ postResolutionCallbackQueue().append(callback);
+}
+
+static void suspendMemoryCacheClientCalls(Document& document)
+{
+ Page* page = document.page();
+ if (!page || !page->areMemoryCacheClientCallsEnabled())
+ return;
+
+ page->setMemoryCacheClientCallsEnabled(false);
+
+ RefPtr<MainFrame> protectedMainFrame = &page->mainFrame();
+ postResolutionCallbackQueue().append([protectedMainFrame]{
+ if (Page* page = protectedMainFrame->page())
+ page->setMemoryCacheClientCallsEnabled(true);
+ });
+}
+
+static unsigned resolutionNestingDepth;
+
+PostResolutionCallbackDisabler::PostResolutionCallbackDisabler(Document& document)
+{
+ ++resolutionNestingDepth;
+
+ if (resolutionNestingDepth == 1)
+ platformStrategies()->loaderStrategy()->suspendPendingRequests();
+
+ // FIXME: It's strange to build this into the disabler.
+ suspendMemoryCacheClientCalls(document);
+}
+
+PostResolutionCallbackDisabler::~PostResolutionCallbackDisabler()
+{
+ if (resolutionNestingDepth == 1) {
+ // Get size each time through the loop because a callback can add more callbacks to the end of the queue.
+ auto& queue = postResolutionCallbackQueue();
+ for (size_t i = 0; i < queue.size(); ++i)
+ queue[i]();
+ queue.clear();
+
+ platformStrategies()->loaderStrategy()->resumePendingRequests();
+ }
+
+ --resolutionNestingDepth;
+}
+
+bool postResolutionCallbacksAreSuspended()
+{
+ return resolutionNestingDepth;
+}
+
+}
+}
</ins></span></pre></div>
<a id="trunkSourceWebCorestyleStyleTreeResolverhfromrev194584trunkSourceWebCorestyleStyleResolveTreeh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/style/StyleTreeResolver.h (from rev 194584, trunk/Source/WebCore/style/StyleResolveTree.h) (0 => 194691)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/style/StyleTreeResolver.h         (rev 0)
+++ trunk/Source/WebCore/style/StyleTreeResolver.h        2016-01-07 08:16:49 UTC (rev 194691)
</span><span class="lines">@@ -0,0 +1,105 @@
</span><ins>+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef StyleTreeResolver_h
+#define StyleTreeResolver_h
+
+#include "RenderStyleConstants.h"
+#include "StyleChange.h"
+#include <functional>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class ContainerNode;
+class Document;
+class Element;
+class HTMLSlotElement;
+class Node;
+class RenderStyle;
+class RenderTreePosition;
+class Settings;
+class ShadowRoot;
+class StyleResolver;
+class Text;
+
+namespace Style {
+
+class TreeResolver {
+public:
+ TreeResolver(Document&);
+
+ void resolve(Change);
+
+private:
+ TreeResolver(ShadowRoot&, TreeResolver& shadowHostTreeResolver);
+
+ void resolveShadowTree(Change, RenderStyle& inheritedStyle);
+
+ Ref<RenderStyle> styleForElement(Element&, RenderStyle& inheritedStyle);
+
+ void resolveRecursively(Element&, RenderStyle& inheritedStyle, RenderTreePosition&, Change);
+ Change resolveLocally(Element&, RenderStyle& inheritedStyle, RenderTreePosition&, Change inheritedChange);
+ void resolveChildren(Element&, RenderStyle&, Change, RenderTreePosition&);
+ void resolveChildAtShadowBoundary(Node&, RenderStyle& inheritedStyle, RenderTreePosition&, Change);
+ void resolveBeforeOrAfterPseudoElement(Element&, Change, PseudoId, RenderTreePosition&);
+
+ void createRenderTreeRecursively(Element&, RenderStyle&, RenderTreePosition&, RefPtr<RenderStyle>&& resolvedStyle);
+ void createRenderer(Element&, RenderStyle& inheritedStyle, RenderTreePosition&, RefPtr<RenderStyle>&& resolvedStyle);
+ void createRenderTreeForBeforeOrAfterPseudoElement(Element&, PseudoId, RenderTreePosition&);
+ void createRenderTreeForChildren(ContainerNode&, RenderStyle&, RenderTreePosition&);
+ void createRenderTreeForShadowRoot(ShadowRoot&);
+
+#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
+ void resolveSlotAssignees(HTMLSlotElement&, RenderStyle& inheritedStyle, RenderTreePosition&, Change);
+ void createRenderTreeForSlotAssignees(HTMLSlotElement&, RenderStyle& inheritedStyle, RenderTreePosition&);
+#endif
+
+ Document& m_document;
+ StyleResolver& m_styleResolver;
+
+ ShadowRoot* m_shadowRoot { nullptr };
+ TreeResolver* m_shadowHostTreeResolver { nullptr };
+};
+
+void detachRenderTree(Element&);
+void detachTextRenderer(Text&);
+
+void updateTextRendererAfterContentChange(Text&, unsigned offsetOfReplacedData, unsigned lengthOfReplacedData);
+
+void queuePostResolutionCallback(std::function<void ()>);
+bool postResolutionCallbacksAreSuspended();
+
+class PostResolutionCallbackDisabler {
+public:
+ explicit PostResolutionCallbackDisabler(Document&);
+ ~PostResolutionCallbackDisabler();
+};
+
+}
+
+}
+
+#endif
</ins></span></pre>
</div>
</div>
</body>
</html>