Commit d30055a8 authored by robert@webkit.org's avatar robert@webkit.org

Positioned Replaced Elements That Aren't RenderReplaced get Incorrect Width

https://bugs.webkit.org/show_bug.cgi?id=93735

Reviewed by Darin Adler.

Source/WebCore:

Replaced elements that aren't RenderReplaced aren't |isReplaced| and don't have an
intrinsic height or width. This causes them to go down the wrong height and width computation
path in RenderBox when they are absolute positioned.

The notion of |isReplaced| is entwined with the notion of being |isInline| so it isn't really
possible to make them isReplaced without re-wiring a lot of code. So instead use an ad-hoc definition
of isReplacedElement in RenderBox to bring all replaced elements into the height and width calculation.
To make sure we get the right height and width in there, give non-RenderReplaced replaced renderers
the helpers for returning their approximation of intrinsic height and width.

Test: fast/replaced/width-and-height-of-positioned-replaced-elements.html

* rendering/RenderBox.cpp:
(WebCore::isReplacedElement):
(WebCore::RenderBox::computePositionedLogicalWidth):
(WebCore::RenderBox::computePositionedLogicalHeight):
* rendering/RenderBox.h:
(WebCore::RenderBox::intrinsicSize):
* rendering/RenderButton.h:
* rendering/RenderListBox.cpp:
(WebCore::RenderListBox::RenderListBox):
(WebCore::RenderListBox::computeLogicalHeight):
* rendering/RenderListBox.h:
* rendering/RenderMenuList.h:
* rendering/RenderReplaced.h:
* rendering/RenderTextControl.cpp:
(WebCore::RenderTextControl::RenderTextControl):
(WebCore::RenderTextControl::computeLogicalHeight):
* rendering/RenderTextControl.h:

LayoutTests:

* fast/forms/onselect-textfield-expected.txt:
* fast/replaced/width-and-height-of-positioned-replaced-elements-expected.png: Added.
* fast/replaced/width-and-height-of-positioned-replaced-elements-expected.txt: Added.
* fast/replaced/width-and-height-of-positioned-replaced-elements.html: Added.
* platform/mac-wk2/fast/replaced/width-and-height-of-positioned-replaced-elements-expected.txt: Added.
* platform/mac/fast/forms/button-positioned-expected.txt:
* platform/mac/fast/forms/input-appearance-preventDefault-expected.txt:
* platform/mac/fast/replaced/width-and-height-of-positioned-replaced-elements-expected.txt: Added.
* platform/qt/fast/forms/button-positioned-expected.txt:
* platform/qt/fast/forms/input-appearance-preventDefault-expected.txt:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@151451 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 4a7ad145
2013-05-27 Robert Hogan <robert@webkit.org>
Positioned Replaced Elements That Aren't RenderReplaced get Incorrect Width
https://bugs.webkit.org/show_bug.cgi?id=93735
Reviewed by Darin Adler.
* fast/forms/onselect-textfield-expected.txt:
* fast/replaced/width-and-height-of-positioned-replaced-elements-expected.png: Added.
* fast/replaced/width-and-height-of-positioned-replaced-elements-expected.txt: Added.
* fast/replaced/width-and-height-of-positioned-replaced-elements.html: Added.
* platform/mac-wk2/fast/replaced/width-and-height-of-positioned-replaced-elements-expected.txt: Added.
* platform/mac/fast/forms/button-positioned-expected.txt:
* platform/mac/fast/forms/input-appearance-preventDefault-expected.txt:
* platform/mac/fast/replaced/width-and-height-of-positioned-replaced-elements-expected.txt: Added.
* platform/qt/fast/forms/button-positioned-expected.txt:
* platform/qt/fast/forms/input-appearance-preventDefault-expected.txt:
2013-06-11 Robert Hogan <robert@webkit.org>
Add baselines for test added in r151444
......
......@@ -9,11 +9,11 @@ After setSelectionRange(3, 5): text field selection start: 3 end: 5
Double clicking to make selection for text field
onselect fired for text field
After double clicking: text field selection start: 6 end: 10
After double clicking: text field selection start: 0 end: 5
Calling blur on text field
After blur: text field selection start: 6 end: 10
After blur: text field selection start: 0 end: 5
Calling focus on text field
After focus: text field selection start: 6 end: 10
After focus: text field selection start: 0 end: 5
layer at (0,0) size 800x600
RenderView at (0,0) size 800x600
layer at (0,0) size 800x51
RenderBlock {HTML} at (0,0) size 800x51
RenderBody {BODY} at (8,16) size 784x19
RenderBlock {P} at (0,0) size 784x19
RenderText {#text} at (0,0) size 581x19
text run at (0,0) width 581: "webkit.org/b/93735: Use the replaced height and width computation for positioned form controls"
layer at (7,32) size 408x28
RenderTextControl {INPUT} at (7,32) size 408x28
layer at (9,36) size 404x20
RenderBlock {DIV} at (2,4) size 404x20
layer at (7,82) size 56x34
RenderButton {INPUT} at (7,82) size 56x34 [bgcolor=#C0C0C0]
RenderBlock (anonymous) at (6,6) size 44x24
RenderText at (6,0) size 32x24
text run at (6,0) width 32: "text"
layer at (7,132) size 136x28
RenderMenuList {SELECT} at (7,132) size 136x28 [bgcolor=#FFFFFF]
RenderBlock (anonymous) at (4,4) size 108x20
RenderText at (0,0) size 80x20
text run at (0,0) width 80: "test"
layer at (7,182) size 423x48
RenderTextControl {TEXTAREA} at (7,182) size 423x48
RenderBlock {DIV} at (2,2) size 419x20
<!DOCTYPE html>
<html>
<head>
<style>
input, select, textarea {
left: 5px;
right: 5px;
position: absolute;
font: 20px/1 Ahem;
}
</style>
</head>
<body>
<p> webkit.org/b/93735: Use the replaced height and width computation for positioned form controls </p>
<input id="input" style="top: 30px">
<input type="button" id="button" value="text" style="top: 80px">
<select id="select" style="top: 130px"><option>test</select>
<textarea id="textarea" style="top: 180px"></textarea>
</body>
</html>
layer at (0,0) size 800x600
RenderView at (0,0) size 800x600
layer at (0,0) size 800x50
RenderBlock {HTML} at (0,0) size 800x50
RenderBody {BODY} at (8,16) size 784x18
RenderBlock {P} at (0,0) size 784x18
RenderText {#text} at (0,0) size 608x18
text run at (0,0) width 608: "webkit.org/b/93735: Use the replaced height and width computation for positioned form controls"
layer at (7,32) size 412x32
RenderTextControl {INPUT} at (7,32) size 412x32 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
layer at (10,38) size 406x20
RenderBlock {DIV} at (3,6) size 406x20
layer at (7,82) size 57x21
RenderButton {INPUT} at (7,82) size 57x21 [bgcolor=#C0C0C0]
RenderBlock (anonymous) at (8,2) size 41x16
RenderText at (8,0) size 25x16
text run at (8,0) width 25: "text"
layer at (7,132) size 55x21
RenderMenuList {SELECT} at (7,132) size 55x21 [bgcolor=#FFFFFF]
RenderBlock (anonymous) at (0,0) size 55x21
RenderText at (8,2) size 24x16
text run at (8,2) width 24: "test"
layer at (7,182) size 427x52 clip at (8,183) size 425x50
RenderTextControl {TEXTAREA} at (7,182) size 427x52 [bgcolor=#FFFFFF] [border: (1px solid #000000)]
RenderBlock {DIV} at (3,3) size 421x20
......@@ -3,13 +3,13 @@ layer at (0,0) size 800x600
layer at (0,0) size 800x600
RenderBlock {HTML} at (0,0) size 800x600
RenderBody {BODY} at (8,8) size 784x584
layer at (10,10) size 154x18
RenderButton {BUTTON} at (10,10) size 154x18 [bgcolor=#C0C0C0] [border: none (2px outset #C0C0C0) none (2px outset #C0C0C0)]
RenderBlock (anonymous) at (8,2) size 138x13
RenderText {#text} at (0,0) size 138x13
text run at (0,0) width 138: "This button is positioned."
layer at (10,10) size 175x18
RenderButton {INPUT} at (10,10) size 175x18 [bgcolor=#C0C0C0]
RenderBlock (anonymous) at (8,2) size 159x13
RenderText at (0,0) size 159x13
text run at (0,0) width 159: "This button is also positioned"
layer at (10,10) size 170x15
RenderButton {BUTTON} at (10,10) size 170x15 [bgcolor=#C0C0C0] [border: none (2px outset #C0C0C0) none (2px outset #C0C0C0)]
RenderBlock (anonymous) at (8,2) size 154x13
RenderText {#text} at (8,0) size 138x13
text run at (8,0) width 138: "This button is positioned."
layer at (10,10) size 191x18
RenderButton {INPUT} at (10,10) size 191x18 [bgcolor=#C0C0C0]
RenderBlock (anonymous) at (8,2) size 175x13
RenderText at (8,0) size 159x13
text run at (8,0) width 159: "This button is also positioned"
......@@ -8,10 +8,10 @@ layer at (0,0) size 800x600
text run at (0,18) width 666: "This tests that preventDefault called onmousedown will prevent a caret from being placed in the text field."
RenderText {#text} at (0,0) size 0x0
RenderText {#text} at (0,0) size 0x0
layer at (12,52) size 123x19
RenderTextControl {INPUT} at (12,52) size 123x19 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
layer at (15,55) size 117x13 scrollWidth 130
RenderBlock {DIV} at (3,3) size 117x13
layer at (12,52) size 129x25
RenderTextControl {INPUT} at (12,52) size 129x25 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
layer at (15,58) size 123x13 scrollWidth 130
RenderBlock {DIV} at (3,6) size 123x13
RenderText {#text} at (0,0) size 129x13
text run at (0,0) width 129: "No caret should be here"
layer at (10,70) size 323x36
......
layer at (0,0) size 800x600
RenderView at (0,0) size 800x600
layer at (0,0) size 800x50
RenderBlock {HTML} at (0,0) size 800x50
RenderBody {BODY} at (8,16) size 784x18
RenderBlock {P} at (0,0) size 784x18
RenderText {#text} at (0,0) size 608x18
text run at (0,0) width 608: "webkit.org/b/93735: Use the replaced height and width computation for positioned form controls"
layer at (7,32) size 412x32
RenderTextControl {INPUT} at (7,32) size 412x32 [bgcolor=#FFFFFF] [border: (2px inset #000000)]
layer at (10,38) size 406x20
RenderBlock {DIV} at (3,6) size 406x20
layer at (7,82) size 57x21
RenderButton {INPUT} at (7,82) size 57x21 [bgcolor=#C0C0C0]
RenderBlock (anonymous) at (8,2) size 41x16
RenderText at (8,0) size 25x16
text run at (8,0) width 25: "text"
layer at (7,132) size 55x21
RenderMenuList {SELECT} at (7,132) size 55x21 [bgcolor=#FFFFFF]
RenderBlock (anonymous) at (0,0) size 55x21
RenderText at (8,2) size 24x16
text run at (8,2) width 24: "test"
layer at (7,182) size 427x52 clip at (8,183) size 425x50
RenderTextControl {TEXTAREA} at (7,182) size 427x52 [bgcolor=#FFFFFF] [border: (1px solid #000000)]
RenderBlock {DIV} at (3,3) size 421x20
......@@ -3,13 +3,13 @@ layer at (0,0) size 800x600
layer at (0,0) size 800x600
RenderBlock {HTML} at (0,0) size 800x600
RenderBody {BODY} at (8,8) size 784x584
layer at (10,10) size 162x31
RenderButton {BUTTON} at (10,10) size 162x31 [bgcolor=#C0C0C0]
RenderBlock (anonymous) at (6,6) size 150x19
RenderText {#text} at (0,0) size 150x19
text run at (0,0) width 150: "This button is positioned."
layer at (10,10) size 186x31
RenderButton {INPUT} at (10,10) size 186x31 [bgcolor=#C0C0C0]
RenderBlock (anonymous) at (6,6) size 174x19
RenderText at (0,0) size 174x19
text run at (0,0) width 174: "This button is also positioned"
layer at (10,10) size 174x29
RenderButton {BUTTON} at (10,10) size 174x29 [bgcolor=#C0C0C0]
RenderBlock (anonymous) at (6,6) size 162x19
RenderText {#text} at (6,0) size 150x19
text run at (6,0) width 150: "This button is positioned."
layer at (10,10) size 198x29
RenderButton {INPUT} at (10,10) size 198x29 [bgcolor=#C0C0C0]
RenderBlock (anonymous) at (6,6) size 186x19
RenderText at (6,0) size 174x19
text run at (6,0) width 174: "This button is also positioned"
......@@ -8,10 +8,10 @@ layer at (0,0) size 800x600
text run at (0,19) width 630: "This tests that preventDefault called onmousedown will prevent a caret from being placed in the text field."
RenderText {#text} at (0,0) size 0x0
RenderText {#text} at (0,0) size 0x0
layer at (12,52) size 192x23
RenderTextControl {INPUT} at (12,52) size 192x23
layer at (14,54) size 188x19
RenderBlock {DIV} at (2,2) size 188x19
layer at (12,52) size 196x27
RenderTextControl {INPUT} at (12,52) size 196x27
layer at (14,56) size 192x19
RenderBlock {DIV} at (2,4) size 192x19
RenderText {#text} at (0,0) size 146x19
text run at (0,0) width 146: "No caret should be here"
layer at (10,70) size 308x38
......
2013-05-27 Robert Hogan <robert@webkit.org>
Positioned Replaced Elements That Aren't RenderReplaced get Incorrect Width
https://bugs.webkit.org/show_bug.cgi?id=93735
Reviewed by Darin Adler.
Replaced elements that aren't RenderReplaced aren't |isReplaced| and don't have an
intrinsic height or width. This causes them to go down the wrong height and width computation
path in RenderBox when they are absolute positioned.
The notion of |isReplaced| is entwined with the notion of being |isInline| so it isn't really
possible to make them isReplaced without re-wiring a lot of code. So instead use an ad-hoc definition
of isReplacedElement in RenderBox to bring all replaced elements into the height and width calculation.
To make sure we get the right height and width in there, give non-RenderReplaced replaced renderers
the helpers for returning their approximation of intrinsic height and width.
Test: fast/replaced/width-and-height-of-positioned-replaced-elements.html
* rendering/RenderBox.cpp:
(WebCore::isReplacedElement):
(WebCore::RenderBox::computePositionedLogicalWidth):
(WebCore::RenderBox::computePositionedLogicalHeight):
* rendering/RenderBox.h:
(WebCore::RenderBox::intrinsicSize):
* rendering/RenderButton.h:
* rendering/RenderListBox.cpp:
(WebCore::RenderListBox::RenderListBox):
(WebCore::RenderListBox::computeLogicalHeight):
* rendering/RenderListBox.h:
* rendering/RenderMenuList.h:
* rendering/RenderReplaced.h:
* rendering/RenderTextControl.cpp:
(WebCore::RenderTextControl::RenderTextControl):
(WebCore::RenderTextControl::computeLogicalHeight):
* rendering/RenderTextControl.h:
2013-06-11 Ryosuke Niwa <rniwa@webkit.org>
There are unused variables in ApplyStyleCommand::mergeEndWithNextIfIdentical and ReplaceSelectionCommand::removeUnrenderedTextNodesAtEnds
......
......@@ -3034,9 +3034,15 @@ static void computeInlineStaticDistance(Length& logicalLeft, Length& logicalRigh
}
}
static bool isReplacedElement(const RenderBox* child)
{
// FIXME: Bug 117267, we should make form control elements isReplaced too so that we can just check for that.
return child->isReplaced() || (child->node() && child->node()->isElementNode() && toElement(child->node())->isFormControlElement() && !child->isFieldset());
}
void RenderBox::computePositionedLogicalWidth(LogicalExtentComputedValues& computedValues, RenderRegion* region) const
{
if (isReplaced()) {
if (isReplacedElement(this)) {
// FIXME: Positioned replaced elements inside a flow thread are not working properly
// with variable width regions (see https://bugs.webkit.org/show_bug.cgi?id=69896 ).
computePositionedLogicalWidthReplaced(computedValues);
......@@ -3378,7 +3384,7 @@ static void computeBlockStaticDistance(Length& logicalTop, Length& logicalBottom
void RenderBox::computePositionedLogicalHeight(LogicalExtentComputedValues& computedValues) const
{
if (isReplaced()) {
if (isReplacedElement(this)) {
computePositionedLogicalHeightReplaced(computedValues);
return;
}
......
......@@ -399,7 +399,6 @@ public:
return document()->inQuirksMode() && style()->logicalHeight().isAuto() && !isFloatingOrOutOfFlowPositioned() && (isRoot() || isBody()) && !document()->shouldDisplaySeamlesslyWithParent() && !isInline();
}
virtual LayoutSize intrinsicSize() const { return LayoutSize(); }
LayoutUnit intrinsicLogicalWidth() const { return style()->isHorizontalWritingMode() ? intrinsicSize().width() : intrinsicSize().height(); }
LayoutUnit intrinsicLogicalHeight() const { return style()->isHorizontalWritingMode() ? intrinsicSize().height() : intrinsicSize().width(); }
......@@ -641,6 +640,7 @@ private:
LayoutUnit viewLogicalHeightForPercentages() const;
virtual LayoutSize intrinsicSize() const { return LayoutSize(); }
void computePositionedLogicalHeight(LogicalExtentComputedValues&) const;
void computePositionedLogicalWidthUsing(Length logicalWidth, const RenderBoxModelObject* containerBlock, TextDirection containerDirection,
LayoutUnit containerLogicalWidth, LayoutUnit bordersPlusPadding,
......
......@@ -67,6 +67,8 @@ private:
void timerFired(Timer<RenderButton>*);
virtual LayoutSize intrinsicSize() const OVERRIDE FINAL { return LayoutSize(maxPreferredLogicalWidth(), LayoutUnit()); }
RenderTextFragment* m_buttonText;
RenderBlock* m_inner;
......
......@@ -89,6 +89,7 @@ RenderListBox::RenderListBox(Element* element)
, m_inAutoscroll(false)
, m_optionsWidth(0)
, m_indexOffset(0)
, m_intrinsicLogicalHeight(0)
{
ASSERT(element);
ASSERT(element->isHTMLElement());
......@@ -269,8 +270,8 @@ LayoutUnit RenderListBox::listHeight() const
void RenderListBox::computeLogicalHeight(LayoutUnit, LayoutUnit logicalTop, LogicalExtentComputedValues& computedValues) const
{
LayoutUnit height = itemHeight() * size() - rowSpacing + borderAndPaddingHeight();
RenderBox::computeLogicalHeight(height, logicalTop, computedValues);
m_intrinsicLogicalHeight = itemHeight() * size() - rowSpacing + borderAndPaddingHeight();
RenderBox::computeLogicalHeight(m_intrinsicLogicalHeight, logicalTop, computedValues);
}
int RenderListBox::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode lineDirection, LinePositionMode linePositionMode) const
......
......@@ -88,6 +88,8 @@ private:
virtual void autoscroll(const IntPoint&);
virtual void stopAutoscroll();
virtual LayoutSize intrinsicSize() const OVERRIDE FINAL { return LayoutSize(maxPreferredLogicalWidth(), m_intrinsicLogicalHeight); }
virtual bool shouldPanScroll() const { return true; }
virtual void panScroll(const IntPoint&);
......@@ -149,6 +151,7 @@ private:
bool m_inAutoscroll;
int m_optionsWidth;
int m_indexOffset;
mutable LayoutUnit m_intrinsicLogicalHeight;
RefPtr<Scrollbar> m_vBar;
};
......
......@@ -75,6 +75,7 @@ private:
virtual const char* renderName() const { return "RenderMenuList"; }
virtual LayoutSize intrinsicSize() const OVERRIDE FINAL { return LayoutSize(maxPreferredLogicalWidth(), logicalHeight()); }
virtual void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const OVERRIDE;
virtual void computePreferredLogicalWidths() OVERRIDE;
......
......@@ -43,7 +43,7 @@ protected:
virtual void layout();
virtual LayoutSize intrinsicSize() const OVERRIDE { return m_intrinsicSize; }
virtual LayoutSize intrinsicSize() const OVERRIDE FINAL { return m_intrinsicSize; }
virtual void computeIntrinsicRatioInformation(FloatSize& intrinsicSize, double& intrinsicRatio, bool& isPercentageIntrinsicSize) const;
virtual void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const OVERRIDE;
......
......@@ -38,6 +38,7 @@ namespace WebCore {
RenderTextControl::RenderTextControl(Element* element)
: RenderBlock(element)
, m_intrinsicLogicalHeight(0)
{
ASSERT(isHTMLTextFormControlElement(element));
}
......@@ -142,21 +143,20 @@ int RenderTextControl::scrollbarThickness() const
return ScrollbarTheme::theme()->scrollbarThickness();
}
void RenderTextControl::computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues& computedValues) const
void RenderTextControl::computeLogicalHeight(LayoutUnit, LayoutUnit logicalTop, LogicalExtentComputedValues& computedValues) const
{
HTMLElement* innerText = innerTextElement();
ASSERT(innerText);
if (RenderBox* innerTextBox = innerText->renderBox()) {
LayoutUnit nonContentHeight = innerTextBox->borderAndPaddingHeight() + innerTextBox->marginHeight();
logicalHeight = computeControlLogicalHeight(innerTextBox->lineHeight(true, HorizontalLine, PositionOfInteriorLineBoxes), nonContentHeight) + borderAndPaddingHeight();
m_intrinsicLogicalHeight = computeControlLogicalHeight(innerTextBox->lineHeight(true, HorizontalLine, PositionOfInteriorLineBoxes), nonContentHeight) + borderAndPaddingHeight();
// We are able to have a horizontal scrollbar if the overflow style is scroll, or if its auto and there's no word wrap.
if ((isHorizontalWritingMode() && (style()->overflowX() == OSCROLL || (style()->overflowX() == OAUTO && innerText->renderer()->style()->overflowWrap() == NormalOverflowWrap)))
|| (!isHorizontalWritingMode() && (style()->overflowY() == OSCROLL || (style()->overflowY() == OAUTO && innerText->renderer()->style()->overflowWrap() == NormalOverflowWrap))))
logicalHeight += scrollbarThickness();
m_intrinsicLogicalHeight += scrollbarThickness();
}
RenderBox::computeLogicalHeight(logicalHeight, logicalTop, computedValues);
RenderBox::computeLogicalHeight(m_intrinsicLogicalHeight, logicalTop, computedValues);
}
void RenderTextControl::hitInnerTextElement(HitTestResult& result, const LayoutPoint& pointInContainer, const LayoutPoint& accumulatedOffset)
......
......@@ -81,6 +81,10 @@ private:
virtual bool canBeProgramaticallyScrolled() const { return true; }
virtual bool requiresForcedStyleRecalcPropagation() const { return true; }
virtual LayoutSize intrinsicSize() const OVERRIDE FINAL { return LayoutSize(maxPreferredLogicalWidth(), m_intrinsicLogicalHeight); }
mutable LayoutUnit m_intrinsicLogicalHeight;
};
inline RenderTextControl* toRenderTextControl(RenderObject* object)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment