Title: [145340] trunk
Revision
145340
Author
[email protected]
Date
2013-03-10 23:13:05 -0700 (Sun, 10 Mar 2013)

Log Message

Implement inert subtrees needed for modal <dialog>
https://bugs.webkit.org/show_bug.cgi?id=110952

Reviewed by Hajime Morrita.

Source/WebCore:

This changes Node::disabled() to return true when a modal dialog is
open and the node is not in the dialog.

Reusing disabled for inertness is useful because then event
targeting and focus control automatically have the desired behavior:
inert nodes are skipped over.

Tests: fast/dom/HTMLDialogElement/closed-dialog-does-not-block-mouse-events.html
       fast/dom/HTMLDialogElement/modal-dialog-blocks-mouse-events.html
       fast/dom/HTMLDialogElement/non-modal-dialog-does-not-block-mouse-events.html

* dom/Document.h:
(WebCore::Document::activeModalDialog): Returns the topmost element in the top layer.
Since now the only elements in the top layer are modal dialogs, it is the active modal dialog.
* dom/Node.cpp:
(WebCore):
(WebCore::Node::isInert): As per the spec, a node that is not an ancestor or descendant of the modal dialog is inert.
(WebCore::Node::disabled): Return false when inert.
* dom/Node.h:
* html/HTMLFormControlElement.cpp:
(WebCore::HTMLFormControlElement::disabled): Fall back to the superclass so inert is taken into account.

LayoutTests:

* fast/dom/HTMLDialogElement/closed-dialog-does-not-block-mouse-events-expected.txt: Added.
* fast/dom/HTMLDialogElement/closed-dialog-does-not-block-mouse-events.html: Added.
* fast/dom/HTMLDialogElement/modal-dialog-blocks-mouse-events-expected.txt: Added.
* fast/dom/HTMLDialogElement/modal-dialog-blocks-mouse-events.html: Added.
* fast/dom/HTMLDialogElement/non-modal-dialog-does-not-block-mouse-events-expected.txt: Added.
* fast/dom/HTMLDialogElement/non-modal-dialog-does-not-block-mouse-events.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (145339 => 145340)


--- trunk/LayoutTests/ChangeLog	2013-03-11 05:42:02 UTC (rev 145339)
+++ trunk/LayoutTests/ChangeLog	2013-03-11 06:13:05 UTC (rev 145340)
@@ -1,3 +1,17 @@
+2013-03-10  Matt Falkenhagen  <[email protected]>
+
+        Implement inert subtrees needed for modal <dialog>
+        https://bugs.webkit.org/show_bug.cgi?id=110952
+
+        Reviewed by Hajime Morrita.
+
+        * fast/dom/HTMLDialogElement/closed-dialog-does-not-block-mouse-events-expected.txt: Added.
+        * fast/dom/HTMLDialogElement/closed-dialog-does-not-block-mouse-events.html: Added.
+        * fast/dom/HTMLDialogElement/modal-dialog-blocks-mouse-events-expected.txt: Added.
+        * fast/dom/HTMLDialogElement/modal-dialog-blocks-mouse-events.html: Added.
+        * fast/dom/HTMLDialogElement/non-modal-dialog-does-not-block-mouse-events-expected.txt: Added.
+        * fast/dom/HTMLDialogElement/non-modal-dialog-does-not-block-mouse-events.html: Added.
+
 2013-03-10  Glenn Adams  <[email protected]>
 
         Line breaking opportunities at the end of a text node are missed

Added: trunk/LayoutTests/fast/dom/HTMLDialogElement/closed-dialog-does-not-block-mouse-events-expected.txt (0 => 145340)


--- trunk/LayoutTests/fast/dom/HTMLDialogElement/closed-dialog-does-not-block-mouse-events-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/HTMLDialogElement/closed-dialog-does-not-block-mouse-events-expected.txt	2013-03-11 06:13:05 UTC (rev 145340)
@@ -0,0 +1,10 @@
+Test for bug 110952. Ensure that closed dialogs do not block mouse events. To test manually, click the red box. The test succeeds if the red box turns green.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS div.firedOn is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/dom/HTMLDialogElement/closed-dialog-does-not-block-mouse-events.html (0 => 145340)


