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 |