Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(43)

Side by Side Diff: WebCore/rendering/RenderBlock.cpp

Issue 3419009: Merge 67281 (Closed) Base URL: http://svn.webkit.org/repository/webkit/branches/chromium/517/
Patch Set: Created 10 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 Apple Inc. All r ights reserved. 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All r ights 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 5071 matching lines...) Expand 10 before | Expand all | Expand 10 after
5082 ASSERT(parentBlock->isRenderBlock()); 5082 ASSERT(parentBlock->isRenderBlock());
5083 firstLineBlock = toRenderBlock(parentBlock); 5083 firstLineBlock = toRenderBlock(parentBlock);
5084 } 5084 }
5085 5085
5086 if (!hasPseudo) 5086 if (!hasPseudo)
5087 return 0; 5087 return 0;
5088 5088
5089 return firstLineBlock; 5089 return firstLineBlock;
5090 } 5090 }
5091 5091
5092 static RenderStyle* styleForFirstLetter(RenderObject* firstLetterBlock, RenderOb ject* firstLetterContainer)
5093 {
5094 RenderStyle* pseudoStyle = firstLetterBlock->getCachedPseudoStyle(FIRST_LETT ER, firstLetterContainer->firstLineStyle());
5095 // Force inline display (except for floating first-letters).
5096 pseudoStyle->setDisplay(pseudoStyle->isFloating() ? BLOCK : INLINE);
5097 // CSS2 says first-letter can't be positioned.
5098 pseudoStyle->setPosition(StaticPosition);
5099 return pseudoStyle;
5100 }
5101
5092 void RenderBlock::updateFirstLetter() 5102 void RenderBlock::updateFirstLetter()
5093 { 5103 {
5094 if (!document()->usesFirstLetterRules()) 5104 if (!document()->usesFirstLetterRules())
5095 return; 5105 return;
5096 // Don't recur 5106 // Don't recur
5097 if (style()->styleType() == FIRST_LETTER) 5107 if (style()->styleType() == FIRST_LETTER)
5098 return; 5108 return;
5099 5109
5100 // FIXME: We need to destroy the first-letter object if it is no longer the first child. Need to find 5110 // FIXME: We need to destroy the first-letter object if it is no longer the first child. Need to find
5101 // an efficient way to check for that situation though before implementing a nything. 5111 // an efficient way to check for that situation though before implementing a nything.
(...skipping 29 matching lines...) Expand all
5131 currChild = currChild->firstChild(); 5141 currChild = currChild->firstChild();
5132 } 5142 }
5133 5143
5134 // Get list markers out of the way. 5144 // Get list markers out of the way.
5135 while (currChild && currChild->isListMarker()) 5145 while (currChild && currChild->isListMarker())
5136 currChild = currChild->nextSibling(); 5146 currChild = currChild->nextSibling();
5137 5147
5138 if (!currChild) 5148 if (!currChild)
5139 return; 5149 return;
5140 5150
5141 RenderObject* firstLetterContainer = currChild->parent();
5142
5143 // If the child already has style, then it has already been created, so we j ust want 5151 // If the child already has style, then it has already been created, so we j ust want
5144 // to update it. 5152 // to update it.
5145 if (firstLetterContainer->style()->styleType() == FIRST_LETTER) { 5153 if (currChild->parent()->style()->styleType() == FIRST_LETTER) {
5146 RenderStyle* pseudo = firstLetterBlock->getCachedPseudoStyle(FIRST_LETTE R, 5154 RenderObject* firstLetter = currChild->parent();
5147 firstLetter Container->parent()->firstLineStyle()); 5155 RenderObject* firstLetterContainer = firstLetter->parent();
5148 firstLetterContainer->setStyle(pseudo); 5156 RenderStyle* pseudoStyle = styleForFirstLetter(firstLetterBlock, firstLe tterContainer);
5149 for (RenderObject* genChild = firstLetterContainer->firstChild(); genChi ld; genChild = genChild->nextSibling()) { 5157
5158 if (Node::diff(firstLetter->style(), pseudoStyle) == Node::Detach) {
5159 // The first-letter renderer needs to be replaced. Create a new rend erer of the right type.
5160 RenderObject* newFirstLetter;
5161 if (pseudoStyle->display() == INLINE)
5162 newFirstLetter = new (renderArena()) RenderInline(document());
5163 else
5164 newFirstLetter = new (renderArena()) RenderBlock(document());
5165 newFirstLetter->setStyle(pseudoStyle);
5166
5167 // Move the first letter into the new renderer.
5168 view()->disableLayoutState();
5169 while (RenderObject* child = firstLetter->firstChild()) {
5170 if (child->isText())
5171 toRenderText(child)->dirtyLineBoxes(true);
5172 firstLetter->removeChild(child);
5173 newFirstLetter->addChild(child, 0);
5174 }
5175 RenderTextFragment* remainingText = toRenderTextFragment(firstLetter ->nextSibling());
5176 ASSERT(remainingText->node()->renderer() == remainingText);
5177 // Replace the old renderer with the new one.
5178 remainingText->setFirstLetter(newFirstLetter);
5179 firstLetter->destroy();
5180 firstLetter = newFirstLetter;
5181 firstLetterContainer->addChild(firstLetter, remainingText);
5182 view()->enableLayoutState();
5183 } else
5184 firstLetter->setStyle(pseudoStyle);
5185
5186 for (RenderObject* genChild = firstLetter->firstChild(); genChild; genCh ild = genChild->nextSibling()) {
5150 if (genChild->isText()) 5187 if (genChild->isText())
5151 genChild->setStyle(pseudo); 5188 genChild->setStyle(pseudoStyle);
5152 } 5189 }
5190
5153 return; 5191 return;
5154 } 5192 }
5155 5193
5194 if (!currChild->isText() || currChild->isBR())
5195 return;
5196
5156 // If the child does not already have style, we create it here. 5197 // If the child does not already have style, we create it here.
5157 if (currChild->isText() && !currChild->isBR() && currChild->parent()->style( )->styleType() != FIRST_LETTER) { 5198 RenderObject* firstLetterContainer = currChild->parent();
5158 // Our layout state is not valid for the repaints we are going to trigge r by
5159 // adding and removing children of firstLetterContainer.
5160 view()->disableLayoutState();
5161 5199
5162 RenderText* textObj = toRenderText(currChild); 5200 // Our layout state is not valid for the repaints we are going to trigger by
5201 // adding and removing children of firstLetterContainer.
5202 view()->disableLayoutState();
5163 5203
5164 // Create our pseudo style now that we have our firstLetterContainer det ermined. 5204 RenderText* textObj = toRenderText(currChild);
5165 RenderStyle* pseudoStyle = firstLetterBlock->getCachedPseudoStyle(FIRST_ LETTER, 5205
5166 firstL etterContainer->firstLineStyle()); 5206 // Create our pseudo style now that we have our firstLetterContainer determi ned.
5207 RenderStyle* pseudoStyle = styleForFirstLetter(firstLetterBlock, firstLetter Container);
5208
5209 RenderObject* firstLetter = 0;
5210 if (pseudoStyle->display() == INLINE)
5211 firstLetter = new (renderArena()) RenderInline(document());
5212 else
5213 firstLetter = new (renderArena()) RenderBlock(document());
5214 firstLetter->setStyle(pseudoStyle);
5215 firstLetterContainer->addChild(firstLetter, currChild);
5216
5217 // The original string is going to be either a generated content string or a DOM node's
5218 // string. We want the original string before it got transformed in case fi rst-letter has
5219 // no text-transform or a different text-transform applied to it.
5220 RefPtr<StringImpl> oldText = textObj->originalText();
5221 ASSERT(oldText);
5222
5223 if (oldText && oldText->length() > 0) {
5224 unsigned length = 0;
5225
5226 // account for leading spaces and punctuation
5227 while (length < oldText->length() && (isSpaceOrNewline((*oldText)[length ]) || Unicode::isPunct((*oldText)[length])))
5228 length++;
5229
5230 // account for first letter
5231 length++;
5232
5233 // construct text fragment for the text after the first letter
5234 // NOTE: this might empty
5235 RenderTextFragment* remainingText =
5236 new (renderArena()) RenderTextFragment(textObj->node() ? textObj->no de() : textObj->document(), oldText.get(), length, oldText->length() - length);
5237 remainingText->setStyle(textObj->style());
5238 if (remainingText->node())
5239 remainingText->node()->setRenderer(remainingText);
5240
5241 RenderObject* nextObj = textObj->nextSibling();
5242 firstLetterContainer->removeChild(textObj);
5243 firstLetterContainer->addChild(remainingText, nextObj);
5244 remainingText->setFirstLetter(firstLetter);
5167 5245
5168 // Force inline display (except for floating first-letters) 5246 // construct text fragment for the first letter
5169 pseudoStyle->setDisplay(pseudoStyle->isFloating() ? BLOCK : INLINE); 5247 RenderTextFragment* letter =
5170 pseudoStyle->setPosition(StaticPosition); // CSS2 says first-letter can' t be positioned. 5248 new (renderArena()) RenderTextFragment(remainingText->node() ? remai ningText->node() : remainingText->document(), oldText.get(), 0, length);
5171 5249 letter->setStyle(pseudoStyle);
5172 RenderObject* firstLetter = 0; 5250 firstLetter->addChild(letter);
5173 if (pseudoStyle->display() == INLINE)
5174 firstLetter = new (renderArena()) RenderInline(document());
5175 else
5176 firstLetter = new (renderArena()) RenderBlock(document());
5177 firstLetter->setStyle(pseudoStyle);
5178 firstLetterContainer->addChild(firstLetter, currChild);
5179
5180 // The original string is going to be either a generated content string or a DOM node's
5181 // string. We want the original string before it got transformed in cas e first-letter has
5182 // no text-transform or a different text-transform applied to it.
5183 RefPtr<StringImpl> oldText = textObj->originalText();
5184 ASSERT(oldText);
5185
5186 if (oldText && oldText->length() > 0) {
5187 unsigned int length = 0;
5188
5189 // account for leading spaces and punctuation
5190 while (length < oldText->length() && (isSpaceOrNewline((*oldText)[le ngth]) || Unicode::isPunct((*oldText)[length])))
5191 length++;
5192
5193 // account for first letter
5194 length++;
5195
5196 // construct text fragment for the text after the first letter
5197 // NOTE: this might empty
5198 RenderTextFragment* remainingText =
5199 new (renderArena()) RenderTextFragment(textObj->node() ? textObj ->node() : textObj->document(), oldText.get(), length, oldText->length() - lengt h);
5200 remainingText->setStyle(textObj->style());
5201 if (remainingText->node())
5202 remainingText->node()->setRenderer(remainingText);
5203
5204 RenderObject* nextObj = textObj->nextSibling();
5205 firstLetterContainer->removeChild(textObj);
5206 firstLetterContainer->addChild(remainingText, nextObj);
5207 remainingText->setFirstLetter(firstLetter);
5208
5209 // construct text fragment for the first letter
5210 RenderTextFragment* letter =
5211 new (renderArena()) RenderTextFragment(remainingText->node() ? r emainingText->node() : remainingText->document(), oldText.get(), 0, length);
5212 letter->setStyle(pseudoStyle);
5213 firstLetter->addChild(letter);
5214 5251
5215 textObj->destroy(); 5252 textObj->destroy();
5216 }
5217 view()->enableLayoutState();
5218 } 5253 }
5254 view()->enableLayoutState();
5219 } 5255 }
5220 5256
5221 // Helper methods for obtaining the last line, computing line counts and heights for line counts 5257 // Helper methods for obtaining the last line, computing line counts and heights for line counts
5222 // (crawling into blocks). 5258 // (crawling into blocks).
5223 static bool shouldCheckLines(RenderObject* obj) 5259 static bool shouldCheckLines(RenderObject* obj)
5224 { 5260 {
5225 return !obj->isFloatingOrPositioned() && !obj->isRunIn() && 5261 return !obj->isFloatingOrPositioned() && !obj->isRunIn() &&
5226 obj->isBlockFlow() && obj->style()->height().isAuto() && 5262 obj->isBlockFlow() && obj->style()->height().isAuto() &&
5227 (!obj->isFlexibleBox() || obj->style()->boxOrient() == VERTICAL); 5263 (!obj->isFlexibleBox() || obj->style()->boxOrient() == VERTICAL);
5228 } 5264 }
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after
5684 else if (isAnonymous()) 5720 else if (isAnonymous())
5685 return "RenderBlock (generated)"; 5721 return "RenderBlock (generated)";
5686 if (isRelPositioned()) 5722 if (isRelPositioned())
5687 return "RenderBlock (relative positioned)"; 5723 return "RenderBlock (relative positioned)";
5688 if (isRunIn()) 5724 if (isRunIn())
5689 return "RenderBlock (run-in)"; 5725 return "RenderBlock (run-in)";
5690 return "RenderBlock"; 5726 return "RenderBlock";
5691 } 5727 }
5692 5728
5693 } // namespace WebCore 5729 } // namespace WebCore
OLDNEW
« no previous file with comments | « LayoutTests/fast/dynamic/first-letter-display-change-expected.txt ('k') | WebCore/rendering/RenderTextFragment.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698