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) 2000 Dirk Mueller (mueller@kde.org) | 4 * (C) 2000 Dirk Mueller (mueller@kde.org) |
5 * (C) 2004 Allan Sandfeld Jensen (kde@carewolf.com) | 5 * (C) 2004 Allan Sandfeld Jensen (kde@carewolf.com) |
6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2011 Apple Inc. All rights reserv
ed. | 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2011 Apple Inc. All rights reserv
ed. |
7 * Copyright (C) 2009 Google Inc. All rights reserved. | 7 * Copyright (C) 2009 Google Inc. All rights reserved. |
8 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo
bile.com/) | 8 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo
bile.com/) |
9 * | 9 * |
10 * This library is free software; you can redistribute it and/or | 10 * This library is free software; you can redistribute it and/or |
(...skipping 742 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
753 | 753 |
754 while (object) { | 754 while (object) { |
755 if (object->selfNeedsLayout()) | 755 if (object->selfNeedsLayout()) |
756 return; | 756 return; |
757 | 757 |
758 // Don't mark the outermost object of an unrooted subtree. That object w
ill be | 758 // Don't mark the outermost object of an unrooted subtree. That object w
ill be |
759 // marked when the subtree is added to the document. | 759 // marked when the subtree is added to the document. |
760 LayoutObject* container = object->container(); | 760 LayoutObject* container = object->container(); |
761 if (!container && !object->isLayoutView()) | 761 if (!container && !object->isLayoutView()) |
762 return; | 762 return; |
763 if (!last->isTextOrSVGChild() && last->style()->hasOutOfFlowPosition())
{ | 763 if (!last->isSVGChild() && last->style()->hasOutOfFlowPosition()) { |
764 bool willSkipRelativelyPositionedInlines = !object->isLayoutBlock()
|| object->isAnonymousBlock(); | 764 bool willSkipRelativelyPositionedInlines = !object->isLayoutBlock()
|| object->isAnonymousBlock(); |
765 // Skip relatively positioned inlines and anonymous blocks to get to
the enclosing LayoutBlock. | 765 // Skip relatively positioned inlines and anonymous blocks to get to
the enclosing LayoutBlock. |
766 while (object && (!object->isLayoutBlock() || object->isAnonymousBlo
ck())) | 766 while (object && (!object->isLayoutBlock() || object->isAnonymousBlo
ck())) |
767 object = object->container(); | 767 object = object->container(); |
768 if (!object || object->posChildNeedsLayout()) | 768 if (!object || object->posChildNeedsLayout()) |
769 return; | 769 return; |
770 if (willSkipRelativelyPositionedInlines) | 770 if (willSkipRelativelyPositionedInlines) |
771 container = object->container(); | 771 container = object->container(); |
772 object->setPosChildNeedsLayout(true); | 772 object->setPosChildNeedsLayout(true); |
773 simplifiedNormalFlowLayout = true; | 773 simplifiedNormalFlowLayout = true; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
809 ASSERT(!needsLayout()); | 809 ASSERT(!needsLayout()); |
810 | 810 |
811 if (isLayoutBlock()) | 811 if (isLayoutBlock()) |
812 toLayoutBlock(this)->checkPositionedObjectsNeedLayout(); | 812 toLayoutBlock(this)->checkPositionedObjectsNeedLayout(); |
813 } | 813 } |
814 #endif | 814 #endif |
815 | 815 |
816 void LayoutObject::setPreferredLogicalWidthsDirty(MarkingBehavior markParents) | 816 void LayoutObject::setPreferredLogicalWidthsDirty(MarkingBehavior markParents) |
817 { | 817 { |
818 m_bitfields.setPreferredLogicalWidthsDirty(true); | 818 m_bitfields.setPreferredLogicalWidthsDirty(true); |
819 if (markParents == MarkContainerChain && (isText() || !style()->hasOutOfFlow
Position())) | 819 if (markParents == MarkContainerChain && !style()->hasOutOfFlowPosition()) |
820 invalidateContainerPreferredLogicalWidths(); | 820 invalidateContainerPreferredLogicalWidths(); |
821 } | 821 } |
822 | 822 |
823 void LayoutObject::clearPreferredLogicalWidthsDirty() | 823 void LayoutObject::clearPreferredLogicalWidthsDirty() |
824 { | 824 { |
825 m_bitfields.setPreferredLogicalWidthsDirty(false); | 825 m_bitfields.setPreferredLogicalWidthsDirty(false); |
826 } | 826 } |
827 | 827 |
828 inline void LayoutObject::invalidateContainerPreferredLogicalWidths() | 828 inline void LayoutObject::invalidateContainerPreferredLogicalWidths() |
829 { | 829 { |
(...skipping 13 matching lines...) Expand all Loading... |
843 // We can optimize this case and not go up any further. | 843 // We can optimize this case and not go up any further. |
844 break; | 844 break; |
845 } | 845 } |
846 o = container; | 846 o = container; |
847 } | 847 } |
848 } | 848 } |
849 | 849 |
850 LayoutBlock* LayoutObject::containerForFixedPosition(const LayoutBoxModelObject*
paintInvalidationContainer, bool* paintInvalidationContainerSkipped) const | 850 LayoutBlock* LayoutObject::containerForFixedPosition(const LayoutBoxModelObject*
paintInvalidationContainer, bool* paintInvalidationContainerSkipped) const |
851 { | 851 { |
852 ASSERT(!paintInvalidationContainerSkipped || !*paintInvalidationContainerSki
pped); | 852 ASSERT(!paintInvalidationContainerSkipped || !*paintInvalidationContainerSki
pped); |
853 ASSERT(!isText()); | |
854 ASSERT(style()->position() == FixedPosition); | 853 ASSERT(style()->position() == FixedPosition); |
855 | 854 |
856 LayoutObject* ancestor = parent(); | 855 LayoutObject* ancestor = parent(); |
857 for (; ancestor && !ancestor->canContainFixedPositionObjects(); ancestor = a
ncestor->parent()) { | 856 for (; ancestor && !ancestor->canContainFixedPositionObjects(); ancestor = a
ncestor->parent()) { |
858 if (paintInvalidationContainerSkipped && ancestor == paintInvalidationCo
ntainer) | 857 if (paintInvalidationContainerSkipped && ancestor == paintInvalidationCo
ntainer) |
859 *paintInvalidationContainerSkipped = true; | 858 *paintInvalidationContainerSkipped = true; |
860 } | 859 } |
861 | 860 |
862 ASSERT(!ancestor || !ancestor->isAnonymousBlock()); | 861 ASSERT(!ancestor || !ancestor->isAnonymousBlock()); |
863 return toLayoutBlock(ancestor); | 862 return toLayoutBlock(ancestor); |
864 } | 863 } |
865 | 864 |
866 LayoutBlock* LayoutObject::containingBlock() const | 865 LayoutBlock* LayoutObject::containingBlock() const |
867 { | 866 { |
868 LayoutObject* o = parent(); | 867 LayoutObject* o = parent(); |
869 if (!o && isLayoutScrollbarPart()) | 868 if (!o && isLayoutScrollbarPart()) |
870 o = toLayoutScrollbarPart(this)->layoutObjectOwningScrollbar(); | 869 o = toLayoutScrollbarPart(this)->layoutObjectOwningScrollbar(); |
871 if (!isTextOrSVGChild() && m_style->position() == FixedPosition) | 870 if (!isSVGChild() && m_style->position() == FixedPosition) |
872 return containerForFixedPosition(); | 871 return containerForFixedPosition(); |
873 if (!isTextOrSVGChild() && m_style->position() == AbsolutePosition) { | 872 if (!isSVGChild() && m_style->position() == AbsolutePosition) { |
874 while (o) { | 873 while (o) { |
875 // For relpositioned inlines, we return the nearest non-anonymous en
closing block. We don't try | 874 // For relpositioned inlines, we return the nearest non-anonymous en
closing block. We don't try |
876 // to return the inline itself. This allows us to avoid having a po
sitioned objects | 875 // to return the inline itself. This allows us to avoid having a po
sitioned objects |
877 // list in all LayoutInlines and lets us return a strongly-typed Lay
outBlock* result | 876 // list in all LayoutInlines and lets us return a strongly-typed Lay
outBlock* result |
878 // from this method. The container() method can actually be used to
obtain the | 877 // from this method. The container() method can actually be used to
obtain the |
879 // inline directly. | 878 // inline directly. |
880 if (o->style()->position() != StaticPosition && (!o->isInline() || o
->isReplaced())) | 879 if (o->style()->position() != StaticPosition && (!o->isInline() || o
->isReplaced())) |
881 break; | 880 break; |
882 | 881 |
883 if (o->canContainFixedPositionObjects()) | 882 if (o->canContainFixedPositionObjects()) |
(...skipping 689 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1573 bool LayoutObject::isSelectable() const | 1572 bool LayoutObject::isSelectable() const |
1574 { | 1573 { |
1575 return !isInert() && !(style()->userSelect() == SELECT_NONE && style()->user
Modify() == READ_ONLY); | 1574 return !isInert() && !(style()->userSelect() == SELECT_NONE && style()->user
Modify() == READ_ONLY); |
1576 } | 1575 } |
1577 | 1576 |
1578 Color LayoutObject::selectionBackgroundColor() const | 1577 Color LayoutObject::selectionBackgroundColor() const |
1579 { | 1578 { |
1580 if (!isSelectable()) | 1579 if (!isSelectable()) |
1581 return Color::transparent; | 1580 return Color::transparent; |
1582 | 1581 |
| 1582 if ((!node() || node()->isTextNode()) && parent()) |
| 1583 return parent()->selectionBackgroundColor(); |
1583 if (RefPtr<ComputedStyle> pseudoStyle = getUncachedPseudoStyleFromParentOrSh
adowHost()) | 1584 if (RefPtr<ComputedStyle> pseudoStyle = getUncachedPseudoStyleFromParentOrSh
adowHost()) |
1584 return resolveColor(*pseudoStyle, CSSPropertyBackgroundColor).blendWithW
hite(); | 1585 return resolveColor(*pseudoStyle, CSSPropertyBackgroundColor).blendWithW
hite(); |
1585 return frame()->selection().isFocusedAndActive() ? | 1586 return frame()->selection().isFocusedAndActive() ? |
1586 LayoutTheme::theme().activeSelectionBackgroundColor() : | 1587 LayoutTheme::theme().activeSelectionBackgroundColor() : |
1587 LayoutTheme::theme().inactiveSelectionBackgroundColor(); | 1588 LayoutTheme::theme().inactiveSelectionBackgroundColor(); |
1588 } | 1589 } |
1589 | 1590 |
1590 Color LayoutObject::selectionColor(int colorProperty) const | 1591 Color LayoutObject::selectionColor(int colorProperty) const |
1591 { | 1592 { |
1592 // If the element is unselectable, or we are only painting the selection, | 1593 // If the element is unselectable, or we are only painting the selection, |
1593 // don't override the foreground color with the selection foreground color. | 1594 // don't override the foreground color with the selection foreground color. |
1594 if (!isSelectable() || (frame()->view()->paintBehavior() & PaintBehaviorSele
ctionOnly)) | 1595 if (!isSelectable() || (frame()->view()->paintBehavior() & PaintBehaviorSele
ctionOnly)) |
1595 return resolveColor(colorProperty); | 1596 return resolveColor(colorProperty); |
1596 | 1597 |
| 1598 if ((!node() || node()->isTextNode()) && parent()) |
| 1599 return parent()->selectionColor(colorProperty); |
1597 if (RefPtr<ComputedStyle> pseudoStyle = getUncachedPseudoStyleFromParentOrSh
adowHost()) | 1600 if (RefPtr<ComputedStyle> pseudoStyle = getUncachedPseudoStyleFromParentOrSh
adowHost()) |
1598 return resolveColor(*pseudoStyle, colorProperty); | 1601 return resolveColor(*pseudoStyle, colorProperty); |
1599 if (!LayoutTheme::theme().supportsSelectionForegroundColors()) | 1602 if (!LayoutTheme::theme().supportsSelectionForegroundColors()) |
1600 return resolveColor(colorProperty); | 1603 return resolveColor(colorProperty); |
1601 return frame()->selection().isFocusedAndActive() ? | 1604 return frame()->selection().isFocusedAndActive() ? |
1602 LayoutTheme::theme().activeSelectionForegroundColor() : | 1605 LayoutTheme::theme().activeSelectionForegroundColor() : |
1603 LayoutTheme::theme().inactiveSelectionForegroundColor(); | 1606 LayoutTheme::theme().inactiveSelectionForegroundColor(); |
1604 } | 1607 } |
1605 | 1608 |
1606 Color LayoutObject::selectionForegroundColor() const | 1609 Color LayoutObject::selectionForegroundColor() const |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1640 } | 1643 } |
1641 } | 1644 } |
1642 | 1645 |
1643 StyleDifference LayoutObject::adjustStyleDifference(StyleDifference diff) const | 1646 StyleDifference LayoutObject::adjustStyleDifference(StyleDifference diff) const |
1644 { | 1647 { |
1645 if (diff.transformChanged() && isSVG()) | 1648 if (diff.transformChanged() && isSVG()) |
1646 diff.setNeedsFullLayout(); | 1649 diff.setNeedsFullLayout(); |
1647 | 1650 |
1648 // If transform changed, and the layer does not paint into its own separate
backing, then we need to invalidate paints. | 1651 // If transform changed, and the layer does not paint into its own separate
backing, then we need to invalidate paints. |
1649 if (diff.transformChanged()) { | 1652 if (diff.transformChanged()) { |
1650 // Text nodes share style with their parents but transforms don't apply
to them, | 1653 if (!hasLayer() || !toLayoutBoxModelObject(this)->layer()->hasStyleDeter
minedDirectCompositingReasons()) |
1651 // hence the !isText() check. | |
1652 if (!isText() && (!hasLayer() || !toLayoutBoxModelObject(this)->layer()-
>hasStyleDeterminedDirectCompositingReasons())) | |
1653 diff.setNeedsPaintInvalidationLayer(); | 1654 diff.setNeedsPaintInvalidationLayer(); |
1654 } | 1655 } |
1655 | 1656 |
1656 // If opacity or zIndex changed, and the layer does not paint into its own s
eparate backing, then we need to invalidate paints (also | 1657 // If opacity or zIndex changed, and the layer does not paint into its own s
eparate backing, then we need to invalidate paints (also |
1657 // ignoring text nodes) | 1658 // ignoring text nodes) |
1658 if (diff.opacityChanged() || diff.zIndexChanged()) { | 1659 if (diff.opacityChanged() || diff.zIndexChanged()) { |
1659 if (!isText() && (!hasLayer() || !toLayoutBoxModelObject(this)->layer()-
>hasStyleDeterminedDirectCompositingReasons())) | 1660 if (!hasLayer() || !toLayoutBoxModelObject(this)->layer()->hasStyleDeter
minedDirectCompositingReasons()) |
1660 diff.setNeedsPaintInvalidationLayer(); | 1661 diff.setNeedsPaintInvalidationLayer(); |
1661 } | 1662 } |
1662 | 1663 |
1663 // If filter changed, and the layer does not paint into its own separate bac
king or it paints with filters, then we need to invalidate paints. | 1664 // If filter changed, and the layer does not paint into its own separate bac
king or it paints with filters, then we need to invalidate paints. |
1664 if (diff.filterChanged() && hasLayer()) { | 1665 if (diff.filterChanged() && hasLayer()) { |
1665 DeprecatedPaintLayer* layer = toLayoutBoxModelObject(this)->layer(); | 1666 DeprecatedPaintLayer* layer = toLayoutBoxModelObject(this)->layer(); |
1666 if (!layer->hasStyleDeterminedDirectCompositingReasons() || layer->paint
sWithFilters()) | 1667 if (!layer->hasStyleDeterminedDirectCompositingReasons() || layer->paint
sWithFilters()) |
1667 diff.setNeedsPaintInvalidationLayer(); | 1668 diff.setNeedsPaintInvalidationLayer(); |
1668 } | 1669 } |
1669 | 1670 |
(...skipping 17 matching lines...) Expand all Loading... |
1687 diff.clearNeedsPaintInvalidation(); | 1688 diff.clearNeedsPaintInvalidation(); |
1688 diff.setNeedsPaintInvalidationObject(); | 1689 diff.setNeedsPaintInvalidationObject(); |
1689 } | 1690 } |
1690 | 1691 |
1691 return diff; | 1692 return diff; |
1692 } | 1693 } |
1693 | 1694 |
1694 void LayoutObject::setPseudoStyle(PassRefPtr<ComputedStyle> pseudoStyle) | 1695 void LayoutObject::setPseudoStyle(PassRefPtr<ComputedStyle> pseudoStyle) |
1695 { | 1696 { |
1696 ASSERT(pseudoStyle->styleType() == BEFORE || pseudoStyle->styleType() == AFT
ER || pseudoStyle->styleType() == FIRST_LETTER); | 1697 ASSERT(pseudoStyle->styleType() == BEFORE || pseudoStyle->styleType() == AFT
ER || pseudoStyle->styleType() == FIRST_LETTER); |
1697 | 1698 RefPtr<ComputedStyle> style = ComputedStyle::createWithInheritableProperties
(*pseudoStyle); |
1698 // FIXME: We should consider just making all pseudo items use an inherited s
tyle. | 1699 setStyle(style.release()); |
1699 | |
1700 // Images are special and must inherit the pseudoStyle so the width and heig
ht of | |
1701 // the pseudo element doesn't change the size of the image. In all other cas
es we | |
1702 // can just share the style. | |
1703 // | |
1704 // Quotes are also LayoutInline, so we need to create an inherited style to
avoid | |
1705 // getting an inline with positioning or an invalid display. | |
1706 // | |
1707 if (isImage() || isQuote()) { | |
1708 RefPtr<ComputedStyle> style = ComputedStyle::create(); | |
1709 style->inheritFrom(*pseudoStyle); | |
1710 setStyle(style.release()); | |
1711 return; | |
1712 } | |
1713 | |
1714 setStyle(pseudoStyle); | |
1715 } | 1700 } |
1716 | 1701 |
1717 void LayoutObject::markContainingBlocksForOverflowRecalc() | 1702 void LayoutObject::markContainingBlocksForOverflowRecalc() |
1718 { | 1703 { |
1719 for (LayoutBlock* container = containingBlock(); container && !container->ch
ildNeedsOverflowRecalcAfterStyleChange(); container = container->containingBlock
()) | 1704 for (LayoutBlock* container = containingBlock(); container && !container->ch
ildNeedsOverflowRecalcAfterStyleChange(); container = container->containingBlock
()) |
1720 container->setChildNeedsOverflowRecalcAfterStyleChange(true); | 1705 container->setChildNeedsOverflowRecalcAfterStyleChange(true); |
1721 } | 1706 } |
1722 | 1707 |
1723 void LayoutObject::setNeedsOverflowRecalcAfterStyleChange() | 1708 void LayoutObject::setNeedsOverflowRecalcAfterStyleChange() |
1724 { | 1709 { |
(...skipping 613 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2338 // exceptions. | 2323 // exceptions. |
2339 // (1) It can be used on orphaned subtrees, i.e., it can be called safely ev
en when | 2324 // (1) It can be used on orphaned subtrees, i.e., it can be called safely ev
en when |
2340 // the object is not part of the primary document subtree yet. | 2325 // the object is not part of the primary document subtree yet. |
2341 // (2) For normal flow elements, it just returns the parent. | 2326 // (2) For normal flow elements, it just returns the parent. |
2342 // (3) For absolute positioned elements, it will return a relative positione
d inline. | 2327 // (3) For absolute positioned elements, it will return a relative positione
d inline. |
2343 // containingBlock() simply skips relpositioned inlines and lets an enclosin
g block handle | 2328 // containingBlock() simply skips relpositioned inlines and lets an enclosin
g block handle |
2344 // the layout of the positioned object. This does mean that computePosition
edLogicalWidth and | 2329 // the layout of the positioned object. This does mean that computePosition
edLogicalWidth and |
2345 // computePositionedLogicalHeight have to use container(). | 2330 // computePositionedLogicalHeight have to use container(). |
2346 LayoutObject* o = parent(); | 2331 LayoutObject* o = parent(); |
2347 | 2332 |
2348 if (isTextOrSVGChild()) | 2333 if (isSVGChild()) |
2349 return o; | 2334 return o; |
2350 | 2335 |
2351 EPosition pos = m_style->position(); | 2336 EPosition pos = m_style->position(); |
2352 if (pos == FixedPosition) | 2337 if (pos == FixedPosition) |
2353 return containerForFixedPosition(paintInvalidationContainer, paintInvali
dationContainerSkipped); | 2338 return containerForFixedPosition(paintInvalidationContainer, paintInvali
dationContainerSkipped); |
2354 | 2339 |
2355 if (pos == AbsolutePosition) { | 2340 if (pos == AbsolutePosition) { |
2356 // We technically just want our containing block, but | 2341 // We technically just want our containing block, but |
2357 // we may not have one if we're part of an uninstalled | 2342 // we may not have one if we're part of an uninstalled |
2358 // subtree. We'll climb as high as we can though. | 2343 // subtree. We'll climb as high as we can though. |
(...skipping 939 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3298 const blink::LayoutObject* root = object1; | 3283 const blink::LayoutObject* root = object1; |
3299 while (root->parent()) | 3284 while (root->parent()) |
3300 root = root->parent(); | 3285 root = root->parent(); |
3301 root->showLayoutTreeAndMark(object1, "*", object2, "-", 0); | 3286 root->showLayoutTreeAndMark(object1, "*", object2, "-", 0); |
3302 } else { | 3287 } else { |
3303 fprintf(stderr, "Cannot showLayoutTree. Root is (nil)\n"); | 3288 fprintf(stderr, "Cannot showLayoutTree. Root is (nil)\n"); |
3304 } | 3289 } |
3305 } | 3290 } |
3306 | 3291 |
3307 #endif | 3292 #endif |
OLD | NEW |