Source/WebCore/ChangeLog

 12013-03-08 Matt Falkenhagen <falken@chromium.org>
 2
 3 Implement inert subtrees needed for modal <dialog>
 4 https://bugs.webkit.org/show_bug.cgi?id=110952
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 This changes Node::disabled() to return true when a modal dialog is
 9 open and the node is not in the dialog.
 10
 11 Reusing disabled for inertness is useful because then event
 12 targeting and focus control automatically have the desired behavior:
 13 inert nodes are skipped over.
 14
 15 Tests: fast/dom/HTMLDialogElement/closed-dialog-does-not-block-mouse-events.html
 16 fast/dom/HTMLDialogElement/modal-dialog-blocks-mouse-events.html
 17 fast/dom/HTMLDialogElement/non-modal-dialog-does-not-block-mouse-events.html
 18
 19 * dom/Document.h:
 20 (WebCore::Document::activeModalDialog): Returns the topmost element in the top layer.
 21 Since now the only elements in the top layer are modal dialogs, it is the active modal dialog.
 22 * dom/Node.cpp:
 23 (WebCore):
 24 (WebCore::Node::isInert): As per the spec, a node that is not an ancestor or descendant of the modal dialog is inert.
 25 (WebCore::Node::disabled): Return false when inert.
 26 * dom/Node.h:
 27 * html/HTMLFormControlElement.cpp:
 28 (WebCore::HTMLFormControlElement::disabled): Fall back to the superclass so inert is taken into account.
 29
1302013-03-07 Sheriff Bot <webkit.review.bot@gmail.com>
231
332 Unreviewed, rolling out r145097.

Source/WebCore/dom/Document.h

@@public:
11791179 void addToTopLayer(Element*);
11801180 void removeFromTopLayer(Element*);
11811181 const Vector<RefPtr<Element> >& topLayerElements() const { return m_topLayerElements; }
 1182 Element* activeModalDialog() const { return !m_topLayerElements.isEmpty() ? m_topLayerElements.last().get() : 0; }
11821183#endif
11831184
11841185#if ENABLE(TEMPLATE_ELEMENT)

Source/WebCore/dom/Node.cpp

@@Node* Node::focusDelegate()
907907 return this;
908908}
909909
 910#if ENABLE(DIALOG_ELEMENT)
 911bool Node::isInert() const
 912{
 913 Element* dialog = document()->activeModalDialog();
 914 return dialog && !containsIncludingShadowDOM(dialog) && !dialog->containsIncludingShadowDOM(this);
 915}
 916#endif
 917
910918unsigned Node::nodeIndex() const
911919{
912920 Node *_tempNode = previousSibling();

@@void Node::dispatchInputEvent()
24512459
24522460bool Node::disabled() const
24532461{
 2462#if ENABLE(DIALOG_ELEMENT)
 2463 if (isInert())
 2464 return true;
 2465#endif
24542466 return false;
24552467}
24562468

Source/WebCore/dom/Node.h

@@public:
414414 virtual bool isMouseFocusable() const;
415415 virtual Node* focusDelegate();
416416
 417#if ENABLE(DIALOG_ELEMENT)
 418 bool isInert() const;
 419#endif
 420
417421 enum UserSelectAllTreatment {
418422 UserSelectAllDoesNotAffectEditability,
419423 UserSelectAllIsAlwaysNonEditable

Source/WebCore/html/HTMLFormControlElement.cpp

@@bool HTMLFormControlElement::disabled() const
281281
282282 if (m_ancestorDisabledState == AncestorDisabledStateUnknown)
283283 updateAncestorDisabledState();
284  return m_ancestorDisabledState == AncestorDisabledStateDisabled;
 284 if (m_ancestorDisabledState == AncestorDisabledStateDisabled)
 285 return true;
 286 return HTMLElement::disabled();
285287}
286288
287289bool HTMLFormControlElement::isRequired() const

LayoutTests/ChangeLog

 12013-03-08 Matt Falkenhagen <falken@chromium.org>
 2
 3 Implement inert subtrees needed for modal <dialog>
 4 https://bugs.webkit.org/show_bug.cgi?id=110952
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 * fast/dom/HTMLDialogElement/closed-dialog-does-not-block-mouse-events-expected.txt: Added.
 9 * fast/dom/HTMLDialogElement/closed-dialog-does-not-block-mouse-events.html: Added.
 10 * fast/dom/HTMLDialogElement/modal-dialog-blocks-mouse-events-expected.txt: Added.
 11 * fast/dom/HTMLDialogElement/modal-dialog-blocks-mouse-events.html: Added.
 12 * fast/dom/HTMLDialogElement/non-modal-dialog-does-not-block-mouse-events-expected.txt: Added.
 13 * fast/dom/HTMLDialogElement/non-modal-dialog-does-not-block-mouse-events.html: Added.
 14
1152013-03-07 Rafael Weinstein <rafaelw@chromium.org>
216
317 Unreviewed gardening.

LayoutTests/fast/dom/HTMLDialogElement/closed-dialog-does-not-block-mouse-events-expected.txt

 1Test 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.
 2
 3On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 4
 5
 6PASS div.firedOn is true
 7PASS successfullyParsed is true
 8
 9TEST COMPLETE
 10

LayoutTests/fast/dom/HTMLDialogElement/closed-dialog-does-not-block-mouse-events.html

 1<!DOCTYPE html>
 2<html>
 3<head>
 4<style>
 5#div {
 6 height: 100px;
 7 width: 100px;
 8 background: red;
 9}
 10</style>
 11<script src="../../js/resources/js-test-pre.js"></script>
 12<script>
 13if (window.internals)
 14 internals.settings.setDialogElementEnabled(true);
 15</script>
 16</head>
 17<body>
 18<div id="div"></div>
 19<dialog id="dialog"></dialog>
 20<dialog></dialog>
 21<script>
 22description('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.');
 23
 24function clickOn(element)
 25{
 26 if (!window.eventSender)
 27 return;
 28
 29 var absoluteTop = 0;
 30 var absoluteLeft = 0;
 31 for (var parentNode = element; parentNode; parentNode = parentNode.offsetParent) {
 32 absoluteLeft += parentNode.offsetLeft;
 33 absoluteTop += parentNode.offsetTop;
 34 }
 35
 36 var x = absoluteLeft + element.offsetWidth / 2;
 37 var y = absoluteTop + element.offsetHeight / 2;
 38 eventSender.mouseMoveTo(x, y);
 39 eventSender.mouseDown();
 40 eventSender.mouseUp()
 41 eventSender.mouseMoveTo(0, 0);
 42}
 43
 44if (window.testRunner)
 45 testRunner.dumpAsText();
 46
 47dialog = document.getElementById('dialog');
 48dialog.showModal();
 49dialog.close();
 50
 51div = document.getElementById('div');
 52div.addEventListener('click', function(event) {
 53 div.firedOn = true;
 54 div.style.backgroundColor = 'green';
 55});
 56
 57clickOn(div);
 58
 59shouldBeTrue('div.firedOn');
 60</script>
 61<script src="../../js/resources/js-test-post.js"></script>
 62</body>
 63</html>

LayoutTests/fast/dom/HTMLDialogElement/modal-dialog-blocks-mouse-events-expected.txt

 1Test 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.
 2
 3On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 4
 5
 6PASS inertDiv.firedOn is false
 7PASS Object.keys(dialogDiv.firedOnEvents).length is events.length
 8PASS successfullyParsed is true
 9
 10TEST COMPLETE
 11

LayoutTests/fast/dom/HTMLDialogElement/modal-dialog-blocks-mouse-events.html

 1<!DOCTYPE html>
 2<html>
 3<head>
 4<style>
 5#inert-div {
 6 height: 100px;
 7 width: 100px;
 8 background: green;
 9}
 10
 11#dialog-div {
 12 height: 100px;
 13 width: 100px;
 14 background: red;
 15}
 16</style>
 17<script src="../../js/resources/js-test-pre.js"></script>
 18<script>
 19if (window.internals)
 20 internals.settings.setDialogElementEnabled(true);
 21</script>
 22</head>
 23<body>
 24<div id="inert-div"></div>
 25<dialog id="dialog">
 26 <div id="dialog-div"></div>
 27</dialog>
 28<script>
 29description('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.');
 30
 31function clickOn(element)
 32{
 33 if (!window.eventSender)
 34 return;
 35
 36 var absoluteTop = 0;
 37 var absoluteLeft = 0;
 38 for (var parentNode = element; parentNode; parentNode = parentNode.offsetParent) {
 39 absoluteLeft += parentNode.offsetLeft;
 40 absoluteTop += parentNode.offsetTop;
 41 }
 42
 43 var x = absoluteLeft + element.offsetWidth / 2;
 44 var y = absoluteTop + element.offsetHeight / 2;
 45 eventSender.mouseMoveTo(x, y);
 46 eventSender.mouseDown();
 47 eventSender.mouseUp();
 48 eventSender.mouseMoveTo(0, 0);
 49}
 50
 51if (window.testRunner)
 52 testRunner.dumpAsText();
 53
 54dialog.showModal();
 55
 56inertDiv = document.getElementById('inert-div');
 57dialogDiv = document.getElementById('dialog-div');
 58inertDiv.firedOn = false;
 59eventFiredOnInertNode = function(event) {
 60 inertDiv.firedOn = true;
 61 inertDiv.style.backgroundColor = 'red';
 62}
 63
 64events = ['mousedown', 'mouseup', 'click', 'mousemove', 'mouseover', 'mouseout'];
 65dialogDiv.firedOnEvents = {};
 66eventFiredOnDialog = function(event) {
 67 dialogDiv.firedOnEvents[event.type] = true;
 68 if (Object.keys(dialogDiv.firedOnEvents).length == events.length)
 69 dialogDiv.style.backgroundColor = 'green';
 70}
 71
 72for (var i = 0; i < events.length; ++i) {
 73 inertDiv.addEventListener(events[i], eventFiredOnInertNode);
 74 dialogDiv.addEventListener(events[i], eventFiredOnDialog);
 75}
 76
 77clickOn(inertDiv);
 78clickOn(dialogDiv);
 79
 80shouldBeFalse('inertDiv.firedOn');
 81shouldBe('Object.keys(dialogDiv.firedOnEvents).length', 'events.length');
 82</script>
 83<script src="../../js/resources/js-test-post.js"></script>
 84</body>
 85</html>

LayoutTests/fast/dom/HTMLDialogElement/non-modal-dialog-does-not-block-mouse-events-expected.txt

 1Test 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.
 2
 3On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 4
 5
 6PASS div.firedOn is true
 7PASS successfullyParsed is true
 8
 9TEST COMPLETE
 10

LayoutTests/fast/dom/HTMLDialogElement/non-modal-dialog-does-not-block-mouse-events.html

 1<!DOCTYPE html>
 2<html>
 3<head>
 4<style>
 5#div {
 6 height: 100px;
 7 width: 100px;
 8 background: red;
 9}
 10</style>
 11<script src="../../js/resources/js-test-pre.js"></script>
 12<script>
 13if (window.internals)
 14 internals.settings.setDialogElementEnabled(true);
 15</script>
 16</head>
 17<body>
 18<div id="div"></div>
 19<dialog id="dialog"></dialog>
 20<script>
 21description('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.');
 22
 23function clickOn(element)
 24{
 25 if (!window.eventSender)
 26 return;
 27
 28 var absoluteTop = 0;
 29 var absoluteLeft = 0;
 30 for (var parentNode = element; parentNode; parentNode = parentNode.offsetParent) {
 31 absoluteLeft += parentNode.offsetLeft;
 32 absoluteTop += parentNode.offsetTop;
 33 }
 34
 35 var x = absoluteLeft + element.offsetWidth / 2;
 36 var y = absoluteTop + element.offsetHeight / 2;
 37 eventSender.mouseMoveTo(x, y);
 38 eventSender.mouseDown();
 39 eventSender.mouseUp()
 40 eventSender.mouseMoveTo(0, 0);
 41}
 42
 43if (window.testRunner)
 44 testRunner.dumpAsText();
 45
 46dialog = document.getElementById('dialog');
 47dialog.show();
 48
 49div = document.getElementById('div');
 50div.firedOn = false;
 51div.addEventListener('click', function(event) {
 52 div.firedOn = true;
 53 div.style.backgroundColor = 'green';
 54});
 55
 56clickOn(div);
 57
 58shouldBeTrue('div.firedOn');
 59</script>
 60<script src="../../js/resources/js-test-post.js"></script>
 61</body>
 62</html>