| 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 |