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

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

Issue 2719713002: Simplify whitespace layout object creation.
Patch Set: Created 3 years, 10 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 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights 4 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights
5 * reserved. 5 * reserved.
6 * 6 *
7 * This library is free software; you can redistribute it and/or 7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public 8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version. 10 * version 2 of the License, or (at your option) any later version.
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 245
246 if (parent.isTable() || parent.isTableRow() || parent.isTableSection() || 246 if (parent.isTable() || parent.isTableRow() || parent.isTableSection() ||
247 parent.isLayoutTableCol() || parent.isFrameSet() || 247 parent.isLayoutTableCol() || parent.isFrameSet() ||
248 parent.isFlexibleBox() || parent.isLayoutGrid() || parent.isSVGRoot() || 248 parent.isFlexibleBox() || parent.isLayoutGrid() || parent.isSVGRoot() ||
249 parent.isSVGContainer() || parent.isSVGImage() || parent.isSVGShape()) { 249 parent.isSVGContainer() || parent.isSVGImage() || parent.isSVGShape()) {
250 return false; 250 return false;
251 } 251 }
252 return true; 252 return true;
253 } 253 }
254 254
255 static inline bool emptyOrEndsWithWhitespace(const WTF::String& string) {
256 unsigned len = string.length();
257 return !len || isASCIISpace(string[len - 1]);
258 }
259
255 bool Text::textLayoutObjectIsNeeded(const ComputedStyle& style, 260 bool Text::textLayoutObjectIsNeeded(const ComputedStyle& style,
256 const LayoutObject& parent) const { 261 const LayoutObject& parent) const {
257 DCHECK(!document().childNeedsDistributionRecalc()); 262 DCHECK(!document().childNeedsDistributionRecalc());
258 263
259 if (!parent.canHaveChildren()) 264 if (!parent.canHaveChildren())
260 return false; 265 return false;
261 266
262 if (isEditingText()) 267 if (isEditingText())
263 return true; 268 return true;
264 269
(...skipping 13 matching lines...) Expand all
278 if (style.whiteSpace() == EWhiteSpace::kPreWrap && parent.isSVG()) 283 if (style.whiteSpace() == EWhiteSpace::kPreWrap && parent.isSVG())
279 return false; 284 return false;
280 285
281 // pre/pre-wrap/pre-line always make layoutObjects. 286 // pre/pre-wrap/pre-line always make layoutObjects.
282 if (style.preserveNewline()) 287 if (style.preserveNewline())
283 return true; 288 return true;
284 289
285 // Avoiding creation of a layoutObject for the text node is a non-essential 290 // Avoiding creation of a layoutObject for the text node is a non-essential
286 // memory optimization. So to avoid blowing up on very wide DOMs, we limit 291 // memory optimization. So to avoid blowing up on very wide DOMs, we limit
287 // the number of siblings to visit. 292 // the number of siblings to visit.
288 unsigned maxSiblingsToVisit = 50; 293 uint32_t maxSiblingsToVisit = 50;
rune 2017/02/27 10:38:06 Looks unnecessary to have a size-specific (32-bit)
289 294 bool ranOutOfSiblings = false;
290 const LayoutObject* prev = 295 const LayoutObject* prev =
291 LayoutTreeBuilderTraversal::previousSiblingLayoutObject( 296 LayoutTreeBuilderTraversal::previousSiblingLayoutObject(
292 *this, maxSiblingsToVisit); 297 *this, maxSiblingsToVisit, &ranOutOfSiblings);
rune 2017/02/27 10:38:06 Can't you send maxSiblingsToVisit as a non-const r
emilio 2017/02/27 12:09:32 That's right. I can, but that'd be somewhat annoyi
293 if (prev && prev->isBR()) // <span><br/> <br/></span> 298
299 while (prev && prev->isFloatingOrOutOfFlowPositioned() &&
300 --maxSiblingsToVisit) {
301 prev = prev->previousSibling();
302 }
303
304 // If we give up due to too many siblings, just create a layout object.
305 if (ranOutOfSiblings || !maxSiblingsToVisit)
306 return true;
307
308 // Collapse whitespace away if we find previous whitespace.
309 if (prev && prev->isText() &&
310 emptyOrEndsWithWhitespace(toLayoutText(prev)->text())) {
rune 2017/02/27 10:38:06 Is checking the previous layout object for white-s
emilio 2017/02/27 12:09:32 Not totally sure about this, but it's likely. Actu
311 return false;
312 }
313
314 // Whitespace after a non-inline is useless.
315 if (prev && !prev->isInline())
294 return false; 316 return false;
295 317
296 if (parent.isLayoutInline()) { 318 // So it is after a <br>
297 // <span><div/> <div/></span> 319 if (prev && prev->isBR())
298 if (prev && !prev->isInline() && !prev->isOutOfFlowPositioned()) 320 return false;
299 return false;
300 } else {
301 if (parent.isLayoutBlock() && !parent.childrenInline() &&
302 (!prev || !prev->isInline()))
303 return false;
304 321
305 LayoutObject* first = parent.slowFirstChild(); 322 // It may matter if we're in an inline and we haven't proven otherwise though.
306 for (; first && first->isFloatingOrOutOfFlowPositioned() && 323 if (parent.isLayoutInline())
307 maxSiblingsToVisit; 324 return true;
308 first = first->nextSibling(), --maxSiblingsToVisit) {
309 }
310 if (!first || first == layoutObject() ||
311 LayoutTreeBuilderTraversal::nextSiblingLayoutObject(
312 *this, maxSiblingsToVisit) == first) {
313 // If we're adding children to this flow our previous siblings are not in
314 // the layout tree yet so we cannot know if we will be the first child in
315 // the line and collapse away. We have to assume we need a layout object.
316 Node* firstChildNode =
317 parent.node() ? LayoutTreeBuilderTraversal::firstChild(*parent.node())
318 : nullptr;
319 if (first && first == layoutObject() && firstChildNode &&
320 !firstChildNode->layoutObject())
321 return true;
322 325
323 // Whitespace at the start of a block just goes away. Don't even 326 // Whitespace at the start of a block just goes away.
324 // make a layout object for this text. 327 return !!prev;
rune 2017/02/27 10:38:06 We still re-attach right-to-left? That means we'll
emilio 2017/02/27 12:09:32 Yes, I believe that's right. I don't think it matt
325 return !firstChildNode;
326 }
327 }
328 return true;
329 } 328 }
330 329
331 static bool isSVGText(Text* text) { 330 static bool isSVGText(Text* text) {
332 Node* parentOrShadowHostNode = text->parentOrShadowHostNode(); 331 Node* parentOrShadowHostNode = text->parentOrShadowHostNode();
333 DCHECK(parentOrShadowHostNode); 332 DCHECK(parentOrShadowHostNode);
334 return parentOrShadowHostNode->isSVGElement() && 333 return parentOrShadowHostNode->isSVGElement() &&
335 !isSVGForeignObjectElement(*parentOrShadowHostNode); 334 !isSVGForeignObjectElement(*parentOrShadowHostNode);
336 } 335 }
337 336
338 LayoutText* Text::createTextLayoutObject(const ComputedStyle& style) { 337 LayoutText* Text::createTextLayoutObject(const ComputedStyle& style) {
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 466
468 Text* Text::cloneWithData(const String& data) { 467 Text* Text::cloneWithData(const String& data) {
469 return create(document(), data); 468 return create(document(), data);
470 } 469 }
471 470
472 DEFINE_TRACE(Text) { 471 DEFINE_TRACE(Text) {
473 CharacterData::trace(visitor); 472 CharacterData::trace(visitor);
474 } 473 }
475 474
476 } // namespace blink 475 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698