Commit 0972cdbe authored by mstensho@opera.com's avatar mstensho@opera.com

[New Multicolumn] Add RenderMultiColumnSpannerSet.

This is in preparation for column-span:all support.

This CL puts basic set renderer insertion needed by column-span:all into
place. Full support for set management (cope with dynamic changes after
inital layout, etc.) and actual support for layout will be introduced in
follow-up CLs. Likewise for layout tests.

Each column-span:all renderer needs a corresponding
RenderMultiColumnSpannerSet. This means that if there's column content
preceding and following the spanner, we need a RenderMultiColumnSet both
before and after it (while, without spanners, there'd never be any need
for more than one column set).

Some extra attention is required when inserting flow thread
descendants now, because we need to figure out if the renderer
inserted should trigger creation of a new column set or a spanner set.

Wrote some unit tests. Layout tests not possible at this time, since this
CL has no (intentional) web-facing changes.

BUG=347325

Review URL: https://codereview.chromium.org/688703003

git-svn-id: svn://svn.chromium.org/blink/trunk@184887 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent d2255a5b
...@@ -1719,6 +1719,8 @@ ...@@ -1719,6 +1719,8 @@
'rendering/RenderMultiColumnFlowThread.h', 'rendering/RenderMultiColumnFlowThread.h',
'rendering/RenderMultiColumnSet.cpp', 'rendering/RenderMultiColumnSet.cpp',
'rendering/RenderMultiColumnSet.h', 'rendering/RenderMultiColumnSet.h',
'rendering/RenderMultiColumnSpannerSet.cpp',
'rendering/RenderMultiColumnSpannerSet.h',
'rendering/RenderObject.cpp', 'rendering/RenderObject.cpp',
'rendering/RenderObjectChildList.cpp', 'rendering/RenderObjectChildList.cpp',
'rendering/RenderPagedFlowThread.cpp', 'rendering/RenderPagedFlowThread.cpp',
...@@ -3611,6 +3613,7 @@ ...@@ -3611,6 +3613,7 @@
'rendering/RenderBlockTest.cpp', 'rendering/RenderBlockTest.cpp',
'rendering/RenderInlineTest.cpp', 'rendering/RenderInlineTest.cpp',
'rendering/RenderOverflowTest.cpp', 'rendering/RenderOverflowTest.cpp',
'rendering/RenderMultiColumnFlowThreadTest.cpp',
'rendering/RenderPartTest.cpp', 'rendering/RenderPartTest.cpp',
'rendering/RenderTableCellTest.cpp', 'rendering/RenderTableCellTest.cpp',
'rendering/RenderTableRowTest.cpp', 'rendering/RenderTableRowTest.cpp',
......
...@@ -67,6 +67,8 @@ public: ...@@ -67,6 +67,8 @@ public:
// can easily avoid drawing the children directly. // can easily avoid drawing the children directly.
virtual LayerType layerTypeRequired() const override final { return NormalLayer; } virtual LayerType layerTypeRequired() const override final { return NormalLayer; }
virtual void flowThreadDescendantWasInserted(RenderObject*) { }
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) override final; virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) override final;
virtual void addRegionToThread(RenderMultiColumnSet*) = 0; virtual void addRegionToThread(RenderMultiColumnSet*) = 0;
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "core/rendering/RenderMultiColumnFlowThread.h" #include "core/rendering/RenderMultiColumnFlowThread.h"
#include "core/rendering/RenderMultiColumnSet.h" #include "core/rendering/RenderMultiColumnSet.h"
#include "core/rendering/RenderMultiColumnSpannerSet.h"
namespace blink { namespace blink {
...@@ -70,21 +71,22 @@ RenderMultiColumnSet* RenderMultiColumnFlowThread::lastMultiColumnSet() const ...@@ -70,21 +71,22 @@ RenderMultiColumnSet* RenderMultiColumnFlowThread::lastMultiColumnSet() const
return 0; return 0;
} }
void RenderMultiColumnFlowThread::addChild(RenderObject* newChild, RenderObject* beforeChild) RenderMultiColumnSpannerSet* RenderMultiColumnFlowThread::containingColumnSpannerSet(const RenderObject* descendant) const
{ {
RenderBlockFlow::addChild(newChild, beforeChild); ASSERT(descendant->isDescendantOf(this));
if (firstMultiColumnSet())
return; // Before we spend time on searching the ancestry, see if there's a quick way to determine
// whether there might be any spanners at all.
// For now we only create one column set. It's created as soon as the multicol container gets RenderMultiColumnSet* firstSet = firstMultiColumnSet();
// any content at all. if (!firstSet || (firstSet == lastMultiColumnSet() && !firstSet->isRenderMultiColumnSpannerSet()))
RenderMultiColumnSet* newSet = RenderMultiColumnSet::createAnonymous(this, multiColumnBlockFlow()->style()); return 0;
// Need to skip RenderBlockFlow's implementation of addChild(), or we'd get redirected right // We have spanners. See if the renderer in question is one or inside of one then.
// back here. for (const RenderObject* ancestor = descendant; ancestor && ancestor != this; ancestor = ancestor->parent()) {
multiColumnBlockFlow()->RenderBlock::addChild(newSet); if (RenderMultiColumnSpannerSet* spanner = m_spannerMap.get(ancestor))
return spanner;
invalidateRegions(); }
return 0;
} }
void RenderMultiColumnFlowThread::populate() void RenderMultiColumnFlowThread::populate()
...@@ -227,6 +229,64 @@ void RenderMultiColumnFlowThread::calculateColumnCountAndWidth(LayoutUnit& width ...@@ -227,6 +229,64 @@ void RenderMultiColumnFlowThread::calculateColumnCountAndWidth(LayoutUnit& width
} }
} }
void RenderMultiColumnFlowThread::createAndInsertMultiColumnSet()
{
RenderBlockFlow* multicolContainer = multiColumnBlockFlow();
RenderMultiColumnSet* newSet = RenderMultiColumnSet::createAnonymous(this, multicolContainer->style());
multicolContainer->RenderBlock::addChild(newSet);
invalidateRegions();
// We cannot handle immediate column set siblings (and there's no need for it, either).
// There has to be at least one spanner separating them.
ASSERT(!newSet->previousSiblingMultiColumnSet() || newSet->previousSiblingMultiColumnSet()->isRenderMultiColumnSpannerSet());
ASSERT(!newSet->nextSiblingMultiColumnSet() || newSet->nextSiblingMultiColumnSet()->isRenderMultiColumnSpannerSet());
}
void RenderMultiColumnFlowThread::createAndInsertSpannerSet(RenderBox* spanner)
{
RenderBlockFlow* multicolContainer = multiColumnBlockFlow();
RenderMultiColumnSpannerSet* newSpannerSet = RenderMultiColumnSpannerSet::createAnonymous(this, multicolContainer->style(), spanner);
multicolContainer->RenderBlock::addChild(newSpannerSet);
m_spannerMap.add(spanner, newSpannerSet);
invalidateRegions();
}
bool RenderMultiColumnFlowThread::descendantIsValidColumnSpanner(RenderObject* descendant) const
{
// We assume that we're inside the flow thread. This function is not to be called otherwise.
ASSERT(descendant->isDescendantOf(this));
// The spec says that column-span only applies to in-flow block-level elements.
if (descendant->style()->columnSpan() != ColumnSpanAll || !descendant->isBox() || descendant->isInline() || descendant->isFloatingOrOutOfFlowPositioned())
return false;
if (!descendant->containingBlock()->isRenderBlockFlow()) {
// Needs to be in a block-flow container, and not e.g. a table.
return false;
}
// This looks like a spanner, but if we're inside something unbreakable, it's not to be treated as one.
for (RenderBlock* ancestor = descendant->containingBlock(); ancestor && ancestor->flowThreadContainingBlock() == this; ancestor = ancestor->containingBlock()) {
if (ancestor->isRenderFlowThread()) {
ASSERT(ancestor == this);
return true;
}
if (m_spannerMap.get(ancestor)) {
// FIXME: do we want to support nested spanners in a different way? The outer spanner
// has already broken out from the columns to become sized by the multicol container,
// which may be good enough for the inner spanner. But margins, borders, padding and
// explicit widths on the outer spanner, or on any children between the outer and inner
// spanner, will affect the width of the inner spanner this way, which might be
// undesirable. The spec has nothing to say on the matter.
return false; // Ignore nested spanners.
}
if (ancestor->isUnsplittableForPagination())
return false;
}
ASSERT_NOT_REACHED();
return false;
}
const char* RenderMultiColumnFlowThread::renderName() const const char* RenderMultiColumnFlowThread::renderName() const
{ {
return "RenderMultiColumnFlowThread"; return "RenderMultiColumnFlowThread";
...@@ -246,6 +306,7 @@ void RenderMultiColumnFlowThread::addRegionToThread(RenderMultiColumnSet* column ...@@ -246,6 +306,7 @@ void RenderMultiColumnFlowThread::addRegionToThread(RenderMultiColumnSet* column
void RenderMultiColumnFlowThread::willBeRemovedFromTree() void RenderMultiColumnFlowThread::willBeRemovedFromTree()
{ {
m_spannerMap.clear();
// Detach all column sets from the flow thread. Cannot destroy them at this point, since they // Detach all column sets from the flow thread. Cannot destroy them at this point, since they
// are siblings of this object, and there may be pointers to this object's sibling somewhere // are siblings of this object, and there may be pointers to this object's sibling somewhere
// further up on the call stack. // further up on the call stack.
...@@ -255,6 +316,25 @@ void RenderMultiColumnFlowThread::willBeRemovedFromTree() ...@@ -255,6 +316,25 @@ void RenderMultiColumnFlowThread::willBeRemovedFromTree()
RenderFlowThread::willBeRemovedFromTree(); RenderFlowThread::willBeRemovedFromTree();
} }
void RenderMultiColumnFlowThread::flowThreadDescendantWasInserted(RenderObject* descendant)
{
// Go through the subtree that was just inserted and create column sets (needed by regular
// column content) and spanner sets (one needed by each spanner).
for (RenderObject* renderer = descendant; renderer; renderer = renderer->nextInPreOrder(descendant)) {
if (containingColumnSpannerSet(renderer))
continue; // Inside a column spanner set. Nothing to do, then.
if (descendantIsValidColumnSpanner(renderer)) {
// This renderer is a spanner, so it needs to establish a spanner set.
createAndInsertSpannerSet(toRenderBox(renderer));
continue;
}
// This renderer is regular column content (i.e. not a spanner). Create a set if necessary.
RenderMultiColumnSet* lastSet = lastMultiColumnSet();
if (!lastSet || lastSet->isRenderMultiColumnSpannerSet())
createAndInsertMultiColumnSet();
}
}
void RenderMultiColumnFlowThread::computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues& computedValues) const void RenderMultiColumnFlowThread::computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues& computedValues) const
{ {
// We simply remain at our intrinsic height. // We simply remain at our intrinsic height.
......
...@@ -28,10 +28,12 @@ ...@@ -28,10 +28,12 @@
#define RenderMultiColumnFlowThread_h #define RenderMultiColumnFlowThread_h
#include "core/rendering/RenderFlowThread.h" #include "core/rendering/RenderFlowThread.h"
#include "wtf/HashMap.h"
namespace blink { namespace blink {
class RenderMultiColumnSet; class RenderMultiColumnSet;
class RenderMultiColumnSpannerSet;
// Flow thread implementation for CSS multicol. This will be inserted as an anonymous child block of // Flow thread implementation for CSS multicol. This will be inserted as an anonymous child block of
// the actual multicol container (i.e. the RenderBlockFlow whose style computes to non-auto // the actual multicol container (i.e. the RenderBlockFlow whose style computes to non-auto
...@@ -51,17 +53,24 @@ class RenderMultiColumnSet; ...@@ -51,17 +53,24 @@ class RenderMultiColumnSet;
// container. It's the RenderMultiColumnSet objects that take up the necessary amount of space, and // container. It's the RenderMultiColumnSet objects that take up the necessary amount of space, and
// make sure that the columns are painted and hit-tested correctly. // make sure that the columns are painted and hit-tested correctly.
// //
// If there is any column content inside the multicol container, we create a
// RenderMultiColumnSet. We only need to create multiple sets if there are spanners
// (column-span:all) in the multicol container. When a spanner is inserted, content preceding it
// gets its own set, and content succeeding it will get another set. The spanner itself will also
// get its own set (RenderMultiColumnSpannerSet).
//
// The width of the flow thread is the same as the column width. The width of a column set is the // The width of the flow thread is the same as the column width. The width of a column set is the
// same as the content box width of the multicol container; in other words exactly enough to hold // same as the content box width of the multicol container; in other words exactly enough to hold
// the number of columns to be used, stacked horizontally, plus column gaps between them. // the number of columns to be used, stacked horizontally, plus column gaps between them.
// //
// Since it's the first child of the multicol container, the flow thread is laid out first, albeit // Since it's the first child of the multicol container, the flow thread is laid out first, albeit
// in a slightly special way, since it's not to take up any space in its ancestors. Afterwards, the // in a slightly special way, since it's not to take up any space in its ancestors. Afterwards, the
// column sets are laid out. They get their height from the columns that they hold. In single // column sets are laid out. Column sets get their height from the columns that they hold. In single
// column-row constrained height non-balancing cases this will simply be the same as the content // column-row constrained height non-balancing cases without spanners this will simply be the same
// height of the multicol container itself. In most other cases we'll have to calculate optimal // as the content height of the multicol container itself. In most other cases we'll have to
// column heights ourselves, though. This process is referred to as column balancing, and then we // calculate optimal column heights ourselves, though. This process is referred to as column
// infer the column set height from the flow thread's height. // balancing, and then we infer the column set height from the height of the flow thread portion
// occupied by each set.
// //
// More on column balancing: the columns' height is unknown in the first layout pass when // More on column balancing: the columns' height is unknown in the first layout pass when
// balancing. This means that we cannot insert any implicit (soft / unforced) breaks (and pagination // balancing. This means that we cannot insert any implicit (soft / unforced) breaks (and pagination
...@@ -97,7 +106,9 @@ public: ...@@ -97,7 +106,9 @@ public:
RenderMultiColumnSet* firstMultiColumnSet() const; RenderMultiColumnSet* firstMultiColumnSet() const;
RenderMultiColumnSet* lastMultiColumnSet() const; RenderMultiColumnSet* lastMultiColumnSet() const;
virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0) override; // Return the spanner set (if any) that contains the specified renderer. This includes the
// renderer for the element that actually establishes the spanner too.
RenderMultiColumnSpannerSet* containingColumnSpannerSet(const RenderObject* descendant) const;
// Populate the flow thread with what's currently its siblings. Called when a regular block // Populate the flow thread with what's currently its siblings. Called when a regular block
// becomes a multicol container. // becomes a multicol container.
...@@ -131,10 +142,14 @@ protected: ...@@ -131,10 +142,14 @@ protected:
private: private:
void calculateColumnCountAndWidth(LayoutUnit& width, unsigned& count) const; void calculateColumnCountAndWidth(LayoutUnit& width, unsigned& count) const;
void createAndInsertMultiColumnSet();
void createAndInsertSpannerSet(RenderBox* spanner);
virtual bool descendantIsValidColumnSpanner(RenderObject* descendant) const;
virtual const char* renderName() const override; virtual const char* renderName() const override;
virtual void addRegionToThread(RenderMultiColumnSet*) override; virtual void addRegionToThread(RenderMultiColumnSet*) override;
virtual void willBeRemovedFromTree() override; virtual void willBeRemovedFromTree() override;
virtual void flowThreadDescendantWasInserted(RenderObject*) override;
virtual void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues&) const override; virtual void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues&) const override;
virtual void updateLogicalWidth() override; virtual void updateLogicalWidth() override;
virtual void setPageBreak(LayoutUnit offset, LayoutUnit spaceShortage) override; virtual void setPageBreak(LayoutUnit offset, LayoutUnit spaceShortage) override;
...@@ -143,6 +158,9 @@ private: ...@@ -143,6 +158,9 @@ private:
virtual bool addForcedRegionBreak(LayoutUnit, RenderObject* breakChild, bool isBefore, LayoutUnit* offsetBreakAdjustment = 0) override; virtual bool addForcedRegionBreak(LayoutUnit, RenderObject* breakChild, bool isBefore, LayoutUnit* offsetBreakAdjustment = 0) override;
virtual bool isPageLogicalHeightKnown() const override; virtual bool isPageLogicalHeightKnown() const override;
typedef HashMap<const RenderObject*, RenderMultiColumnSpannerSet*> SpannerMap;
SpannerMap m_spannerMap;
unsigned m_columnCount; // The used value of column-count unsigned m_columnCount; // The used value of column-count
LayoutUnit m_columnHeightAvailable; // Total height available to columns, or 0 if auto. LayoutUnit m_columnHeightAvailable; // Total height available to columns, or 0 if auto.
bool m_inBalancingPass; // Set when relayouting for column balancing. bool m_inBalancingPass; // Set when relayouting for column balancing.
......
...@@ -206,6 +206,12 @@ void RenderMultiColumnSet::addContentRun(LayoutUnit endOffsetFromFirstPage) ...@@ -206,6 +206,12 @@ void RenderMultiColumnSet::addContentRun(LayoutUnit endOffsetFromFirstPage)
bool RenderMultiColumnSet::recalculateColumnHeight(BalancedHeightCalculation calculationMode) bool RenderMultiColumnSet::recalculateColumnHeight(BalancedHeightCalculation calculationMode)
{ {
if (previousSiblingMultiColumnSet()) {
// FIXME: column spanner layout is not yet implemented. Until it's in place, we only operate
// on the first set during layout. We need to ignore the others here, or assertions will
// fail.
return false;
}
ASSERT(multiColumnFlowThread()->heightIsAuto()); ASSERT(multiColumnFlowThread()->heightIsAuto());
LayoutUnit oldColumnHeight = m_columnHeight; LayoutUnit oldColumnHeight = m_columnHeight;
......
...@@ -50,7 +50,7 @@ namespace blink { ...@@ -50,7 +50,7 @@ namespace blink {
// //
// Column spans result in the creation of new column sets, since a spanning renderer has to be // Column spans result in the creation of new column sets, since a spanning renderer has to be
// placed in between the column sets that come before and after the span. // placed in between the column sets that come before and after the span.
class RenderMultiColumnSet final : public RenderRegion { class RenderMultiColumnSet : public RenderRegion {
public: public:
enum BalancedHeightCalculation { GuessFromFlowThreadPortion, StretchBySpaceShortage }; enum BalancedHeightCalculation { GuessFromFlowThreadPortion, StretchBySpaceShortage };
...@@ -95,7 +95,7 @@ public: ...@@ -95,7 +95,7 @@ public:
void addContentRun(LayoutUnit endOffsetFromFirstPage); void addContentRun(LayoutUnit endOffsetFromFirstPage);
// (Re-)calculate the column height if it's auto. // (Re-)calculate the column height if it's auto.
bool recalculateColumnHeight(BalancedHeightCalculation); virtual bool recalculateColumnHeight(BalancedHeightCalculation);
// Record space shortage (the amount of space that would have been enough to prevent some // Record space shortage (the amount of space that would have been enough to prevent some
// element from being moved to the next column) at a column break. The smallest amount of space // element from being moved to the next column) at a column break. The smallest amount of space
...@@ -127,9 +127,10 @@ public: ...@@ -127,9 +127,10 @@ public:
// The "CSS actual" value of column-count. This includes overflowing columns, if any. // The "CSS actual" value of column-count. This includes overflowing columns, if any.
unsigned actualColumnCount() const; unsigned actualColumnCount() const;
private: protected:
RenderMultiColumnSet(RenderFlowThread*); RenderMultiColumnSet(RenderFlowThread*);
private:
virtual void insertedIntoTree() override final; virtual void insertedIntoTree() override final;
virtual void willBeRemovedFromTree() override final; virtual void willBeRemovedFromTree() override final;
......
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "config.h"
#include "core/rendering/RenderMultiColumnSpannerSet.h"
namespace blink {
RenderMultiColumnSpannerSet* RenderMultiColumnSpannerSet::createAnonymous(RenderMultiColumnFlowThread* flowThread, RenderStyle* parentStyle, RenderBox* rendererInFlowThread)
{
RenderMultiColumnSpannerSet* newSpanner = new RenderMultiColumnSpannerSet(flowThread, rendererInFlowThread);
Document& document = flowThread->document();
newSpanner->setDocumentForAnonymous(&document);
RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(parentStyle, BLOCK);
newSpanner->setStyle(newStyle);
return newSpanner;
}
RenderMultiColumnSpannerSet::RenderMultiColumnSpannerSet(RenderMultiColumnFlowThread* flowThread, RenderBox* rendererInFlowThread)
: RenderMultiColumnSet(flowThread)
, m_rendererInFlowThread(rendererInFlowThread)
{
}
bool RenderMultiColumnSpannerSet::recalculateColumnHeight(BalancedHeightCalculation calculationMode)
{
return false;
}
const char* RenderMultiColumnSpannerSet::renderName() const
{
return "RenderMultiColumnSpannerSet";
}
}
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef RenderMultiColumnSpannerSet_h
#define RenderMultiColumnSpannerSet_h
#include "core/rendering/RenderMultiColumnSet.h"
namespace blink {
// "Column" set for column-span:all elements. Positions the portion of the flow thread that a
// spanner takes up. The actual renderer that sets column-span all is laid out as part of flow
// thread layout (although it cannot use the flow thread width when calculating its own with; it has
// to pretend that the containing block is the multicol container, not the flow
// thread). RenderMultiColumnSpannerSet just makes sure that it's positioned correctly among other
// column sets, within the multicol container.
//
// FIXME: should consider not inheriting from RenderMultiColumnSet (but rather from some common base
// class). Most of what's in RenderMultiColumnSet is of no interest to us.
class RenderMultiColumnSpannerSet final : public RenderMultiColumnSet {
public:
virtual bool isOfType(RenderObjectType type) const override { return type == RenderObjectRenderMultiColumnSpannerSet || RenderMultiColumnSet::isOfType(type); }
static RenderMultiColumnSpannerSet* createAnonymous(RenderMultiColumnFlowThread*, RenderStyle* parentStyle, RenderBox*);
RenderBox* rendererInFlowThread() const { return m_rendererInFlowThread; }
protected:
virtual bool recalculateColumnHeight(BalancedHeightCalculation) override;
virtual const char* renderName() const override;
private:
RenderMultiColumnSpannerSet(RenderMultiColumnFlowThread*, RenderBox*);
RenderBox* m_rendererInFlowThread; // The actual column-span:all renderer inside the flow thread.
};
DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderMultiColumnSpannerSet, isRenderMultiColumnSpannerSet());
} // namespace blink
#endif
...@@ -2402,6 +2402,9 @@ void RenderObject::insertedIntoTree() ...@@ -2402,6 +2402,9 @@ void RenderObject::insertedIntoTree()
if (!isFloating() && parent()->childrenInline()) if (!isFloating() && parent()->childrenInline())
parent()->dirtyLinesFromChangedChild(this); parent()->dirtyLinesFromChangedChild(this);
if (RenderFlowThread* flowThread = parent()->flowThreadContainingBlock())
flowThread->flowThreadDescendantWasInserted(this);
} }
void RenderObject::willBeRemovedFromTree() void RenderObject::willBeRemovedFromTree()
...@@ -2451,7 +2454,6 @@ void RenderObject::removeFromRenderFlowThreadRecursive(RenderFlowThread* renderF ...@@ -2451,7 +2454,6 @@ void RenderObject::removeFromRenderFlowThreadRecursive(RenderFlowThread* renderF
for (RenderObject* child = children->firstChild(); child; child = child->nextSibling()) for (RenderObject* child = children->firstChild(); child; child = child->nextSibling())
child->removeFromRenderFlowThreadRecursive(renderFlowThread); child->removeFromRenderFlowThreadRecursive(renderFlowThread);
} }
setFlowThreadState(NotInsideFlowThread); setFlowThreadState(NotInsideFlowThread);
} }
......
...@@ -357,6 +357,7 @@ public: ...@@ -357,6 +357,7 @@ public:
bool isRenderIFrame() const { return isOfType(RenderObjectRenderIFrame); } bool isRenderIFrame() const { return isOfType(RenderObjectRenderIFrame); }
bool isRenderImage() const { return isOfType(RenderObjectRenderImage); } bool isRenderImage() const { return isOfType(RenderObjectRenderImage); }
bool isRenderMultiColumnSet() const { return isOfType(RenderObjectRenderMultiColumnSet); } bool isRenderMultiColumnSet() const { return isOfType(RenderObjectRenderMultiColumnSet); }
bool isRenderMultiColumnSpannerSet() const { return isOfType(RenderObjectRenderMultiColumnSpannerSet); }
bool isRenderRegion() const { return isOfType(RenderObjectRenderRegion); } bool isRenderRegion() const { return isOfType(RenderObjectRenderRegion); }
bool isRenderScrollbarPart() const { return isOfType(RenderObjectRenderScrollbarPart); } bool isRenderScrollbarPart() const { return isOfType(RenderObjectRenderScrollbarPart); }
bool isRenderTableCol() const { return isOfType(RenderObjectRenderTableCol); } bool isRenderTableCol() const { return isOfType(RenderObjectRenderTableCol); }
...@@ -507,7 +508,7 @@ public: ...@@ -507,7 +508,7 @@ public:
// RenderBlock::createAnonymousBlock(). This includes creating an anonymous // RenderBlock::createAnonymousBlock(). This includes creating an anonymous
// RenderBlock having a BLOCK or BOX display. Other classes such as RenderTextFragment // RenderBlock having a BLOCK or BOX display. Other classes such as RenderTextFragment
// are not RenderBlocks and will return false. See https://bugs.webkit.org/show_bug.cgi?id=56709. // are not RenderBlocks and will return false. See https://bugs.webkit.org/show_bug.cgi?id=56709.
return isAnonymous() && (style()->display() == BLOCK || style()->display() == BOX) && style()->styleType() == NOPSEUDO && isRenderBlock() && !isListMarker() && !isRenderFlowThread() return isAnonymous() && (style()->display() == BLOCK || style()->display() == BOX) && style()->styleType() == NOPSEUDO && isRenderBlock() && !isListMarker() && !isRenderFlowThread() && !isRenderMultiColumnSet()
&& !isRenderFullScreen() && !isRenderFullScreen()
&& !isRenderFullScreenPlaceholder(); && !isRenderFullScreenPlaceholder();
} }
...@@ -1083,6 +1084,7 @@ protected: ...@@ -1083,6 +1084,7 @@ protected:
RenderObjectRenderImage, RenderObjectRenderImage,
RenderObjectRenderInline, RenderObjectRenderInline,
RenderObjectRenderMultiColumnSet, RenderObjectRenderMultiColumnSet,
RenderObjectRenderMultiColumnSpannerSet,
RenderObjectRenderPart, RenderObjectRenderPart,
RenderObjectRenderRegion, RenderObjectRenderRegion,
RenderObjectRenderScrollbarPart, RenderObjectRenderScrollbarPart,
......
...@@ -25,6 +25,9 @@ public: ...@@ -25,6 +25,9 @@ public:
virtual bool needsNewWidth() const override; virtual bool needsNewWidth() const override;
virtual void updateLogicalWidth() override; virtual void updateLogicalWidth() override;
virtual void layout(); virtual void layout();
private:
virtual bool descendantIsValidColumnSpanner(RenderObject* /*descendant*/) const override { return false; }
}; };
} // namespace blink } // namespace blink
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "core/dom/Document.h" #include "core/dom/Document.h"
#include "core/frame/FrameView.h" #include "core/frame/FrameView.h"
#include "core/frame/Settings.h"
#include "core/html/HTMLElement.h" #include "core/html/HTMLElement.h"
#include "core/testing/DummyPageHolder.h" #include "core/testing/DummyPageHolder.h"
#include "wtf/OwnPtr.h" #include "wtf/OwnPtr.h"
...@@ -17,6 +18,8 @@ protected: ...@@ -17,6 +18,8 @@ protected:
{ {
m_pageHolder = DummyPageHolder::create(IntSize(800, 600)); m_pageHolder = DummyPageHolder::create(IntSize(800, 600));
document().settings()->setRegionBasedColumnsEnabled(true);
// This ensures that the minimal DOM tree gets attached // This ensures that the minimal DOM tree gets attached
// correctly for tests that don't call setBodyInnerHTML. // correctly for tests that don't call setBodyInnerHTML.
document().view()->updateLayoutAndStyleIfNeededRecursive(); document().view()->updateLayoutAndStyleIfNeededRecursive();
...@@ -24,9 +27,9 @@ protected: ...@@ -24,9 +27,9 @@ protected:
Document& document() const { return m_pageHolder->document(); } Document& document() const { return m_pageHolder->document(); }
void setBodyInnerHTML(const char* htmlContent) void setBodyInnerHTML(const String& htmlContent)
{ {
document().body()->setInnerHTML(String::fromUTF8(htmlContent), ASSERT_NO_EXCEPTION); document().body()->setInnerHTML(htmlContent, ASSERT_NO_EXCEPTION);
document().view()->updateLayoutAndStyleIfNeededRecursive(); document().view()->updateLayoutAndStyleIfNeededRecursive();
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment