Title: [140307] trunk
- Revision
- 140307
- Author
- [email protected]
- Date
- 2013-01-20 23:59:39 -0800 (Sun, 20 Jan 2013)
Log Message
Elements must be reattached when inserted/removed from top layer
https://bugs.webkit.org/show_bug.cgi?id=105489
Relanding r139402 as rollout due to suspected perf regression did not help (bug 106726).
Reviewed by Julien Chaffraix.
Source/WebCore:
Ensure a reattach occurs when an element is inserted/removed from top layer, so its renderer can be inserted correctly:
as a child of RenderView in top layer sibling order if it's in the top layer, and in the usual place otherwise.
We previously relied on style recalc to catch when an element is inserted/removed from the top layer, because it
only happens on dialog.show/close which toggle display: none. But that is incorrect because, for example, close()
followed immediately by show() results in no style change.
Tests: fast/dom/HTMLDialogElement/removed-element-is-removed-from-top-layer.html
fast/dom/HTMLDialogElement/top-layer-stacking-correct-order-remove-readd.html
* dom/Element.cpp:
(WebCore::Element::removedFrom): Call Document::removeFromTopLayer to let the element be removed from the top layer vector.
removeFromTopLayer calls Element::setIsInTopLayer(false) itself if needed.
(WebCore::Element::setIsInTopLayer): Ensure a reattach occurs if the element is already attached.
LayoutTests:
* fast/dom/HTMLDialogElement/removed-element-is-removed-from-top-layer-expected.html: Added.
* fast/dom/HTMLDialogElement/removed-element-is-removed-from-top-layer.html: Added.
This tests that a top layer element removed from the document does not reappear in the top layer if readded.
This test actually would pass before this patch, but just by good fortune (see bug).
* fast/dom/HTMLDialogElement/top-layer-stacking-correct-order-remove-readd-expected.html: Added.
* fast/dom/HTMLDialogElement/top-layer-stacking-correct-order-remove-readd.html: Added.
This tests that top layer ordering is correct after removing and readding an element to the top layer.
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (140306 => 140307)
--- trunk/LayoutTests/ChangeLog 2013-01-21 07:50:51 UTC (rev 140306)
+++ trunk/LayoutTests/ChangeLog 2013-01-21 07:59:39 UTC (rev 140307)
@@ -1,3 +1,20 @@
+2013-01-20 Matt Falkenhagen <[email protected]>
+
+ Elements must be reattached when inserted/removed from top layer
+ https://bugs.webkit.org/show_bug.cgi?id=105489
+
+ Relanding r139402 as rollout due to suspected perf regression did not help (bug 106726).
+
+ Reviewed by Julien Chaffraix.
+
+ * fast/dom/HTMLDialogElement/removed-element-is-removed-from-top-layer-expected.html: Added.
+ * fast/dom/HTMLDialogElement/removed-element-is-removed-from-top-layer.html: Added.
+ This tests that a top layer element removed from the document does not reappear in the top layer if readded.
+ This test actually would pass before this patch, but just by good fortune (see bug).
+ * fast/dom/HTMLDialogElement/top-layer-stacking-correct-order-remove-readd-expected.html: Added.
+ * fast/dom/HTMLDialogElement/top-layer-stacking-correct-order-remove-readd.html: Added.
+ This tests that top layer ordering is correct after removing and readding an element to the top layer.
+
2013-01-20 Yury Semikhatsky <[email protected]>
Web Inspector: change HeapSnapshotLoader to allow loading native heap snapshots
Added: trunk/LayoutTests/fast/dom/HTMLDialogElement/removed-element-is-removed-from-top-layer-expected.html (0 => 140307)
--- trunk/LayoutTests/fast/dom/HTMLDialogElement/removed-element-is-removed-from-top-layer-expected.html (rev 0)
+++ trunk/LayoutTests/fast/dom/HTMLDialogElement/removed-element-is-removed-from-top-layer-expected.html 2013-01-21 07:59:39 UTC (rev 140307)
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+if (window.internals)
+ internals.settings.setDialogElementEnabled(true);
+</script>
+<style>
+.pseudodialog {
+ position: absolute;
+ left: 0; right: 0;
+ margin: auto;
+ border: solid;
+ padding: 1em;
+ background: white;
+ color: black;
+ height: 100px;
+ width: 100px;
+}
+
+#bottomDialog {
+ background-color: blue;
+ top: 100px;
+}
+
+#topDialog {
+ background-color: green;
+ top: 150px;
+ left: 50px;
+}
+</style>
+</head>
+<body>
+<p>Bug <a href="" Elements must be reattached when inserted/removed from top layer
+<p>The test passes if you see a green rectangle stacked on top of a blue rectangle.
+<div id="bottomDialog" class="pseudodialog"></div>
+<div id="topDialog" class="pseudodialog"></div>
+</body>
+</html>
+
Added: trunk/LayoutTests/fast/dom/HTMLDialogElement/removed-element-is-removed-from-top-layer.html (0 => 140307)
--- trunk/LayoutTests/fast/dom/HTMLDialogElement/removed-element-is-removed-from-top-layer.html (rev 0)
+++ trunk/LayoutTests/fast/dom/HTMLDialogElement/removed-element-is-removed-from-top-layer.html 2013-01-21 07:59:39 UTC (rev 140307)
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+if (window.internals)
+ internals.settings.setDialogElementEnabled(true);
+</script>
+<style>
+dialog {
+ height: 100px;
+ width: 100px;
+}
+
+#bottomDialog {
+ background-color: blue;
+ top: 100px;
+}
+
+#topDialog {
+ background-color: green;
+ top: 150px;
+ left: 50px;
+}
+</style>
+</head>
+<body>
+<p>Bug <a href="" Elements must be reattached when inserted/removed from top layer
+<p>The test passes if you see a green rectangle stacked on top of a blue rectangle.
+<dialog id="bottomDialog"></dialog>
+<dialog id="topDialog"></dialog>
+<script>
+document.getElementById('topDialog').showModal();
+var bottomDialog = document.getElementById('bottomDialog');
+bottomDialog.showModal();
+bottomDialog.offsetTop; // force a layout
+var parent = bottomDialog.parentNode;
+parent.removeChild(bottomDialog);
+parent.appendChild(bottomDialog);
+</script>
+</body>
+</html>
+
Added: trunk/LayoutTests/fast/dom/HTMLDialogElement/top-layer-stacking-correct-order-remove-readd-expected.html (0 => 140307)
--- trunk/LayoutTests/fast/dom/HTMLDialogElement/top-layer-stacking-correct-order-remove-readd-expected.html (rev 0)
+++ trunk/LayoutTests/fast/dom/HTMLDialogElement/top-layer-stacking-correct-order-remove-readd-expected.html 2013-01-21 07:59:39 UTC (rev 140307)
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+if (window.internals)
+ internals.settings.setDialogElementEnabled(true);
+</script>
+<style>
+.pseudodialog {
+ height: 100px;
+ width: 100px;
+ position: absolute;
+ left: 0; right: 0;
+ margin: auto;
+ border: solid;
+ padding: 1em;
+ background: white;
+ color: black;
+}
+</style>
+</head>
+<body>
+<p>Bug <a href="" Elements must be reattached when inserted/removed from top layer
+<p>The test passes if you see a green rectangle stacked on top of a blue rectangle.
+
+<div class="pseudodialog" style="top: 100px; background-color: blue"></div>
+<div class="pseudodialog" style="top: 150px; left: 50px; background-color: green"></div>
+</body>
+</html>
Added: trunk/LayoutTests/fast/dom/HTMLDialogElement/top-layer-stacking-correct-order-remove-readd.html (0 => 140307)
--- trunk/LayoutTests/fast/dom/HTMLDialogElement/top-layer-stacking-correct-order-remove-readd.html (rev 0)
+++ trunk/LayoutTests/fast/dom/HTMLDialogElement/top-layer-stacking-correct-order-remove-readd.html 2013-01-21 07:59:39 UTC (rev 140307)
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+if (window.internals)
+ internals.settings.setDialogElementEnabled(true);
+</script>
+<style>
+dialog {
+ height: 100px;
+ width: 100px;
+}
+
+#bottomDialog {
+ background-color: blue;
+ top: 100px;
+}
+
+#topDialog {
+ background-color: green;
+ top: 150px;
+ left: 50px;
+}
+</style>
+</head>
+<body>
+<p>Bug <a href="" Elements must be reattached when inserted/removed from top layer
+<p>The test passes if you see a green rectangle stacked on top of a blue rectangle.
+
+<dialog id="topDialog"></dialog>
+<dialog id="bottomDialog"></dialog>
+<script>
+var topDialog = document.getElementById('topDialog');
+var bottomDialog = document.getElementById('bottomDialog');
+topDialog.showModal();
+bottomDialog.showModal();
+topDialog.offsetTop; // force a layout
+topDialog.close();
+topDialog.showModal();
+</script>
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (140306 => 140307)
--- trunk/Source/WebCore/ChangeLog 2013-01-21 07:50:51 UTC (rev 140306)
+++ trunk/Source/WebCore/ChangeLog 2013-01-21 07:59:39 UTC (rev 140307)
@@ -1,3 +1,27 @@
+2013-01-20 Matt Falkenhagen <[email protected]>
+
+ Elements must be reattached when inserted/removed from top layer
+ https://bugs.webkit.org/show_bug.cgi?id=105489
+
+ Relanding r139402 as rollout due to suspected perf regression did not help (bug 106726).
+
+ Reviewed by Julien Chaffraix.
+
+ Ensure a reattach occurs when an element is inserted/removed from top layer, so its renderer can be inserted correctly:
+ as a child of RenderView in top layer sibling order if it's in the top layer, and in the usual place otherwise.
+
+ We previously relied on style recalc to catch when an element is inserted/removed from the top layer, because it
+ only happens on dialog.show/close which toggle display: none. But that is incorrect because, for example, close()
+ followed immediately by show() results in no style change.
+
+ Tests: fast/dom/HTMLDialogElement/removed-element-is-removed-from-top-layer.html
+ fast/dom/HTMLDialogElement/top-layer-stacking-correct-order-remove-readd.html
+
+ * dom/Element.cpp:
+ (WebCore::Element::removedFrom): Call Document::removeFromTopLayer to let the element be removed from the top layer vector.
+ removeFromTopLayer calls Element::setIsInTopLayer(false) itself if needed.
+ (WebCore::Element::setIsInTopLayer): Ensure a reattach occurs if the element is already attached.
+
2013-01-20 Yury Semikhatsky <[email protected]>
Web Inspector: change HeapSnapshotLoader to allow loading native heap snapshots
Modified: trunk/Source/WebCore/dom/Element.cpp (140306 => 140307)
--- trunk/Source/WebCore/dom/Element.cpp 2013-01-21 07:50:51 UTC (rev 140306)
+++ trunk/Source/WebCore/dom/Element.cpp 2013-01-21 07:59:39 UTC (rev 140307)
@@ -1171,7 +1171,7 @@
#endif
#if ENABLE(DIALOG_ELEMENT)
- setIsInTopLayer(false);
+ document()->removeFromTopLayer(this);
#endif
#if ENABLE(FULLSCREEN_API)
if (containsFullScreenElement())
@@ -2390,7 +2390,10 @@
void Element::setIsInTopLayer(bool inTopLayer)
{
ensureElementRareData()->setIsInTopLayer(inTopLayer);
- setNeedsStyleRecalc(SyntheticStyleChange);
+
+ // We must ensure a reattach occurs so the renderer is inserted in the correct sibling order under RenderView according to its
+ // top layer position, or in its usual place if not in the top layer.
+ reattachIfAttached();
}
#endif
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes