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 783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
794 if (beforeChildContainer->isAnonymous()) { | 794 if (beforeChildContainer->isAnonymous()) { |
795 // If the requested beforeChild is not one of our children, then thi
s is because | 795 // If the requested beforeChild is not one of our children, then thi
s is because |
796 // there is an anonymous container within this object that contains
the beforeChild. | 796 // there is an anonymous container within this object that contains
the beforeChild. |
797 RenderObject* beforeChildAnonymousContainer = beforeChildContainer; | 797 RenderObject* beforeChildAnonymousContainer = beforeChildContainer; |
798 if (beforeChildAnonymousContainer->isAnonymousBlock() | 798 if (beforeChildAnonymousContainer->isAnonymousBlock() |
799 // Full screen renderers and full screen placeholders act as ano
nymous blocks, not tables: | 799 // Full screen renderers and full screen placeholders act as ano
nymous blocks, not tables: |
800 || beforeChildAnonymousContainer->isRenderFullScreen() | 800 || beforeChildAnonymousContainer->isRenderFullScreen() |
801 || beforeChildAnonymousContainer->isRenderFullScreenPlaceholder(
) | 801 || beforeChildAnonymousContainer->isRenderFullScreenPlaceholder(
) |
802 ) { | 802 ) { |
803 // Insert the child into the anonymous block box instead of here
. | 803 // Insert the child into the anonymous block box instead of here
. |
804 if (newChild->isInline() || newChild->isFloatingOrOutOfFlowPosit
ioned() || beforeChild->parent()->firstChild() != beforeChild) | 804 if (newChild->isInline() || newChild->isFloatingOrOutOfFlowPosit
ioned() || beforeChild->parent()->slowFirstChild() != beforeChild) |
805 beforeChild->parent()->addChild(newChild, beforeChild); | 805 beforeChild->parent()->addChild(newChild, beforeChild); |
806 else | 806 else |
807 addChild(newChild, beforeChild->parent()); | 807 addChild(newChild, beforeChild->parent()); |
808 return; | 808 return; |
809 } | 809 } |
810 | 810 |
811 ASSERT(beforeChildAnonymousContainer->isTable()); | 811 ASSERT(beforeChildAnonymousContainer->isTable()); |
812 if (newChild->isTablePart()) { | 812 if (newChild->isTablePart()) { |
813 // Insert into the anonymous table. | 813 // Insert into the anonymous table. |
814 beforeChildAnonymousContainer->addChild(newChild, beforeChild); | 814 beforeChildAnonymousContainer->addChild(newChild, beforeChild); |
(...skipping 1859 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2674 | 2674 |
2675 if (!hasPercentHeightDescendant(descendant)) | 2675 if (!hasPercentHeightDescendant(descendant)) |
2676 return; | 2676 return; |
2677 | 2677 |
2678 removePercentHeightDescendant(descendant); | 2678 removePercentHeightDescendant(descendant); |
2679 } | 2679 } |
2680 | 2680 |
2681 void RenderBlock::clearPercentHeightDescendantsFrom(RenderBox* parent) | 2681 void RenderBlock::clearPercentHeightDescendantsFrom(RenderBox* parent) |
2682 { | 2682 { |
2683 ASSERT(gPercentHeightContainerMap); | 2683 ASSERT(gPercentHeightContainerMap); |
2684 for (RenderObject* curr = parent->firstChild(); curr; curr = curr->nextInPre
Order(parent)) { | 2684 for (RenderObject* curr = parent->slowFirstChild(); curr; curr = curr->nextI
nPreOrder(parent)) { |
2685 if (!curr->isBox()) | 2685 if (!curr->isBox()) |
2686 continue; | 2686 continue; |
2687 | 2687 |
2688 RenderBox* box = toRenderBox(curr); | 2688 RenderBox* box = toRenderBox(curr); |
2689 if (!hasPercentHeightDescendant(box)) | 2689 if (!hasPercentHeightDescendant(box)) |
2690 continue; | 2690 continue; |
2691 | 2691 |
2692 removePercentHeightDescendant(box); | 2692 removePercentHeightDescendant(box); |
2693 } | 2693 } |
2694 } | 2694 } |
(...skipping 1179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3874 if (hasPseudo) | 3874 if (hasPseudo) |
3875 break; | 3875 break; |
3876 RenderObject* parentBlock = firstLineBlock->parent(); | 3876 RenderObject* parentBlock = firstLineBlock->parent(); |
3877 // We include isRenderButton in this check because buttons are | 3877 // We include isRenderButton in this check because buttons are |
3878 // implemented using flex box but should still support first-line. The | 3878 // implemented using flex box but should still support first-line. The |
3879 // flex box spec requires that flex box does not support first-line, | 3879 // flex box spec requires that flex box does not support first-line, |
3880 // though. | 3880 // though. |
3881 // FIXME: Remove when buttons are implemented with align-items instead | 3881 // FIXME: Remove when buttons are implemented with align-items instead |
3882 // of flexbox. | 3882 // of flexbox. |
3883 if (firstLineBlock->isReplaced() || firstLineBlock->isFloating() | 3883 if (firstLineBlock->isReplaced() || firstLineBlock->isFloating() |
3884 || !parentBlock || parentBlock->firstChild() != firstLineBlock | 3884 || !parentBlock |
3885 || (!parentBlock->isRenderBlockFlow() && !parentBlock->isRenderButto
n())) | 3885 || (!parentBlock->isRenderBlockFlow() && !parentBlock->isRenderButto
n())) |
3886 break; | 3886 break; |
3887 ASSERT_WITH_SECURITY_IMPLICATION(parentBlock->isRenderBlock()); | 3887 ASSERT_WITH_SECURITY_IMPLICATION(parentBlock->isRenderBlock()); |
| 3888 if (toRenderBlock(parentBlock)->firstChild() != firstLineBlock) |
| 3889 break; |
3888 firstLineBlock = toRenderBlock(parentBlock); | 3890 firstLineBlock = toRenderBlock(parentBlock); |
3889 } | 3891 } |
3890 | 3892 |
3891 if (!hasPseudo) | 3893 if (!hasPseudo) |
3892 return 0; | 3894 return 0; |
3893 | 3895 |
3894 return firstLineBlock; | 3896 return firstLineBlock; |
3895 } | 3897 } |
3896 | 3898 |
3897 static RenderStyle* styleForFirstLetter(RenderObject* firstLetterBlock, RenderOb
ject* firstLetterContainer) | 3899 static RenderStyle* styleForFirstLetter(RenderObject* firstLetterBlock, RenderOb
ject* firstLetterContainer) |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3932 // first-letter, though. | 3934 // first-letter, though. |
3933 // FIXME: Remove when buttons are implemented with align-items instead | 3935 // FIXME: Remove when buttons are implemented with align-items instead |
3934 // of flexbox. | 3936 // of flexbox. |
3935 bool canHaveFirstLetterRenderer = firstLetterBlock->style()->hasPseudoSt
yle(FIRST_LETTER) | 3937 bool canHaveFirstLetterRenderer = firstLetterBlock->style()->hasPseudoSt
yle(FIRST_LETTER) |
3936 && firstLetterBlock->canHaveGeneratedChildren() | 3938 && firstLetterBlock->canHaveGeneratedChildren() |
3937 && (!firstLetterBlock->isFlexibleBox() || firstLetterBlock->isRender
Button()); | 3939 && (!firstLetterBlock->isFlexibleBox() || firstLetterBlock->isRender
Button()); |
3938 if (canHaveFirstLetterRenderer) | 3940 if (canHaveFirstLetterRenderer) |
3939 return firstLetterBlock; | 3941 return firstLetterBlock; |
3940 | 3942 |
3941 RenderObject* parentBlock = firstLetterBlock->parent(); | 3943 RenderObject* parentBlock = firstLetterBlock->parent(); |
3942 if (firstLetterBlock->isReplaced() || !parentBlock || parentBlock->first
Child() != firstLetterBlock || | 3944 if (firstLetterBlock->isReplaced() || !parentBlock |
3943 (!parentBlock->isRenderBlockFlow() && !parentBlock->isRenderButton()
)) | 3945 || (!parentBlock->isRenderBlockFlow() && !parentBlock->isRenderButto
n())) { |
| 3946 return 0; |
| 3947 } |
| 3948 ASSERT(parentBlock->isRenderBlock()); |
| 3949 if (toRenderBlock(parentBlock)->firstChild() != firstLetterBlock) |
3944 return 0; | 3950 return 0; |
3945 firstLetterBlock = parentBlock; | 3951 firstLetterBlock = parentBlock; |
3946 } | 3952 } |
3947 | 3953 |
3948 return 0; | 3954 return 0; |
3949 } | 3955 } |
3950 | 3956 |
3951 void RenderBlock::updateFirstLetterStyle(RenderObject* firstLetterBlock, RenderO
bject* currentChild) | 3957 void RenderBlock::updateFirstLetterStyle(RenderObject* firstLetterBlock, RenderO
bject* currentChild) |
3952 { | 3958 { |
3953 RenderObject* firstLetter = currentChild->parent(); | 3959 RenderObject* firstLetter = currentChild->parent(); |
3954 RenderObject* firstLetterContainer = firstLetter->parent(); | 3960 RenderObject* firstLetterContainer = firstLetter->parent(); |
3955 RenderStyle* pseudoStyle = styleForFirstLetter(firstLetterBlock, firstLetter
Container); | 3961 RenderStyle* pseudoStyle = styleForFirstLetter(firstLetterBlock, firstLetter
Container); |
3956 ASSERT(firstLetter->isFloating() || firstLetter->isInline()); | 3962 ASSERT(firstLetter->isFloating() || firstLetter->isInline()); |
3957 | 3963 |
3958 if (RenderStyle::stylePropagationDiff(firstLetter->style(), pseudoStyle) ==
Reattach) { | 3964 if (RenderStyle::stylePropagationDiff(firstLetter->style(), pseudoStyle) ==
Reattach) { |
3959 // The first-letter renderer needs to be replaced. Create a new renderer
of the right type. | 3965 // The first-letter renderer needs to be replaced. Create a new renderer
of the right type. |
3960 RenderBoxModelObject* newFirstLetter; | 3966 RenderBoxModelObject* newFirstLetter; |
3961 if (pseudoStyle->display() == INLINE) | 3967 if (pseudoStyle->display() == INLINE) |
3962 newFirstLetter = RenderInline::createAnonymous(&document()); | 3968 newFirstLetter = RenderInline::createAnonymous(&document()); |
3963 else | 3969 else |
3964 newFirstLetter = RenderBlockFlow::createAnonymous(&document()); | 3970 newFirstLetter = RenderBlockFlow::createAnonymous(&document()); |
3965 newFirstLetter->setStyle(pseudoStyle); | 3971 newFirstLetter->setStyle(pseudoStyle); |
3966 | 3972 |
3967 // Move the first letter into the new renderer. | 3973 // Move the first letter into the new renderer. |
3968 LayoutStateDisabler layoutStateDisabler(*this); | 3974 LayoutStateDisabler layoutStateDisabler(*this); |
3969 while (RenderObject* child = firstLetter->firstChild()) { | 3975 while (RenderObject* child = firstLetter->slowFirstChild()) { |
3970 if (child->isText()) | 3976 if (child->isText()) |
3971 toRenderText(child)->removeAndDestroyTextBoxes(); | 3977 toRenderText(child)->removeAndDestroyTextBoxes(); |
3972 firstLetter->removeChild(child); | 3978 firstLetter->removeChild(child); |
3973 newFirstLetter->addChild(child, 0); | 3979 newFirstLetter->addChild(child, 0); |
3974 } | 3980 } |
3975 | 3981 |
3976 RenderObject* nextSibling = firstLetter->nextSibling(); | 3982 RenderObject* nextSibling = firstLetter->nextSibling(); |
3977 if (RenderTextFragment* remainingText = toRenderBoxModelObject(firstLett
er)->firstLetterRemainingText()) { | 3983 if (RenderTextFragment* remainingText = toRenderBoxModelObject(firstLett
er)->firstLetterRemainingText()) { |
3978 ASSERT(remainingText->isAnonymous() || remainingText->node()->render
er() == remainingText); | 3984 ASSERT(remainingText->isAnonymous() || remainingText->node()->render
er() == remainingText); |
3979 // Replace the old renderer with the new one. | 3985 // Replace the old renderer with the new one. |
3980 remainingText->setFirstLetter(newFirstLetter); | 3986 remainingText->setFirstLetter(newFirstLetter); |
3981 newFirstLetter->setFirstLetterRemainingText(remainingText); | 3987 newFirstLetter->setFirstLetterRemainingText(remainingText); |
3982 } | 3988 } |
3983 // To prevent removal of single anonymous block in RenderBlock::removeCh
ild and causing | 3989 // To prevent removal of single anonymous block in RenderBlock::removeCh
ild and causing |
3984 // |nextSibling| to go stale, we remove the old first letter using remov
eChildNode first. | 3990 // |nextSibling| to go stale, we remove the old first letter using remov
eChildNode first. |
3985 firstLetterContainer->virtualChildren()->removeChildNode(firstLetterCont
ainer, firstLetter); | 3991 firstLetterContainer->virtualChildren()->removeChildNode(firstLetterCont
ainer, firstLetter); |
3986 firstLetter->destroy(); | 3992 firstLetter->destroy(); |
3987 firstLetter = newFirstLetter; | 3993 firstLetter = newFirstLetter; |
3988 firstLetterContainer->addChild(firstLetter, nextSibling); | 3994 firstLetterContainer->addChild(firstLetter, nextSibling); |
3989 } else | 3995 } else |
3990 firstLetter->setStyle(pseudoStyle); | 3996 firstLetter->setStyle(pseudoStyle); |
3991 | 3997 |
3992 for (RenderObject* genChild = firstLetter->firstChild(); genChild; genChild
= genChild->nextSibling()) { | 3998 for (RenderObject* genChild = firstLetter->slowFirstChild(); genChild; genCh
ild = genChild->nextSibling()) { |
3993 if (genChild->isText()) | 3999 if (genChild->isText()) |
3994 genChild->setStyle(pseudoStyle); | 4000 genChild->setStyle(pseudoStyle); |
3995 } | 4001 } |
3996 } | 4002 } |
3997 | 4003 |
3998 static inline unsigned firstLetterLength(const String& text) | 4004 static inline unsigned firstLetterLength(const String& text) |
3999 { | 4005 { |
4000 unsigned length = 0; | 4006 unsigned length = 0; |
4001 unsigned textLength = text.length(); | 4007 unsigned textLength = text.length(); |
4002 | 4008 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4085 if (style()->styleType() == FIRST_LETTER) | 4091 if (style()->styleType() == FIRST_LETTER) |
4086 return; | 4092 return; |
4087 | 4093 |
4088 // FIXME: We need to destroy the first-letter object if it is no longer the
first child. Need to find | 4094 // FIXME: We need to destroy the first-letter object if it is no longer the
first child. Need to find |
4089 // an efficient way to check for that situation though before implementing a
nything. | 4095 // an efficient way to check for that situation though before implementing a
nything. |
4090 RenderObject* firstLetterBlock = findFirstLetterBlock(this); | 4096 RenderObject* firstLetterBlock = findFirstLetterBlock(this); |
4091 if (!firstLetterBlock) | 4097 if (!firstLetterBlock) |
4092 return; | 4098 return; |
4093 | 4099 |
4094 // Drill into inlines looking for our first text child. | 4100 // Drill into inlines looking for our first text child. |
4095 RenderObject* currChild = firstLetterBlock->firstChild(); | 4101 RenderObject* currChild = firstLetterBlock->slowFirstChild(); |
4096 unsigned length = 0; | 4102 unsigned length = 0; |
4097 while (currChild) { | 4103 while (currChild) { |
4098 if (currChild->isText()) { | 4104 if (currChild->isText()) { |
4099 // FIXME: If there is leading punctuation in a different RenderText
than | 4105 // FIXME: If there is leading punctuation in a different RenderText
than |
4100 // the first letter, we'll not apply the correct style to it. | 4106 // the first letter, we'll not apply the correct style to it. |
4101 length = firstLetterLength(toRenderText(currChild)->originalText()); | 4107 length = firstLetterLength(toRenderText(currChild)->originalText()); |
4102 if (length) | 4108 if (length) |
4103 break; | 4109 break; |
4104 currChild = currChild->nextSibling(); | 4110 currChild = currChild->nextSibling(); |
4105 } else if (currChild->isListMarker()) { | 4111 } else if (currChild->isListMarker()) { |
4106 currChild = currChild->nextSibling(); | 4112 currChild = currChild->nextSibling(); |
4107 } else if (currChild->isFloatingOrOutOfFlowPositioned()) { | 4113 } else if (currChild->isFloatingOrOutOfFlowPositioned()) { |
4108 if (currChild->style()->styleType() == FIRST_LETTER) { | 4114 if (currChild->style()->styleType() == FIRST_LETTER) { |
4109 currChild = currChild->firstChild(); | 4115 currChild = currChild->slowFirstChild(); |
4110 break; | 4116 break; |
4111 } | 4117 } |
4112 currChild = currChild->nextSibling(); | 4118 currChild = currChild->nextSibling(); |
4113 } else if (currChild->isReplaced() || currChild->isRenderButton() || cur
rChild->isMenuList()) | 4119 } else if (currChild->isReplaced() || currChild->isRenderButton() || cur
rChild->isMenuList()) { |
4114 break; | 4120 break; |
4115 else if (currChild->style()->hasPseudoStyle(FIRST_LETTER) && currChild->
canHaveGeneratedChildren()) { | 4121 } else if (currChild->style()->hasPseudoStyle(FIRST_LETTER) && currChild
->canHaveGeneratedChildren()) { |
4116 // We found a lower-level node with first-letter, which supersedes t
he higher-level style | 4122 // We found a lower-level node with first-letter, which supersedes t
he higher-level style |
4117 firstLetterBlock = currChild; | 4123 firstLetterBlock = currChild; |
4118 currChild = currChild->firstChild(); | 4124 currChild = currChild->slowFirstChild(); |
4119 } else | 4125 } else { |
4120 currChild = currChild->firstChild(); | 4126 currChild = currChild->slowFirstChild(); |
| 4127 } |
4121 } | 4128 } |
4122 | 4129 |
4123 if (!currChild) | 4130 if (!currChild) |
4124 return; | 4131 return; |
4125 | 4132 |
4126 // If the child already has style, then it has already been created, so we j
ust want | 4133 // If the child already has style, then it has already been created, so we j
ust want |
4127 // to update it. | 4134 // to update it. |
4128 if (currChild->parent()->style()->styleType() == FIRST_LETTER) { | 4135 if (currChild->parent()->style()->styleType() == FIRST_LETTER) { |
4129 updateFirstLetterStyle(firstLetterBlock, currChild); | 4136 updateFirstLetterStyle(firstLetterBlock, currChild); |
4130 return; | 4137 return; |
(...skipping 854 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4985 void RenderBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* m
arkedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const Render
Object* obj) const | 4992 void RenderBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* m
arkedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const Render
Object* obj) const |
4986 { | 4993 { |
4987 showRenderObject(); | 4994 showRenderObject(); |
4988 for (const RootInlineBox* root = firstRootBox(); root; root = root->nextRoot
Box()) | 4995 for (const RootInlineBox* root = firstRootBox(); root; root = root->nextRoot
Box()) |
4989 root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLa
bel2, obj, 1); | 4996 root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLa
bel2, obj, 1); |
4990 } | 4997 } |
4991 | 4998 |
4992 #endif | 4999 #endif |
4993 | 5000 |
4994 } // namespace WebCore | 5001 } // namespace WebCore |
OLD | NEW |