--- trunk/LayoutTests/fast/dom/HTMLDialogElement/closed-dialog-does-not-block-mouse-events.html	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/HTMLDialogElement/closed-dialog-does-not-block-mouse-events.html	2013-03-11 06:13:05 UTC (rev 145340)
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+#div {
+    height: 100px;
+    width: 100px;
+    background: red;
+}
+</style>
+<script src=""
+<script>
+if (window.internals)
+    internals.settings.setDialogElementEnabled(true);
+</script>
+</head>
+<body>
+<div id="div"></div>
+<dialog id="dialog"></dialog>
+<dialog></dialog>
+<script>
+description('Test for bug 110952. Ensure that closed dialogs do not block mouse events. To test manually, click the red box. The test succeeds if the red box turns green.');
+
+function clickOn(element)
+{
+    if (!window.eventSender)
+        return;
+
+    var absoluteTop = 0;
+    var absoluteLeft = 0;
+    for (var parentNode = element; parentNode; parentNode = parentNode.offsetParent) {
+      absoluteLeft += parentNode.offsetLeft;
+      absoluteTop += parentNode.offsetTop;
+    }
+
+    var x = absoluteLeft + element.offsetWidth / 2;
+    var y = absoluteTop + element.offsetHeight / 2;
+    eventSender.mouseMoveTo(x, y);
+    eventSender.mouseDown();
+    eventSender.mouseUp()
+    eventSender.mouseMoveTo(0, 0);
+}
+
+if (window.testRunner)
+    testRunner.dumpAsText();
+
+dialog = document.getElementById('dialog');
+dialog.showModal();
+dialog.close();
+
+div = document.getElementById('div');
+div.addEventListener('click', function(event) {
+    div.firedOn = true;
+    div.style.backgroundColor = 'green';
+});
+
+clickOn(div);
+
+shouldBeTrue('div.firedOn');
+</script>
+<script src=""
+</body>
+</html>

Added: trunk/LayoutTests/fast/dom/HTMLDialogElement/modal-dialog-blocks-mouse-events-expected.txt (0 => 145340)


--- trunk/LayoutTests/fast/dom/HTMLDialogElement/modal-dialog-blocks-mouse-events-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/HTMLDialogElement/modal-dialog-blocks-mouse-events-expected.txt	2013-03-11 06:13:05 UTC (rev 145340)
@@ -0,0 +1,11 @@
+Test for bug 110952. Ensure that mouse events are not dispatched to an inert node. To test manually, move the mouse to the green box, click, and then move the mouse outside. Then repeat for the red box. The test succeeds if green box remains green and the red box turns green.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS inertDiv.firedOn is false
+PASS Object.keys(dialogDiv.firedOnEvents).length is events.length
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/dom/HTMLDialogElement/modal-dialog-blocks-mouse-events.html (0 => 145340)


--- trunk/LayoutTests/fast/dom/HTMLDialogElement/modal-dialog-blocks-mouse-events.html	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/HTMLDialogElement/modal-dialog-blocks-mouse-events.html	2013-03-11 06:13:05 UTC (rev 145340)
@@ -0,0 +1,85 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+#inert-div {
+    height: 100px;
+    width: 100px;
+    background: green;
+}
+
+#dialog-div {
+    height: 100px;
+    width: 100px;
+    background: red;
+}
+</style>
+<script src=""
+<script>
+if (window.internals)
+    internals.settings.setDialogElementEnabled(true);
+</script>
+</head>
+<body>
+<div id="inert-div"></div>
+<dialog id="dialog">
+    <div id="dialog-div"></div>
+</dialog>
+<script>
+description('Test for bug 110952. Ensure that mouse events are not dispatched to an inert node. To test manually, move the mouse to the green box, click, and then move the mouse outside. Then repeat for the red box. The test succeeds if green box remains green and the red box turns green.');
+
+function clickOn(element)
+{
+    if (!window.eventSender)
+        return;
+
+    var absoluteTop = 0;
+    var absoluteLeft = 0;
+    for (var parentNode = element; parentNode; parentNode = parentNode.offsetParent) {
+      absoluteLeft += parentNode.offsetLeft;
+      absoluteTop += parentNode.offsetTop;
+    }
+
+    var x = absoluteLeft + element.offsetWidth / 2;
+    var y = absoluteTop + element.offsetHeight / 2;
+    eventSender.mouseMoveTo(x, y);
+    eventSender.mouseDown();
+    eventSender.mouseUp();
+    eventSender.mouseMoveTo(0, 0);
+}
+
+if (window.testRunner)
+    testRunner.dumpAsText();
+
+dialog.showModal();
+
+inertDiv = document.getElementById('inert-div');
+dialogDiv = document.getElementById('dialog-div');
+inertDiv.firedOn = false;
+eventFiredOnInertNode = function(event) {
+    inertDiv.firedOn = true;
+    inertDiv.style.backgroundColor = 'red';
+}
+
+events =  ['mousedown', 'mouseup', 'click', 'mousemove', 'mouseover', 'mouseout'];
+dialogDiv.firedOnEvents = {};
+eventFiredOnDialog = function(event) {
+    dialogDiv.firedOnEvents[event.type] = true;
+    if (Object.keys(dialogDiv.firedOnEvents).length == events.length)
+        dialogDiv.style.backgroundColor = 'green';
+}
+
+for (var i = 0; i < events.length; ++i) {
+    inertDiv.addEventListener(events[i], eventFiredOnInertNode);
+    dialogDiv.addEventListener(events[i], eventFiredOnDialog);
+}
+
+clickOn(inertDiv);
+clickOn(dialogDiv);
+
+shouldBeFalse('inertDiv.firedOn');
+shouldBe('Object.keys(dialogDiv.firedOnEvents).length', 'events.length');
+</script>
+<script src=""
+</body>
+</html>

