- Revision
- 137738
- Author
- [email protected]
- Date
- 2012-12-14 03:58:39 -0800 (Fri, 14 Dec 2012)
Log Message
Text Autosizing: Don't autosize unwrappable blocks
https://bugs.webkit.org/show_bug.cgi?id=104925
Patch by John Mellor <[email protected]> on 2012-12-14
Reviewed by Julien Chaffraix.
Source/WebCore:
If we autosize an unwrappable block (white-space:nowrap/pre), it'll
expand sideways. This doesn't actually improve its legibility, and it
can often severely break web page layouts. This patch prevents us from
autosizing unwrappable blocks. A follow-up patch will address the more
complex issue of unwrappable inline elements.
Tests: fast/text-autosizing/unwrappable-blocks.html
fast/text-autosizing/unwrappable-inlines.html
* rendering/TextAutosizer.cpp:
(WebCore::TextAutosizer::processContainer):
Use containerShouldbeAutosized instead of contentHeightIsConstrained.
(WebCore::contentHeightIsConstrained):
Unchanged, just moved lower down the file.
(WebCore::TextAutosizer::containerShouldbeAutosized):
Checks that the block is wrappable, and also that contentHeightIsConstrained is false.
(WebCore::TextAutosizer::measureDescendantTextWidth):
Use containerShouldbeAutosized instead of contentHeightIsConstrained.
* rendering/TextAutosizer.h:
Declared containerShouldbeAutosized.
LayoutTests:
Added tests verifying that this prevents unwrappable blocks from being
autosized, and that this has no effect on unwrappable inlines.
* fast/text-autosizing/unwrappable-blocks-expected.html: Added.
* fast/text-autosizing/unwrappable-blocks.html: Added.
* fast/text-autosizing/unwrappable-inlines-expected.html: Added.
* fast/text-autosizing/unwrappable-inlines.html: Added.
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (137737 => 137738)
--- trunk/LayoutTests/ChangeLog 2012-12-14 11:16:05 UTC (rev 137737)
+++ trunk/LayoutTests/ChangeLog 2012-12-14 11:58:39 UTC (rev 137738)
@@ -1,3 +1,18 @@
+2012-12-14 John Mellor <[email protected]>
+
+ Text Autosizing: Don't autosize unwrappable blocks
+ https://bugs.webkit.org/show_bug.cgi?id=104925
+
+ Reviewed by Julien Chaffraix.
+
+ Added tests verifying that this prevents unwrappable blocks from being
+ autosized, and that this has no effect on unwrappable inlines.
+
+ * fast/text-autosizing/unwrappable-blocks-expected.html: Added.
+ * fast/text-autosizing/unwrappable-blocks.html: Added.
+ * fast/text-autosizing/unwrappable-inlines-expected.html: Added.
+ * fast/text-autosizing/unwrappable-inlines.html: Added.
+
2012-12-14 Kentaro Hara <[email protected]>
Remove an exception message from insertedIntoDocument-no-crash-expected.txt
Added: trunk/LayoutTests/fast/text-autosizing/unwrappable-blocks-expected.html (0 => 137738)
--- trunk/LayoutTests/fast/text-autosizing/unwrappable-blocks-expected.html (rev 0)
+++ trunk/LayoutTests/fast/text-autosizing/unwrappable-blocks-expected.html 2012-12-14 11:58:39 UTC (rev 137738)
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+<head>
+
+<meta name="viewport" content="width=800">
+<style>
+html { font-size: 16px; }
+body { width: 800px; margin: 0; }
+pre { margin: 0; }
+</style>
+
+</head>
+<body>
+
+<pre>
+ This text should not be autosized, as <pre> elements have white-space:pre which cannot be wrapped.<br>
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+</pre>
+
+<div style="white-space: nowrap">
+ This text should not be autosized, as it has white-space:nowrap which cannot be wrapped.<br>
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+</div>
+
+<pre style="white-space: pre-wrap; font-size: 2.5rem">
+ This text should be autosized to 40px computed font-size (16 * 800/320) since it has white-space:pre-wrap which allows text wrapping (even though it doesn't collapse white space).
+</pre>
+
+<div style="font-size: 2.5rem">
+ This text should be autosized to 40px computed font-size (16 * 800/320).
+</div>
+
+</body>
+</html>
Added: trunk/LayoutTests/fast/text-autosizing/unwrappable-blocks.html (0 => 137738)
--- trunk/LayoutTests/fast/text-autosizing/unwrappable-blocks.html (rev 0)
+++ trunk/LayoutTests/fast/text-autosizing/unwrappable-blocks.html 2012-12-14 11:58:39 UTC (rev 137738)
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+<head>
+
+<meta name="viewport" content="width=800">
+<style>
+html { font-size: 16px; }
+body { width: 800px; margin: 0; }
+pre { margin: 0; }
+</style>
+
+<script>
+if (window.internals) {
+ window.internals.settings.setTextAutosizingEnabled(true);
+ window.internals.settings.setTextAutosizingWindowSizeOverride(320, 480);
+} else if (window.console && console.warn) {
+ console.warn("This test depends on the Text Autosizing setting being true, so run it in DumpRenderTree, or manually enable Text Autosizing, and either use a mobile device with 320px device-width (like Nexus S or iPhone), or define HACK_FORCE_TEXT_AUTOSIZING_ON_DESKTOP.");
+}
+</script>
+
+</head>
+<body>
+
+<pre>
+ This text should not be autosized, as <pre> elements have white-space:pre which cannot be wrapped.<br>
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+</pre>
+
+<div style="white-space: nowrap">
+ This text should not be autosized, as it has white-space:nowrap which cannot be wrapped.<br>
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+</div>
+
+<pre style="white-space: pre-wrap">
+ This text should be autosized to 40px computed font-size (16 * 800/320) since it has white-space:pre-wrap which allows text wrapping (even though it doesn't collapse white space).
+</pre>
+
+<div>
+ This text should be autosized to 40px computed font-size (16 * 800/320).
+</div>
+
+</body>
+</html>
Added: trunk/LayoutTests/fast/text-autosizing/unwrappable-inlines-expected.html (0 => 137738)
--- trunk/LayoutTests/fast/text-autosizing/unwrappable-inlines-expected.html (rev 0)
+++ trunk/LayoutTests/fast/text-autosizing/unwrappable-inlines-expected.html 2012-12-14 11:58:39 UTC (rev 137738)
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+<head>
+
+<meta name="viewport" content="width=800">
+<style>
+html { font-size: 16px; }
+body { width: 800px; margin: 0; }
+pre { margin: 0; }
+</style>
+
+</head>
+<body>
+
+<div>
+<span style="white-space: pre; font-size: 2.5rem">
+ This text is expected be autosized to 40px computed font-size (16 * 800/320), since Text Autosizing is not yet smart enough to detect that all the children of this div are unwrappable. Ideally it would not get autosized.
+</span>
+</div>
+
+<div>
+<span style="white-space: nowrap; font-size: 2.5rem">
+ This text is expected be autosized to 40px computed font-size (16 * 800/320), since Text Autosizing is not yet smart enough to detect that all the children of this div are unwrappable. Ideally it would not get autosized.
+</span>
+</div>
+
+<div>
+<span style="white-space: pre-wrap; font-size: 2.5rem">
+ This text should be autosized to 40px computed font-size (16 * 800/320) since it has white-space:pre-wrap which allows text wrapping (even though it doesn't collapse white space).
+</span>
+</div>
+
+<div>
+<span style="font-size: 2.5rem">
+ This text should be autosized to 40px computed font-size (16 * 800/320).
+</span>
+</div>
+
+</body>
+</html>
Added: trunk/LayoutTests/fast/text-autosizing/unwrappable-inlines.html (0 => 137738)
--- trunk/LayoutTests/fast/text-autosizing/unwrappable-inlines.html (rev 0)
+++ trunk/LayoutTests/fast/text-autosizing/unwrappable-inlines.html 2012-12-14 11:58:39 UTC (rev 137738)
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html>
+<head>
+
+<meta name="viewport" content="width=800">
+<style>
+html { font-size: 16px; }
+body { width: 800px; margin: 0; }
+pre { margin: 0; }
+</style>
+
+<script>
+if (window.internals) {
+ window.internals.settings.setTextAutosizingEnabled(true);
+ window.internals.settings.setTextAutosizingWindowSizeOverride(320, 480);
+} else if (window.console && console.warn) {
+ console.warn("This test depends on the Text Autosizing setting being true, so run it in DumpRenderTree, or manually enable Text Autosizing, and either use a mobile device with 320px device-width (like Nexus S or iPhone), or define HACK_FORCE_TEXT_AUTOSIZING_ON_DESKTOP.");
+}
+</script>
+
+</head>
+<body>
+
+<div>
+<span style="white-space: pre">
+ This text is expected be autosized to 40px computed font-size (16 * 800/320), since Text Autosizing is not yet smart enough to detect that all the children of this div are unwrappable. Ideally it would not get autosized.
+</span>
+</div>
+
+<div>
+<span style="white-space: nowrap">
+ This text is expected be autosized to 40px computed font-size (16 * 800/320), since Text Autosizing is not yet smart enough to detect that all the children of this div are unwrappable. Ideally it would not get autosized.
+</span>
+</div>
+
+<div>
+<span style="white-space: pre-wrap">
+ This text should be autosized to 40px computed font-size (16 * 800/320) since it has white-space:pre-wrap which allows text wrapping (even though it doesn't collapse white space).
+</span>
+</div>
+
+<div>
+<span>
+ This text should be autosized to 40px computed font-size (16 * 800/320).
+</span>
+</div>
+
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (137737 => 137738)
--- trunk/Source/WebCore/ChangeLog 2012-12-14 11:16:05 UTC (rev 137737)
+++ trunk/Source/WebCore/ChangeLog 2012-12-14 11:58:39 UTC (rev 137738)
@@ -1,3 +1,31 @@
+2012-12-14 John Mellor <[email protected]>
+
+ Text Autosizing: Don't autosize unwrappable blocks
+ https://bugs.webkit.org/show_bug.cgi?id=104925
+
+ Reviewed by Julien Chaffraix.
+
+ If we autosize an unwrappable block (white-space:nowrap/pre), it'll
+ expand sideways. This doesn't actually improve its legibility, and it
+ can often severely break web page layouts. This patch prevents us from
+ autosizing unwrappable blocks. A follow-up patch will address the more
+ complex issue of unwrappable inline elements.
+
+ Tests: fast/text-autosizing/unwrappable-blocks.html
+ fast/text-autosizing/unwrappable-inlines.html
+
+ * rendering/TextAutosizer.cpp:
+ (WebCore::TextAutosizer::processContainer):
+ Use containerShouldbeAutosized instead of contentHeightIsConstrained.
+ (WebCore::contentHeightIsConstrained):
+ Unchanged, just moved lower down the file.
+ (WebCore::TextAutosizer::containerShouldbeAutosized):
+ Checks that the block is wrappable, and also that contentHeightIsConstrained is false.
+ (WebCore::TextAutosizer::measureDescendantTextWidth):
+ Use containerShouldbeAutosized instead of contentHeightIsConstrained.
+ * rendering/TextAutosizer.h:
+ Declared containerShouldbeAutosized.
+
2012-12-14 Vsevolod Vlasov <[email protected]>
Web Inspector: Duplicate scripts appear in workspace when script was referenced by url with a fragment part.
Modified: trunk/Source/WebCore/rendering/TextAutosizer.cpp (137737 => 137738)
--- trunk/Source/WebCore/rendering/TextAutosizer.cpp 2012-12-14 11:16:05 UTC (rev 137737)
+++ trunk/Source/WebCore/rendering/TextAutosizer.cpp 2012-12-14 11:58:39 UTC (rev 137738)
@@ -119,31 +119,11 @@
processContainer(multiplier, container, subtreeRoot, windowInfo);
}
-static bool contentHeightIsConstrained(const RenderBlock* container)
-{
- // FIXME: Propagate constrainedness down the tree, to avoid inefficiently walking back up from each box.
- // FIXME: This code needs to take into account vertical writing modes.
- // FIXME: Consider additional heuristics, such as ignoring fixed heights if the content is already overflowing before autosizing kicks in.
- for (; container; container = container->containingBlock()) {
- RenderStyle* style = container->style();
- if (style->overflowY() >= OSCROLL)
- return false;
- if (style->height().isSpecified() || style->maxHeight().isSpecified()) {
- // Some sites (e.g. wikipedia) set their html and/or body elements to height:100%,
- // without intending to constrain the height of the content within them.
- return !container->isRoot() && !container->isBody();
- }
- if (container->isFloatingOrOutOfFlowPositioned())
- return false;
- }
- return false;
-}
-
void TextAutosizer::processContainer(float multiplier, RenderBlock* container, RenderObject* subtreeRoot, const TextAutosizingWindowInfo& windowInfo)
{
ASSERT(isAutosizingContainer(container));
- float localMultiplier = contentHeightIsConstrained(container) ? 1 : multiplier;
+ float localMultiplier = containerShouldbeAutosized(container) ? multiplier: 1;
RenderObject* descendant = nextInPreOrderSkippingDescendantsOfContainers(subtreeRoot, subtreeRoot);
while (descendant) {
@@ -250,6 +230,36 @@
// renderers, and probably flexboxes...
}
+static bool contentHeightIsConstrained(const RenderBlock* container)
+{
+ // FIXME: Propagate constrainedness down the tree, to avoid inefficiently walking back up from each box.
+ // FIXME: This code needs to take into account vertical writing modes.
+ // FIXME: Consider additional heuristics, such as ignoring fixed heights if the content is already overflowing before autosizing kicks in.
+ for (; container; container = container->containingBlock()) {
+ RenderStyle* style = container->style();
+ if (style->overflowY() >= OSCROLL)
+ return false;
+ if (style->height().isSpecified() || style->maxHeight().isSpecified()) {
+ // Some sites (e.g. wikipedia) set their html and/or body elements to height:100%,
+ // without intending to constrain the height of the content within them.
+ return !container->isRoot() && !container->isBody();
+ }
+ if (container->isFloatingOrOutOfFlowPositioned())
+ return false;
+ }
+ return false;
+}
+
+bool TextAutosizer::containerShouldbeAutosized(const RenderBlock* container)
+{
+ // Don't autosize block-level text that can't wrap (as it's likely to
+ // expand sideways and break the page's layout).
+ if (!container->style()->autoWrap())
+ return false;
+
+ return !contentHeightIsConstrained(container);
+}
+
bool TextAutosizer::clusterShouldBeAutosized(const RenderBlock* lowestCommonAncestor, float commonAncestorWidth)
{
// Don't autosize clusters that contain less than 4 lines of text (in
@@ -273,7 +283,7 @@
void TextAutosizer::measureDescendantTextWidth(const RenderBlock* container, float minTextWidth, float& textWidth)
{
- bool skipLocalText = contentHeightIsConstrained(container);
+ bool skipLocalText = !containerShouldbeAutosized(container);
RenderObject* descendant = nextInPreOrderSkippingDescendantsOfContainers(container, container);
while (descendant) {
Modified: trunk/Source/WebCore/rendering/TextAutosizer.h (137737 => 137738)
--- trunk/Source/WebCore/rendering/TextAutosizer.h 2012-12-14 11:16:05 UTC (rev 137737)
+++ trunk/Source/WebCore/rendering/TextAutosizer.h 2012-12-14 11:58:39 UTC (rev 137738)
@@ -70,6 +70,7 @@
static bool isAutosizingContainer(const RenderObject*);
static bool isAutosizingCluster(const RenderBlock*);
+ static bool containerShouldbeAutosized(const RenderBlock* container);
static bool clusterShouldBeAutosized(const RenderBlock* lowestCommonAncestor, float commonAncestorWidth);
static void measureDescendantTextWidth(const RenderBlock* container, float minTextWidth, float& textWidth);