Commit fd0b8a9b authored by scheib@chromium.org's avatar scheib@chromium.org
Browse files

Pointer Lock handles disconnected DOM elements

https://bugs.webkit.org/show_bug.cgi?id=77029

Reviewed by Adrienne Walker.

Source/WebCore:

Pointer Lock Controller now checks when elements or documents are
removed, and unlocks if the target element is being removed.

Tests: pointer-lock/locked-element-iframe-removed-from-dom.html
       pointer-lock/locked-element-removed-from-dom.html

* dom/Document.cpp:
(WebCore::Document::detach):
* dom/Element.cpp:
(WebCore::Element::removedFrom):
(WebCore::Element::webkitRequestPointerLock):
* page/PointerLockController.cpp:
(WebCore::PointerLockController::requestPointerLock):
(WebCore::PointerLockController::elementRemoved):
(WebCore):
(WebCore::PointerLockController::documentDetached):
(WebCore::PointerLockController::didLosePointerLock):
(WebCore::PointerLockController::enqueueEvent):
* page/PointerLockController.h:
(WebCore):
(PointerLockController):

LayoutTests:

Two new tests that verify pointer lock is released when the target
is removed from the document.

* pointer-lock/locked-element-iframe-removed-from-dom-expected.txt: Added.
* pointer-lock/locked-element-iframe-removed-from-dom.html: Added.
* pointer-lock/locked-element-removed-from-dom-expected.txt: Added.
* pointer-lock/locked-element-removed-from-dom.html: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@122626 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent c9c1237a
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
2012-07-13  Vincent Scheib  <scheib@chromium.org>
        Pointer Lock handles disconnected DOM elements
        https://bugs.webkit.org/show_bug.cgi?id=77029
        Reviewed by Adrienne Walker.
        Two new tests that verify pointer lock is released when the target
        is removed from the document.
        * pointer-lock/locked-element-iframe-removed-from-dom-expected.txt: Added.
        * pointer-lock/locked-element-iframe-removed-from-dom.html: Added.
        * pointer-lock/locked-element-removed-from-dom-expected.txt: Added.
        * pointer-lock/locked-element-removed-from-dom.html: Added.
2012-07-13  W. James MacLean  <wjmaclean@chromium.org>
        [chromium] Unreviewed gardening. storage/indexeddb/cursor-key-order.html has starting crashing on occassion.
+18 −0
Original line number Diff line number Diff line
Test removing an iframe containing a locked element causes lock to be released.

On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".


     Lock target in iframe. (main document handler)
     Lock target in iframe. (iframe handler)
PASS onwebkitpointerlockchange received after: Lock target in iframe. (iframe handler)
PASS document.webkitPointerLockElement is targetDiv1
PASS targetDiv1.parentElement.parentElement is targetIframe1.contentDocument.body
     Remove iframe & immediately lock target2. (main document handler)
     Remove iframe & immediately lock target2. (iframe handler)
PASS document.webkitPointerLockElement is targetDiv2
PASS onwebkitpointerlockchange received after: Remove iframe & immediately lock target2. (main document handler)
PASS successfullyParsed is true

TEST COMPLETE
+49 −0
Original line number Diff line number Diff line
<!DOCTYPE HTML>
<html>
<head>
<script src="../fast/js/resources/js-test-pre.js"></script>
<script src="resources/pointer-lock-test-harness.js"></script>
</head>
<body>
<div>
  <iframe id="iframe1"></iframe>
  <div id="target2"></div>
