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