WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
patch.txt (text/plain), 49.59 KB, created by
Dave Hyatt
on 2015-09-14 15:18:30 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Dave Hyatt
Created:
2015-09-14 15:18:30 PDT
Size:
49.59 KB
patch
obsolete
>Index: Source/WebCore/ChangeLog >=================================================================== >--- Source/WebCore/ChangeLog (revision 189750) >+++ Source/WebCore/ChangeLog (working copy) >@@ -1,3 +1,85 @@ >+2015-09-14 David Hyatt <hyatt@apple.com> >+ >+ [New Block-Inside-Inline Model] Implement margin collapsing across contiguous anonymous inline blocks. >+ https://bugs.webkit.org/show_bug.cgi?id=149132 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Added new tests inside fast/block/inside-inlines/ >+ >+ * rendering/InlineFlowBox.cpp: >+ (WebCore::InlineFlowBox::anonymousInlineBlock): >+ Change this accessor to be more robust and be willing to both recur (in case we ever do decide intermediate line boxes should exist) >+ and to type check. This is not currently needed, but I'm just being paranoid and future proof. >+ >+ (WebCore::InlineFlowBox::addToLine): >+ Again, for thoroughness, I am making sure to propagate the hasAnonymousInlineBlock() bit through to parents. This is only needed >+ if we build intermediate line boxes for lines with anonymous inline blocks. >+ >+ (WebCore::InlineFlowBox::placeBoxesInBlockDirection): >+ Anonymous inline blocks receive a layout via layoutBlockChild, in order to make sure that margin collapsing runs. This means >+ that unlike other line objects, the position of the child has been determined already. Therefore we simply set the position >+ of the line box that wraps the anonymous inline block to the already-computed position for that block. >+ >+ Also patch the code that sets lineTop and lineBottom using the root box's dimensions. We don't really care about the root line >+ box on anonymous inline block lines and just want to set lineTop and lineBottom to fit the anonymous inline block. >+ >+ * rendering/RenderBlockFlow.cpp: >+ (WebCore::RenderBlockFlow::collapseMargins): >+ (WebCore::RenderBlockFlow::collapseMarginsWithChildInfo): >+ Refactor collapseMargins to call a helper function that can pass in a previous "sibling", and that can handle the child >+ being null. We do this to perform a margin collapse when anonymous inline blocks run up against regular lines (which is like >+ collapsing with a sibling block "child"). >+ >+ * rendering/RenderBlockFlow.h: >+ Tweak the MarginInfo constructor to take a const RenderBlockFlow. Tweak some line layout methods to pass in the LineLayoutState >+ so that MarginInfo is available during line layout. >+ >+ * rendering/RenderBlockLineLayout.cpp: >+ (WebCore::RenderBlockFlow::createLineBoxes): >+ When we create a new line box, if it is not an anonymous inline block line and our previous line was, simulate a margin >+ collapse in order to possibly push the line box down or up. Note we probably need to re-run line layout in this case and are >+ not doing that yet. >+ >+ (WebCore::constructBidiRunsForSegment): >+ (WebCore::RenderBlockFlow::layoutRunsAndFloats): >+ (WebCore::RenderBlockFlow::layoutRunsAndFloatsInRange): >+ (WebCore::RenderBlockFlow::layoutLineBoxes): >+ (WebCore::RenderBlockFlow::determineStartPosition): >+ (WebCore::RenderBlockFlow::matchedEndLine): >+ (WebCore::RenderBlockFlow::updateRegionForLine): >+ (WebCore::RenderBlockFlow::marginCollapseLinesFromStart): >+ Patch line layout to run margin collapsing when anonymous inline blocks are encountered. This involves making sure >+ margin info and float bottom positions are passed through so that layoutBlockChild can be properly called on >+ anonymous inline blocks that we encounter. >+ >+ In addition line layout when it syncs dirty lines has to run margin collapsing on earlier lines in order to make >+ sure margin info is properly set up at the first dirty line position. >+ >+ Note that there will be more improvements/changes in this area (dirty line syncing), as the current model is inefficient >+ when many anonymous inline blocks are scattered throughout a large-scale line box tree. >+ >+ * rendering/RootInlineBox.cpp: >+ (WebCore::RootInlineBox::alignBoxesInBlockDirection): >+ (WebCore::RootInlineBox::ascentAndDescentForBox): >+ Make sure to rely on the block layout code for the placement of the boxes themselves. Set up the line box code to not have >+ an effect on ascent/descent. >+ >+ * rendering/line/BreakingContext.h: >+ (WebCore::BreakingContext::BreakingContext): >+ (WebCore::BreakingContext::handleReplaced): >+ When we encounter an anonymous inline block, lay it out when it is seen. We have to delay the layout, since we have >+ to be able to perform it mid-line-layout when the containing block's logical height is at the correct value and all previous >+ lines are placed. Margin info also has to be current. >+ >+ * rendering/line/LineBreaker.cpp: >+ * rendering/line/LineBreaker.h: >+ Patched to pass LineLayoutState through so that the stuff we need to perform block layout is available (margin info and float vars). >+ >+ * rendering/line/LineLayoutState.h: >+ Add the block layout margin and float bottom information to the line layout state so that we have it available when performing >+ layouts and margin collapses on anonymous inline block children. >+ > 2015-09-14 Alex Christensen <achristensen@webkit.org> > > [Win] Unreviewed build fix after r189746 >Index: Source/WebCore/rendering/InlineFlowBox.cpp >=================================================================== >--- Source/WebCore/rendering/InlineFlowBox.cpp (revision 189594) >+++ Source/WebCore/rendering/InlineFlowBox.cpp (working copy) >@@ -71,7 +71,13 @@ void InlineFlowBox::setHasBadChildList() > > RenderBlockFlow* InlineFlowBox::anonymousInlineBlock() const > { >- return m_hasAnonymousInlineBlock ? &downcast<RenderBlockFlow>(firstChild()->renderer()) : nullptr; >+ if (!m_hasAnonymousInlineBlock || !firstChild()) >+ return nullptr; >+ if (is<InlineFlowBox>(*firstChild())) >+ return downcast<InlineFlowBox>(*firstChild()).anonymousInlineBlock(); >+ if (firstChild()->renderer().isAnonymousInlineBlock()) >+ return &downcast<RenderBlockFlow>(firstChild()->renderer()); >+ return nullptr; > } > > LayoutUnit InlineFlowBox::getFlowSpacingLogicalWidth() >@@ -117,7 +123,11 @@ void InlineFlowBox::addToLine(InlineBox* > } else if (is<InlineFlowBox>(*child)) { > if (downcast<InlineFlowBox>(*child).hasTextDescendants()) > setHasTextDescendantsOnAncestors(this); >+ if (downcast<InlineFlowBox>(*child).hasAnonymousInlineBlock()) >+ setHasAnonymousInlineBlock(true); > } >+ if (child->renderer().isAnonymousInlineBlock()) >+ setHasAnonymousInlineBlock(true); > > if (descendantsHaveSameLineHeightAndBaseline() && !child->renderer().isOutOfFlowPositioned()) { > const RenderStyle& parentStyle = lineStyle(); >@@ -652,6 +662,11 @@ void InlineFlowBox::placeBoxesInBlockDir > child->setLogicalTop(child->logicalTop() + top + posAdjust); > } > >+ if (child->renderer().isAnonymousInlineBlock()) { >+ const auto& box = downcast<RenderBox>(child->renderer()); >+ child->setLogicalTop(box.logicalTop()); >+ } >+ > LayoutUnit newLogicalTop = child->logicalTop(); > LayoutUnit newLogicalTopIncludingMargins = newLogicalTop; > LayoutUnit boxHeight = child->logicalHeight(); >@@ -727,7 +742,7 @@ void InlineFlowBox::placeBoxesInBlockDir > } > > if (isRootBox) { >- if (strictMode || hasTextChildren() || (descendantsHaveSameLineHeightAndBaseline() && hasTextDescendants())) { >+ if (!hasAnonymousInlineBlock() && (strictMode || hasTextChildren() || (descendantsHaveSameLineHeightAndBaseline() && hasTextDescendants()))) { > if (!setLineTop) { > setLineTop = true; > lineTop = pixelSnappedLogicalTop(); >Index: Source/WebCore/rendering/RenderBlockFlow.cpp >=================================================================== >--- Source/WebCore/rendering/RenderBlockFlow.cpp (revision 189594) >+++ Source/WebCore/rendering/RenderBlockFlow.cpp (working copy) >@@ -65,7 +65,7 @@ COMPILE_ASSERT(sizeof(RenderBlockFlow::M > COMPILE_ASSERT(sizeof(RenderBlockFlow::MarginInfo) == sizeof(SameSizeAsMarginInfo), MarginInfo_should_stay_small); > > // Our MarginInfo state used when laying out block children. >-RenderBlockFlow::MarginInfo::MarginInfo(RenderBlockFlow& block, LayoutUnit beforeBorderPadding, LayoutUnit afterBorderPadding) >+RenderBlockFlow::MarginInfo::MarginInfo(const RenderBlockFlow& block, LayoutUnit beforeBorderPadding, LayoutUnit afterBorderPadding) > : m_atBeforeSideOfBlock(true) > , m_atAfterSideOfBlock(false) > , m_hasMarginBeforeQuirk(false) >@@ -967,15 +967,22 @@ bool RenderBlockFlow::childrenPreventSel > > LayoutUnit RenderBlockFlow::collapseMargins(RenderBox& child, MarginInfo& marginInfo) > { >- bool childDiscardMarginBefore = mustDiscardMarginBeforeForChild(child); >- bool childDiscardMarginAfter = mustDiscardMarginAfterForChild(child); >- bool childIsSelfCollapsing = child.isSelfCollapsingBlock(); >+ return collapseMarginsWithChildInfo(&child, child.previousSibling(), marginInfo); >+} > >+LayoutUnit RenderBlockFlow::collapseMarginsWithChildInfo(RenderBox* child, RenderObject* prevSibling, MarginInfo& marginInfo) >+{ >+ bool childDiscardMarginBefore = child ? mustDiscardMarginBeforeForChild(*child) : false; >+ bool childDiscardMarginAfter = child ? mustDiscardMarginAfterForChild(*child) : false; >+ bool childIsSelfCollapsing = child ? child->isSelfCollapsingBlock() : false; >+ bool beforeQuirk = child ? hasMarginBeforeQuirk(*child) : false; >+ bool afterQuirk = child ? hasMarginAfterQuirk(*child) : false; >+ > // The child discards the before margin when the the after margin has discard in the case of a self collapsing block. > childDiscardMarginBefore = childDiscardMarginBefore || (childDiscardMarginAfter && childIsSelfCollapsing); >- >+ > // Get the four margin values for the child and cache them. >- const MarginValues childMargins = marginValuesForChild(child); >+ const MarginValues childMargins = child ? marginValuesForChild(*child) : MarginValues(0, 0, 0, 0); > > // Get our max pos and neg top margins. > LayoutUnit posTop = childMargins.positiveMarginBefore(); >@@ -988,28 +995,24 @@ LayoutUnit RenderBlockFlow::collapseMarg > negTop = std::max(negTop, childMargins.negativeMarginAfter()); > } > >- // See if the top margin is quirky. We only care if this child has >- // margins that will collapse with us. >- bool topQuirk = hasMarginBeforeQuirk(child); >- > if (marginInfo.canCollapseWithMarginBefore()) { > if (!childDiscardMarginBefore && !marginInfo.discardMargin()) { > // This child is collapsing with the top of the > // block. If it has larger margin values, then we need to update > // our own maximal values. >- if (!document().inQuirksMode() || !marginInfo.quirkContainer() || !topQuirk) >+ if (!document().inQuirksMode() || !marginInfo.quirkContainer() || !beforeQuirk) > setMaxMarginBeforeValues(std::max(posTop, maxPositiveMarginBefore()), std::max(negTop, maxNegativeMarginBefore())); > > // The minute any of the margins involved isn't a quirk, don't > // collapse it away, even if the margin is smaller (www.webreference.com > // has an example of this, a <dt> with 0.8em author-specified inside > // a <dl> inside a <td>. >- if (!marginInfo.determinedMarginBeforeQuirk() && !topQuirk && (posTop - negTop)) { >+ if (!marginInfo.determinedMarginBeforeQuirk() && !beforeQuirk && (posTop - negTop)) { > setHasMarginBeforeQuirk(false); > marginInfo.setDeterminedMarginBeforeQuirk(true); > } > >- if (!marginInfo.determinedMarginBeforeQuirk() && topQuirk && !marginBefore()) >+ if (!marginInfo.determinedMarginBeforeQuirk() && beforeQuirk && !marginBefore()) > // We have no top margin and our top child has a quirky margin. > // We will pick up this quirky margin and pass it through. > // This deals with the <td><div><p> case. >@@ -1028,18 +1031,18 @@ LayoutUnit RenderBlockFlow::collapseMarg > } > > if (marginInfo.quirkContainer() && marginInfo.atBeforeSideOfBlock() && (posTop - negTop)) >- marginInfo.setHasMarginBeforeQuirk(topQuirk); >+ marginInfo.setHasMarginBeforeQuirk(beforeQuirk); > > LayoutUnit beforeCollapseLogicalTop = logicalHeight(); > LayoutUnit logicalTop = beforeCollapseLogicalTop; > > LayoutUnit clearanceForSelfCollapsingBlock; >- RenderObject* prev = child.previousSibling(); >+ > // If the child's previous sibling is a self-collapsing block that cleared a float then its top border edge has been set at the bottom border edge > // of the float. Since we want to collapse the child's top margin with the self-collapsing block's top and bottom margins we need to adjust our parent's height to match the > // margin top of the self-collapsing block. If the resulting collapsed margin leaves the child still intruding into the float then we will want to clear it. >- if (!marginInfo.canCollapseWithMarginBefore() && is<RenderBlockFlow>(prev) && downcast<RenderBlockFlow>(*prev).isSelfCollapsingBlock()) { >- clearanceForSelfCollapsingBlock = downcast<RenderBlockFlow>(*prev).marginOffsetForSelfCollapsingBlock(); >+ if (!marginInfo.canCollapseWithMarginBefore() && is<RenderBlockFlow>(prevSibling) && downcast<RenderBlockFlow>(*prevSibling).isSelfCollapsingBlock()) { >+ clearanceForSelfCollapsingBlock = downcast<RenderBlockFlow>(*prevSibling).marginOffsetForSelfCollapsingBlock(); > setLogicalHeight(logicalHeight() - clearanceForSelfCollapsingBlock); > } > >@@ -1067,13 +1070,13 @@ LayoutUnit RenderBlockFlow::collapseMarg > logicalTop = logicalHeight() + collapsedBeforePos - collapsedBeforeNeg; > } > } else { >- if (mustSeparateMarginBeforeForChild(child)) { >+ if (child && mustSeparateMarginBeforeForChild(*child)) { > ASSERT(!marginInfo.discardMargin() || (marginInfo.discardMargin() && !marginInfo.margin())); > // If we are at the before side of the block and we collapse, ignore the computed margin > // and just add the child margin to the container height. This will correctly position > // the child inside the container. > LayoutUnit separateMargin = !marginInfo.canCollapseWithMarginBefore() ? marginInfo.margin() : LayoutUnit::fromPixel(0); >- setLogicalHeight(logicalHeight() + separateMargin + marginBeforeForChild(child)); >+ setLogicalHeight(logicalHeight() + separateMargin + marginBeforeForChild(*child)); > logicalTop = logicalHeight(); > } else if (!marginInfo.discardMargin() && (!marginInfo.atBeforeSideOfBlock() > || (!marginInfo.canCollapseMarginBeforeWithChildren() >@@ -1093,7 +1096,7 @@ LayoutUnit RenderBlockFlow::collapseMarg > marginInfo.clearMargin(); > > if (marginInfo.margin()) >- marginInfo.setHasMarginAfterQuirk(hasMarginAfterQuirk(child)); >+ marginInfo.setHasMarginAfterQuirk(afterQuirk); > } > > // If margins would pull us past the top of the next page, then we need to pull back and pretend like the margins >@@ -1106,10 +1109,10 @@ LayoutUnit RenderBlockFlow::collapseMarg > setLogicalHeight(logicalHeight() + (logicalTop - oldLogicalTop)); > } > >- if (is<RenderBlockFlow>(prev) && !prev->isFloatingOrOutOfFlowPositioned()) { >+ if (is<RenderBlockFlow>(prevSibling) && !prevSibling->isFloatingOrOutOfFlowPositioned()) { > // If |child| is a self-collapsing block it may have collapsed into a previous sibling and although it hasn't reduced the height of the parent yet > // any floats from the parent will now overhang. >- RenderBlockFlow& block = downcast<RenderBlockFlow>(*prev); >+ RenderBlockFlow& block = downcast<RenderBlockFlow>(*prevSibling); > LayoutUnit oldLogicalHeight = logicalHeight(); > setLogicalHeight(logicalTop); > if (block.containsFloats() && !block.avoidsFloats() && (block.logicalTop() + block.lowestFloatLogicalBottom()) > logicalTop) >@@ -1120,8 +1123,8 @@ LayoutUnit RenderBlockFlow::collapseMarg > // into the margin area of the self-collapsing block then the float it clears is now intruding into |child|. Layout again so that we can look for > // floats in the parent that overhang |child|'s new logical top. > bool logicalTopIntrudesIntoFloat = clearanceForSelfCollapsingBlock > 0 && logicalTop < beforeCollapseLogicalTop; >- if (logicalTopIntrudesIntoFloat && containsFloats() && !child.avoidsFloats() && lowestFloatLogicalBottom() > logicalTop) >- child.setNeedsLayout(); >+ if (child && logicalTopIntrudesIntoFloat && containsFloats() && !child->avoidsFloats() && lowestFloatLogicalBottom() > logicalTop) >+ child->setNeedsLayout(); > } > > return logicalTop; >Index: Source/WebCore/rendering/RenderBlockFlow.h >=================================================================== >--- Source/WebCore/rendering/RenderBlockFlow.h (revision 189594) >+++ Source/WebCore/rendering/RenderBlockFlow.h (working copy) >@@ -194,7 +194,7 @@ public: > LayoutUnit m_negativeMargin; > > public: >- MarginInfo(RenderBlockFlow&, LayoutUnit beforeBorderPadding, LayoutUnit afterBorderPadding); >+ MarginInfo(const RenderBlockFlow&, LayoutUnit beforeBorderPadding, LayoutUnit afterBorderPadding); > > void setAtBeforeSideOfBlock(bool b) { m_atBeforeSideOfBlock = b; } > void setAtAfterSideOfBlock(bool b) { m_atAfterSideOfBlock = b; } >@@ -249,6 +249,8 @@ public: > void updateStaticInlinePositionForChild(RenderBox& child, LayoutUnit logicalTop); > > LayoutUnit collapseMargins(RenderBox& child, MarginInfo&); >+ LayoutUnit collapseMarginsWithChildInfo(RenderBox* child, RenderObject* prevSibling, MarginInfo&); >+ > LayoutUnit clearFloatsIfNeeded(RenderBox& child, MarginInfo&, LayoutUnit oldTopPosMargin, LayoutUnit oldTopNegMargin, LayoutUnit yPos); > LayoutUnit estimateLogicalTopPosition(RenderBox& child, const MarginInfo&, LayoutUnit& estimateWithoutPagination); > void marginBeforeEstimateForChild(RenderBox&, LayoutUnit&, LayoutUnit&, bool&) const; >@@ -565,7 +567,7 @@ private: > BidiRun* handleTrailingSpaces(BidiRunList<BidiRun>&, BidiContext*); > void appendFloatingObjectToLastLine(FloatingObject*); > // Helper function for layoutInlineChildren() >- RootInlineBox* createLineBoxesFromBidiRuns(unsigned bidiLevel, BidiRunList<BidiRun>&, const InlineIterator& end, LineInfo&, VerticalPositionCache&, BidiRun* trailingSpaceRun, WordMeasurements&); >+ RootInlineBox* createLineBoxesFromBidiRuns(unsigned bidiLevel, BidiRunList<BidiRun>&, const InlineIterator& end, LineInfo&, VerticalPositionCache&, BidiRun* trailingSpaceRun, WordMeasurements&, LineLayoutState&); > void layoutRunsAndFloats(LineLayoutState&, bool hasInlineChild); > const InlineIterator& restartLayoutRunsAndFloatsInRange(LayoutUnit oldLogicalHeight, LayoutUnit newLogicalHeight, FloatingObject* lastFloatFromPreviousLine, InlineBidiResolver&, const InlineIterator&); > void layoutRunsAndFloatsInRange(LineLayoutState&, InlineBidiResolver&, const InlineIterator& cleanLineStart, const BidiStatus& cleanLineBidiStatus, unsigned consecutiveHyphenatedLines); >@@ -586,7 +588,7 @@ private: > // line, i.e., that it can't be re-used. > bool lineWidthForPaginatedLineChanged(RootInlineBox*, LayoutUnit lineDelta, RenderFlowThread*) const; > void updateLogicalWidthForAlignment(const ETextAlign&, const RootInlineBox*, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float& availableLogicalWidth, int expansionOpportunityCount); >- >+ void marginCollapseLinesFromStart(LineLayoutState&, RootInlineBox* stopLine); > // END METHODS DEFINED IN RenderBlockLineLayout > > bool namedFlowFragmentNeedsUpdate() const; >Index: Source/WebCore/rendering/RenderBlockLineLayout.cpp >=================================================================== >--- Source/WebCore/rendering/RenderBlockLineLayout.cpp (revision 189587) >+++ Source/WebCore/rendering/RenderBlockLineLayout.cpp (working copy) >@@ -192,7 +192,6 @@ InlineFlowBox* RenderBlockFlow::createLi > InlineFlowBox* parentBox = nullptr; > InlineFlowBox* result = nullptr; > bool hasDefaultLineBoxContain = style().lineBoxContain() == RenderStyle::initialLineBoxContain(); >- bool isBlockInsideInline = childBox->renderer().isAnonymousInlineBlock(); > do { > ASSERT_WITH_SECURITY_IMPLICATION(is<RenderInline>(*obj) || obj == this); > >@@ -216,7 +215,6 @@ InlineFlowBox* RenderBlockFlow::createLi > parentBox = downcast<InlineFlowBox>(newBox); > parentBox->setIsFirstLine(lineInfo.isFirstLine()); > parentBox->setIsHorizontal(isHorizontalWritingMode()); >- parentBox->setHasAnonymousInlineBlock(isBlockInsideInline); > if (!hasDefaultLineBoxContain) > parentBox->clearDescendantsHaveSameLineHeightAndBaseline(); > constructedNewBox = true; >@@ -1097,7 +1095,7 @@ static inline void constructBidiRunsForS > } > > // This function constructs line boxes for all of the text runs in the resolver and computes their position. >-RootInlineBox* RenderBlockFlow::createLineBoxesFromBidiRuns(unsigned bidiLevel, BidiRunList<BidiRun>& bidiRuns, const InlineIterator& end, LineInfo& lineInfo, VerticalPositionCache& verticalPositionCache, BidiRun* trailingSpaceRun, WordMeasurements& wordMeasurements) >+RootInlineBox* RenderBlockFlow::createLineBoxesFromBidiRuns(unsigned bidiLevel, BidiRunList<BidiRun>& bidiRuns, const InlineIterator& end, LineInfo& lineInfo, VerticalPositionCache& verticalPositionCache, BidiRun* trailingSpaceRun, WordMeasurements& wordMeasurements, LineLayoutState& layoutState) > { > if (!bidiRuns.runCount()) > return nullptr; >@@ -1112,6 +1110,21 @@ RootInlineBox* RenderBlockFlow::createLi > lineBox->setBidiLevel(bidiLevel); > lineBox->setEndsWithBreak(lineInfo.previousLineBrokeCleanly()); > >+ // If our previous line was an anonymous block and we are not an anonymous block, >+ // simulate a margin collapse now so that we get the proper >+ // increased height. We also have to simulate a margin collapse to propagate margins >+ // through to the top of our block. >+ // FIXME: Pushing the line down could have the effect of changing how the break information >+ // will be computed. We will probably need to rewind line layout and find a new break spot >+ // when the collapse we perform here moves the line. This is similar to how pagination works, >+ // so we have a way of handling this. >+ if (!lineBox->hasAnonymousInlineBlock()) { >+ RootInlineBox* prevRoot = lineBox->prevRootBox(); >+ if (prevRoot && prevRoot->hasAnonymousInlineBlock()) >+ collapseMarginsWithChildInfo(nullptr, nullptr, layoutState.marginInfo()); >+ layoutState.marginInfo().setAtBeforeSideOfBlock(false); >+ } >+ > bool isSVGRootInlineBox = is<SVGRootInlineBox>(*lineBox); > > GlyphOverflowAndFallbackFontsMap textBoxDataMap; >@@ -1157,7 +1170,10 @@ void RenderBlockFlow::layoutRunsAndFloat > // We want to skip ahead to the first dirty line > InlineBidiResolver resolver; > RootInlineBox* startLine = determineStartPosition(layoutState, resolver); >- >+ >+ if (startLine) >+ marginCollapseLinesFromStart(layoutState, startLine); >+ > unsigned consecutiveHyphenatedLines = 0; > if (startLine) { > for (RootInlineBox* line = startLine->prevRootBox(); line && line->isHyphenated(); line = line->prevRootBox()) >@@ -1242,6 +1258,7 @@ void RenderBlockFlow::layoutRunsAndFloat > layoutState.setEndLineMatched(matchedEndLine(layoutState, resolver, cleanLineStart, cleanLineBidiStatus)); > if (layoutState.endLineMatched()) { > resolver.setPosition(InlineIterator(resolver.position().root(), 0, 0), 0); >+ layoutState.marginInfo().clearMargin(); > break; > } > } >@@ -1256,7 +1273,7 @@ void RenderBlockFlow::layoutRunsAndFloat > FloatingObject* lastFloatFromPreviousLine = (containsFloats()) ? m_floatingObjects->set().last().get() : 0; > > WordMeasurements wordMeasurements; >- end = lineBreaker.nextLineBreak(resolver, layoutState.lineInfo(), renderTextInfo, lastFloatFromPreviousLine, consecutiveHyphenatedLines, wordMeasurements); >+ end = lineBreaker.nextLineBreak(resolver, layoutState.lineInfo(), layoutState, renderTextInfo, lastFloatFromPreviousLine, consecutiveHyphenatedLines, wordMeasurements); > cachePriorCharactersIfNeeded(renderTextInfo.lineBreakIterator); > renderTextInfo.lineBreakIterator.resetPriorContext(); > if (resolver.position().atEnd()) { >@@ -1301,7 +1318,7 @@ void RenderBlockFlow::layoutRunsAndFloat > // inline flow boxes. > > LayoutUnit oldLogicalHeight = logicalHeight(); >- RootInlineBox* lineBox = createLineBoxesFromBidiRuns(resolver.status().context->level(), bidiRuns, end, layoutState.lineInfo(), verticalPositionCache, trailingSpaceRun, wordMeasurements); >+ RootInlineBox* lineBox = createLineBoxesFromBidiRuns(resolver.status().context->level(), bidiRuns, end, layoutState.lineInfo(), verticalPositionCache, trailingSpaceRun, wordMeasurements, layoutState); > > bidiRuns.deleteRuns(); > resolver.markCurrentRunEmpty(); // FIXME: This can probably be replaced by an ASSERT (or just removed). >@@ -1552,7 +1569,7 @@ void RenderBlockFlow::layoutLineBoxes(bo > // Figure out if we should clear out our line boxes. > // FIXME: Handle resize eventually! > bool isFullLayout = !firstRootBox() || selfNeedsLayout() || relayoutChildren || clearLinesForPagination; >- LineLayoutState layoutState(isFullLayout, repaintLogicalTop, repaintLogicalBottom, flowThread); >+ LineLayoutState layoutState(*this, isFullLayout, repaintLogicalTop, repaintLogicalBottom, flowThread); > > if (isFullLayout) > lineBoxes().deleteLineBoxes(); >@@ -1632,10 +1649,18 @@ void RenderBlockFlow::layoutLineBoxes(bo > else > lastLineAnnotationsAdjustment = lastRootBox()->computeOverAnnotationAdjustment(lowestAllowedPosition); > } >- >- // Now add in the bottom border/padding. >- setLogicalHeight(logicalHeight() + lastLineAnnotationsAdjustment + borderAndPaddingAfter() + scrollbarLogicalHeight()); >- >+ >+ // Now do the handling of the bottom of the block, adding in our bottom border/padding and >+ // determining the correct collapsed bottom margin information. This collapse is only necessary >+ // if our last child was an anonymous inline block that might need to propagate margin information out to >+ // us. >+ LayoutUnit beforeEdge = borderAndPaddingBefore(); >+ LayoutUnit afterEdge = borderAndPaddingAfter() + scrollbarLogicalHeight() + lastLineAnnotationsAdjustment; >+ if (lastRootBox() && lastRootBox()->hasAnonymousInlineBlock()) >+ handleAfterSideOfBlock(beforeEdge, afterEdge, layoutState.marginInfo()); >+ else >+ setLogicalHeight(logicalHeight() + afterEdge); >+ > if (!firstRootBox() && hasLineIfEmpty()) > setLogicalHeight(logicalHeight() + lineHeight(true, isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes)); > >@@ -1740,7 +1765,7 @@ RootInlineBox* RenderBlockFlow::determin > // We have a dirty line. > if (RootInlineBox* prevRootBox = curr->prevRootBox()) { > // We have a previous line. >- if (!dirtiedByFloat && (!prevRootBox->endsWithBreak() || !prevRootBox->lineBreakObj() || (is<RenderText>(*prevRootBox->lineBreakObj()) && prevRootBox->lineBreakPos() >= downcast<RenderText>(*prevRootBox->lineBreakObj()).textLength()))) { >+ if (!dirtiedByFloat && !curr->hasAnonymousInlineBlock() && (!prevRootBox->endsWithBreak() || !prevRootBox->lineBreakObj() || (is<RenderText>(*prevRootBox->lineBreakObj()) && prevRootBox->lineBreakPos() >= downcast<RenderText>(*prevRootBox->lineBreakObj()).textLength()))) { > // The previous line didn't break cleanly or broke at a newline > // that has been deleted, so treat it as dirty too. > curr = prevRootBox; >@@ -1903,7 +1928,7 @@ bool RenderBlockFlow::matchedEndLine(Lin > RootInlineBox* originalEndLine = layoutState.endLine(); > RootInlineBox* line = originalEndLine; > for (int i = 0; i < numLines && line; i++, line = line->nextRootBox()) { >- if (line->lineBreakObj() == resolver.position().renderer() && line->lineBreakPos() == resolver.position().offset()) { >+ if (line->lineBreakObj() == resolver.position().renderer() && line->lineBreakPos() == resolver.position().offset() && !line->hasAnonymousInlineBlock()) { > // We have a match. > if (line->lineBreakBidiStatus() != resolver.status()) > return false; // ...but the bidi state doesn't match. >@@ -2134,4 +2159,38 @@ void RenderBlockFlow::updateRegionForLin > lineBox->setIsFirstAfterPageBreak(true); > } > >+void RenderBlockFlow::marginCollapseLinesFromStart(LineLayoutState& layoutState, RootInlineBox* stopLine) >+{ >+ // We have to handle an anonymous inline block streak at the start of the block in order to make sure our own margins are >+ // correct. We only have to do this if the children can propagate margins out to us. >+ if (layoutState.marginInfo().canCollapseWithMarginBefore()) { >+ setLogicalHeight(borderAndPaddingBefore()); >+ RootInlineBox* startLine = firstRootBox(); >+ RootInlineBox* curr; >+ for (curr = startLine; curr && curr->hasAnonymousInlineBlock() && layoutState.marginInfo().canCollapseWithMarginBefore(); curr = curr->nextRootBox()) { >+ if (curr == stopLine) >+ return; >+ layoutBlockChild(*curr->anonymousInlineBlock(), layoutState.marginInfo(), >+ layoutState.prevFloatBottomFromAnonymousInlineBlock(), layoutState.maxFloatBottomFromAnonymousInlineBlock()); >+ } >+ } >+ >+ // Now that we've handled the top of the block, if the stopLine isn't an anonymous block, then we're done. >+ if (!stopLine->hasAnonymousInlineBlock()) >+ return; >+ >+ // Re-run margin collapsing on the block sequence that stopLine is a part of. >+ // First go backwards to get the entire sequence. >+ RootInlineBox* prev = stopLine; >+ for ( ; prev->hasAnonymousInlineBlock(); prev = prev->prevRootBox()) { }; >+ >+ // Update the block height to the correct state. >+ setLogicalHeight(prev->lineBottomWithLeading()); >+ >+ // Now run margin collapsing on those lines. >+ for (prev = prev->nextRootBox(); prev != stopLine; prev = prev->nextRootBox()) >+ layoutBlockChild(*prev->anonymousInlineBlock(), layoutState.marginInfo(), >+ layoutState.prevFloatBottomFromAnonymousInlineBlock(), layoutState.maxFloatBottomFromAnonymousInlineBlock()); >+} >+ > } >Index: Source/WebCore/rendering/RootInlineBox.cpp >=================================================================== >--- Source/WebCore/rendering/RootInlineBox.cpp (revision 189587) >+++ Source/WebCore/rendering/RootInlineBox.cpp (working copy) >@@ -294,7 +294,9 @@ LayoutUnit RootInlineBox::alignBoxesInBl > > maxHeight = std::max<LayoutUnit>(0, maxHeight); // FIXME: Is this really necessary? > >- setLineTopBottomPositions(lineTop, lineBottom, heightOfBlock, heightOfBlock + maxHeight); >+ LayoutUnit lineTopWithLeading = !hasAnonymousInlineBlock() ? heightOfBlock : lineTop; >+ LayoutUnit lineBottomWithLeading = !hasAnonymousInlineBlock() ? heightOfBlock + maxHeight : lineBottom; >+ setLineTopBottomPositions(lineTop, lineBottom, lineTopWithLeading, lineBottomWithLeading); > setPaginatedLineWidth(blockFlow().availableLogicalWidthForContent(heightOfBlock)); > > LayoutUnit annotationsAdjustment = beforeAnnotationsAdjustment(); >@@ -866,7 +868,7 @@ void RootInlineBox::ascentAndDescentForB > // not to be included. > if (box.renderer().isReplaced()) { > if (hasAnonymousInlineBlock()) { >- ascent = box.logicalHeight(); // Margins exist "outside" the line, since they have to collapse. >+ ascent = 0; // Margins exist "outside" the line, since they have to collapse. > descent = 0; > affectsAscent = true; > affectsDescent = true; >Index: Source/WebCore/rendering/line/BreakingContext.h >=================================================================== >--- Source/WebCore/rendering/line/BreakingContext.h (revision 189587) >+++ Source/WebCore/rendering/line/BreakingContext.h (working copy) >@@ -28,6 +28,7 @@ > #include "Hyphenation.h" > #include "LineBreaker.h" > #include "LineInfo.h" >+#include "LineLayoutState.h" > #include "LineWidth.h" > #include "RenderCombineText.h" > #include "RenderCounter.h" >@@ -93,7 +94,7 @@ private: > > class BreakingContext { > public: >- BreakingContext(LineBreaker& lineBreaker, InlineBidiResolver& resolver, LineInfo& inLineInfo, LineWidth& lineWidth, RenderTextInfo& inRenderTextInfo, FloatingObject* inLastFloatFromPreviousLine, bool appliedStartWidth, RenderBlockFlow& block) >+ BreakingContext(LineBreaker& lineBreaker, InlineBidiResolver& resolver, LineInfo& inLineInfo, LineLayoutState& layoutState, LineWidth& lineWidth, RenderTextInfo& inRenderTextInfo, FloatingObject* inLastFloatFromPreviousLine, bool appliedStartWidth, RenderBlockFlow& block) > : m_lineBreaker(lineBreaker) > , m_resolver(resolver) > , m_current(resolver.position()) >@@ -111,6 +112,7 @@ public: > , m_renderTextInfo(inRenderTextInfo) > , m_lastFloatFromPreviousLine(inLastFloatFromPreviousLine) > , m_width(lineWidth) >+ , m_lineLayoutState(layoutState) > , m_currWS(NORMAL) > , m_lastWS(NORMAL) > , m_preservesNewline(false) >@@ -253,6 +255,8 @@ private: > FloatingObject* m_lastFloatFromPreviousLine; > > LineWidth m_width; >+ >+ LineLayoutState& m_lineLayoutState; > > EWhiteSpace m_currWS; > EWhiteSpace m_lastWS; >@@ -529,7 +533,8 @@ inline void BreakingContext::handleRepla > } > > if (replacedBox.isAnonymousInlineBlock()) >- replacedBox.layoutIfNeeded(); >+ m_block.layoutBlockChild(replacedBox, m_lineLayoutState.marginInfo(), >+ m_lineLayoutState.prevFloatBottomFromAnonymousInlineBlock(), m_lineLayoutState.maxFloatBottomFromAnonymousInlineBlock()); > > if (m_ignoringSpaces) > m_lineMidpointState.stopIgnoringSpaces(InlineIterator(0, m_current.renderer(), 0)); >Index: Source/WebCore/rendering/line/LineBreaker.cpp >=================================================================== >--- Source/WebCore/rendering/line/LineBreaker.cpp (revision 189587) >+++ Source/WebCore/rendering/line/LineBreaker.cpp (working copy) >@@ -77,7 +77,7 @@ void LineBreaker::skipLeadingWhitespace( > resolver.commitExplicitEmbedding(); > } > >-InlineIterator LineBreaker::nextLineBreak(InlineBidiResolver& resolver, LineInfo& lineInfo, RenderTextInfo& renderTextInfo, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLines, WordMeasurements& wordMeasurements) >+InlineIterator LineBreaker::nextLineBreak(InlineBidiResolver& resolver, LineInfo& lineInfo, LineLayoutState& layoutState, RenderTextInfo& renderTextInfo, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLines, WordMeasurements& wordMeasurements) > { > reset(); > >@@ -92,7 +92,7 @@ InlineIterator LineBreaker::nextLineBrea > if (resolver.position().atEnd()) > return resolver.position(); > >- BreakingContext context(*this, resolver, lineInfo, width, renderTextInfo, lastFloatFromPreviousLine, appliedStartWidth, m_block); >+ BreakingContext context(*this, resolver, lineInfo, layoutState, width, renderTextInfo, lastFloatFromPreviousLine, appliedStartWidth, m_block); > > while (context.currentObject()) { > context.initializeForCurrentObject(); >Index: Source/WebCore/rendering/line/LineBreaker.h >=================================================================== >--- Source/WebCore/rendering/line/LineBreaker.h (revision 189587) >+++ Source/WebCore/rendering/line/LineBreaker.h (working copy) >@@ -52,7 +52,7 @@ public: > reset(); > } > >- InlineIterator nextLineBreak(InlineBidiResolver&, LineInfo&, RenderTextInfo&, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLines, WordMeasurements&); >+ InlineIterator nextLineBreak(InlineBidiResolver&, LineInfo&, LineLayoutState&, RenderTextInfo&, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLines, WordMeasurements&); > > bool lineWasHyphenated() { return m_hyphenated; } > const Vector<RenderBox*>& positionedObjects() { return m_positionedObjects; } >Index: Source/WebCore/rendering/line/LineLayoutState.h >=================================================================== >--- Source/WebCore/rendering/line/LineLayoutState.h (revision 189587) >+++ Source/WebCore/rendering/line/LineLayoutState.h (working copy) >@@ -35,7 +35,7 @@ > #define LineLayoutState_h > > #include "LayoutRect.h" >-#include "RenderBox.h" >+#include "RenderBlockFlow.h" > > namespace WebCore { > >@@ -56,7 +56,7 @@ struct FloatWithRect { > // during an entire linebox tree layout pass (aka layoutInlineChildren). > class LineLayoutState { > public: >- LineLayoutState(bool fullLayout, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom, RenderFlowThread* flowThread) >+ LineLayoutState(const RenderBlockFlow& blockFlow, bool fullLayout, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom, RenderFlowThread* flowThread) > : m_endLineLogicalTop(0) > , m_endLine(0) > , m_lastFloat(0) >@@ -65,6 +65,7 @@ public: > , m_flowThread(flowThread) > , m_repaintLogicalTop(repaintLogicalTop) > , m_repaintLogicalBottom(repaintLogicalBottom) >+ , m_marginInfo(blockFlow, blockFlow.borderAndPaddingBefore(), blockFlow.borderAndPaddingAfter() + blockFlow.scrollbarLogicalHeight()) > , m_endLineMatched(false) > , m_checkForFloatsFromLastLine(false) > , m_isFullLayout(fullLayout) >@@ -119,6 +120,10 @@ public: > m_repaintLogicalBottom = std::max(m_repaintLogicalBottom, box->logicalBottomVisualOverflow() + std::max<LayoutUnit>(paginationDelta, 0)); > } > >+ RenderBlockFlow::MarginInfo& marginInfo() { return m_marginInfo; } >+ LayoutUnit& prevFloatBottomFromAnonymousInlineBlock() { return m_prevFloatBottomFromAnonymousInlineBlock; } >+ LayoutUnit& maxFloatBottomFromAnonymousInlineBlock() { return m_maxFloatBottomFromAnonymousInlineBlock; } >+ > private: > LineInfo m_lineInfo; > LayoutUnit m_endLineLogicalTop; >@@ -136,6 +141,10 @@ private: > LayoutUnit& m_repaintLogicalTop; > LayoutUnit& m_repaintLogicalBottom; > >+ RenderBlockFlow::MarginInfo m_marginInfo; >+ LayoutUnit m_prevFloatBottomFromAnonymousInlineBlock; >+ LayoutUnit m_maxFloatBottomFromAnonymousInlineBlock; >+ > bool m_endLineMatched : 1; > bool m_checkForFloatsFromLastLine : 1; > bool m_isFullLayout : 1; >Index: LayoutTests/ChangeLog >=================================================================== >--- LayoutTests/ChangeLog (revision 189751) >+++ LayoutTests/ChangeLog (working copy) >@@ -1,3 +1,22 @@ >+2015-09-14 David Hyatt <hyatt@apple.com> >+ >+ 2015-09-14 David Hyatt <hyatt@apple.com> >+ >+ [New Block-Inside-Inline Model] Implement margin collapsing across contiguous anonymous inline blocks. >+ https://bugs.webkit.org/show_bug.cgi?id=149132 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * fast/block/inside-inlines/new-model/margin-collapse: Added. >+ * fast/block/inside-inlines/new-model/margin-collapse/001-expected.html: Added. >+ * fast/block/inside-inlines/new-model/margin-collapse/001.html: Added. >+ * fast/block/inside-inlines/new-model/margin-collapse/002-expected.html: Added. >+ * fast/block/inside-inlines/new-model/margin-collapse/002.html: Added. >+ * fast/block/inside-inlines/new-model/margin-collapse/003-expected.html: Added. >+ * fast/block/inside-inlines/new-model/margin-collapse/003.html: Added. >+ * fast/block/inside-inlines/new-model/margin-collapse/004-expected.html: Added. >+ * fast/block/inside-inlines/new-model/margin-collapse/004.html: Added. >+ > 2015-09-14 Chris Dumez <cdumez@apple.com> > > Disable PICTURE_SIZES on AppleWin >Index: LayoutTests/fast/block/inside-inlines/new-model/margin-collapse/001-expected.html >=================================================================== >--- LayoutTests/fast/block/inside-inlines/new-model/margin-collapse/001-expected.html (revision 0) >+++ LayoutTests/fast/block/inside-inlines/new-model/margin-collapse/001-expected.html (working copy) >@@ -0,0 +1,40 @@ >+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"> >+<html lang="en"> >+ <head> >+ <title>Margin Collapsing: in flow (block-inside-inline version)</title> >+ <style type="text/css"> >+ table { border-spacing: 0; font-size: 50px; border: solid; } >+ td { background: orange; padding: 0; } >+ div { margin: 1em 0; } >+ .a { background: yellow; } >+ .b { background: lime; } >+ .c { background: aqua; } >+ .d { background: blue; } >+ .red { background: red; } >+ </style> >+ </head> >+ <body> >+ <p>The following two columns should be pixel perfect identical with no red visible.</p> >+ <table> >+ <tr> >+ <td class="test"> >+ <span><div class="d"> >+ <span><div class="red"><span><div class="red"><span><div class="a">A</div></span></div><span><div class="red"></div></span></div></span> >+ <span><div class="red"></div></span> >+ <span><div class="red"><span><div class="red"></div></span></div></span> >+ <span><div class="red"><span><div class="b"><span><div class="red"></div></span>B</div></span></div></span> >+ <span><div class="c">C</div></span> >+ </div></span> >+ </td> >+ <td class="control"> >+ <div class="d"> >+ <div class="a">A</div> >+ <div class="b">B</div> >+ <div class="c">C</div> >+ </div> >+ </td> >+ </tr> >+ </table> >+ <p>This test is meaningless if you don't pass <a href="006.html#">test 006</a>.</p> >+ </body> >+</html> >Index: LayoutTests/fast/block/inside-inlines/new-model/margin-collapse/001.html >=================================================================== >--- LayoutTests/fast/block/inside-inlines/new-model/margin-collapse/001.html (revision 0) >+++ LayoutTests/fast/block/inside-inlines/new-model/margin-collapse/001.html (working copy) >@@ -0,0 +1,44 @@ >+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"> >+<html lang="en"> >+ <head> >+ <title>Margin Collapsing: in flow (block-inside-inline version)</title> >+ <style type="text/css"> >+ table { border-spacing: 0; font-size: 50px; border: solid; } >+ td { background: orange; padding: 0; } >+ div { margin: 1em 0; } >+ .a { background: yellow; } >+ .b { background: lime; } >+ .c { background: aqua; } >+ .d { background: blue; } >+ .red { background: red; } >+ </style> >+ <script> >+if (window.internals) >+ window.internals.settings.setNewBlockInsideInlineModelEnabled(true) >+</script> >+ </head> >+ <body> >+ <p>The following two columns should be pixel perfect identical with no red visible.</p> >+ <table> >+ <tr> >+ <td class="test"> >+ <span><div class="d"> >+ <span><div class="red"><span><div class="red"><span><div class="a">A</div></span></div><span><div class="red"></div></span></div></span> >+ <span><div class="red"></div></span> >+ <span><div class="red"><span><div class="red"></div></span></div></span> >+ <span><div class="red"><span><div class="b"><span><div class="red"></div></span>B</div></span></div></span> >+ <span><div class="c">C</div></span> >+ </div></span> >+ </td> >+ <td class="control"> >+ <div class="d"> >+ <div class="a">A</div> >+ <div class="b">B</div> >+ <div class="c">C</div> >+ </div> >+ </td> >+ </tr> >+ </table> >+ <p>This test is meaningless if you don't pass <a href="006.html#">test 006</a>.</p> >+ </body> >+</html> >Index: LayoutTests/fast/block/inside-inlines/new-model/margin-collapse/002-expected.html >=================================================================== >--- LayoutTests/fast/block/inside-inlines/new-model/margin-collapse/002-expected.html (revision 0) >+++ LayoutTests/fast/block/inside-inlines/new-model/margin-collapse/002-expected.html (working copy) >@@ -0,0 +1,16 @@ >+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"> >+<html lang="en"> >+ <head> >+ <title>Margin Collapsing: absolutely positioned (block-inside-inline version)</title> >+ <style type="text/css"> >+ div.test { background: green; position: absolute; } >+ div.test div { background: red; margin: 5em 2.5em; } >+ div.control { height: 5em; width: 5em; background: red; position: absolute; } >+ </style> >+ </head> >+ <body> >+ <p>This page should have one square green block and no red.</p> >+ <div class="control"></div> >+ <div class="test"><span><div></div></span></div> >+ </body> >+</html> >Index: LayoutTests/fast/block/inside-inlines/new-model/margin-collapse/002.html >=================================================================== >--- LayoutTests/fast/block/inside-inlines/new-model/margin-collapse/002.html (revision 0) >+++ LayoutTests/fast/block/inside-inlines/new-model/margin-collapse/002.html (working copy) >@@ -0,0 +1,20 @@ >+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"> >+<html lang="en"> >+ <head> >+ <title>Margin Collapsing: absolutely positioned (block-inside-inline version)</title> >+ <style type="text/css"> >+ div.test { background: green; position: absolute; } >+ div.test div { background: red; margin: 5em 2.5em; } >+ div.control { height: 5em; width: 5em; background: red; position: absolute; } >+ </style> >+ <script> >+if (window.internals) >+ window.internals.settings.setNewBlockInsideInlineModelEnabled(true) >+</script> >+ </head> >+ <body> >+ <p>This page should have one square green block and no red.</p> >+ <div class="control"></div> >+ <div class="test"><span><div></div></span></div> >+ </body> >+</html> >Index: LayoutTests/fast/block/inside-inlines/new-model/margin-collapse/003-expected.html >=================================================================== >--- LayoutTests/fast/block/inside-inlines/new-model/margin-collapse/003-expected.html (revision 0) >+++ LayoutTests/fast/block/inside-inlines/new-model/margin-collapse/003-expected.html (working copy) >@@ -0,0 +1,19 @@ >+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"> >+<html lang="en"> >+ <head> >+ <title>Margin Collapsing: fixed positioned (block-inside-inline version)</title> >+ <style type="text/css"> >+ div.test { background: green; position: fixed; top: 4em; } >+ div.test div { background: red; margin: 5em 2.5em; } >+ div.control { height: 5em; width: 5em; background: red; position: fixed; top: 4em; } >+ </style> >+ </head> >+ <body> >+ <p>This page should have one square green block and no red.</p> >+ <div class="control"></div> >+ <div class="test"><span> >+ <div></div> >+ </span> >+ </div> >+ </body> >+</html> >Index: LayoutTests/fast/block/inside-inlines/new-model/margin-collapse/003.html >=================================================================== >--- LayoutTests/fast/block/inside-inlines/new-model/margin-collapse/003.html (revision 0) >+++ LayoutTests/fast/block/inside-inlines/new-model/margin-collapse/003.html (working copy) >@@ -0,0 +1,23 @@ >+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"> >+<html lang="en"> >+ <head> >+ <title>Margin Collapsing: fixed positioned (block-inside-inline version)</title> >+ <style type="text/css"> >+ div.test { background: green; position: fixed; top: 4em; } >+ div.test div { background: red; margin: 5em 2.5em; } >+ div.control { height: 5em; width: 5em; background: red; position: fixed; top: 4em; } >+ </style> >+ <script> >+if (window.internals) >+ window.internals.settings.setNewBlockInsideInlineModelEnabled(true) >+</script> >+ </head> >+ <body> >+ <p>This page should have one square green block and no red.</p> >+ <div class="control"></div> >+ <div class="test"><span> >+ <div></div> >+ </span> >+ </div> >+ </body> >+</html> >Index: LayoutTests/fast/block/inside-inlines/new-model/margin-collapse/004-expected.html >=================================================================== >--- LayoutTests/fast/block/inside-inlines/new-model/margin-collapse/004-expected.html (revision 0) >+++ LayoutTests/fast/block/inside-inlines/new-model/margin-collapse/004-expected.html (working copy) >@@ -0,0 +1,18 @@ >+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"> >+<html lang="en"> >+ <head> >+ <title>Margin Collapsing: floats (block-inside-inline version)</title> >+ <style type="text/css"> >+ div.test { background: green; float: left; } >+ div.test div { background: red; margin: 5em 2.5em; } >+ div.control { height: 5em; width: 5em; margin: 0 0 -5em 0; background: red; } >+ </style> >+ </head> >+ <body> >+ <p>This page should have one square green block and no red.</p> >+ <div class="control"></div> >+ <div class="test"> >+ <span><div></div></span> >+ </div> >+ </body> >+</html> >Index: LayoutTests/fast/block/inside-inlines/new-model/margin-collapse/004.html >=================================================================== >--- LayoutTests/fast/block/inside-inlines/new-model/margin-collapse/004.html (revision 0) >+++ LayoutTests/fast/block/inside-inlines/new-model/margin-collapse/004.html (working copy) >@@ -0,0 +1,22 @@ >+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"> >+<html lang="en"> >+ <head> >+ <title>Margin Collapsing: floats (block-inside-inline version)</title> >+ <style type="text/css"> >+ div.test { background: green; float: left; } >+ div.test div { background: red; margin: 5em 2.5em; } >+ div.control { height: 5em; width: 5em; margin: 0 0 -5em 0; background: red; } >+ </style> >+ <script> >+if (window.internals) >+ window.internals.settings.setNewBlockInsideInlineModelEnabled(true) >+</script> >+ </head> >+ <body> >+ <p>This page should have one square green block and no red.</p> >+ <div class="control"></div> >+ <div class="test"> >+ <span><div></div></span> >+ </div> >+ </body> >+</html>
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 149132
:
261137
|
261140
|
261149
|
261150
|
261155
|
261195