</div>
<script>
    description("Test removing an iframe containing a locked element causes lock to be released.")
    window.jsTestIsAsync = true;

    targetIframe1 = document.getElementById("iframe1");
    targetDiv2 = document.getElementById("target2");

    todo = [
        function () {
            // Load a blank iframe.
            targetIframe1.src = "about:blank";
            targetIframe1.onload = function () { doNextStepWithUserGesture(); }
        },
        function () {
            // Nest target element into iframe document.
            targetIframe1.contentDocument.body.innerHTML ="<div><div></div></div>";
            targetDiv1 = targetIframe1.contentDocument.body.firstChild.firstChild
            expectNoEvents("Lock target in iframe. (main document handler)");
            expectOnlyChangeEvent("Lock target in iframe. (iframe handler)", targetIframe1.contentDocument);
            targetDiv1.webkitRequestPointerLock();
            // doNextStep called by event handler.
        },
        function () {
            shouldBe("document.webkitPointerLockElement", "targetDiv1");
            shouldBe("targetDiv1.parentElement.parentElement", "targetIframe1.contentDocument.body");
            expectOnlyChangeEvent("Remove iframe & immediately lock target2. (main document handler)");
            expectNoEvents("Remove iframe & immediately lock target2. (iframe handler)", targetIframe1.contentDocument);
            targetIframe1.parentElement.removeChild(targetIframe1);
            targetDiv2.webkitRequestPointerLock();
            shouldBe("document.webkitPointerLockElement", "targetDiv2");
            // doNextStep called by event handler.
        },
    ];
    doNextStep();
</script>
<script src="../fast/js/resources/js-test-post.js"></script>
</body>
</html>
+21 −0
Original line number Diff line number Diff line
Test removing a locked element from a document causes lock to be released.

On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".


     Lock target in iframe. (main document handler).
     Lock target in iframe. (iframe handler)
PASS onwebkitpointerlockchange received after: Lock target in iframe. (iframe handler)
PASS document.webkitPointerLockElement is targetDiv1
PASS targetDiv1.parentElement.parentElement is targetIframe1.contentDocument.body
     Remove targetDiv1's parent from iframe & immediately lock target2. (main document handler)
     Remove targetDiv1's parent from iframe & immediately lock target2. (iframe handler)
PASS document.webkitPointerLockElement is null
PASS targetDiv1.parentElement.parentElement is null
PASS onwebkitpointerlockerror received after: Remove targetDiv1's parent from iframe & immediately lock target2. (main document handler)
PASS onwebkitpointerlockchange received after: Remove targetDiv1's parent from iframe & immediately lock target2. (iframe handler)
PASS successfullyParsed is true

TEST COMPLETE

+50 −0
Original line number Diff line number Diff line
<!DOCTYPE HTML>
<html>
<head>
<script src="../fast/js/resources/js-test-pre.js"></script>
<script src="resources/pointer-lock-test-harness.js"></script>
</head>
<body>
<div>
  <iframe id="iframe1"></iframe>
  <div id="target2"></div>
</div>
<script>
    description("Test removing a locked element from a document causes lock to be released.")
    window.jsTestIsAsync = true;

    targetIframe1 = document.getElementById("iframe1");
    targetDiv2 = document.getElementById("target2");

    todo = [
        function () {
            // Load a blank iframe.
            targetIframe1.src = "about:blank";
            targetIframe1.onload = function () { doNextStepWithUserGesture(); }
        },
        function () {
            // Nest target element into iframe document.
            targetIframe1.contentDocument.body.innerHTML ="<div><div></div></div>";
            targetDiv1 = targetIframe1.contentDocument.body.firstChild.firstChild
            expectNoEvents("Lock target in iframe. (main document handler).");
            expectOnlyChangeEvent("Lock target in iframe. (iframe handler)", targetIframe1.contentDocument);
            targetDiv1.webkitRequestPointerLock();
            // doNextStep called by event handler.
        },
        function () {
            shouldBe("document.webkitPointerLockElement", "targetDiv1");
            shouldBe("targetDiv1.parentElement.parentElement", "targetIframe1.contentDocument.body");
            expectOnlyErrorEvent("Remove targetDiv1's parent from iframe & immediately lock target2. (main document handler)");
            expectOnlyChangeEvent("Remove targetDiv1's parent from iframe & immediately lock target2. (iframe handler)", targetIframe1.contentDocument);
            targetDiv1.parentElement.parentElement.removeChild(targetDiv1.parentElement);
            targetDiv2.webkitRequestPointerLock();
            shouldBe("document.webkitPointerLockElement", "null");
            shouldBe("targetDiv1.parentElement.parentElement", "null");
            // doNextStep called by event handler.
        },
    ];
    doNextStep();
</script>
<script src="../fast/js/resources/js-test-post.js"></script>
</body>
</html>
Loading