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

Side by Side Diff: Source/core/rendering/TextAutosizer.cpp

Issue 14146029: Fix textarea font autosizing oscillation when the number of lines exceeds 4. The proposed fix is no… (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: autosize textareas by default Created 7 years, 8 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) 2012 Google Inc. All rights reserved. 2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 * Copyright (C) 2012 Apple Inc. All rights reserved. 3 * Copyright (C) 2012 Apple Inc. All rights reserved.
4 * 4 *
5 * This library is free software; you can redistribute it and/or 5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public 6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either 7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version. 8 * version 2 of the License, or (at your option) any later version.
9 * 9 *
10 * This library is distributed in the hope that it will be useful, 10 * This library is distributed in the hope that it will be useful,
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 // the same amount even if they're different widths; so do hasColumns() 357 // the same amount even if they're different widths; so do hasColumns()
358 // containers, and probably flexboxes... 358 // containers, and probably flexboxes...
359 } 359 }
360 360
361 bool TextAutosizer::isAutosizingCluster(const RenderBlock* renderer, TextAutosiz ingClusterInfo& parentClusterInfo) 361 bool TextAutosizer::isAutosizingCluster(const RenderBlock* renderer, TextAutosiz ingClusterInfo& parentClusterInfo)
362 { 362 {
363 ASSERT(isAutosizingContainer(renderer)); 363 ASSERT(isAutosizingContainer(renderer));
364 364
365 return isNarrowDescendant(renderer, parentClusterInfo) 365 return isNarrowDescendant(renderer, parentClusterInfo)
366 || isWiderDescendant(renderer, parentClusterInfo) 366 || isWiderDescendant(renderer, parentClusterInfo)
367 || isIndependentDescendant(renderer); 367 || isIndependentDescendant(renderer)
368 || containerIsTextArea(renderer);
johnme 2013/04/29 11:11:26 Please add this as a condition in isIndependentDes
timvolodine 2013/04/29 17:59:13 Done.
368 } 369 }
369 370
370 bool TextAutosizer::containerShouldBeAutosized(const RenderBlock* container) 371 bool TextAutosizer::containerShouldBeAutosized(const RenderBlock* container)
371 { 372 {
372 if (containerContainsOneOfTags(container, formInputTags())) 373 if (containerContainsOneOfTags(container, formInputTags()))
373 return false; 374 return false;
374 375
375 if (containerIsRowOfLinks(container)) 376 if (containerIsRowOfLinks(container))
376 return false; 377 return false;
377 378
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 linkCount++; 432 linkCount++;
432 // Skip traversing descendants of the link. 433 // Skip traversing descendants of the link.
433 renderer = renderer->nextInPreOrderAfterChildren(container); 434 renderer = renderer->nextInPreOrderAfterChildren(container);
434 } else 435 } else
435 renderer = nextInPreOrderSkippingDescendantsOfContainers(renderer, c ontainer); 436 renderer = nextInPreOrderSkippingDescendantsOfContainers(renderer, c ontainer);
436 } 437 }
437 438
438 return (linkCount >= 3); 439 return (linkCount >= 3);
439 } 440 }
440 441
442 bool TextAutosizer::containerIsTextArea(const RenderBlock* container)
johnme 2013/04/29 11:11:26 Nit: This method is so simple, that you might as w
timvolodine 2013/04/29 17:59:13 Done.
443 {
444 return container->isTextArea();
445 }
446
441 bool TextAutosizer::contentHeightIsConstrained(const RenderBlock* container) 447 bool TextAutosizer::contentHeightIsConstrained(const RenderBlock* container)
442 { 448 {
443 // FIXME: Propagate constrainedness down the tree, to avoid inefficiently wa lking back up from each box. 449 // FIXME: Propagate constrainedness down the tree, to avoid inefficiently wa lking back up from each box.
444 // FIXME: This code needs to take into account vertical writing modes. 450 // FIXME: This code needs to take into account vertical writing modes.
445 // FIXME: Consider additional heuristics, such as ignoring fixed heights if the content is already overflowing before autosizing kicks in. 451 // FIXME: Consider additional heuristics, such as ignoring fixed heights if the content is already overflowing before autosizing kicks in.
446 for (; container; container = container->containingBlock()) { 452 for (; container; container = container->containingBlock()) {
447 RenderStyle* style = container->style(); 453 RenderStyle* style = container->style();
448 if (style->overflowY() >= OSCROLL) 454 if (style->overflowY() >= OSCROLL)
449 return false; 455 return false;
450 if (style->height().isSpecified() || style->maxHeight().isSpecified()) { 456 if (style->height().isSpecified() || style->maxHeight().isSpecified()) {
(...skipping 18 matching lines...) Expand all
469 // Don't autosize clusters that contain less than 4 lines of text (in 475 // Don't autosize clusters that contain less than 4 lines of text (in
470 // practice less lines are required, since measureDescendantTextWidth 476 // practice less lines are required, since measureDescendantTextWidth
471 // assumes that characters are 1em wide, but most characters are narrower 477 // assumes that characters are 1em wide, but most characters are narrower
472 // than that, so we're overestimating their contribution to the linecount). 478 // than that, so we're overestimating their contribution to the linecount).
473 // 479 //
474 // This is to reduce the likelihood of autosizing things like headers and 480 // This is to reduce the likelihood of autosizing things like headers and
475 // footers, which can be quite visually distracting. The rationale is that 481 // footers, which can be quite visually distracting. The rationale is that
476 // if a cluster contains very few lines of text then it's ok to have to zoom 482 // if a cluster contains very few lines of text then it's ok to have to zoom
477 // in and pan from side to side to read each line, since if there are very 483 // in and pan from side to side to read each line, since if there are very
478 // few lines of text you'll only need to pan across once or twice. 484 // few lines of text you'll only need to pan across once or twice.
485 //
486 // An exception to the 4 lines of text are the textarea clusters, which are
487 // always autosized by default (i.e. threated as if they contain more than 4
488 // lines of text). This is to ensure that the text does not suddenly gets
johnme 2013/04/29 11:11:26 Nit: s/gets/get/
timvolodine 2013/04/29 17:59:13 Done.
489 // autosized when the user enters more than 4 lines of text.
479 float totalTextWidth = 0; 490 float totalTextWidth = 0;
480 const float minLinesOfText = 4; 491 const float minLinesOfText = 4;
481 float minTextWidth = blockWidth * minLinesOfText; 492 float minTextWidth = blockWidth * minLinesOfText;
482 for (size_t i = 0; i < clusterInfos.size(); ++i) { 493 for (size_t i = 0; i < clusterInfos.size(); ++i) {
483 measureDescendantTextWidth(clusterInfos[i].blockContainingAllText, clust erInfos[i], minTextWidth, totalTextWidth); 494 measureDescendantTextWidth(clusterInfos[i].blockContainingAllText, clust erInfos[i], minTextWidth, totalTextWidth);
484 if (totalTextWidth >= minTextWidth) 495 if (totalTextWidth >= minTextWidth)
485 return true; 496 return true;
497 if (containerIsTextArea(clusterInfos[i].root))
johnme 2013/04/29 11:11:26 Nit: would be nice to move this check to the start
timvolodine 2013/04/29 17:59:13 Done.
498 return true;
486 } 499 }
487 return false; 500 return false;
488 } 501 }
489 502
490 void TextAutosizer::measureDescendantTextWidth(const RenderBlock* container, Tex tAutosizingClusterInfo& clusterInfo, float minTextWidth, float& textWidth) 503 void TextAutosizer::measureDescendantTextWidth(const RenderBlock* container, Tex tAutosizingClusterInfo& clusterInfo, float minTextWidth, float& textWidth)
491 { 504 {
492 bool skipLocalText = !containerShouldBeAutosized(container); 505 bool skipLocalText = !containerShouldBeAutosized(container);
493 506
494 RenderObject* descendant = nextInPreOrderSkippingDescendantsOfContainers(con tainer, container); 507 RenderObject* descendant = nextInPreOrderSkippingDescendantsOfContainers(con tainer, container);
495 while (descendant) { 508 while (descendant) {
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
606 if (i + 1 < clusterInfos.size()) { 619 if (i + 1 < clusterInfos.size()) {
607 float currentWidth = clusterInfos[i].root->contentLogicalWidth(); 620 float currentWidth = clusterInfos[i].root->contentLogicalWidth();
608 float nextWidth = clusterInfos[i + 1].root->contentLogicalWidth(); 621 float nextWidth = clusterInfos[i + 1].root->contentLogicalWidth();
609 if (currentWidth - nextWidth > maxWidthDifferenceWithinGroup) 622 if (currentWidth - nextWidth > maxWidthDifferenceWithinGroup)
610 groups.grow(groups.size() + 1); 623 groups.grow(groups.size() + 1);
611 } 624 }
612 } 625 }
613 } 626 }
614 627
615 } // namespace WebCore 628 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698