Added: trunk/LayoutTests/fast/dom/HTMLDialogElement/non-modal-dialog-does-not-block-mouse-events-expected.txt (0 => 145340)


--- trunk/LayoutTests/fast/dom/HTMLDialogElement/non-modal-dialog-does-not-block-mouse-events-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/HTMLDialogElement/non-modal-dialog-does-not-block-mouse-events-expected.txt	2013-03-11 06:13:05 UTC (rev 145340)
@@ -0,0 +1,10 @@
+Test for bug 110952. Ensure that non-modal dialogs do not block mouse events. To test manually, click the red box. The test succeeds if the red box turns green.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS div.firedOn is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/dom/HTMLDialogElement/non-modal-dialog-does-not-block-mouse-events.html (0 => 145340)


--- trunk/LayoutTests/fast/dom/HTMLDialogElement/non-modal-dialog-does-not-block-mouse-events.html	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/HTMLDialogElement/non-modal-dialog-does-not-block-mouse-events.html	2013-03-11 06:13:05 UTC (rev 145340)
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+#div {
+    height: 100px;
+    width: 100px;
+    background: red;
+}
+</style>
+<script src=""
+<script>
+if (window.internals)
+    internals.settings.setDialogElementEnabled(true);
+</script>
+</head>
+<body>
+<div id="div"></div>
+<dialog id="dialog"></dialog>
+<script>
+description('Test for bug 110952. Ensure that non-modal dialogs do not block mouse events. To test manually, click the red box. The test succeeds if the red box turns green.');
+
+function clickOn(element)
+{
+    if (!window.eventSender)
+        return;
+
+    var absoluteTop = 0;
+    var absoluteLeft = 0;
+    for (var parentNode = element; parentNode; parentNode = parentNode.offsetParent) {
+      absoluteLeft += parentNode.offsetLeft;
+      absoluteTop += parentNode.offsetTop;
+    }
+
+    var x = absoluteLeft + element.offsetWidth / 2;
+    var y = absoluteTop + element.offsetHeight / 2;
+    eventSender.mouseMoveTo(x, y);
+    eventSender.mouseDown();
+    eventSender.mouseUp()
+    eventSender.mouseMoveTo(0, 0);
+}
+
+if (window.testRunner)
+    testRunner.dumpAsText();
+
+dialog = document.getElementById('dialog');
+dialog.show();
+
+div = document.getElementById('div');
+div.firedOn = false;
+div.addEventListener('click', function(event) {
+    div.firedOn = true;
+    div.style.backgroundColor = 'green';
+});
+
+clickOn(div);
+
+shouldBeTrue('div.firedOn');
+</script>
+<script src=""
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (145339 => 145340)


--- trunk/Source/WebCore/ChangeLog	2013-03-11 05:42:02 UTC (rev 145339)
+++ trunk/Source/WebCore/ChangeLog	2013-03-11 06:13:05 UTC (rev 145340)
@@ -1,3 +1,32 @@
+2013-03-10  Matt Falkenhagen  <[email protected]>
+
+        Implement inert subtrees needed for modal <dialog>
+        https://bugs.webkit.org/show_bug.cgi?id=110952
+
+        Reviewed by Hajime Morrita.
+
+        This changes Node::disabled() to return true when a modal dialog is
+        open and the node is not in the dialog.
+
+        Reusing disabled for inertness is useful because then event
+        targeting and focus control automatically have the desired behavior:
+        inert nodes are skipped over.
+
+        Tests: fast/dom/HTMLDialogElement/closed-dialog-does-not-block-mouse-events.html
+               fast/dom/HTMLDialogElement/modal-dialog-blocks-mouse-events.html
+               fast/dom/HTMLDialogElement/non-modal-dialog-does-not-block-mouse-events.html
+
+        * dom/Document.h:
+        (WebCore::Document::activeModalDialog): Returns the topmost element in the top layer.
+        Since now the only elements in the top layer are modal dialogs, it is the active modal dialog.
+        * dom/Node.cpp:
+        (WebCore):
+        (WebCore::Node::isInert): As per the spec, a node that is not an ancestor or descendant of the modal dialog is inert.
+        (WebCore::Node::disabled): Return false when inert.
+        * dom/Node.h:
+        * html/HTMLFormControlElement.cpp:
+        (WebCore::HTMLFormControlElement::disabled): Fall back to the superclass so inert is taken into account.
+
 2013-03-10  Glenn Adams  <[email protected]>
 
         Line breaking opportunities at the end of a text node are missed

Modified: trunk/Source/WebCore/dom/Document.h (145339 => 145340)


--- trunk/Source/WebCore/dom/Document.h	2013-03-11 05:42:02 UTC (rev 145339)
+++ trunk/Source/WebCore/dom/Document.h	2013-03-11 06:13:05 UTC (rev 145340)
@@ -1179,6 +1179,7 @@
     void addToTopLayer(Element*);
     void removeFromTopLayer(Element*);
     const Vector<RefPtr<Element> >& topLayerElements() const { return m_topLayerElements; }
+    Element* activeModalDialog() const { return !m_topLayerElements.isEmpty() ? m_topLayerElements.last().get() : 0; }
 #endif
 
 #if ENABLE(TEMPLATE_ELEMENT)

Modified: trunk/Source/WebCore/dom/Node.cpp (145339 => 145340)


--- trunk/Source/WebCore/dom/Node.cpp	2013-03-11 05:42:02 UTC (rev 145339)
+++ trunk/Source/WebCore/dom/Node.cpp	2013-03-11 06:13:05 UTC (rev 145340)
@@ -902,6 +902,14 @@
     return this;
 }
 
+#if ENABLE(DIALOG_ELEMENT)
+bool Node::isInert() const
+{
+    Element* dialog = document()->activeModalDialog();
+    return dialog && !containsIncludingShadowDOM(dialog) && !dialog->containsIncludingShadowDOM(this);
+}
+#endif
+
 unsigned Node::nodeIndex() const
 {
     Node *_tempNode = previousSibling();
@@ -2446,6 +2454,10 @@
 
 bool Node::disabled() const
 {
+#if ENABLE(DIALOG_ELEMENT)
+    if (isInert())
+        return true;
+#endif
     return false;
 }
 

Modified: trunk/Source/WebCore/dom/Node.h (145339 => 145340)


--- trunk/Source/WebCore/dom/Node.h	2013-03-11 05:42:02 UTC (rev 145339)
+++ trunk/Source/WebCore/dom/Node.h	2013-03-11 06:13:05 UTC (rev 145340)
@@ -414,6 +414,10 @@
     virtual bool isMouseFocusable() const;
     virtual Node* focusDelegate();
 
+#if ENABLE(DIALOG_ELEMENT)
+    bool isInert() const;
+#endif
+
     enum UserSelectAllTreatment {
         UserSelectAllDoesNotAffectEditability,
         UserSelectAllIsAlwaysNonEditable

Modified: trunk/Source/WebCore/html/HTMLFormControlElement.cpp (145339 => 145340)


--- trunk/Source/WebCore/html/HTMLFormControlElement.cpp	2013-03-11 05:42:02 UTC (rev 145339)
+++ trunk/Source/WebCore/html/HTMLFormControlElement.cpp	2013-03-11 06:13:05 UTC (rev 145340)
@@ -281,7 +281,9 @@
 
     if (m_ancestorDisabledState == AncestorDisabledStateUnknown)
         updateAncestorDisabledState();
-    return m_ancestorDisabledState == AncestorDisabledStateDisabled;
+    if (m_ancestorDisabledState == AncestorDisabledStateDisabled)
+        return true;
+    return HTMLElement::disabled();
 }
 
 bool HTMLFormControlElement::isRequired() const
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to