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

Side by Side Diff: third_party/WebKit/Source/core/dom/FirstLetterPseudoElement.cpp

Issue 2390543002: Reflow comments in core/dom/. (Closed)
Patch Set: Reformat comments in core/dom/. Created 4 years, 2 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, 2011 Apple Inc. All rights reserved. 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc.
6 * All rights reserved.
6 * Copyright (C) Research In Motion Limited 2010. All rights reserved. 7 * Copyright (C) Research In Motion Limited 2010. 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
(...skipping 16 matching lines...) Expand all
32 #include "core/layout/LayoutTextFragment.h" 33 #include "core/layout/LayoutTextFragment.h"
33 #include "core/layout/api/LayoutTextFragmentItem.h" 34 #include "core/layout/api/LayoutTextFragmentItem.h"
34 #include "wtf/text/WTFString.h" 35 #include "wtf/text/WTFString.h"
35 #include "wtf/text/icu/UnicodeIcu.h" 36 #include "wtf/text/icu/UnicodeIcu.h"
36 37
37 namespace blink { 38 namespace blink {
38 39
39 using namespace WTF; 40 using namespace WTF;
40 using namespace Unicode; 41 using namespace Unicode;
41 42
42 // CSS 2.1 http://www.w3.org/TR/CSS21/selector.html#first-letter 43 // CSS 2.1 http://www.w3.org/TR/CSS21/selector.html#first-letter "Punctuation
43 // "Punctuation (i.e, characters defined in Unicode [UNICODE] in the "open" (Ps) , "close" (Pe), 44 // (i.e, characters defined in Unicode [UNICODE] in the "open" (Ps), "close"
44 // "initial" (Pi). "final" (Pf) and "other" (Po) punctuation classes), that prec edes or follows the first letter should be included" 45 // (Pe), "initial" (Pi). "final" (Pf) and "other" (Po) punctuation classes),
46 // that precedes or follows the first letter should be included"
45 static inline bool isPunctuationForFirstLetter(UChar c) { 47 static inline bool isPunctuationForFirstLetter(UChar c) {
46 CharCategory charCategory = category(c); 48 CharCategory charCategory = category(c);
47 return charCategory == Punctuation_Open || 49 return charCategory == Punctuation_Open ||
48 charCategory == Punctuation_Close || 50 charCategory == Punctuation_Close ||
49 charCategory == Punctuation_InitialQuote || 51 charCategory == Punctuation_InitialQuote ||
50 charCategory == Punctuation_FinalQuote || 52 charCategory == Punctuation_FinalQuote ||
51 charCategory == Punctuation_Other; 53 charCategory == Punctuation_Other;
52 } 54 }
53 55
54 static inline bool isSpaceForFirstLetter(UChar c) { 56 static inline bool isSpaceForFirstLetter(UChar c) {
55 return isSpaceOrNewline(c) || c == noBreakSpaceCharacter; 57 return isSpaceOrNewline(c) || c == noBreakSpaceCharacter;
56 } 58 }
57 59
58 unsigned FirstLetterPseudoElement::firstLetterLength(const String& text) { 60 unsigned FirstLetterPseudoElement::firstLetterLength(const String& text) {
59 unsigned length = 0; 61 unsigned length = 0;
60 unsigned textLength = text.length(); 62 unsigned textLength = text.length();
61 63
62 if (textLength == 0) 64 if (textLength == 0)
63 return length; 65 return length;
64 66
65 // Account for leading spaces first. 67 // Account for leading spaces first.
66 while (length < textLength && isSpaceForFirstLetter(text[length])) 68 while (length < textLength && isSpaceForFirstLetter(text[length]))
67 length++; 69 length++;
68 // Now account for leading punctuation. 70 // Now account for leading punctuation.
69 while (length < textLength && isPunctuationForFirstLetter(text[length])) 71 while (length < textLength && isPunctuationForFirstLetter(text[length]))
70 length++; 72 length++;
71 73
72 // Bail if we didn't find a letter before the end of the text or before a spac e. 74 // Bail if we didn't find a letter before the end of the text or before a
75 // space.
73 if (isSpaceForFirstLetter(text[length]) || length == textLength) 76 if (isSpaceForFirstLetter(text[length]) || length == textLength)
74 return 0; 77 return 0;
75 78
76 // Account the next character for first letter. 79 // Account the next character for first letter.
77 length++; 80 length++;
78 81
79 // Keep looking for allowed punctuation for the :first-letter. 82 // Keep looking for allowed punctuation for the :first-letter.
80 for (; length < textLength; ++length) { 83 for (; length < textLength; ++length) {
81 UChar c = text[length]; 84 UChar c = text[length];
82 if (!isPunctuationForFirstLetter(c)) 85 if (!isPunctuationForFirstLetter(c))
83 break; 86 break;
84 } 87 }
85 return length; 88 return length;
86 } 89 }
87 90
88 // Once we see any of these layoutObjects we can stop looking for first-letter a s 91 // Once we see any of these layoutObjects we can stop looking for first-letter
89 // they signal the end of the first line of text. 92 // as they signal the end of the first line of text.
90 static bool isInvalidFirstLetterLayoutObject(const LayoutObject* obj) { 93 static bool isInvalidFirstLetterLayoutObject(const LayoutObject* obj) {
91 return (obj->isBR() || (obj->isText() && toLayoutText(obj)->isWordBreak())); 94 return (obj->isBR() || (obj->isText() && toLayoutText(obj)->isWordBreak()));
92 } 95 }
93 96
94 LayoutObject* FirstLetterPseudoElement::firstLetterTextLayoutObject( 97 LayoutObject* FirstLetterPseudoElement::firstLetterTextLayoutObject(
95 const Element& element) { 98 const Element& element) {
96 LayoutObject* parentLayoutObject = 0; 99 LayoutObject* parentLayoutObject = 0;
97 100
98 // If we are looking at a first letter element then we need to find the 101 // If we are looking at a first letter element then we need to find the
99 // first letter text layoutObject from the parent node, and not ourselves. 102 // first letter text layoutObject from the parent node, and not ourselves.
100 if (element.isFirstLetterPseudoElement()) 103 if (element.isFirstLetterPseudoElement())
101 parentLayoutObject = element.parentOrShadowHostElement()->layoutObject(); 104 parentLayoutObject = element.parentOrShadowHostElement()->layoutObject();
102 else 105 else
103 parentLayoutObject = element.layoutObject(); 106 parentLayoutObject = element.layoutObject();
104 107
105 if (!parentLayoutObject || 108 if (!parentLayoutObject ||
106 !parentLayoutObject->style()->hasPseudoStyle(PseudoIdFirstLetter) || 109 !parentLayoutObject->style()->hasPseudoStyle(PseudoIdFirstLetter) ||
107 !canHaveGeneratedChildren(*parentLayoutObject) || 110 !canHaveGeneratedChildren(*parentLayoutObject) ||
108 !parentLayoutObject->behavesLikeBlockContainer()) 111 !parentLayoutObject->behavesLikeBlockContainer())
109 return nullptr; 112 return nullptr;
110 113
111 // Drill down into our children and look for our first text child. 114 // Drill down into our children and look for our first text child.
112 LayoutObject* firstLetterTextLayoutObject = 115 LayoutObject* firstLetterTextLayoutObject =
113 parentLayoutObject->slowFirstChild(); 116 parentLayoutObject->slowFirstChild();
114 while (firstLetterTextLayoutObject) { 117 while (firstLetterTextLayoutObject) {
115 // This can be called when the first letter layoutObject is already in the t ree. We do not 118 // This can be called when the first letter layoutObject is already in the
116 // want to consider that layoutObject for our text layoutObject so we go to the sibling (which is 119 // tree. We do not want to consider that layoutObject for our text
117 // the LayoutTextFragment for the remaining text). 120 // layoutObject so we go to the sibling (which is the LayoutTextFragment for
121 // the remaining text).
118 if (firstLetterTextLayoutObject->style() && 122 if (firstLetterTextLayoutObject->style() &&
119 firstLetterTextLayoutObject->style()->styleType() == 123 firstLetterTextLayoutObject->style()->styleType() ==
120 PseudoIdFirstLetter) { 124 PseudoIdFirstLetter) {
121 firstLetterTextLayoutObject = firstLetterTextLayoutObject->nextSibling(); 125 firstLetterTextLayoutObject = firstLetterTextLayoutObject->nextSibling();
122 } else if (firstLetterTextLayoutObject->isText()) { 126 } else if (firstLetterTextLayoutObject->isText()) {
123 // FIXME: If there is leading punctuation in a different LayoutText than 127 // FIXME: If there is leading punctuation in a different LayoutText than
124 // the first letter, we'll not apply the correct style to it. 128 // the first letter, we'll not apply the correct style to it.
125 RefPtr<StringImpl> str = 129 RefPtr<StringImpl> str =
126 toLayoutText(firstLetterTextLayoutObject)->isTextFragment() 130 toLayoutText(firstLetterTextLayoutObject)->isTextFragment()
127 ? toLayoutTextFragment(firstLetterTextLayoutObject) 131 ? toLayoutTextFragment(firstLetterTextLayoutObject)
(...skipping 18 matching lines...) Expand all
146 firstLetterTextLayoutObject->isMenuList()) { 150 firstLetterTextLayoutObject->isMenuList()) {
147 return nullptr; 151 return nullptr;
148 } else if (firstLetterTextLayoutObject 152 } else if (firstLetterTextLayoutObject
149 ->isFlexibleBoxIncludingDeprecated() || 153 ->isFlexibleBoxIncludingDeprecated() ||
150 firstLetterTextLayoutObject->isLayoutGrid()) { 154 firstLetterTextLayoutObject->isLayoutGrid()) {
151 firstLetterTextLayoutObject = firstLetterTextLayoutObject->nextSibling(); 155 firstLetterTextLayoutObject = firstLetterTextLayoutObject->nextSibling();
152 } else if (!firstLetterTextLayoutObject->isInline() && 156 } else if (!firstLetterTextLayoutObject->isInline() &&
153 firstLetterTextLayoutObject->style()->hasPseudoStyle( 157 firstLetterTextLayoutObject->style()->hasPseudoStyle(
154 PseudoIdFirstLetter) && 158 PseudoIdFirstLetter) &&
155 canHaveGeneratedChildren(*firstLetterTextLayoutObject)) { 159 canHaveGeneratedChildren(*firstLetterTextLayoutObject)) {
156 // There is a layoutObject further down the tree which has PseudoIdFirstLe tter set. When that node 160 // There is a layoutObject further down the tree which has
157 // is attached we will handle setting up the first letter then. 161 // PseudoIdFirstLetter set. When that node is attached we will handle
162 // setting up the first letter then.
158 return nullptr; 163 return nullptr;
159 } else { 164 } else {
160 firstLetterTextLayoutObject = 165 firstLetterTextLayoutObject =
161 firstLetterTextLayoutObject->slowFirstChild(); 166 firstLetterTextLayoutObject->slowFirstChild();
162 } 167 }
163 } 168 }
164 169
165 // No first letter text to display, we're done. 170 // No first letter text to display, we're done.
166 // FIXME: This black-list of disallowed LayoutText subclasses is fragile. crbu g.com/422336. 171 // FIXME: This black-list of disallowed LayoutText subclasses is fragile.
172 // crbug.com/422336.
167 // Should counter be on this list? What about LayoutTextFragment? 173 // Should counter be on this list? What about LayoutTextFragment?
168 if (!firstLetterTextLayoutObject || !firstLetterTextLayoutObject->isText() || 174 if (!firstLetterTextLayoutObject || !firstLetterTextLayoutObject->isText() ||
169 isInvalidFirstLetterLayoutObject(firstLetterTextLayoutObject)) 175 isInvalidFirstLetterLayoutObject(firstLetterTextLayoutObject))
170 return nullptr; 176 return nullptr;
171 177
172 return firstLetterTextLayoutObject; 178 return firstLetterTextLayoutObject;
173 } 179 }
174 180
175 FirstLetterPseudoElement::FirstLetterPseudoElement(Element* parent) 181 FirstLetterPseudoElement::FirstLetterPseudoElement(Element* parent)
176 : PseudoElement(parent, PseudoIdFirstLetter), 182 : PseudoElement(parent, PseudoIdFirstLetter),
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 268
263 return pseudoStyle; 269 return pseudoStyle;
264 } 270 }
265 271
266 void FirstLetterPseudoElement::attachFirstLetterTextLayoutObjects() { 272 void FirstLetterPseudoElement::attachFirstLetterTextLayoutObjects() {
267 LayoutObject* nextLayoutObject = 273 LayoutObject* nextLayoutObject =
268 FirstLetterPseudoElement::firstLetterTextLayoutObject(*this); 274 FirstLetterPseudoElement::firstLetterTextLayoutObject(*this);
269 DCHECK(nextLayoutObject); 275 DCHECK(nextLayoutObject);
270 DCHECK(nextLayoutObject->isText()); 276 DCHECK(nextLayoutObject->isText());
271 277
272 // The original string is going to be either a generated content string or a D OM node's 278 // The original string is going to be either a generated content string or a
273 // string. We want the original string before it got transformed in case first -letter has 279 // DOM node's string. We want the original string before it got transformed in
274 // no text-transform or a different text-transform applied to it. 280 // case first-letter has no text-transform or a different text-transform
281 // applied to it.
275 String oldText = toLayoutText(nextLayoutObject)->isTextFragment() 282 String oldText = toLayoutText(nextLayoutObject)->isTextFragment()
276 ? toLayoutTextFragment(nextLayoutObject)->completeText() 283 ? toLayoutTextFragment(nextLayoutObject)->completeText()
277 : toLayoutText(nextLayoutObject)->originalText(); 284 : toLayoutText(nextLayoutObject)->originalText();
278 DCHECK(oldText.impl()); 285 DCHECK(oldText.impl());
279 286
280 ComputedStyle* pseudoStyle = styleForFirstLetter(nextLayoutObject->parent()); 287 ComputedStyle* pseudoStyle = styleForFirstLetter(nextLayoutObject->parent());
281 layoutObject()->setStyle(pseudoStyle); 288 layoutObject()->setStyle(pseudoStyle);
282 289
283 // FIXME: This would already have been calculated in firstLetterLayoutObject. Can we pass the length through? 290 // FIXME: This would already have been calculated in firstLetterLayoutObject.
291 // Can we pass the length through?
284 unsigned length = FirstLetterPseudoElement::firstLetterLength(oldText); 292 unsigned length = FirstLetterPseudoElement::firstLetterLength(oldText);
285 293
286 // Construct a text fragment for the text after the first letter. 294 // Construct a text fragment for the text after the first letter.
287 // This text fragment might be empty. 295 // This text fragment might be empty.
288 LayoutTextFragment* remainingText = new LayoutTextFragment( 296 LayoutTextFragment* remainingText = new LayoutTextFragment(
289 nextLayoutObject->node() ? nextLayoutObject->node() 297 nextLayoutObject->node() ? nextLayoutObject->node()
290 : &nextLayoutObject->document(), 298 : &nextLayoutObject->document(),
291 oldText.impl(), length, oldText.length() - length); 299 oldText.impl(), length, oldText.length() - length);
292 remainingText->setFirstLetterPseudoElement(this); 300 remainingText->setFirstLetterPseudoElement(this);
293 remainingText->setIsRemainingTextLayoutObject(true); 301 remainingText->setIsRemainingTextLayoutObject(true);
(...skipping 14 matching lines...) Expand all
308 letter->setStyle(pseudoStyle); 316 letter->setStyle(pseudoStyle);
309 layoutObject()->addChild(letter); 317 layoutObject()->addChild(letter);
310 318
311 nextLayoutObject->destroy(); 319 nextLayoutObject->destroy();
312 } 320 }
313 321
314 void FirstLetterPseudoElement::didRecalcStyle(StyleRecalcChange) { 322 void FirstLetterPseudoElement::didRecalcStyle(StyleRecalcChange) {
315 if (!layoutObject()) 323 if (!layoutObject())
316 return; 324 return;
317 325
318 // The layoutObjects inside pseudo elements are anonymous so they don't get no tified of recalcStyle and must have 326 // The layoutObjects inside pseudo elements are anonymous so they don't get
319 // the style propagated downward manually similar to LayoutObject::propagateSt yleToAnonymousChildren. 327 // notified of recalcStyle and must have
328 // the style propagated downward manually similar to
329 // LayoutObject::propagateStyleToAnonymousChildren.
320 LayoutObject* layoutObject = this->layoutObject(); 330 LayoutObject* layoutObject = this->layoutObject();
321 for (LayoutObject* child = layoutObject->nextInPreOrder(layoutObject); child; 331 for (LayoutObject* child = layoutObject->nextInPreOrder(layoutObject); child;
322 child = child->nextInPreOrder(layoutObject)) { 332 child = child->nextInPreOrder(layoutObject)) {
323 // We need to re-calculate the correct style for the first letter element 333 // We need to re-calculate the correct style for the first letter element
324 // and then apply that to the container and the text fragment inside. 334 // and then apply that to the container and the text fragment inside.
325 if (child->style()->styleType() == PseudoIdFirstLetter && 335 if (child->style()->styleType() == PseudoIdFirstLetter &&
326 m_remainingTextLayoutObject) { 336 m_remainingTextLayoutObject) {
327 if (ComputedStyle* pseudoStyle = 337 if (ComputedStyle* pseudoStyle =
328 styleForFirstLetter(m_remainingTextLayoutObject->parent())) 338 styleForFirstLetter(m_remainingTextLayoutObject->parent()))
329 child->setPseudoStyle(pseudoStyle); 339 child->setPseudoStyle(pseudoStyle);
330 continue; 340 continue;
331 } 341 }
332 342
333 // We only manage the style for the generated content items. 343 // We only manage the style for the generated content items.
334 if (!child->isText() && !child->isQuote() && !child->isImage()) 344 if (!child->isText() && !child->isQuote() && !child->isImage())
335 continue; 345 continue;
336 346
337 child->setPseudoStyle(layoutObject->mutableStyle()); 347 child->setPseudoStyle(layoutObject->mutableStyle());
338 } 348 }
339 } 349 }
340 350
341 } // namespace blink 351 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698