Title: [271357] trunk/Source/WebCore
- Revision
- 271357
- Author
- [email protected]
- Date
- 2021-01-11 03:44:41 -0800 (Mon, 11 Jan 2021)
Log Message
[css-multicol] Restore placeholders on multicolumn children position changes.
https://bugs.webkit.org/show_bug.cgi?id=218501
Reviewed by Zalan Bujtas.
Whenever there is a placeholder in a multicolumn flow ("column-span: all") it must be ensured that the spanner
associated to that placeholder is properly restored as a child of the multicolumn flow when the element with
"column-span:all" is moved out of the multicolumn flow (for example by removing it, by making it out-of-flow
or because an ancestor becomes another multicolumn flow).
This was smoothly handled by the current code for the in-flow -> out-of-flow transition but not the other way
around, i.e in the case of making the placeholder (or an ancestor) an absolutely positioned element.
* rendering/updating/RenderTreeBuilder.cpp:
(WebCore::RenderTreeBuilder::normalizeTreeAfterStyleChange): restore column spanners then the element becomes
out-of-flow as it's removed from the multicolumn flow.
* rendering/updating/RenderTreeBuilderMultiColumn.cpp:
(WebCore::RenderTreeBuilder::MultiColumn::createFragmentedFlow): Call the newly created method
restoreColumnSpannersForContainer().
(WebCore::RenderTreeBuilder::MultiColumn::restoreColumnSpannersForContainer): Refactored from createFragmentedFlow()
as it's now used by normalizeTreeAfterStyleChange().
* rendering/updating/RenderTreeBuilderMultiColumn.h:
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (271356 => 271357)
--- trunk/Source/WebCore/ChangeLog 2021-01-11 11:15:28 UTC (rev 271356)
+++ trunk/Source/WebCore/ChangeLog 2021-01-11 11:44:41 UTC (rev 271357)
@@ -1,3 +1,28 @@
+2021-01-07 Sergio Villar Senin <[email protected]>
+
+ [css-multicol] Restore placeholders on multicolumn children position changes.
+ https://bugs.webkit.org/show_bug.cgi?id=218501
+
+ Reviewed by Zalan Bujtas.
+
+ Whenever there is a placeholder in a multicolumn flow ("column-span: all") it must be ensured that the spanner
+ associated to that placeholder is properly restored as a child of the multicolumn flow when the element with
+ "column-span:all" is moved out of the multicolumn flow (for example by removing it, by making it out-of-flow
+ or because an ancestor becomes another multicolumn flow).
+
+ This was smoothly handled by the current code for the in-flow -> out-of-flow transition but not the other way
+ around, i.e in the case of making the placeholder (or an ancestor) an absolutely positioned element.
+
+ * rendering/updating/RenderTreeBuilder.cpp:
+ (WebCore::RenderTreeBuilder::normalizeTreeAfterStyleChange): restore column spanners then the element becomes
+ out-of-flow as it's removed from the multicolumn flow.
+ * rendering/updating/RenderTreeBuilderMultiColumn.cpp:
+ (WebCore::RenderTreeBuilder::MultiColumn::createFragmentedFlow): Call the newly created method
+ restoreColumnSpannersForContainer().
+ (WebCore::RenderTreeBuilder::MultiColumn::restoreColumnSpannersForContainer): Refactored from createFragmentedFlow()
+ as it's now used by normalizeTreeAfterStyleChange().
+ * rendering/updating/RenderTreeBuilderMultiColumn.h:
+
2020-12-04 Sergio Villar Senin <[email protected]>
[css-multicol] Update fragment flow state on element insertion when element position changes
Modified: trunk/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp (271356 => 271357)
--- trunk/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp 2021-01-11 11:15:28 UTC (rev 271356)
+++ trunk/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp 2021-01-11 11:44:41 UTC (rev 271357)
@@ -598,9 +598,18 @@
// Out of flow children of RenderMultiColumnFlow are not really part of the multicolumn flow. We need to ensure that changes in positioning like this
// trigger insertions into the multicolumn flow.
- if (auto* enclosingFragmentedFlow = parent.enclosingFragmentedFlow(); is<RenderMultiColumnFlow>(enclosingFragmentedFlow) && wasOutOfFlowPositioned && !isOutOfFlowPositioned) {
- multiColumnBuilder().multiColumnDescendantInserted(downcast<RenderMultiColumnFlow>(*enclosingFragmentedFlow), renderer);
- renderer.initializeFragmentedFlowStateOnInsertion();
+ if (auto* enclosingFragmentedFlow = parent.enclosingFragmentedFlow(); is<RenderMultiColumnFlow>(enclosingFragmentedFlow)) {
+ auto movingIntoMulticolumn = wasOutOfFlowPositioned && !isOutOfFlowPositioned;
+ if (movingIntoMulticolumn) {
+ multiColumnBuilder().multiColumnDescendantInserted(downcast<RenderMultiColumnFlow>(*enclosingFragmentedFlow), renderer);
+ renderer.initializeFragmentedFlowStateOnInsertion();
+ return;
+ }
+ auto movingOutOfMulticolumn = !wasOutOfFlowPositioned && isOutOfFlowPositioned;
+ if (movingOutOfMulticolumn) {
+ multiColumnBuilder().restoreColumnSpannersForContainer(renderer, downcast<RenderMultiColumnFlow>(*enclosingFragmentedFlow));
+ return;
+ }
}
}
Modified: trunk/Source/WebCore/rendering/updating/RenderTreeBuilderMultiColumn.cpp (271356 => 271357)
--- trunk/Source/WebCore/rendering/updating/RenderTreeBuilderMultiColumn.cpp 2021-01-11 11:15:28 UTC (rev 271356)
+++ trunk/Source/WebCore/rendering/updating/RenderTreeBuilderMultiColumn.cpp 2021-01-11 11:44:41 UTC (rev 271357)
@@ -153,29 +153,8 @@
flow.deleteLines();
// If this soon-to-be multicolumn flow is already part of a multicolumn context, we need to move back the descendant spanners
// to their original position before moving subtrees around.
- auto* enclosingflow = flow.enclosingFragmentedFlow();
- if (is<RenderMultiColumnFlow>(enclosingflow)) {
- auto& spanners = downcast<RenderMultiColumnFlow>(enclosingflow)->spannerMap();
- Vector<RenderMultiColumnSpannerPlaceholder*> placeholdersToDelete;
- for (auto& spannerAndPlaceholder : spanners) {
- auto& placeholder = *spannerAndPlaceholder.value;
- if (!placeholder.isDescendantOf(&flow))
- continue;
- placeholdersToDelete.append(&placeholder);
- }
- for (auto* placeholder : placeholdersToDelete) {
- auto* spanner = placeholder->spanner();
- if (!spanner) {
- ASSERT_NOT_REACHED();
- continue;
- }
- // Move the spanner back to its original position.
- auto& spannerOriginalParent = *placeholder->parent();
- // Detaching the spanner takes care of removing the placeholder (and merges the RenderMultiColumnSets).
- auto spannerToReInsert = m_builder.detach(*spanner->parent(), *spanner);
- m_builder.attach(spannerOriginalParent, WTFMove(spannerToReInsert));
- }
- }
+ if (auto* enclosingflow = flow.enclosingFragmentedFlow(); is<RenderMultiColumnFlow>(enclosingflow))
+ restoreColumnSpannersForContainer(flow, downcast<RenderMultiColumnFlow>(*enclosingflow));
auto newFragmentedFlow = WebCore::createRenderer<RenderMultiColumnFlow>(flow.document(), RenderStyle::createAnonymousStyleWithDisplay(flow.style(), DisplayType::Block));
newFragmentedFlow->initializeStyle();
@@ -195,6 +174,30 @@
flow.setMultiColumnFlow(fragmentedFlow);
}
+void RenderTreeBuilder::MultiColumn::restoreColumnSpannersForContainer(const RenderElement& container, RenderMultiColumnFlow& multiColumnFlow)
+{
+ auto& spanners = multiColumnFlow.spannerMap();
+ Vector<RenderMultiColumnSpannerPlaceholder*> placeholdersToRestore;
+ for (auto& spannerAndPlaceholder : spanners) {
+ auto& placeholder = *spannerAndPlaceholder.value;
+ if (!placeholder.isDescendantOf(&container))
+ continue;
+ placeholdersToRestore.append(&placeholder);
+ }
+ for (auto* placeholder : placeholdersToRestore) {
+ auto* spanner = placeholder->spanner();
+ if (!spanner) {
+ ASSERT_NOT_REACHED();
+ continue;
+ }
+ // Move the spanner back to its original position.
+ auto& spannerOriginalParent = *placeholder->parent();
+ // Detaching the spanner takes care of removing the placeholder (and merges the RenderMultiColumnSets).
+ auto spannerToReInsert = m_builder.detach(*spanner->parent(), *spanner);
+ m_builder.attach(spannerOriginalParent, WTFMove(spannerToReInsert));
+ }
+}
+
void RenderTreeBuilder::MultiColumn::destroyFragmentedFlow(RenderBlockFlow& flow)
{
auto& multiColumnFlow = *flow.multiColumnFlow();
Modified: trunk/Source/WebCore/rendering/updating/RenderTreeBuilderMultiColumn.h (271356 => 271357)
--- trunk/Source/WebCore/rendering/updating/RenderTreeBuilderMultiColumn.h 2021-01-11 11:15:28 UTC (rev 271356)
+++ trunk/Source/WebCore/rendering/updating/RenderTreeBuilderMultiColumn.h 2021-01-11 11:44:41 UTC (rev 271357)
@@ -42,6 +42,7 @@
// sets. If |child| is such a renderer, resolve it to the placeholder that lives at the original
// location in the tree.
RenderObject* resolveMovedChild(RenderFragmentedFlow& enclosingFragmentedFlow, RenderObject* beforeChild);
+ void restoreColumnSpannersForContainer(const RenderElement& container, RenderMultiColumnFlow&);
void multiColumnDescendantInserted(RenderMultiColumnFlow&, RenderObject& newDescendant);
void multiColumnRelativeWillBeRemoved(RenderMultiColumnFlow&, RenderObject& relative);
static RenderObject* adjustBeforeChildForMultiColumnSpannerIfNeeded(RenderObject& beforeChild);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes