Commit fcd2c934 authored by darin's avatar darin

LayoutTests:

        Reviewed by Darin and Hyatt.

        - test for http://bugzilla.opendarwin.org/show_bug.cgi?id=9561
          REGRESSION: Content property on :before of button causes hang on click or hover

        * fast/forms/button-generated-content-expected.checksum: Added.
        * fast/forms/button-generated-content-expected.png: Added.
        * fast/forms/button-generated-content-expected.txt: Added.
        * fast/forms/button-generated-content.html: Added.

WebCore:

        Reviewed by Darin and Hyatt.

        - fix http://bugzilla.opendarwin.org/show_bug.cgi?id=9561
          REGRESSION: Content property on :before of button causes hang on click or hover

        Test: fast/forms/button-generated-content.html

        * rendering/RenderBlock.cpp:
        (WebCore::RenderBlock::setStyle):
        * rendering/RenderButton.cpp:
        (WebCore::RenderButton::updatePseudoChild): Added. Calls updatePseudoChildForObject()
        on the button itself or on its inner div, if it has one.
        * rendering/RenderButton.h:
        (WebCore::RenderButton::createsAnonymousWrapper): Added. Returns true.
        * rendering/RenderContainer.cpp:
        (WebCore::RenderContainer::pseudoChild): Added. Returns the child containing
        generated content of the requested type if there is one, or otherwise the
        child before/after which such generated content should come.
        (WebCore::RenderContainer::updatePseudoChild): Removed the child parameter and moved the guts
        of this method into updatePseudoChildForObject, which this method calls unless the object
        is an anonymous wrapper.
        (WebCore::RenderContainer::updatePseudoChildForObject): Added. Does the what
        updatePseudoChildForObject did previously, but fetches the pseudo style from
        the styledObject parameter.
        * rendering/RenderContainer.h:
        * rendering/RenderInline.cpp:
        (WebCore::RenderInline::setStyle):
        (WebCore::RenderInline::addChildToFlow):
        (WebCore::RenderInline::splitInlines):
        (WebCore::RenderInline::splitFlow):
        * rendering/RenderObject.h:
        (WebCore::RenderObject::createsAnonymousWrapper): Added. This method replaces
        allowsReusingAnonymousChild and returns the opposite of what that method used to
        return. Returns true if the object creates an anonymous child to contain all its
        other children.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@15079 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 35f007a7
2006-06-28 Mitz Pettel <opendarwin.org@mitzpettel.com>
Reviewed by Darin and Hyatt.
- test for http://bugzilla.opendarwin.org/show_bug.cgi?id=9561
REGRESSION: Content property on :before of button causes hang on click or hover
* fast/forms/button-generated-content-expected.checksum: Added.
* fast/forms/button-generated-content-expected.png: Added.
* fast/forms/button-generated-content-expected.txt: Added.
* fast/forms/button-generated-content.html: Added.
2006-06-28 Rob Buis <buis@kde.org>
Reviewed by Darin.
246284ca17b3a6079f72e3711ea22082
\ No newline at end of file
layer at (0,0) size 800x600
RenderView at (0,0) size 800x600
layer at (0,0) size 800x270
RenderBlock {HTML} at (0,0) size 800x270
RenderBody {BODY} at (8,16) size 784x246
RenderBlock {P} at (0,0) size 784x36
RenderText {#text} at (0,0) size 314x18
text run at (0,0) width 292: "This is a test of generated content in <button> "
text run at (292,0) width 22: "for "
RenderInline {I} at (0,0) size 767x36
RenderInline {A} at (0,0) size 348x18 [color=#0000EE]
RenderText {#text} at (314,0) size 348x18
text run at (314,0) width 348: "http://bugzilla.opendarwin.org/show_bug.cgi?id=9561"
RenderText {#text} at (662,0) size 767x36
text run at (662,0) width 4: " "
text run at (666,0) width 101: "REGRESSION:"
text run at (0,18) width 430: "Content property on :before of button causes hang on click or hover"
RenderText {#text} at (430,18) size 4x18
text run at (430,18) width 4: "."
RenderBlock {HR} at (0,52) size 784x2 [border: (1px inset #000000)]
RenderBlock (anonymous) at (0,62) size 784x184
RenderButton {BUTTON} at (2,2) size 51x18 [color=#0000FF] [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0) none (2px outset #C0C0C0)]
RenderBlock (anonymous) at (8,2) size 35x13
RenderInline (generated) at (0,0) size 35x13
RenderText at (0,0) size 35x13
text run at (0,0) width 35: "before"
RenderText {#text} at (55,1) size 4x18
text run at (55,1) width 4: " "
RenderButton {BUTTON} at (61,2) size 87x18 [color=#0000FF] [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0) none (2px outset #C0C0C0)]
RenderBlock (anonymous) at (8,2) size 71x13
RenderInline (generated) at (0,0) size 35x13
RenderText at (0,0) size 35x13
text run at (0,0) width 35: "before"
RenderText {#text} at (35,0) size 36x13
text run at (35,0) width 36: "button"
RenderText {#text} at (150,1) size 4x18
text run at (150,1) width 4: " "
RenderBR {BR} at (0,0) size 0x0
RenderButton {BUTTON} at (2,24) size 41x18 [color=#0000FF] [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0) none (2px outset #C0C0C0)]
RenderBlock (anonymous) at (8,2) size 25x13
RenderInline (generated) at (0,0) size 25x13
RenderText at (0,0) size 25x13
text run at (0,0) width 25: "after"
RenderText {#text} at (45,23) size 4x18
text run at (45,23) width 4: " "
RenderButton {BUTTON} at (51,24) size 77x18 [color=#0000FF] [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0) none (2px outset #C0C0C0)]
RenderBlock (anonymous) at (8,2) size 61x13
RenderText {#text} at (0,0) size 36x13
text run at (0,0) width 36: "button"
RenderInline (generated) at (0,0) size 25x13
RenderText at (36,0) size 25x13
text run at (36,0) width 25: "after"
RenderText {#text} at (130,23) size 4x18
text run at (130,23) width 4: " "
RenderBR {BR} at (0,0) size 0x0
RenderButton {BUTTON} at (2,46) size 16x15 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0) none (2px outset #C0C0C0)]
RenderBlock (anonymous) at (8,7) size 0x0
RenderText {#text} at (20,49) size 4x18
text run at (20,49) width 4: " "
RenderButton {BUTTON} at (26,50) size 52x18 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0) none (2px outset #C0C0C0)]
RenderBlock (anonymous) at (8,2) size 36x13
RenderText {#text} at (0,0) size 36x13
text run at (0,0) width 36: "button"
RenderText {#text} at (80,49) size 4x18
text run at (80,49) width 4: " "
RenderBR {BR} at (0,0) size 0x0
RenderButton {BUTTON} at (2,72) size 16x15 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0) none (2px outset #C0C0C0)]
RenderBlock (anonymous) at (8,7) size 0x0
RenderText {#text} at (20,75) size 4x18
text run at (20,75) width 4: " "
RenderButton {BUTTON} at (26,76) size 52x18 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0) none (2px outset #C0C0C0)]
RenderBlock (anonymous) at (8,2) size 36x13
RenderText {#text} at (0,0) size 36x13
text run at (0,0) width 36: "button"
RenderText {#text} at (80,75) size 4x18
text run at (80,75) width 4: " "
RenderBR {BR} at (0,0) size 0x0
RenderButton {BUTTON} at (2,98) size 51x18 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0) none (2px outset #C0C0C0)]
RenderBlock (anonymous) at (8,2) size 35x13
RenderInline (generated) at (0,0) size 35x13
RenderText at (0,0) size 35x13
text run at (0,0) width 35: "before"
RenderText {#text} at (55,97) size 4x18
text run at (55,97) width 4: " "
RenderButton {BUTTON} at (61,98) size 87x18 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0) none (2px outset #C0C0C0)]
RenderBlock (anonymous) at (8,2) size 71x13
RenderInline (generated) at (0,0) size 35x13
RenderText at (0,0) size 35x13
text run at (0,0) width 35: "before"
RenderText {#text} at (35,0) size 36x13
text run at (35,0) width 36: "button"
RenderText {#text} at (150,97) size 4x18
text run at (150,97) width 4: " "
RenderBR {BR} at (0,0) size 0x0
RenderButton {BUTTON} at (2,120) size 41x18 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0) none (2px outset #C0C0C0)]
RenderBlock (anonymous) at (8,2) size 25x13
RenderInline (generated) at (0,0) size 25x13
RenderText at (0,0) size 25x13
text run at (0,0) width 25: "after"
RenderText {#text} at (45,119) size 4x18
text run at (45,119) width 4: " "
RenderButton {BUTTON} at (51,120) size 77x18 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0) none (2px outset #C0C0C0)]
RenderBlock (anonymous) at (8,2) size 61x13
RenderText {#text} at (0,0) size 36x13
text run at (0,0) width 36: "button"
RenderInline (generated) at (0,0) size 25x13
RenderText at (36,0) size 25x13
text run at (36,0) width 25: "after"
RenderText {#text} at (130,119) size 4x18
text run at (130,119) width 4: " "
RenderBR {BR} at (0,0) size 0x0
RenderButton {BUTTON} at (2,142) size 51x18 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0) none (2px outset #C0C0C0)]
RenderBlock (anonymous) at (8,2) size 35x13
RenderInline (generated) at (0,0) size 35x13
RenderText at (0,0) size 35x13
text run at (0,0) width 35: "before"
RenderText {#text} at (55,141) size 4x18
text run at (55,141) width 4: " "
RenderButton {BUTTON} at (61,142) size 87x18 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0) none (2px outset #C0C0C0)]
RenderBlock (anonymous) at (8,2) size 71x13
RenderInline (generated) at (0,0) size 35x13
RenderText at (0,0) size 35x13
text run at (0,0) width 35: "before"
RenderText {#text} at (35,0) size 36x13
text run at (35,0) width 36: "button"
RenderText {#text} at (150,141) size 4x18
text run at (150,141) width 4: " "
RenderBR {BR} at (0,0) size 0x0
RenderButton {BUTTON} at (2,164) size 41x18 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0) none (2px outset #C0C0C0)]
RenderBlock (anonymous) at (8,2) size 25x13
RenderInline (generated) at (0,0) size 25x13
RenderText at (0,0) size 25x13
text run at (0,0) width 25: "after"
RenderText {#text} at (45,163) size 4x18
text run at (45,163) width 4: " "
RenderButton {BUTTON} at (51,164) size 77x18 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0) none (2px outset #C0C0C0)]
RenderBlock (anonymous) at (8,2) size 61x13
RenderText {#text} at (0,0) size 36x13
text run at (0,0) width 36: "button"
RenderInline (generated) at (0,0) size 25x13
RenderText at (36,0) size 25x13
text run at (36,0) width 25: "after"
RenderText {#text} at (130,163) size 4x18
text run at (130,163) width 4: " "
RenderBR {BR} at (0,0) size 0x0
<!DOCTYPE HTML>
<html>
<head>
<title></title>
<style type="text/css">
button.bef:before { content:'before'; }
button.aft:after { content:'after'; }
button.bef1:before { content:'BEFORE'; }
button.aft1:after { content:'AFTER'; }
</style>
<script type="text/javascript">
function test()
{
// force layout
document.body.offsetTop;
// change style, forcing generated content to update
document.getElementById("a").style.color = "blue";
document.getElementById("b").style.color = "blue";
document.getElementById("c").style.color = "blue";
document.getElementById("d").style.color = "blue";
// remove generated content
document.getElementById("e").className = "";
document.getElementById("f").className = "";
document.getElementById("g").className = "";
document.getElementById("h").className = "";
// add generated content
document.getElementById("i").className = "bef";
document.getElementById("j").className = "bef";
document.getElementById("k").className = "aft";
document.getElementById("l").className = "aft";
// replace generated content
document.getElementById("m").className = "bef";
document.getElementById("n").className = "bef";
document.getElementById("o").className = "aft";
document.getElementById("p").className = "aft";
}
</script>
</head>
<body onload="test();">
<p>
This is a test of generated content in &lt;button> for
<i><a href="http://bugzilla.opendarwin.org/show_bug.cgi?id=9561">http://bugzilla.opendarwin.org/show_bug.cgi?id=9561</a>
REGRESSION: Content property on :before of button causes hang on click or hover</i>.
</p>
<hr>
<button id="a" class="bef"></button>
<button id="b" class="bef">button</button>
<br>
<button id="c" class="aft"></button>
<button id="d" class="aft">button</button>
<br>
<button id="e" class="bef"></button>
<button id="f" class="bef">button</button>
<br>
<button id="g" class="aft"></button>
<button id="h" class="aft">button</button>
<br>
<button id="i"></button>
<button id="j">button</button>
<br>
<button id="k"></button>
<button id="l">button</button>
<br>
<button id="m" class="bef1"></button>
<button id="n" class="bef1">button</button>
<br>
<button id="o" class="aft1"></button>
<button id="p" class="aft1">button</button>
<br>
</body>
</html>
2006-06-28 Mitz Pettel <opendarwin.org@mitzpettel.com>
Reviewed by Darin and Hyatt.
- fix http://bugzilla.opendarwin.org/show_bug.cgi?id=9561
REGRESSION: Content property on :before of button causes hang on click or hover
Test: fast/forms/button-generated-content.html
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::setStyle):
* rendering/RenderButton.cpp:
(WebCore::RenderButton::updatePseudoChild): Added. Calls updatePseudoChildForObject()
on the button itself or on its inner div, if it has one.
* rendering/RenderButton.h:
(WebCore::RenderButton::createsAnonymousWrapper): Added. Returns true.
* rendering/RenderContainer.cpp:
(WebCore::RenderContainer::pseudoChild): Added. Returns the child containing
generated content of the requested type if there is one, or otherwise the
child before/after which such generated content should come.
(WebCore::RenderContainer::updatePseudoChild): Removed the child parameter and moved the guts
of this method into updatePseudoChildForObject, which this method calls unless the object
is an anonymous wrapper.
(WebCore::RenderContainer::updatePseudoChildForObject): Added. Does the what
updatePseudoChildForObject did previously, but fetches the pseudo style from
the styledObject parameter.
* rendering/RenderContainer.h:
* rendering/RenderInline.cpp:
(WebCore::RenderInline::setStyle):
(WebCore::RenderInline::addChildToFlow):
(WebCore::RenderInline::splitInlines):
(WebCore::RenderInline::splitFlow):
* rendering/RenderObject.h:
(WebCore::RenderObject::createsAnonymousWrapper): Added. This method replaces
allowsReusingAnonymousChild and returns the opposite of what that method used to
return. Returns true if the object creates an anonymous child to contain all its
other children.
2006-06-27 Brady Eidson <beidson@apple.com>
Reviewed by Maciej
......
......@@ -125,10 +125,8 @@ void RenderBlock::setStyle(RenderStyle* _style)
m_tabWidth = -1;
// Update pseudos for :before and :after now.
RenderObject* first = firstChild();
while (first && first->isListMarker()) first = first->nextSibling();
updatePseudoChild(RenderStyle::BEFORE, first);
updatePseudoChild(RenderStyle::AFTER, lastChild());
updatePseudoChild(RenderStyle::BEFORE);
updatePseudoChild(RenderStyle::AFTER);
}
void RenderBlock::addChildToFlow(RenderObject* newChild, RenderObject* beforeChild)
......
......@@ -96,6 +96,14 @@ void RenderButton::updateFromElement()
}
}
void RenderButton::updatePseudoChild(RenderStyle::PseudoId type)
{
if (m_inner)
m_inner->updatePseudoChildForObject(type, this);
else
updatePseudoChildForObject(type, this);
}
void RenderButton::paintObject(PaintInfo& i, int _tx, int _ty)
{
// Push a clip.
......
......@@ -38,11 +38,13 @@ public:
virtual void addChild(RenderObject* newChild, RenderObject *beforeChild = 0);
virtual void removeChild(RenderObject* oldChild);
virtual void removeLeftoverAnonymousBoxes() {}
virtual bool allowsReusingAnonymousChild() const { return false; }
virtual bool createsAnonymousWrapper() const { return true; }
virtual void setStyle(RenderStyle*);
virtual void updateFromElement();
virtual void updatePseudoChild(RenderStyle::PseudoId);
virtual void paintObject(PaintInfo&, int tx, int ty);
virtual const char* renderName() const { return "RenderButton"; }
......
......@@ -214,13 +214,37 @@ void RenderContainer::removeChild(RenderObject* oldChild)
removeChildNode(oldChild);
}
void RenderContainer::updatePseudoChild(RenderStyle::PseudoId type, RenderObject* child)
RenderObject* RenderContainer::pseudoChild(RenderStyle::PseudoId type) const
{
if (type == RenderStyle::BEFORE) {
RenderObject* first = firstChild();
while (first && first->isListMarker())
first = first->nextSibling();
return first;
}
if (type == RenderStyle::AFTER)
return lastChild();
assert(false);
return 0;
}
void RenderContainer::updatePseudoChild(RenderStyle::PseudoId type)
{
// If this is an anonymous wrapper, then parent applies its own pseudo style to it.
if (parent() && parent()->createsAnonymousWrapper())
return;
updatePseudoChildForObject(type, this);
}
void RenderContainer::updatePseudoChildForObject(RenderStyle::PseudoId type, RenderObject* styledObject)
{
// In CSS2, before/after pseudo-content cannot nest. Check this first.
if (style()->styleType() == RenderStyle::BEFORE || style()->styleType() == RenderStyle::AFTER)
return;
RenderStyle* pseudo = getPseudoStyle(type);
RenderStyle* pseudo = styledObject->getPseudoStyle(type);
RenderObject* child = pseudoChild(type);
// Whether or not we currently have generated content attached.
bool oldContentPresent = child && (child->style()->styleType() == type);
......
......@@ -57,7 +57,9 @@ public:
virtual void removeLeftoverAnonymousBoxes();
void updatePseudoChild(RenderStyle::PseudoId type, RenderObject* child);
RenderObject* pseudoChild(RenderStyle::PseudoId) const;
virtual void updatePseudoChild(RenderStyle::PseudoId);
void updatePseudoChildForObject(RenderStyle::PseudoId, RenderObject*);
virtual VisiblePosition positionForCoordinates(int x, int y);
......
......@@ -64,10 +64,8 @@ void RenderInline::setStyle(RenderStyle* _style)
m_lineHeight = -1;
// Update pseudos for :before and :after now.
RenderObject* first = firstChild();
while (first && first->isListMarker()) first = first->nextSibling();
updatePseudoChild(RenderStyle::BEFORE, first);
updatePseudoChild(RenderStyle::AFTER, lastChild());
updatePseudoChild(RenderStyle::BEFORE);
updatePseudoChild(RenderStyle::AFTER);
}
bool RenderInline::isInlineContinuation() const
......@@ -99,7 +97,7 @@ void RenderInline::addChildToFlow(RenderObject* newChild, RenderObject* beforeCh
// has to move into the inline continuation. Call updatePseudoChild to ensure that our :after
// content gets properly destroyed.
bool isLastChild = (beforeChild == lastChild());
updatePseudoChild(RenderStyle::AFTER, lastChild());
updatePseudoChild(RenderStyle::AFTER);
if (isLastChild && beforeChild != lastChild())
beforeChild = 0; // We destroyed the last child, so now we need to update our insertion
// point to be 0. It's just a straight append now.
......@@ -163,7 +161,7 @@ void RenderInline::splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock,
// Someone may have indirectly caused a <q> to split. When this happens, the :after content
// has to move into the inline continuation. Call updatePseudoChild to ensure that the inline's :after
// content gets properly destroyed.
curr->updatePseudoChild(RenderStyle::AFTER, curr->lastChild());
curr->updatePseudoChild(RenderStyle::AFTER);
// Now we need to take all of the children starting from the first child
// *after* currChild and append them all to the clone.
......@@ -199,7 +197,7 @@ void RenderInline::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox
RenderBlock* pre = 0;
RenderBlock* block = containingBlock();
bool madeNewBeforeBlock = false;
if (block->isAnonymousBlock() && (!block->parent() || block->parent()->allowsReusingAnonymousChild())) {
if (block->isAnonymousBlock() && (!block->parent() || !block->parent()->createsAnonymousWrapper())) {
// We can reuse this block and make it the preBlock of the next continuation.
pre = block;
block = block->containingBlock();
......
......@@ -195,7 +195,7 @@ public:
virtual bool canHaveChildren() const;
virtual void addChild(RenderObject *newChild, RenderObject *beforeChild = 0);
virtual void removeChild(RenderObject *oldChild);
virtual bool allowsReusingAnonymousChild() const { return true; }
virtual bool createsAnonymousWrapper() const { return false; }
// raw tree manipulation
virtual RenderObject* removeChildNode(RenderObject* child);
......
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