Diff
Modified: trunk/LayoutTests/ChangeLog (139153 => 139154)
--- trunk/LayoutTests/ChangeLog 2013-01-09 04:41:41 UTC (rev 139153)
+++ trunk/LayoutTests/ChangeLog 2013-01-09 04:46:50 UTC (rev 139154)
@@ -1,3 +1,17 @@
+2013-01-08 Matt Falkenhagen <[email protected]>
+
+ Make NodeRenderingContext::parentRenderer and nextRenderer top layer aware
+ https://bugs.webkit.org/show_bug.cgi?id=103477
+
+ Reviewed by Hajime Morita.
+
+ * fast/dom/HTMLDialogElement/modal-dialog-in-replaced-renderer-expected.html: Added.
+ * fast/dom/HTMLDialogElement/modal-dialog-in-replaced-renderer.html: Added.
+ * fast/dom/HTMLDialogElement/modal-dialog-in-table-column-expected.html: Added.
+ * fast/dom/HTMLDialogElement/modal-dialog-in-table-column.html: Added.
+ * fast/dom/HTMLDialogElement/modal-dialog-sibling-expected.html: Added.
+ * fast/dom/HTMLDialogElement/modal-dialog-sibling.html: Added.
+
2013-01-08 Hayato Ito <[email protected]>
[Shadow DOM] The MouseEvent offsetX and offsetY attributes must return the coordinates relative to the origin of the padding edge of the relative target after retargeting.
Added: trunk/LayoutTests/fast/dom/HTMLDialogElement/modal-dialog-in-replaced-renderer-expected.html (0 => 139154)
--- trunk/LayoutTests/fast/dom/HTMLDialogElement/modal-dialog-in-replaced-renderer-expected.html (rev 0)
+++ trunk/LayoutTests/fast/dom/HTMLDialogElement/modal-dialog-in-replaced-renderer-expected.html 2013-01-09 04:46:50 UTC (rev 139154)
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+if (window.internals)
+ internals.settings.setDialogElementEnabled(true);
+</script>
+<style>
+dialog {
+ background: green;
+ border-color: green;
+}
+div {
+ content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPAQMAAAABGAcJAAAAA1BMVEUAgACc+aWRAAAADElEQVR42mNgIAEAAAAtAAH7KhMqAAAAAElFTkSuQmCC);
+}
+</style>
+<body>
+<p>Bug <a href="" Make
+NodeRenderingContext::parentRenderer and nextRenderer top layer aware
+<p>The test passes if you see a green square near the top and green rectangle in the center of the viewport.
+<div></div>
+<dialog id="dialog"></dialog>
+<script>
+document.getElementById('dialog').showModal();
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/fast/dom/HTMLDialogElement/modal-dialog-in-replaced-renderer.html (0 => 139154)
--- trunk/LayoutTests/fast/dom/HTMLDialogElement/modal-dialog-in-replaced-renderer.html (rev 0)
+++ trunk/LayoutTests/fast/dom/HTMLDialogElement/modal-dialog-in-replaced-renderer.html 2013-01-09 04:46:50 UTC (rev 139154)
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+if (window.internals)
+ internals.settings.setDialogElementEnabled(true);
+</script>
+<style>
+dialog {
+ background: green;
+ border-color: green;
+}
+div {
+ content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPAQMAAAABGAcJAAAAA1BMVEUAgACc+aWRAAAADElEQVR42mNgIAEAAAAtAAH7KhMqAAAAAElFTkSuQmCC);
+}
+</style>
+<body>
+<p>Bug <a href="" Make
+NodeRenderingContext::parentRenderer and nextRenderer top layer aware
+<p>The test passes if you see a green square near the top and green rectangle in the center of the viewport.
+<div>
+<dialog id="dialog"></dialog>
+</div>
+<script>
+document.getElementById('dialog').showModal();
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/fast/dom/HTMLDialogElement/modal-dialog-in-table-column-expected.html (0 => 139154)
--- trunk/LayoutTests/fast/dom/HTMLDialogElement/modal-dialog-in-table-column-expected.html (rev 0)
+++ trunk/LayoutTests/fast/dom/HTMLDialogElement/modal-dialog-in-table-column-expected.html 2013-01-09 04:46:50 UTC (rev 139154)
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+if (window.internals)
+ internals.settings.setDialogElementEnabled(true);
+</script>
+<style>
+dialog {
+ background: green;
+ border-color: green;
+}
+</style>
+<body>
+<p>Bug <a href="" Make
+NodeRenderingContext::parentRenderer and nextRenderer top layer aware
+<p>The test passes if you see a green rectangle in the center of the viewport.
+<dialog id="dialog"></dialog>
+<script>
+document.getElementById('dialog').showModal();
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/fast/dom/HTMLDialogElement/modal-dialog-in-table-column.html (0 => 139154)
--- trunk/LayoutTests/fast/dom/HTMLDialogElement/modal-dialog-in-table-column.html (rev 0)
+++ trunk/LayoutTests/fast/dom/HTMLDialogElement/modal-dialog-in-table-column.html 2013-01-09 04:46:50 UTC (rev 139154)
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+if (window.internals)
+ internals.settings.setDialogElementEnabled(true);
+</script>
+<style>
+dialog {
+ background: green;
+ border-color: green;
+}
+div {
+ display: table-column;
+}
+</style>
+<body>
+<p>Bug <a href="" Make
+NodeRenderingContext::parentRenderer and nextRenderer top layer aware
+<p>The test passes if you see a green rectangle in the center of the viewport.
+<div>
+<dialog id="dialog"></dialog>
+</div>
+<script>
+document.getElementById('dialog').showModal();
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/fast/dom/HTMLDialogElement/modal-dialog-sibling-expected.html (0 => 139154)
--- trunk/LayoutTests/fast/dom/HTMLDialogElement/modal-dialog-sibling-expected.html (rev 0)
+++ trunk/LayoutTests/fast/dom/HTMLDialogElement/modal-dialog-sibling-expected.html 2013-01-09 04:46:50 UTC (rev 139154)
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+if (window.internals)
+ internals.settings.setDialogElementEnabled(true);
+</script>
+<style>
+dialog {
+ background: green;
+ border-color: green;
+}
+</style>
+<body>
+<p>Bug <a href="" Make
+NodeRenderingContext::parentRenderer and nextRenderer top layer aware
+<p>The test passes if you see a green rectangle in the center of the viewport.
+<dialog id="dialog"></dialog>
+<script>
+document.getElementById('dialog').showModal();
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/fast/dom/HTMLDialogElement/modal-dialog-sibling.html (0 => 139154)
--- trunk/LayoutTests/fast/dom/HTMLDialogElement/modal-dialog-sibling.html (rev 0)
+++ trunk/LayoutTests/fast/dom/HTMLDialogElement/modal-dialog-sibling.html 2013-01-09 04:46:50 UTC (rev 139154)
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+if (window.internals)
+ internals.settings.setDialogElementEnabled(true);
+</script>
+<style>
+dialog {
+ background: green;
+ border-color: green;
+}
+</style>
+<body>
+<p>Bug <a href="" Make
+NodeRenderingContext::parentRenderer and nextRenderer top layer aware
+<p>The test passes if you see a green rectangle in the center of the viewport.
+<div style="display: none" id="div"></div>
+<dialog id="dialog"></dialog>
+<script>
+document.getElementById('dialog').showModal();
+document.getElementById('dialog').offsetTop; // force a layout/renderer creation
+document.getElementById('div').style.display = 'block';
+</script>
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (139153 => 139154)
--- trunk/Source/WebCore/ChangeLog 2013-01-09 04:41:41 UTC (rev 139153)
+++ trunk/Source/WebCore/ChangeLog 2013-01-09 04:46:50 UTC (rev 139154)
@@ -1,3 +1,34 @@
+2013-01-08 Matt Falkenhagen <[email protected]>
+
+ Make NodeRenderingContext::parentRenderer and nextRenderer top layer aware
+ https://bugs.webkit.org/show_bug.cgi?id=103477
+
+ Reviewed by Hajime Morita.
+
+ Original patch by Elliott Sprehn (minor code and layout tests added).
+
+ Instead of using adjustInsertionPointForTopLayerElement and reassigning
+ pointers passed by reference we should just make nextRenderer and parentRenderer
+ handle the top layer properly. Right now they would return the wrong values
+ since we only correctly handle the top layer during renderer creation.
+
+ This makes handling of top layer elements consistent with handling of
+ other special renderering systems like flow threads.
+
+ Tests: fast/dom/HTMLDialogElement/modal-dialog-in-replaced-renderer.html
+ fast/dom/HTMLDialogElement/modal-dialog-in-table-column.html
+ fast/dom/HTMLDialogElement/modal-dialog-sibling.html
+
+ * dom/NodeRenderingContext.cpp:
+ (WebCore::isRendererReparented): Added this helper function. We must skip
+ renderers that are reparented in nextRenderer and previousRenderer.
+ (WebCore):
+ (WebCore::adjustInsertionPointForTopLayerElement): Removed this method.
+ (WebCore::NodeRenderingContext::nextRenderer):
+ (WebCore::NodeRenderingContext::previousRenderer):
+ (WebCore::NodeRenderingContext::parentRenderer):
+ (WebCore::NodeRenderingContext::createRendererForElementIfNeeded):
+
2013-01-08 Kent Tamura <[email protected]>
REGRESSION(r135836): Invalid user input for input[type=number] should be cleared by input.value=""
Modified: trunk/Source/WebCore/dom/NodeRenderingContext.cpp (139153 => 139154)
--- trunk/Source/WebCore/dom/NodeRenderingContext.cpp 2013-01-09 04:41:41 UTC (rev 139153)
+++ trunk/Source/WebCore/dom/NodeRenderingContext.cpp 2013-01-09 04:46:50 UTC (rev 139154)
@@ -73,11 +73,38 @@
{
}
+static bool isRendererReparented(const RenderObject* renderer)
+{
+ if (!renderer->node()->isElementNode())
+ return false;
+ if (renderer->style() && !renderer->style()->flowThread().isEmpty())
+ return true;
+#if ENABLE(DIALOG_ELEMENT)
+ if (toElement(renderer->node())->isInTopLayer())
+ return true;
+#endif
+ return false;
+}
+
RenderObject* NodeRenderingContext::nextRenderer() const
{
if (RenderObject* renderer = m_node->renderer())
return renderer->nextSibling();
+#if ENABLE(DIALOG_ELEMENT)
+ Element* element = m_node->isElementNode() ? toElement(m_node) : 0;
+ if (element && element->isInTopLayer()) {
+ const Vector<RefPtr<Element> >& topLayerElements = element->document()->topLayerElements();
+ size_t position = topLayerElements.find(element);
+ ASSERT(position != notFound);
+ for (size_t i = position + 1; i < topLayerElements.size(); ++i) {
+ if (RenderObject* renderer = topLayerElements[i]->renderer())
+ return renderer;
+ }
+ return 0;
+ }
+#endif
+
if (m_parentFlowRenderer)
return m_parentFlowRenderer->nextRendererForNode(m_node);
@@ -87,12 +114,9 @@
return 0;
for (Node* sibling = NodeRenderingTraversal::nextSibling(m_node); sibling; sibling = NodeRenderingTraversal::nextSibling(sibling)) {
- if (RenderObject* renderer = sibling->renderer()) {
- // Renderers for elements attached to a flow thread should be skipped because they are parented differently.
- if (renderer->node()->isElementNode() && renderer->style() && !renderer->style()->flowThread().isEmpty())
- continue;
+ RenderObject* renderer = sibling->renderer();
+ if (renderer && !isRendererReparented(renderer))
return renderer;
- }
}
return 0;
@@ -103,18 +127,22 @@
if (RenderObject* renderer = m_node->renderer())
return renderer->previousSibling();
+#if ENABLE(DIALOG_ELEMENT)
+ // FIXME: This doesn't work correctly for things in the top layer that are
+ // display: none. We'd need to duplicate the logic in nextRenderer, but since
+ // nothing needs that yet just assert.
+ ASSERT(!m_node->isElementNode() || !toElement(m_node)->isInTopLayer());
+#endif
+
if (m_parentFlowRenderer)
return m_parentFlowRenderer->previousRendererForNode(m_node);
// FIXME: We should have the same O(N^2) avoidance as nextRenderer does
// however, when I tried adding it, several tests failed.
for (Node* sibling = NodeRenderingTraversal::previousSibling(m_node); sibling; sibling = NodeRenderingTraversal::previousSibling(sibling)) {
- if (RenderObject* renderer = sibling->renderer()) {
- // Renderers for elements attached to a flow thread should be skipped because they are parented differently.
- if (renderer->node()->isElementNode() && renderer->style() && !renderer->style()->flowThread().isEmpty())
- continue;
+ RenderObject* renderer = sibling->renderer();
+ if (renderer && !isRendererReparented(renderer))
return renderer;
- }
}
return 0;
@@ -124,6 +152,21 @@
{
if (RenderObject* renderer = m_node->renderer())
return renderer->parent();
+
+#if ENABLE(DIALOG_ELEMENT)
+ if (m_node->isElementNode() && toElement(m_node)->isInTopLayer()) {
+ // The parent renderer of top layer elements is the RenderView, but only
+ // if the normal parent would have had a renderer.
+ // FIXME: This behavior isn't quite right as the spec for top layer
+ // only talks about display: none ancestors so putting a <dialog> inside
+ // an <optgroup> seems like it should still work even though this check
+ // will prevent it.
+ if (!m_renderingParent || !m_renderingParent->renderer())
+ return 0;
+ return m_node->document()->renderView();
+ }
+#endif
+
if (m_parentFlowRenderer)
return m_parentFlowRenderer;
@@ -195,26 +238,6 @@
return m_node->parentNode() && m_node->parentNode()->isShadowRoot();
}
-#if ENABLE(DIALOG_ELEMENT)
-static void adjustInsertionPointForTopLayerElement(Element* element, RenderObject*& parentRenderer, RenderObject*& nextRenderer)
-{
- parentRenderer = parentRenderer->view();
- nextRenderer = 0;
- const Vector<RefPtr<Element> >& topLayerElements = element->document()->topLayerElements();
- size_t topLayerPosition = topLayerElements.find(element);
- ASSERT(topLayerPosition != notFound);
- // Find the next top layer renderer that's stacked above this element. Note that the immediate next element in the top layer
- // stack might not have a renderer (due to display: none, or possibly it is not attached yet).
- for (size_t i = topLayerPosition + 1; i < topLayerElements.size(); ++i) {
- nextRenderer = topLayerElements[i]->renderer();
- if (nextRenderer) {
- ASSERT(nextRenderer->parent() == parentRenderer);
- break;
- }
- }
-}
-#endif
-
void NodeRenderingContext::createRendererForElementIfNeeded()
{
ASSERT(!m_node->renderer());
@@ -233,11 +256,6 @@
RenderObject* parentRenderer = this->parentRenderer();
RenderObject* nextRenderer = this->nextRenderer();
-
-#if ENABLE(DIALOG_ELEMENT)
- if (element->isInTopLayer())
- adjustInsertionPointForTopLayerElement(element, parentRenderer, nextRenderer);
-#endif
Document* document = element->document();
RenderObject* newRenderer = element->createRenderer(document->renderArena(), m_style.get());