| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
| 4 * (C) 2007 David Smith (catfish.man@gmail.com) | 4 * (C) 2007 David Smith (catfish.man@gmail.com) |
| 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc.
All rights reserved. | 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc.
All rights reserved. |
| 6 * Copyright (C) Research In Motion Limited 2010. All rights reserved. | 6 * Copyright (C) Research In Motion Limited 2010. All rights reserved. |
| 7 * | 7 * |
| 8 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
| 9 * modify it under the terms of the GNU Library General Public | 9 * modify it under the terms of the GNU Library General Public |
| 10 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 static int gDelayUpdateScrollInfo = 0; | 81 static int gDelayUpdateScrollInfo = 0; |
| 82 static DelayedUpdateScrollInfoSet* gDelayedUpdateScrollInfoSet = 0; | 82 static DelayedUpdateScrollInfoSet* gDelayedUpdateScrollInfoSet = 0; |
| 83 | 83 |
| 84 RenderBlock::RenderBlock(ContainerNode* node) | 84 RenderBlock::RenderBlock(ContainerNode* node) |
| 85 : RenderBox(node) | 85 : RenderBox(node) |
| 86 , m_hasMarginBeforeQuirk(false) | 86 , m_hasMarginBeforeQuirk(false) |
| 87 , m_hasMarginAfterQuirk(false) | 87 , m_hasMarginAfterQuirk(false) |
| 88 , m_beingDestroyed(false) | 88 , m_beingDestroyed(false) |
| 89 , m_hasMarkupTruncation(false) | 89 , m_hasMarkupTruncation(false) |
| 90 , m_hasBorderOrPaddingLogicalWidthChanged(false) | 90 , m_hasBorderOrPaddingLogicalWidthChanged(false) |
| 91 , m_hasOnlySelfCollapsingChildren(false) | |
| 92 { | 91 { |
| 93 // RenderBlockFlow calls setChildrenInline(true). | 92 // RenderBlockFlow calls setChildrenInline(true). |
| 94 // By default, subclasses do not have inline children. | 93 // By default, subclasses do not have inline children. |
| 95 } | 94 } |
| 96 | 95 |
| 97 void RenderBlock::trace(Visitor* visitor) | 96 void RenderBlock::trace(Visitor* visitor) |
| 98 { | 97 { |
| 99 visitor->trace(m_children); | 98 visitor->trace(m_children); |
| 100 RenderBox::trace(visitor); | 99 RenderBox::trace(visitor); |
| 101 } | 100 } |
| (...skipping 729 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 831 ASSERT_NOT_REACHED(); | 830 ASSERT_NOT_REACHED(); |
| 832 | 831 |
| 833 break; | 832 break; |
| 834 } | 833 } |
| 835 setContinuation(0); | 834 setContinuation(0); |
| 836 destroy(); | 835 destroy(); |
| 837 } | 836 } |
| 838 } | 837 } |
| 839 } | 838 } |
| 840 | 839 |
| 841 bool RenderBlock::isSelfCollapsingBlock() const | |
| 842 { | |
| 843 // We are not self-collapsing if we | |
| 844 // (a) have a non-zero height according to layout (an optimization to avoid
wasting time) | |
| 845 // (b) are a table, | |
| 846 // (c) have border/padding, | |
| 847 // (d) have a min-height | |
| 848 // (e) have specified that one of our margins can't collapse using a CSS ext
ension | |
| 849 // (f) establish a new block formatting context. | |
| 850 | |
| 851 // The early exit must be done before we check for clean layout. | |
| 852 // We should be able to give a quick answer if the box is a relayout boundar
y. | |
| 853 // Being a relayout boundary implies a block formatting context, and also | |
| 854 // our internal layout shouldn't affect our container in any way. | |
| 855 if (createsBlockFormattingContext()) | |
| 856 return false; | |
| 857 | |
| 858 ASSERT(!needsLayout()); | |
| 859 | |
| 860 if (logicalHeight() > 0 | |
| 861 || borderAndPaddingLogicalHeight() | |
| 862 || style()->logicalMinHeight().isPositive() | |
| 863 || style()->marginBeforeCollapse() == MSEPARATE || style()->marginAfterC
ollapse() == MSEPARATE) | |
| 864 return false; | |
| 865 | |
| 866 Length logicalHeightLength = style()->logicalHeight(); | |
| 867 bool hasAutoHeight = logicalHeightLength.isAuto(); | |
| 868 if (logicalHeightLength.isPercent()) { | |
| 869 hasAutoHeight = true; | |
| 870 for (RenderBlock* cb = containingBlock(); !cb->isRenderView(); cb = cb->
containingBlock()) { | |
| 871 if (cb->style()->logicalHeight().isFixed()) | |
| 872 hasAutoHeight = false; | |
| 873 } | |
| 874 } | |
| 875 | |
| 876 // If the height is 0 or auto, then whether or not we are a self-collapsing
block depends | |
| 877 // on whether we have content that is all self-collapsing or not. | |
| 878 if (hasAutoHeight || ((logicalHeightLength.isFixed() || logicalHeightLength.
isPercent()) && logicalHeightLength.isZero())) { | |
| 879 // If the block has inline children, see if we generated any line boxes.
If we have any | |
| 880 // line boxes, then we can't be self-collapsing, since we have content. | |
| 881 if (childrenInline()) | |
| 882 return !firstLineBox(); | |
| 883 | |
| 884 // Whether or not we collapse is dependent on whether all our normal flo
w children | |
| 885 // are also self-collapsing. | |
| 886 if (m_hasOnlySelfCollapsingChildren) | |
| 887 return true; | |
| 888 for (RenderBox* child = firstChildBox(); child; child = child->nextSibli
ngBox()) { | |
| 889 if (child->isFloatingOrOutOfFlowPositioned()) | |
| 890 continue; | |
| 891 if (!child->isSelfCollapsingBlock()) | |
| 892 return false; | |
| 893 } | |
| 894 return true; | |
| 895 } | |
| 896 return false; | |
| 897 } | |
| 898 | |
| 899 void RenderBlock::startDelayUpdateScrollInfo() | 840 void RenderBlock::startDelayUpdateScrollInfo() |
| 900 { | 841 { |
| 901 if (gDelayUpdateScrollInfo == 0) { | 842 if (gDelayUpdateScrollInfo == 0) { |
| 902 ASSERT(!gDelayedUpdateScrollInfoSet); | 843 ASSERT(!gDelayedUpdateScrollInfoSet); |
| 903 gDelayedUpdateScrollInfoSet = new DelayedUpdateScrollInfoSet; | 844 gDelayedUpdateScrollInfoSet = new DelayedUpdateScrollInfoSet; |
| 904 } | 845 } |
| 905 ASSERT(gDelayedUpdateScrollInfoSet); | 846 ASSERT(gDelayedUpdateScrollInfoSet); |
| 906 ++gDelayUpdateScrollInfo; | 847 ++gDelayUpdateScrollInfo; |
| 907 } | 848 } |
| 908 | 849 |
| (...skipping 1819 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2728 } | 2669 } |
| 2729 | 2670 |
| 2730 void RenderBlock::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accum
ulatedOffset) const | 2671 void RenderBlock::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accum
ulatedOffset) const |
| 2731 { | 2672 { |
| 2732 // For blocks inside inlines, we go ahead and include margins so that we run
right up to the | 2673 // For blocks inside inlines, we go ahead and include margins so that we run
right up to the |
| 2733 // inline boxes above and below us (thus getting merged with them to form a
single irregular | 2674 // inline boxes above and below us (thus getting merged with them to form a
single irregular |
| 2734 // shape). | 2675 // shape). |
| 2735 if (isAnonymousBlockContinuation()) { | 2676 if (isAnonymousBlockContinuation()) { |
| 2736 // FIXME: This is wrong for block-flows that are horizontal. | 2677 // FIXME: This is wrong for block-flows that are horizontal. |
| 2737 // https://bugs.webkit.org/show_bug.cgi?id=46781 | 2678 // https://bugs.webkit.org/show_bug.cgi?id=46781 |
| 2738 rects.append(pixelSnappedIntRect(accumulatedOffset.x(), accumulatedOffse
t.y() - collapsedMarginBefore(), | 2679 rects.append(pixelSnappedIntRect(accumulatedOffset.x(), accumulatedOffse
t.y() - marginBefore(), |
| 2739 width(), height() + collapsedMarginBefore() + co
llapsedMarginAfter())); | 2680 width(), height() + marginBefore() + marginAfter
())); |
| 2740 continuation()->absoluteRects(rects, accumulatedOffset - toLayoutSize(lo
cation() + | 2681 continuation()->absoluteRects(rects, accumulatedOffset - toLayoutSize(lo
cation() + |
| 2741 inlineElementContinuation()->containingBlock()->location())); | 2682 inlineElementContinuation()->containingBlock()->location())); |
| 2742 } else | 2683 } else |
| 2743 rects.append(pixelSnappedIntRect(accumulatedOffset, size())); | 2684 rects.append(pixelSnappedIntRect(accumulatedOffset, size())); |
| 2744 } | 2685 } |
| 2745 | 2686 |
| 2746 void RenderBlock::absoluteQuads(Vector<FloatQuad>& quads) const | 2687 void RenderBlock::absoluteQuads(Vector<FloatQuad>& quads) const |
| 2747 { | 2688 { |
| 2748 // For blocks inside inlines, we go ahead and include margins so that we run
right up to the | 2689 // For blocks inside inlines, we go ahead and include margins so that we run
right up to the |
| 2749 // inline boxes above and below us (thus getting merged with them to form a
single irregular | 2690 // inline boxes above and below us (thus getting merged with them to form a
single irregular |
| 2750 // shape). | 2691 // shape). |
| 2751 if (isAnonymousBlockContinuation()) { | 2692 if (isAnonymousBlockContinuation()) { |
| 2752 // FIXME: This is wrong for block-flows that are horizontal. | 2693 // FIXME: This is wrong for block-flows that are horizontal. |
| 2753 // https://bugs.webkit.org/show_bug.cgi?id=46781 | 2694 // https://bugs.webkit.org/show_bug.cgi?id=46781 |
| 2754 FloatRect localRect(0, -collapsedMarginBefore().toFloat(), | 2695 FloatRect localRect(0, -marginBefore().toFloat(), |
| 2755 width().toFloat(), (height() + collapsedMarginBefore() + collapsedMa
rginAfter()).toFloat()); | 2696 width().toFloat(), (height() + marginBefore() + marginAfter()).toFlo
at()); |
| 2756 quads.append(localToAbsoluteQuad(localRect, 0 /* mode */)); | 2697 quads.append(localToAbsoluteQuad(localRect, 0 /* mode */)); |
| 2757 continuation()->absoluteQuads(quads); | 2698 continuation()->absoluteQuads(quads); |
| 2758 } else { | 2699 } else { |
| 2759 quads.append(RenderBox::localToAbsoluteQuad(FloatRect(0, 0, width().toFl
oat(), height().toFloat()), 0 /* mode */)); | 2700 quads.append(RenderBox::localToAbsoluteQuad(FloatRect(0, 0, width().toFl
oat(), height().toFloat()), 0 /* mode */)); |
| 2760 } | 2701 } |
| 2761 } | 2702 } |
| 2762 | 2703 |
| 2763 LayoutRect RenderBlock::rectWithOutlineForPaintInvalidation(const RenderLayerMod
elObject* paintInvalidationContainer, LayoutUnit outlineWidth, const PaintInvali
dationState* paintInvalidationState) const | 2704 LayoutRect RenderBlock::rectWithOutlineForPaintInvalidation(const RenderLayerMod
elObject* paintInvalidationContainer, LayoutUnit outlineWidth, const PaintInvali
dationState* paintInvalidationState) const |
| 2764 { | 2705 { |
| 2765 LayoutRect r(RenderBox::rectWithOutlineForPaintInvalidation(paintInvalidatio
nContainer, outlineWidth, paintInvalidationState)); | 2706 LayoutRect r(RenderBox::rectWithOutlineForPaintInvalidation(paintInvalidatio
nContainer, outlineWidth, paintInvalidationState)); |
| 2766 if (isAnonymousBlockContinuation()) | 2707 if (isAnonymousBlockContinuation()) |
| 2767 r.inflateY(collapsedMarginBefore()); // FIXME: This is wrong for block-f
lows that are horizontal. | 2708 r.inflateY(marginBefore()); // FIXME: This is wrong for block-flows that
are horizontal. |
| 2768 return r; | 2709 return r; |
| 2769 } | 2710 } |
| 2770 | 2711 |
| 2771 RenderObject* RenderBlock::hoverAncestor() const | 2712 RenderObject* RenderBlock::hoverAncestor() const |
| 2772 { | 2713 { |
| 2773 return isAnonymousBlockContinuation() ? continuation() : RenderBox::hoverAnc
estor(); | 2714 return isAnonymousBlockContinuation() ? continuation() : RenderBox::hoverAnc
estor(); |
| 2774 } | 2715 } |
| 2775 | 2716 |
| 2776 void RenderBlock::childBecameNonInline(RenderObject*) | 2717 void RenderBlock::childBecameNonInline(RenderObject*) |
| 2777 { | 2718 { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2813 // For blocks inside inlines, we go ahead and include margins so that we run
right up to the | 2754 // For blocks inside inlines, we go ahead and include margins so that we run
right up to the |
| 2814 // inline boxes above and below us (thus getting merged with them to form a
single irregular | 2755 // inline boxes above and below us (thus getting merged with them to form a
single irregular |
| 2815 // shape). | 2756 // shape). |
| 2816 if (inlineElementContinuation()) { | 2757 if (inlineElementContinuation()) { |
| 2817 // FIXME: This check really isn't accurate. | 2758 // FIXME: This check really isn't accurate. |
| 2818 bool nextInlineHasLineBox = inlineElementContinuation()->firstLineBox(); | 2759 bool nextInlineHasLineBox = inlineElementContinuation()->firstLineBox(); |
| 2819 // FIXME: This is wrong. The principal renderer may not be the continuat
ion preceding this block. | 2760 // FIXME: This is wrong. The principal renderer may not be the continuat
ion preceding this block. |
| 2820 // FIXME: This is wrong for block-flows that are horizontal. | 2761 // FIXME: This is wrong for block-flows that are horizontal. |
| 2821 // https://bugs.webkit.org/show_bug.cgi?id=46781 | 2762 // https://bugs.webkit.org/show_bug.cgi?id=46781 |
| 2822 bool prevInlineHasLineBox = toRenderInline(inlineElementContinuation()->
node()->renderer())->firstLineBox(); | 2763 bool prevInlineHasLineBox = toRenderInline(inlineElementContinuation()->
node()->renderer())->firstLineBox(); |
| 2823 LayoutUnit topMargin = prevInlineHasLineBox ? collapsedMarginBefore() :
LayoutUnit(); | 2764 LayoutUnit topMargin = prevInlineHasLineBox ? marginBefore() : LayoutUni
t(); |
| 2824 LayoutUnit bottomMargin = nextInlineHasLineBox ? collapsedMarginAfter()
: LayoutUnit(); | 2765 LayoutUnit bottomMargin = nextInlineHasLineBox ? marginAfter() : LayoutU
nit(); |
| 2825 LayoutRect rect(additionalOffset.x(), additionalOffset.y() - topMargin,
width(), height() + topMargin + bottomMargin); | 2766 LayoutRect rect(additionalOffset.x(), additionalOffset.y() - topMargin,
width(), height() + topMargin + bottomMargin); |
| 2826 if (!rect.isEmpty()) | 2767 if (!rect.isEmpty()) |
| 2827 rects.append(pixelSnappedIntRect(rect)); | 2768 rects.append(pixelSnappedIntRect(rect)); |
| 2828 } else if (width() && height()) { | 2769 } else if (width() && height()) { |
| 2829 rects.append(pixelSnappedIntRect(additionalOffset, size())); | 2770 rects.append(pixelSnappedIntRect(additionalOffset, size())); |
| 2830 } | 2771 } |
| 2831 | 2772 |
| 2832 if (!hasOverflowClip() && !hasControlClip()) { | 2773 if (!hasOverflowClip() && !hasControlClip()) { |
| 2833 for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBo
x()) { | 2774 for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBo
x()) { |
| 2834 LayoutUnit top = std::max<LayoutUnit>(curr->lineTop(), curr->top()); | 2775 LayoutUnit top = std::max<LayoutUnit>(curr->lineTop(), curr->top()); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 2859 rects.append(rect); | 2800 rects.append(rect); |
| 2860 } | 2801 } |
| 2861 } | 2802 } |
| 2862 } | 2803 } |
| 2863 | 2804 |
| 2864 RenderBox* RenderBlock::createAnonymousBoxWithSameTypeAs(const RenderObject* par
ent) const | 2805 RenderBox* RenderBlock::createAnonymousBoxWithSameTypeAs(const RenderObject* par
ent) const |
| 2865 { | 2806 { |
| 2866 return createAnonymousWithParentRendererAndDisplay(parent, style()->display(
)); | 2807 return createAnonymousWithParentRendererAndDisplay(parent, style()->display(
)); |
| 2867 } | 2808 } |
| 2868 | 2809 |
| 2869 LayoutUnit RenderBlock::collapsedMarginBeforeForChild(const RenderBox* child) co
nst | 2810 LayoutUnit RenderBlock::marginBeforeForChild(const RenderBox* child) const |
| 2870 { | 2811 { |
| 2871 // FIXME(sky): Remove | 2812 // FIXME(sky): Remove |
| 2872 return child->collapsedMarginBefore(); | 2813 return child->marginBefore(); |
| 2873 } | 2814 } |
| 2874 | 2815 |
| 2875 LayoutUnit RenderBlock::collapsedMarginAfterForChild(const RenderBox* child) co
nst | 2816 LayoutUnit RenderBlock::marginAfterForChild(const RenderBox* child) const |
| 2876 { | 2817 { |
| 2877 // FIXME(sky): Remove | 2818 // FIXME(sky): Remove |
| 2878 return child->collapsedMarginAfter(); | 2819 return child->marginAfter(); |
| 2879 } | 2820 } |
| 2880 | 2821 |
| 2881 bool RenderBlock::hasMarginBeforeQuirk(const RenderBox* child) const | 2822 bool RenderBlock::hasMarginBeforeQuirk(const RenderBox* child) const |
| 2882 { | 2823 { |
| 2883 return child->isRenderBlock() ? toRenderBlock(child)->hasMarginBeforeQuirk()
: child->style()->hasMarginBeforeQuirk(); | 2824 return child->isRenderBlock() ? toRenderBlock(child)->hasMarginBeforeQuirk()
: child->style()->hasMarginBeforeQuirk(); |
| 2884 } | 2825 } |
| 2885 | 2826 |
| 2886 bool RenderBlock::hasMarginAfterQuirk(const RenderBox* child) const | 2827 bool RenderBlock::hasMarginAfterQuirk(const RenderBox* child) const |
| 2887 { | 2828 { |
| 2888 return child->isRenderBlock() ? toRenderBlock(child)->hasMarginAfterQuirk()
: child->style()->hasMarginAfterQuirk(); | 2829 return child->isRenderBlock() ? toRenderBlock(child)->hasMarginAfterQuirk()
: child->style()->hasMarginAfterQuirk(); |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3027 void RenderBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* m
arkedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const Render
Object* obj) const | 2968 void RenderBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* m
arkedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const Render
Object* obj) const |
| 3028 { | 2969 { |
| 3029 showRenderObject(); | 2970 showRenderObject(); |
| 3030 for (const RootInlineBox* root = firstRootBox(); root; root = root->nextRoot
Box()) | 2971 for (const RootInlineBox* root = firstRootBox(); root; root = root->nextRoot
Box()) |
| 3031 root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLa
bel2, obj, 1); | 2972 root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLa
bel2, obj, 1); |
| 3032 } | 2973 } |
| 3033 | 2974 |
| 3034 #endif | 2975 #endif |
| 3035 | 2976 |
| 3036 } // namespace blink | 2977 } // namespace blink |
| OLD | NEW |