Title: [173631] trunk/Source/WebCore
Revision
173631
Author
[email protected]
Date
2014-09-15 14:47:18 -0700 (Mon, 15 Sep 2014)

Log Message

Videos with controls enabled never receive 'dragstart' events.
https://bugs.webkit.org/show_bug.cgi?id=136837

Reviewed by Simon Fraser.

When initiating a drag, the DragController checks whether the hit-tested element at a
drag location is a child of the drag source, and bails if early if that is not the case.
For a <video> element with controls, the hit-tested element is an element within the
<video> element's Shadow DOM. Because the DragController uses a method which does not
take Shadow DOM into account when determining a child-parent relationship, this test fails
and all drag operations fail as well.

For <video> elements only, when testing whether the drag source is an ancestor of the
hit-tested element, use containsIncludingShadowDOM() instead of contains(). To ensure that
the controls are still usable when a drag listener is active on a <video> element, mark
the controls as a draggable element, but simply call preventDefault() in the controls'
'dragstart' handler, ensuring the timeline and volume controls are themselves still draggable.

* Modules/mediacontrols/mediaControlsApple.css:
(audio::-webkit-media-controls-panel):
* Modules/mediacontrols/mediaControlsApple.js:
(Controller.prototype.createControls):
(Controller.prototype.handlePanelDragStart):
* page/DragController.cpp:
(WebCore::DragController::startDrag):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (173630 => 173631)


--- trunk/Source/WebCore/ChangeLog	2014-09-15 21:40:28 UTC (rev 173630)
+++ trunk/Source/WebCore/ChangeLog	2014-09-15 21:47:18 UTC (rev 173631)
@@ -1,3 +1,31 @@
+2014-09-15  Jer Noble  <[email protected]>
+
+        Videos with controls enabled never receive 'dragstart' events.
+        https://bugs.webkit.org/show_bug.cgi?id=136837
+
+        Reviewed by Simon Fraser.
+
+        When initiating a drag, the DragController checks whether the hit-tested element at a
+        drag location is a child of the drag source, and bails if early if that is not the case.
+        For a <video> element with controls, the hit-tested element is an element within the
+        <video> element's Shadow DOM. Because the DragController uses a method which does not
+        take Shadow DOM into account when determining a child-parent relationship, this test fails
+        and all drag operations fail as well.
+
+        For <video> elements only, when testing whether the drag source is an ancestor of the
+        hit-tested element, use containsIncludingShadowDOM() instead of contains(). To ensure that
+        the controls are still usable when a drag listener is active on a <video> element, mark
+        the controls as a draggable element, but simply call preventDefault() in the controls'
+        'dragstart' handler, ensuring the timeline and volume controls are themselves still draggable.
+
+        * Modules/mediacontrols/mediaControlsApple.css:
+        (audio::-webkit-media-controls-panel):
+        * Modules/mediacontrols/mediaControlsApple.js:
+        (Controller.prototype.createControls):
+        (Controller.prototype.handlePanelDragStart):
+        * page/DragController.cpp:
+        (WebCore::DragController::startDrag):
+
 2014-09-15  Roger Fong  <[email protected]>
 
         Unreviewed. Add an unimplemented case to handle CSSPropertyWebkitInitialLetter so we don't get an assertion failure.

Modified: trunk/Source/WebCore/Modules/mediacontrols/mediaControlsApple.css (173630 => 173631)


--- trunk/Source/WebCore/Modules/mediacontrols/mediaControlsApple.css	2014-09-15 21:40:28 UTC (rev 173630)
+++ trunk/Source/WebCore/Modules/mediacontrols/mediaControlsApple.css	2014-09-15 21:47:18 UTC (rev 173631)
@@ -80,6 +80,7 @@
     height: 25px;
     line-height: 25px;
     -webkit-user-select: none;
+    -webkit-user-drag: element;
     background-color: transparent;
     background-image: -webkit-linear-gradient(top,
         rgba(0,  0,  0,  .92) 0,

Modified: trunk/Source/WebCore/Modules/mediacontrols/mediaControlsApple.js (173630 => 173631)


--- trunk/Source/WebCore/Modules/mediacontrols/mediaControlsApple.js	2014-09-15 21:40:28 UTC (rev 173630)
+++ trunk/Source/WebCore/Modules/mediacontrols/mediaControlsApple.js	2014-09-15 21:47:18 UTC (rev 173631)
@@ -296,6 +296,7 @@
         this.listenFor(panel, 'transitionend', this.handlePanelTransitionEnd);
         this.listenFor(panel, 'click', this.handlePanelClick);
         this.listenFor(panel, 'dblclick', this.handlePanelClick);
+        this.listenFor(panel, 'dragstart', this.handlePanelDragStart);
 
         var rewindButton = this.controls.rewindButton = document.createElement('button');
         rewindButton.setAttribute('pseudo', '-webkit-media-controls-rewind-button');
@@ -697,6 +698,12 @@
         event.preventDefault();
     },
 
+    handlePanelDragStart: function(event)
+    {
+        // Prevent drags in the panel from triggering a drag event on the <video> element.
+        event.preventDefault();
+    },
+
     handleRewindButtonClicked: function(event)
     {
         var newTime = Math.max(

Modified: trunk/Source/WebCore/page/DragController.cpp (173630 => 173631)


--- trunk/Source/WebCore/page/DragController.cpp	2014-09-15 21:40:28 UTC (rev 173630)
+++ trunk/Source/WebCore/page/DragController.cpp	2014-09-15 21:47:18 UTC (rev 173631)
@@ -721,7 +721,16 @@
         return false;
 
     HitTestResult hitTestResult = src.eventHandler().hitTestResultAtPoint(dragOrigin, HitTestRequest::ReadOnly | HitTestRequest::Active);
-    if (!state.source->contains(hitTestResult.innerNode()))
+
+    // FIXME(136836): Investigate whether all elements should use the containsIncludingShadowDOM() path here.
+    bool includeShadowDOM = state.source->isMediaElement();
+    bool sourceContainsHitNode;
+    if (includeShadowDOM)
+        sourceContainsHitNode = state.source->contains(hitTestResult.innerNode());
+    else
+        sourceContainsHitNode = state.source->containsIncludingShadowDOM(hitTestResult.innerNode());
+
+    if (!sourceContainsHitNode)
         // The original node being dragged isn't under the drag origin anymore... maybe it was
         // hidden or moved out from under the cursor. Regardless, we don't want to start a drag on
         // something that's not actually under the drag origin.
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to