Chromium Code Reviews| 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 * Copyright (C) 2014 Samsung Electronics. All rights reserved. | |
| 7 * | 8 * |
| 8 * This library is free software; you can redistribute it and/or | 9 * This library is free software; you can redistribute it and/or |
| 9 * modify it under the terms of the GNU Library General Public | 10 * modify it under the terms of the GNU Library General Public |
| 10 * License as published by the Free Software Foundation; either | 11 * License as published by the Free Software Foundation; either |
| 11 * version 2 of the License, or (at your option) any later version. | 12 * version 2 of the License, or (at your option) any later version. |
| 12 * | 13 * |
| 13 * This library is distributed in the hope that it will be useful, | 14 * This library is distributed in the hope that it will be useful, |
| 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 16 * Library General Public License for more details. | 17 * Library General Public License for more details. |
| (...skipping 3842 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3859 static RenderStyle* styleForFirstLetter(RenderObject* firstLetterBlock, RenderOb ject* firstLetterContainer) | 3860 static RenderStyle* styleForFirstLetter(RenderObject* firstLetterBlock, RenderOb ject* firstLetterContainer) |
| 3860 { | 3861 { |
| 3861 RenderStyle* pseudoStyle = firstLetterBlock->getCachedPseudoStyle(FIRST_LETT ER, firstLetterContainer->firstLineStyle()); | 3862 RenderStyle* pseudoStyle = firstLetterBlock->getCachedPseudoStyle(FIRST_LETT ER, firstLetterContainer->firstLineStyle()); |
| 3862 // Force inline display (except for floating first-letters). | 3863 // Force inline display (except for floating first-letters). |
| 3863 pseudoStyle->setDisplay(pseudoStyle->isFloating() ? BLOCK : INLINE); | 3864 pseudoStyle->setDisplay(pseudoStyle->isFloating() ? BLOCK : INLINE); |
| 3864 // CSS2 says first-letter can't be positioned. | 3865 // CSS2 says first-letter can't be positioned. |
| 3865 pseudoStyle->setPosition(StaticPosition); | 3866 pseudoStyle->setPosition(StaticPosition); |
| 3866 return pseudoStyle; | 3867 return pseudoStyle; |
| 3867 } | 3868 } |
| 3868 | 3869 |
| 3869 // CSS 2.1 http://www.w3.org/TR/CSS21/selector.html#first-letter | |
| 3870 // "Punctuation (i.e, characters defined in Unicode [UNICODE] in the "open" (Ps) , "close" (Pe), | |
| 3871 // "initial" (Pi). "final" (Pf) and "other" (Po) punctuation classes), that prec edes or follows the first letter should be included" | |
| 3872 static inline bool isPunctuationForFirstLetter(UChar c) | |
| 3873 { | |
| 3874 CharCategory charCategory = category(c); | |
| 3875 return charCategory == Punctuation_Open | |
| 3876 || charCategory == Punctuation_Close | |
| 3877 || charCategory == Punctuation_InitialQuote | |
| 3878 || charCategory == Punctuation_FinalQuote | |
| 3879 || charCategory == Punctuation_Other; | |
| 3880 } | |
| 3881 | |
| 3882 static inline bool isSpaceForFirstLetter(UChar c) | |
| 3883 { | |
| 3884 return isSpaceOrNewline(c) || c == noBreakSpace; | |
| 3885 } | |
| 3886 | |
| 3887 static inline RenderObject* findFirstLetterBlock(RenderBlock* start) | 3870 static inline RenderObject* findFirstLetterBlock(RenderBlock* start) |
| 3888 { | 3871 { |
| 3889 RenderObject* firstLetterBlock = start; | 3872 RenderObject* firstLetterBlock = start; |
| 3890 while (true) { | 3873 while (true) { |
| 3891 // We include isRenderButton in these two checks because buttons are | 3874 // We include isRenderButton in these two checks because buttons are |
| 3892 // implemented using flex box but should still support first-letter. | 3875 // implemented using flex box but should still support first-letter. |
| 3893 // The flex box spec requires that flex box does not support | 3876 // The flex box spec requires that flex box does not support |
| 3894 // first-letter, though. | 3877 // first-letter, though. |
| 3895 // FIXME: Remove when buttons are implemented with align-items instead | 3878 // FIXME: Remove when buttons are implemented with align-items instead |
| 3896 // of flexbox. | 3879 // of flexbox. |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3950 firstLetterContainer->addChild(firstLetter, nextSibling); | 3933 firstLetterContainer->addChild(firstLetter, nextSibling); |
| 3951 } else | 3934 } else |
| 3952 firstLetter->setStyle(pseudoStyle); | 3935 firstLetter->setStyle(pseudoStyle); |
| 3953 | 3936 |
| 3954 for (RenderObject* genChild = firstLetter->firstChild(); genChild; genChild = genChild->nextSibling()) { | 3937 for (RenderObject* genChild = firstLetter->firstChild(); genChild; genChild = genChild->nextSibling()) { |
| 3955 if (genChild->isText()) | 3938 if (genChild->isText()) |
| 3956 genChild->setStyle(pseudoStyle); | 3939 genChild->setStyle(pseudoStyle); |
| 3957 } | 3940 } |
| 3958 } | 3941 } |
| 3959 | 3942 |
| 3960 static inline unsigned firstLetterLength(const String& text) | |
| 3961 { | |
| 3962 unsigned length = 0; | |
| 3963 unsigned textLength = text.length(); | |
| 3964 | |
| 3965 // Account for leading spaces first. | |
| 3966 while (length < textLength && isSpaceForFirstLetter(text[length])) | |
| 3967 length++; | |
| 3968 | |
| 3969 // Now account for leading punctuation. | |
| 3970 while (length < textLength && isPunctuationForFirstLetter(text[length])) | |
| 3971 length++; | |
| 3972 | |
| 3973 // Bail if we didn't find a letter before the end of the text or before a sp ace. | |
| 3974 if (isSpaceForFirstLetter(text[length]) || (textLength && length == textLeng th)) | |
| 3975 return 0; | |
| 3976 | |
| 3977 // Account the next character for first letter. | |
| 3978 length++; | |
| 3979 | |
| 3980 // Keep looking allowed punctuation for the :first-letter. | |
| 3981 for (unsigned scanLength = length; scanLength < textLength; ++scanLength) { | |
| 3982 UChar c = text[scanLength]; | |
| 3983 | |
| 3984 if (!isPunctuationForFirstLetter(c)) | |
| 3985 break; | |
| 3986 | |
| 3987 length = scanLength + 1; | |
| 3988 } | |
| 3989 | |
| 3990 // FIXME: If textLength is 0, length may still be 1! | |
| 3991 return length; | |
| 3992 } | |
| 3993 | |
| 3994 void RenderBlock::createFirstLetterRenderer(RenderObject* firstLetterBlock, Rend erObject* currentChild, unsigned length) | 3943 void RenderBlock::createFirstLetterRenderer(RenderObject* firstLetterBlock, Rend erObject* currentChild, unsigned length) |
| 3995 { | 3944 { |
| 3996 ASSERT(length && currentChild->isText()); | 3945 ASSERT(length && currentChild->isText()); |
| 3997 | 3946 |
| 3998 RenderObject* firstLetterContainer = currentChild->parent(); | 3947 RenderObject* firstLetterContainer = currentChild->parent(); |
| 3999 RenderStyle* pseudoStyle = styleForFirstLetter(firstLetterBlock, firstLetter Container); | 3948 RenderStyle* pseudoStyle = styleForFirstLetter(firstLetterBlock, firstLetter Container); |
| 4000 RenderObject* firstLetter = 0; | 3949 RenderObject* firstLetter = 0; |
| 4001 if (pseudoStyle->display() == INLINE) | 3950 if (pseudoStyle->display() == INLINE) |
| 4002 firstLetter = RenderInline::createAnonymous(&document()); | 3951 firstLetter = RenderInline::createAnonymous(&document()); |
| 4003 else | 3952 else |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 4028 | 3977 |
| 4029 // construct text fragment for the first letter | 3978 // construct text fragment for the first letter |
| 4030 RenderTextFragment* letter = | 3979 RenderTextFragment* letter = |
| 4031 new RenderTextFragment(remainingText->node() ? remainingText->node() : & remainingText->document(), oldText.impl(), 0, length); | 3980 new RenderTextFragment(remainingText->node() ? remainingText->node() : & remainingText->document(), oldText.impl(), 0, length); |
| 4032 letter->setStyle(pseudoStyle); | 3981 letter->setStyle(pseudoStyle); |
| 4033 firstLetter->addChild(letter); | 3982 firstLetter->addChild(letter); |
| 4034 | 3983 |
| 4035 textObj->destroy(); | 3984 textObj->destroy(); |
| 4036 } | 3985 } |
| 4037 | 3986 |
| 3987 static bool isRendererAllowedForFirstLetter(RenderObject* renderer) | |
| 3988 { | |
| 3989 // FIXME: This black-list of disallowed RenderText subclasses is fragile. | |
| 3990 // Should counter be on this list? What about RenderTextFragment? | |
| 3991 return renderer->isText() && !renderer->isBR() && !toRenderText(renderer)->i sWordBreak(); | |
| 3992 } | |
| 3993 | |
| 3994 typedef Vector<std::pair<RenderObject*, unsigned> > FirstLetterRenderersList; | |
| 3995 | |
| 3996 enum FirstLetterSearchState { | |
| 3997 SearchLeadingSpaces, | |
| 3998 SearchLeadingPunctuation, | |
| 3999 SearchFirstLetterCharacter, | |
| 4000 SearchTrailingPunctuation | |
| 4001 }; | |
| 4002 | |
| 4003 class FirstLetterFinder { | |
| 4004 WTF_MAKE_NONCOPYABLE(FirstLetterFinder); | |
| 4005 public: | |
| 4006 FirstLetterFinder(RenderObject* block) | |
| 4007 : m_containerBlock(block) | |
| 4008 , m_renderers() | |
| 4009 , m_searchState(SearchLeadingSpaces) | |
| 4010 , m_firstLetterFound(false) | |
| 4011 { | |
| 4012 // The purpose of this class is to find the renderers that would be part | |
| 4013 // of the first-letter pseudo element, so go find them right now. | |
| 4014 findTextRenderers(); | |
| 4015 } | |
| 4016 | |
| 4017 FirstLetterRenderersList& renderers() { return m_renderers; } | |
| 4018 RenderObject* containerBlock() { return m_containerBlock; } | |
| 4019 | |
| 4020 private: | |
| 4021 void findTextRenderers() | |
| 4022 { | |
| 4023 // Drill into inlines looking for the render objects to be transformed i nto first-letter pseudoelements. | |
| 4024 RenderObject* currentChild = m_containerBlock->firstChild(); | |
| 4025 unsigned currentLength = 0; | |
| 4026 | |
| 4027 while (currentChild) { | |
| 4028 if (currentChild->isText()) { | |
| 4029 // Process the renderer and store it in the list if valid text w as found. | |
| 4030 currentLength = processTextRenderer(currentChild); | |
| 4031 if (currentLength) | |
| 4032 m_renderers.append(std::make_pair(currentChild, currentLengt h)); | |
| 4033 | |
| 4034 // No need to keep looking if we haven't found anything with the | |
| 4035 // current renderer or if we already made a decision. | |
| 4036 String text = rendererTextForFirstLetter(currentChild); | |
| 4037 if (!currentLength || currentLength < text.length()) | |
| 4038 break; | |
| 4039 | |
| 4040 // We need to look the next object traversing the tree in preord er as if the current renderer | |
| 4041 // was a leaf node (which probably is anyway) but without leavin g the scope of the parent block. | |
| 4042 currentChild = currentChild->nextInPreOrderAfterChildren(m_conta inerBlock); | |
| 4043 } else if (currentChild->isListMarker()) { | |
| 4044 currentChild = currentChild->nextSibling(); | |
| 4045 } else if (currentChild->isFloatingOrOutOfFlowPositioned()) { | |
| 4046 if (currentChild->style()->styleType() == FIRST_LETTER) { | |
| 4047 currentChild = currentChild->firstChild(); | |
| 4048 if (currentChild) { | |
| 4049 // If found a floating/out-of-flow element with the firs t-letter | |
| 4050 // style already applied, it means it has been previousl y identified | |
| 4051 // and so we should discard whatever we found so far and use that. | |
| 4052 m_firstLetterFound = true; | |
| 4053 m_renderers.append(std::make_pair(currentChild, renderer TextForFirstLetter(currentChild).length())); | |
| 4054 } | |
| 4055 break; | |
| 4056 } | |
| 4057 currentChild = currentChild->nextSibling(); | |
| 4058 } else if (currentChild->isReplaced() || currentChild->isRenderButto n() || currentChild->isMenuList()) { | |
| 4059 break; | |
| 4060 } else if (currentChild->style()->hasPseudoStyle(FIRST_LETTER) && cu rrentChild->canHaveGeneratedChildren()) { | |
| 4061 // We found a lower-level node with first-letter, which supersed es the higher-level style, | |
| 4062 // so we replace the block originally considered as the containe r and empty the list of | |
| 4063 // renderers we might have detected so far, as we no longer need to consider those. | |
| 4064 m_containerBlock = currentChild; | |
| 4065 currentChild = currentChild->firstChild(); | |
| 4066 m_renderers.clear(); | |
|
mario.prada
2014/04/23 14:17:48
This line is the main change compared to the patch
| |
| 4067 } else { | |
| 4068 currentChild = currentChild->firstChild(); | |
| 4069 } | |
| 4070 } | |
| 4071 | |
| 4072 if (!m_firstLetterFound) { | |
| 4073 // Empty the list of renderers if we did not find a correct set of t hem | |
| 4074 // to further generate new elements to apply the first-letter style over. | |
| 4075 m_renderers.clear(); | |
| 4076 } | |
| 4077 } | |
| 4078 | |
| 4079 String rendererTextForFirstLetter(RenderObject* renderer) const | |
| 4080 { | |
| 4081 ASSERT(renderer->isText()); | |
| 4082 RenderText* textRenderer = toRenderText(renderer); | |
| 4083 | |
| 4084 String result = textRenderer->originalText(); | |
| 4085 if (!result.isNull()) | |
| 4086 return result; | |
| 4087 | |
| 4088 if (isRendererAllowedForFirstLetter(renderer)) | |
| 4089 return textRenderer->text(); | |
| 4090 | |
| 4091 return String(); | |
| 4092 } | |
| 4093 | |
| 4094 unsigned processTextRenderer(RenderObject* renderer) | |
| 4095 { | |
| 4096 ASSERT(renderer->isText()); | |
| 4097 String text = rendererTextForFirstLetter(renderer); | |
| 4098 | |
| 4099 // Early return in case we encounter the wrong characters at the beginni ng. | |
| 4100 if (text.isEmpty() | |
| 4101 || (m_searchState == SearchLeadingPunctuation && isSpaceForFirstLett er(text[0])) | |
| 4102 || (m_firstLetterFound && !isPunctuationForFirstLetter(text[0]))) | |
| 4103 return 0; | |
| 4104 | |
| 4105 // Now start looking for valid characters for the first-letter pseudo el ement. | |
| 4106 bool doneSearching = false; | |
| 4107 unsigned textLength = text.length(); | |
| 4108 unsigned length = 0; | |
| 4109 | |
| 4110 while (!doneSearching && length < textLength) { | |
| 4111 switch (m_searchState) { | |
| 4112 case SearchLeadingSpaces: | |
| 4113 advancePositionWhile<isSpaceForFirstLetter>(text, length); | |
| 4114 if (length < textLength) | |
| 4115 m_searchState = SearchLeadingPunctuation; | |
| 4116 break; | |
| 4117 | |
| 4118 case SearchLeadingPunctuation: | |
| 4119 advancePositionWhile<isPunctuationForFirstLetter>(text, length); | |
| 4120 if (length < textLength) | |
| 4121 m_searchState = SearchFirstLetterCharacter; | |
| 4122 break; | |
| 4123 | |
| 4124 case SearchFirstLetterCharacter: | |
| 4125 // Now spaces are allowed between leading punctuation and the le tter. | |
| 4126 if (isSpaceForFirstLetter(text[length])) | |
| 4127 return 0; | |
| 4128 | |
| 4129 m_firstLetterFound = true; | |
| 4130 m_searchState = SearchTrailingPunctuation; | |
| 4131 length++; | |
| 4132 break; | |
| 4133 | |
| 4134 case SearchTrailingPunctuation: | |
| 4135 for (unsigned scanLength = length; scanLength < textLength; ++sc anLength) { | |
| 4136 UChar c = text[scanLength]; | |
| 4137 if (!isPunctuationForFirstLetter(c)) { | |
| 4138 doneSearching = true; | |
| 4139 break; | |
| 4140 } | |
| 4141 length = scanLength + 1; | |
| 4142 } | |
| 4143 break; | |
| 4144 } | |
| 4145 } | |
| 4146 | |
| 4147 ASSERT(length <= textLength); | |
| 4148 return length; | |
| 4149 } | |
| 4150 | |
| 4151 template<bool characterPredicate(UChar)> | |
| 4152 void advancePositionWhile(const String& text, unsigned& position) | |
| 4153 { | |
| 4154 unsigned textLength = text.length(); | |
| 4155 while (position < textLength && characterPredicate(text[position])) | |
| 4156 position++; | |
| 4157 } | |
| 4158 | |
| 4159 // CSS 2.1 http://www.w3.org/TR/CSS21/selector.html#first-letter | |
| 4160 // "Punctuation (i.e, characters defined in Unicode [UNICODE] in the "open" (Ps), "close" (Pe), | |
| 4161 // "initial" (Pi). "final" (Pf) and "other" (Po) punctuation classes), that precedes or follows the first letter should be included" | |
| 4162 static inline bool isPunctuationForFirstLetter(UChar c) | |
| 4163 { | |
| 4164 CharCategory charCategory = category(c); | |
| 4165 return charCategory == Punctuation_Open | |
| 4166 || charCategory == Punctuation_Close | |
| 4167 || charCategory == Punctuation_InitialQuote | |
| 4168 || charCategory == Punctuation_FinalQuote | |
| 4169 || charCategory == Punctuation_Other; | |
| 4170 } | |
| 4171 | |
| 4172 static inline bool isSpaceForFirstLetter(UChar c) | |
| 4173 { | |
| 4174 return isSpaceOrNewline(c) || c == noBreakSpace; | |
| 4175 } | |
| 4176 | |
| 4177 RenderObject* m_containerBlock; | |
| 4178 FirstLetterRenderersList m_renderers; | |
| 4179 FirstLetterSearchState m_searchState; | |
| 4180 bool m_firstLetterFound; | |
| 4181 }; | |
| 4182 | |
| 4038 void RenderBlock::updateFirstLetter() | 4183 void RenderBlock::updateFirstLetter() |
| 4039 { | 4184 { |
| 4040 if (!document().styleEngine()->usesFirstLetterRules()) | 4185 if (!document().styleEngine()->usesFirstLetterRules()) |
| 4041 return; | 4186 return; |
| 4042 // Don't recur | 4187 |
| 4188 // Early return if the renderer is already known to be part of a first-lette r pseudo element. | |
| 4043 if (style()->styleType() == FIRST_LETTER) | 4189 if (style()->styleType() == FIRST_LETTER) |
| 4044 return; | 4190 return; |
| 4045 | 4191 |
| 4046 // FIXME: We need to destroy the first-letter object if it is no longer the first child. Need to find | 4192 // FIXME: We need to destroy the first-letter object if it is no longer the first child. Need to find |
| 4047 // an efficient way to check for that situation though before implementing a nything. | 4193 // an efficient way to check for that situation though before implementing a nything. |
| 4048 RenderObject* firstLetterBlock = findFirstLetterBlock(this); | 4194 RenderObject* firstLetterBlock = findFirstLetterBlock(this); |
| 4049 if (!firstLetterBlock) | 4195 if (!firstLetterBlock) |
| 4050 return; | 4196 return; |
| 4051 | 4197 |
| 4052 // Drill into inlines looking for our first text child. | 4198 // Find the renderers to apply the first-letter style over. |
| 4053 RenderObject* currChild = firstLetterBlock->firstChild(); | 4199 FirstLetterFinder firstLetterFinder(firstLetterBlock); |
| 4054 unsigned length = 0; | 4200 FirstLetterRenderersList& renderers = firstLetterFinder.renderers(); |
| 4055 while (currChild) { | 4201 if (renderers.isEmpty()) |
| 4056 if (currChild->isText()) { | |
| 4057 // FIXME: If there is leading punctuation in a different RenderText than | |
| 4058 // the first letter, we'll not apply the correct style to it. | |
| 4059 length = firstLetterLength(toRenderText(currChild)->originalText()); | |
| 4060 if (length) | |
| 4061 break; | |
| 4062 currChild = currChild->nextSibling(); | |
| 4063 } else if (currChild->isListMarker()) { | |
| 4064 currChild = currChild->nextSibling(); | |
| 4065 } else if (currChild->isFloatingOrOutOfFlowPositioned()) { | |
| 4066 if (currChild->style()->styleType() == FIRST_LETTER) { | |
| 4067 currChild = currChild->firstChild(); | |
| 4068 break; | |
| 4069 } | |
| 4070 currChild = currChild->nextSibling(); | |
| 4071 } else if (currChild->isReplaced() || currChild->isRenderButton() || cur rChild->isMenuList()) | |
| 4072 break; | |
| 4073 else if (currChild->style()->hasPseudoStyle(FIRST_LETTER) && currChild-> canHaveGeneratedChildren()) { | |
| 4074 // We found a lower-level node with first-letter, which supersedes t he higher-level style | |
| 4075 firstLetterBlock = currChild; | |
| 4076 currChild = currChild->firstChild(); | |
| 4077 } else | |
| 4078 currChild = currChild->firstChild(); | |
| 4079 } | |
| 4080 | |
| 4081 if (!currChild) | |
| 4082 return; | 4202 return; |
| 4083 | 4203 |
| 4084 // If the child already has style, then it has already been created, so we j ust want | 4204 // The FindLetterFinder might change what considers to be the container bloc k |
| 4085 // to update it. | 4205 // for the render objects that form the first-letter pseudo element from the one |
| 4086 if (currChild->parent()->style()->styleType() == FIRST_LETTER) { | 4206 // originally passed to the constructor so we need to update the pointer now . |
| 4087 updateFirstLetterStyle(firstLetterBlock, currChild); | 4207 firstLetterBlock = firstLetterFinder.containerBlock(); |
| 4088 return; | 4208 |
| 4209 // Create the new renderers for the first-letter pseudo elements. | |
| 4210 for (FirstLetterRenderersList::const_iterator it = renderers.begin(); it != renderers.end(); ++it) { | |
| 4211 RenderObject* currentRenderer = it->first; | |
| 4212 ASSERT(currentRenderer->isText()); | |
| 4213 | |
| 4214 // If the child already has style, then it has already been created, so we just want | |
| 4215 // to update it. | |
| 4216 if (currentRenderer->parent()->style()->styleType() == FIRST_LETTER) { | |
| 4217 updateFirstLetterStyle(firstLetterBlock, currentRenderer); | |
| 4218 continue; | |
| 4219 } | |
| 4220 | |
| 4221 if (!isRendererAllowedForFirstLetter(currentRenderer)) | |
| 4222 continue; | |
| 4223 | |
| 4224 // Our layout state is not valid for the repaints we are going to trigge r by | |
| 4225 // adding and removing children of firstLetterContainer. | |
| 4226 LayoutStateDisabler layoutStateDisabler(*this); | |
| 4227 | |
| 4228 unsigned lengthForRenderer = it->second; | |
| 4229 if (lengthForRenderer) | |
| 4230 createFirstLetterRenderer(firstLetterBlock, currentRenderer, lengthF orRenderer); | |
| 4089 } | 4231 } |
| 4090 | |
| 4091 // FIXME: This black-list of disallowed RenderText subclasses is fragile. | |
| 4092 // Should counter be on this list? What about RenderTextFragment? | |
| 4093 if (!currChild->isText() || currChild->isBR() || toRenderText(currChild)->is WordBreak()) | |
| 4094 return; | |
| 4095 | |
| 4096 // Our layout state is not valid for the repaints we are going to trigger by | |
| 4097 // adding and removing children of firstLetterContainer. | |
| 4098 LayoutStateDisabler layoutStateDisabler(*this); | |
| 4099 | |
| 4100 createFirstLetterRenderer(firstLetterBlock, currChild, length); | |
| 4101 } | 4232 } |
| 4102 | 4233 |
| 4103 // Helper methods for obtaining the last line, computing line counts and heights for line counts | 4234 // Helper methods for obtaining the last line, computing line counts and heights for line counts |
| 4104 // (crawling into blocks). | 4235 // (crawling into blocks). |
| 4105 static bool shouldCheckLines(RenderObject* obj) | 4236 static bool shouldCheckLines(RenderObject* obj) |
| 4106 { | 4237 { |
| 4107 return !obj->isFloatingOrOutOfFlowPositioned() | 4238 return !obj->isFloatingOrOutOfFlowPositioned() |
| 4108 && obj->isRenderBlock() && obj->style()->height().isAuto() | 4239 && obj->isRenderBlock() && obj->style()->height().isAuto() |
| 4109 && (!obj->isDeprecatedFlexibleBox() || obj->style()->boxOrient() == VERT ICAL); | 4240 && (!obj->isDeprecatedFlexibleBox() || obj->style()->boxOrient() == VERT ICAL); |
| 4110 } | 4241 } |
| (...skipping 843 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4954 void RenderBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* m arkedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const Render Object* obj) const | 5085 void RenderBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* m arkedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const Render Object* obj) const |
| 4955 { | 5086 { |
| 4956 showRenderObject(); | 5087 showRenderObject(); |
| 4957 for (const RootInlineBox* root = firstRootBox(); root; root = root->nextRoot Box()) | 5088 for (const RootInlineBox* root = firstRootBox(); root; root = root->nextRoot Box()) |
| 4958 root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLa bel2, obj, 1); | 5089 root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLa bel2, obj, 1); |
| 4959 } | 5090 } |
| 4960 | 5091 |
| 4961 #endif | 5092 #endif |
| 4962 | 5093 |
| 4963 } // namespace WebCore | 5094 } // namespace WebCore |
| OLD | NEW |