Cannot bring up custom media controls at all on v.youku.com
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 13 Jul 2019 12:59:35 +0000 (12:59 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 13 Jul 2019 12:59:35 +0000 (12:59 +0000)
https://bugs.webkit.org/show_bug.cgi?id=199699
<rdar://problem/51835327>

Reviewed by Simon Fraser.

Source/WebCore:

The "find the node under the finger" heuristic should only find nodes that are visible to hit-testing.

When the user taps on the screen, we run a "find the best node under the finger" heuristic and use the node's location
to dispatch the associated event (e.g. mousePressed).
Ideally the "best node under the finger" and the final target node for the associated event are the same.
However these two methods configure the hit-testing process differently which could lead to node mismatch.
The "best node" heuristic calls hit-testing with AllowChildFrameContent. This flag allows hit-testing to descend into
subframes even if the subframe is not visible to hit-testing (visibility: hidden).
While event dispatching never descends into subfames through hit-testing, but instead it forwards the dispatching to subframes that are visible to hit-testing.

This patch addresses the mismatching node issue by calling the descending version of hit-testing with a flag that enforces visiblity check before descending into a subframe.

Tests: fast/events/touch/ios/visibility-hidden-iframe-click.html
       fast/events/touch/ios/visibility-hidden-nested-iframe-click.html

* page/ios/FrameIOS.mm:
(WebCore::Frame::hitTestResultAtViewportLocation):
* rendering/HitTestRequest.h:
(WebCore::HitTestRequest::skipsChildFrameContentInvisibleToHitTest const):
* rendering/RenderWidget.cpp:
(WebCore::RenderWidget::nodeAtPoint):

Source/WebKit:

* WebProcess/InjectedBundle/InjectedBundleNavigationAction.cpp:
(WebKit::InjectedBundleNavigationAction::InjectedBundleNavigationAction):
* WebProcess/WebPage/Cocoa/WebPageCocoa.mm:
(WebKit::WebPage::performDictionaryLookupAtLocation):
* WebProcess/WebPage/WebFrame.cpp:
(WebKit::WebFrame::hitTest const):
* WebProcess/WebPage/WebPage.cpp:
(WebKit::handleContextMenuEvent):
(WebKit::WebPage::characterIndexForPointAsync):
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::handleStylusSingleTapAtPoint):
(WebKit::textInteractionPositionInformation):
* WebProcess/WebPage/mac/WebPageMac.mm:
(WebKit::WebPage::shouldDelayWindowOrderingEvent):
(WebKit::WebPage::acceptsFirstMouse):
(WebKit::WebPage::performImmediateActionHitTestAtLocation):

Source/WebKitLegacy/mac:

* WebCoreSupport/WebFrameLoaderClient.mm:
(WebFrameLoaderClient::actionDictionary const):
* WebView/WebFrame.mm:
(-[WebFrame elementAtPoint:]):
* WebView/WebHTMLView.mm:
(-[WebHTMLView elementAtPoint:allowShadowContent:]):
* WebView/WebImmediateActionController.mm:
(-[WebImmediateActionController performHitTestAtPoint:]):

Source/WebKitLegacy/win:

* WebActionPropertyBag.cpp:
(WebActionPropertyBag::Read):
* WebView.cpp:
(WebView::handleContextMenuEvent):
(WebView::elementAtPoint):

LayoutTests:

* fast/events/touch/ios/visibility-hidden-iframe-click-expected.txt: Added.
* fast/events/touch/ios/visibility-hidden-iframe-click.html: Added.
* fast/events/touch/ios/visibility-hidden-nested-iframe-click-expected.txt: Added.
* fast/events/touch/ios/visibility-hidden-nested-iframe-click.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@247416 268f45cc-cd09-0410-ab3c-d52691b4dbfc

32 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/events/touch/ios/visibility-hidden-iframe-click-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/touch/ios/visibility-hidden-iframe-click.html [new file with mode: 0644]
LayoutTests/fast/events/touch/ios/visibility-hidden-nested-iframe-click-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/touch/ios/visibility-hidden-nested-iframe-click.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/page/AutoscrollController.cpp
Source/WebCore/page/ContextMenuController.cpp
Source/WebCore/page/DragController.cpp
Source/WebCore/page/EventHandler.cpp
Source/WebCore/page/EventHandler.h
Source/WebCore/page/FocusController.cpp
Source/WebCore/page/Frame.cpp
Source/WebCore/page/ios/FrameIOS.mm
Source/WebCore/rendering/HitTestRequest.h
Source/WebCore/rendering/RenderWidget.cpp
Source/WebCore/testing/Internals.mm
Source/WebKit/ChangeLog
Source/WebKit/WebProcess/InjectedBundle/InjectedBundleNavigationAction.cpp
Source/WebKit/WebProcess/WebPage/Cocoa/WebPageCocoa.mm
Source/WebKit/WebProcess/WebPage/WebFrame.cpp
Source/WebKit/WebProcess/WebPage/WebPage.cpp
Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm
Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm
Source/WebKitLegacy/mac/ChangeLog
Source/WebKitLegacy/mac/WebCoreSupport/WebFrameLoaderClient.mm
Source/WebKitLegacy/mac/WebView/WebFrame.mm
Source/WebKitLegacy/mac/WebView/WebHTMLView.mm
Source/WebKitLegacy/mac/WebView/WebImmediateActionController.mm
Source/WebKitLegacy/win/ChangeLog
Source/WebKitLegacy/win/WebActionPropertyBag.cpp
Source/WebKitLegacy/win/WebView.cpp

index ca250d9..82127c3 100644 (file)
@@ -1,3 +1,16 @@
+2019-07-13  Zalan Bujtas  <zalan@apple.com>
+
+        Cannot bring up custom media controls at all on v.youku.com
+        https://bugs.webkit.org/show_bug.cgi?id=199699
+        <rdar://problem/51835327>
+
+        Reviewed by Simon Fraser.
+
+        * fast/events/touch/ios/visibility-hidden-iframe-click-expected.txt: Added.
+        * fast/events/touch/ios/visibility-hidden-iframe-click.html: Added.
+        * fast/events/touch/ios/visibility-hidden-nested-iframe-click-expected.txt: Added.
+        * fast/events/touch/ios/visibility-hidden-nested-iframe-click.html: Added.
+
 2019-07-12  Youenn Fablet  <youenn@apple.com>
 
         Stopping a cloned MediaStream video track should not stop any other video track
diff --git a/LayoutTests/fast/events/touch/ios/visibility-hidden-iframe-click-expected.txt b/LayoutTests/fast/events/touch/ios/visibility-hidden-iframe-click-expected.txt
new file mode 100644 (file)
index 0000000..ec17b98
--- /dev/null
@@ -0,0 +1,2 @@
+PASS if 'clicked' text is shown below
+clicked
diff --git a/LayoutTests/fast/events/touch/ios/visibility-hidden-iframe-click.html b/LayoutTests/fast/events/touch/ios/visibility-hidden-iframe-click.html
new file mode 100644 (file)
index 0000000..0f849a4
--- /dev/null
@@ -0,0 +1,48 @@
+<!DOCTYPE html><!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+<html>
+<head>
+<title>This tests the case when the tap target node is a hidden iframe.</title>
+<script src="../../../../resources/basic-gestures.js"></script>
+<style>
+#tapThis {
+ width: 400px;
+ height: 400px;
+ background-color: green;
+}
+
+iframe {
+  position: absolute;
+  height: 500px;
+  width: 500px;
+  left: 0px;
+  top: 0px;
+  visibility: hidden;
+}
+</style>
+
+<script>
+async function test() {
+    if (!window.testRunner || !testRunner.runUIScript)
+        return;
+
+    testRunner.waitUntilDone();
+    testRunner.dumpAsText();
+
+    await tapAtPoint(200, 200);
+}
+</script>
+</head>
+<body onload="test()">
+<div id=tapThis>PASS if 'clicked' text is shown below</div>
+<iframe srcdoc="<body><pre style='width: 500px; height: 500px; background-color: yellow'></pre></body>"></iframe>
+<pre id=result></pre>
+<script>
+tapThis.addEventListener("click", function( event ) {   
+    result.innerHTML = "clicked";
+    if (window.testRunner)
+        testRunner.notifyDone();
+
+}, false);
+</script>
+</body>
+</html>
diff --git a/LayoutTests/fast/events/touch/ios/visibility-hidden-nested-iframe-click-expected.txt b/LayoutTests/fast/events/touch/ios/visibility-hidden-nested-iframe-click-expected.txt
new file mode 100644 (file)
index 0000000..f116331
--- /dev/null
@@ -0,0 +1,3 @@
+PASS if 'clicked' text is shown below
+
+clicked
diff --git a/LayoutTests/fast/events/touch/ios/visibility-hidden-nested-iframe-click.html b/LayoutTests/fast/events/touch/ios/visibility-hidden-nested-iframe-click.html
new file mode 100644 (file)
index 0000000..a0dc1f2
--- /dev/null
@@ -0,0 +1,52 @@
+ <!DOCTYPE html><!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+<html>
+<head>
+<title>This tests the case when the target node of the tap is a nested iframe with visibility hidden.</title>
+<script src="../../../../resources/basic-gestures.js"></script>
+<style>
+#tapThis {
+ width: 400px;
+ height: 400px;
+ background-color: green;
+}
+
+iframe {
+  position: absolute;
+  height: 300px;
+  width: 300px;
+  left: 0px;
+  top: 0px;
+}
+</style>
+
+<script>
+async function test() {
+    if (!window.testRunner || !testRunner.runUIScript)
+        return;
+
+    testRunner.waitUntilDone();
+    testRunner.dumpAsText();
+
+    await tapAtPoint(100, 100);
+}
+</script>
+</head>
+<body onload="test()">
+<div id=tapThis>PASS if 'clicked' text is shown below</div>
+<iframe frameborder=0 id=visibleIframe srcdoc="
+<body>
+<div id=nestedFrameDiv style='width: 280px; height: 280px; background-color: blue; opacity: 0.7;'></div>
+<iframe frameborder=0 style='position: absolute; left: 0px; top: 0px; width: 200px; height: 200px; background-color: red; visibility: hidden'></iframe>
+<script>
+nestedFrameDiv.addEventListener('click', function( event ) {   
+    window.parent.result.innerHTML = 'clicked';
+    if (window.testRunner)
+        testRunner.notifyDone();
+
+}, false);
+</script>
+</body>
+"></iframe>
+<pre id=result></pre>
+</body>
+</html>
index ea154d6..52ca927 100644 (file)
@@ -1,3 +1,33 @@
+2019-07-13  Zalan Bujtas  <zalan@apple.com>
+
+        Cannot bring up custom media controls at all on v.youku.com
+        https://bugs.webkit.org/show_bug.cgi?id=199699
+        <rdar://problem/51835327>
+
+        Reviewed by Simon Fraser.
+
+        The "find the node under the finger" heuristic should only find nodes that are visible to hit-testing.
+
+        When the user taps on the screen, we run a "find the best node under the finger" heuristic and use the node's location
+        to dispatch the associated event (e.g. mousePressed).
+        Ideally the "best node under the finger" and the final target node for the associated event are the same.
+        However these two methods configure the hit-testing process differently which could lead to node mismatch.
+        The "best node" heuristic calls hit-testing with AllowChildFrameContent. This flag allows hit-testing to descend into
+        subframes even if the subframe is not visible to hit-testing (visibility: hidden).
+        While event dispatching never descends into subfames through hit-testing, but instead it forwards the dispatching to subframes that are visible to hit-testing.
+
+        This patch addresses the mismatching node issue by calling the descending version of hit-testing with a flag that enforces visiblity check before descending into a subframe.
+
+        Tests: fast/events/touch/ios/visibility-hidden-iframe-click.html
+               fast/events/touch/ios/visibility-hidden-nested-iframe-click.html
+
+        * page/ios/FrameIOS.mm:
+        (WebCore::Frame::hitTestResultAtViewportLocation):
+        * rendering/HitTestRequest.h:
+        (WebCore::HitTestRequest::skipsChildFrameContentInvisibleToHitTest const):
+        * rendering/RenderWidget.cpp:
+        (WebCore::RenderWidget::nodeAtPoint):
+
 2019-07-13  Chris Dumez  <cdumez@apple.com>
 
         Fix non thread-safe usage of makeWeakPtr() in MediaPlayerPrivateAVFoundation
index 4af7ccd..b3b1227 100644 (file)
@@ -127,7 +127,7 @@ void AutoscrollController::updateAutoscrollRenderer()
     RenderObject* renderer = m_autoscrollRenderer;
 
 #if ENABLE(PAN_SCROLLING)
-    HitTestResult hitTest = m_autoscrollRenderer->frame().eventHandler().hitTestResultAtPoint(m_panScrollStartPos, HitTestRequest::ReadOnly | HitTestRequest::Active);
+    HitTestResult hitTest = m_autoscrollRenderer->frame().eventHandler().hitTestResultAtPoint(m_panScrollStartPos, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::AllowChildFrameContent);
 
     if (Node* nodeAtPoint = hitTest.innerNode())
         renderer = nodeAtPoint->renderer();
index 85256af..5ab8bf6 100644 (file)
@@ -164,7 +164,7 @@ std::unique_ptr<ContextMenu> ContextMenuController::maybeCreateContextMenu(Event
     if (!frame)
         return nullptr;
 
-    auto result = frame->eventHandler().hitTestResultAtPoint(mouseEvent.absoluteLocation());
+    auto result = frame->eventHandler().hitTestResultAtPoint(mouseEvent.absoluteLocation(), HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowUserAgentShadowContent | HitTestRequest::AllowChildFrameContent);
     if (!result.innerNonSharedNode())
         return nullptr;
 
index b8d7661..075ad6a 100644 (file)
@@ -656,7 +656,7 @@ bool DragController::canProcessDrag(const DragData& dragData)
     if (!m_page.mainFrame().contentRenderer())
         return false;
 
-    result = m_page.mainFrame().eventHandler().hitTestResultAtPoint(point, HitTestRequest::ReadOnly | HitTestRequest::Active);
+    result = m_page.mainFrame().eventHandler().hitTestResultAtPoint(point, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::AllowChildFrameContent);
 
     auto* dragNode = result.innerNonSharedNode();
     if (!dragNode)
@@ -905,7 +905,7 @@ bool DragController::startDrag(Frame& src, const DragState& state, DragOperation
         return false;
 
     Ref<Frame> protector(src);
-    HitTestResult hitTestResult = src.eventHandler().hitTestResultAtPoint(dragOrigin, HitTestRequest::ReadOnly | HitTestRequest::Active);
+    HitTestResult hitTestResult = src.eventHandler().hitTestResultAtPoint(dragOrigin, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::AllowChildFrameContent);
 
     bool sourceContainsHitNode = state.source->containsIncludingShadowDOM(hitTestResult.innerNode());
     if (!sourceContainsHitNode) {
index fb32128..ef05ff1 100644 (file)
@@ -1207,8 +1207,7 @@ HitTestResult EventHandler::hitTestResultAtPoint(const LayoutPoint& point, HitTe
     if (!document)
         return result;
 
-    // hitTestResultAtPoint is specifically used to hitTest into all frames, thus it always allows child frame content.
-    HitTestRequest request(hitType | HitTestRequest::AllowChildFrameContent);
+    HitTestRequest request(hitType);
     document->hitTest(request, result);
     if (!request.readOnly())
         m_frame.document()->updateHoverActiveState(request, result.targetElement());
@@ -4158,7 +4157,7 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
         if (pointState == PlatformTouchPoint::TouchPressed) {
             HitTestResult result;
             if (freshTouchEvents) {
-                result = hitTestResultAtPoint(pagePoint, hitType);
+                result = hitTestResultAtPoint(pagePoint, hitType | HitTestRequest::AllowChildFrameContent);
                 m_originatingTouchPointTargetKey = touchPointTargetKey;
             } else if (m_originatingTouchPointDocument.get() && m_originatingTouchPointDocument->frame()) {
                 LayoutPoint pagePointInOriginatingDocument = documentPointForWindowPoint(*m_originatingTouchPointDocument->frame(), point.pos());
index e71133b..afb4010 100644 (file)
@@ -152,7 +152,7 @@ public:
     WEBCORE_EXPORT void dispatchFakeMouseMoveEventSoon();
     void dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad&);
 
-    WEBCORE_EXPORT HitTestResult hitTestResultAtPoint(const LayoutPoint&, HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowUserAgentShadowContent, const LayoutSize& padding = LayoutSize()) const;
+    WEBCORE_EXPORT HitTestResult hitTestResultAtPoint(const LayoutPoint&, HitTestRequest::HitTestRequestType, const LayoutSize& padding = LayoutSize()) const;
 
     bool mousePressed() const { return m_mousePressed; }
     Node* mousePressNode() const { return m_mousePressNode.get(); }
index d29c78f..41d4844 100644 (file)
@@ -967,7 +967,7 @@ static void updateFocusCandidateIfNeeded(FocusDirection direction, const FocusCa
         // If 2 nodes are intersecting, do hit test to find which node in on top.
         LayoutUnit x = intersectionRect.x() + intersectionRect.width() / 2;
         LayoutUnit y = intersectionRect.y() + intersectionRect.height() / 2;
-        HitTestResult result = candidate.visibleNode->document().page()->mainFrame().eventHandler().hitTestResultAtPoint(IntPoint(x, y), HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::IgnoreClipping | HitTestRequest::DisallowUserAgentShadowContent);
+        HitTestResult result = candidate.visibleNode->document().page()->mainFrame().eventHandler().hitTestResultAtPoint(IntPoint(x, y), HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::IgnoreClipping | HitTestRequest::DisallowUserAgentShadowContent | HitTestRequest::AllowChildFrameContent);
         if (candidate.visibleNode->contains(result.innerNode())) {
             closest = candidate;
             return;
index 615e691..eba6596 100644 (file)
@@ -728,7 +728,7 @@ String Frame::displayStringModifiedByEncoding(const String& str) const
 
 VisiblePosition Frame::visiblePositionForPoint(const IntPoint& framePoint) const
 {
-    HitTestResult result = eventHandler().hitTestResultAtPoint(framePoint, HitTestRequest::ReadOnly | HitTestRequest::Active);
+    HitTestResult result = eventHandler().hitTestResultAtPoint(framePoint, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::AllowChildFrameContent);
     Node* node = result.innerNonSharedNode();
     if (!node)
         return VisiblePosition();
@@ -750,7 +750,7 @@ Document* Frame::documentAtPoint(const IntPoint& point)
     HitTestResult result = HitTestResult(pt);
 
     if (contentRenderer())
-        result = eventHandler().hitTestResultAtPoint(pt);
+        result = eventHandler().hitTestResultAtPoint(pt, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowUserAgentShadowContent | HitTestRequest::AllowChildFrameContent);
     return result.innerNode() ? &result.innerNode()->document() : 0;
 }
 
index 3f0706a..b59c794 100644 (file)
@@ -182,7 +182,7 @@ CGRect Frame::renderRectForPoint(CGPoint point, bool* isReplaced, float* fontSiz
     if (!layer)
         return CGRectZero;
 
-    HitTestResult result = eventHandler().hitTestResultAtPoint(IntPoint(roundf(point.x), roundf(point.y)));
+    HitTestResult result = eventHandler().hitTestResultAtPoint(IntPoint(roundf(point.x), roundf(point.y)), HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowUserAgentShadowContent | HitTestRequest::AllowChildFrameContent);
 
     Node* node = result.innerNode();
     if (!node)
@@ -226,7 +226,7 @@ CGRect Frame::renderRectForPoint(CGPoint point, bool* isReplaced, float* fontSiz
 void Frame::betterApproximateNode(const IntPoint& testPoint, const NodeQualifier& nodeQualifierFunction, Node*& best, Node* failedNode, IntPoint& bestPoint, IntRect& bestRect, const IntRect& testRect)
 {
     IntRect candidateRect;
-    Node* candidate = nodeQualifierFunction(eventHandler().hitTestResultAtPoint(testPoint), failedNode, &candidateRect);
+    Node* candidate = nodeQualifierFunction(eventHandler().hitTestResultAtPoint(testPoint, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowUserAgentShadowContent | HitTestRequest::AllowVisibleChildFrameContentOnly), failedNode, &candidateRect);
 
     // Bail if we have no candidate, or the candidate is already equal to our current best node,
     // or our candidate is the avoidedNode and there is a current best node.
@@ -261,7 +261,8 @@ bool Frame::hitTestResultAtViewportLocation(const FloatPoint& viewportLocation,
         return false;
 
     center = view->windowToContents(roundedIntPoint(viewportLocation));
-    hitTestResult = eventHandler().hitTestResultAtPoint(center);
+    HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowUserAgentShadowContent | HitTestRequest::AllowVisibleChildFrameContentOnly;
+    hitTestResult = eventHandler().hitTestResultAtPoint(center, hitType);
     return true;
 }
 
@@ -310,7 +311,7 @@ Node* Frame::qualifyingNodeAtViewportLocation(const FloatPoint& viewportLocation
             IntSize testOffset(testOffsets[n] * searchRadius, testOffsets[n + 1] * searchRadius);
             IntPoint testPoint = testCenter + testOffset;
 
-            HitTestResult candidateInfo = eventHandler().hitTestResultAtPoint(testPoint);
+            HitTestResult candidateInfo = eventHandler().hitTestResultAtPoint(testPoint, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowUserAgentShadowContent | HitTestRequest::AllowChildFrameContent);
             Node* candidateNode = nodeQualifierFunction(candidateInfo, 0, 0);
             if (candidateNode && candidateNode->isDescendantOf(originalApproximateNode)) {
                 approximateNode = candidateNode;
index 1cf5144..f089634 100644 (file)
@@ -39,12 +39,13 @@ public:
         DisallowUserAgentShadowContent = 1 << 8,
         AllowFrameScrollbars = 1 << 9,
         AllowChildFrameContent = 1 << 10,
-        ChildFrameHitTest = 1 << 11,
-        AccessibilityHitTest = 1 << 12,
+        AllowVisibleChildFrameContentOnly = 1 << 11,
+        ChildFrameHitTest = 1 << 12,
+        AccessibilityHitTest = 1 << 13,
         // Collect a list of nodes instead of just one. Used for elementsFromPoint and rect-based tests.
-        CollectMultipleElements = 1 << 13,
+        CollectMultipleElements = 1 << 14,
         // When using list-based testing, continue hit testing even after a hit has been found.
-        IncludeAllElementsUnderPoint = 1 << 14
+        IncludeAllElementsUnderPoint = 1 << 15
     };
 
     typedef unsigned HitTestRequestType;
@@ -66,6 +67,7 @@ public:
     bool disallowsUserAgentShadowContent() const { return m_requestType & DisallowUserAgentShadowContent; }
     bool allowsFrameScrollbars() const { return m_requestType & AllowFrameScrollbars; }
     bool allowsChildFrameContent() const { return m_requestType & AllowChildFrameContent; }
+    bool allowsVisibleChildFrameContent() const { return m_requestType & AllowVisibleChildFrameContentOnly; }
     bool isChildFrameHitTest() const { return m_requestType & ChildFrameHitTest; }
     bool resultIsElementList() const { return m_requestType & CollectMultipleElements; }
     bool includesAllElementsUnderPoint() const { return m_requestType & IncludeAllElementsUnderPoint; }
index 155d2cb..7d77538 100644 (file)
@@ -362,7 +362,9 @@ RenderWidget* RenderWidget::find(const Widget& widget)
 
 bool RenderWidget::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction action)
 {
-    if (request.allowsChildFrameContent() && is<FrameView>(widget()) && downcast<FrameView>(*widget()).renderView()) {
+    auto shouldHitTestChildFrameContent = request.allowsChildFrameContent() || (request.allowsVisibleChildFrameContent() && visibleToHitTesting());
+    auto hasRenderView = is<FrameView>(widget()) && downcast<FrameView>(*widget()).renderView();
+    if (shouldHitTestChildFrameContent && hasRenderView) {
         FrameView& childFrameView = downcast<FrameView>(*widget());
 
         LayoutPoint adjustedLocation = accumulatedOffset + location();
index 20d71ba..b3ad6b9 100644 (file)
@@ -61,7 +61,7 @@ ExceptionOr<RefPtr<Range>> Internals::rangeForDictionaryLookupAtLocation(int x,
 
     document->updateLayoutIgnorePendingStylesheets();
 
-    HitTestResult result = document->frame()->mainFrame().eventHandler().hitTestResultAtPoint(IntPoint(x, y));
+    HitTestResult result = document->frame()->mainFrame().eventHandler().hitTestResultAtPoint(IntPoint(x, y), HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowUserAgentShadowContent | HitTestRequest::AllowChildFrameContent);
     RefPtr<Range> range;
     std::tie(range, std::ignore) = DictionaryLookup::rangeAtHitTestResult(result);
     return WTFMove(range);
index f66a667..25eef33 100644 (file)
@@ -1,3 +1,28 @@
+2019-07-13  Zalan Bujtas  <zalan@apple.com>
+
+        Cannot bring up custom media controls at all on v.youku.com
+        https://bugs.webkit.org/show_bug.cgi?id=199699
+        <rdar://problem/51835327>
+
+        Reviewed by Simon Fraser.
+
+        * WebProcess/InjectedBundle/InjectedBundleNavigationAction.cpp:
+        (WebKit::InjectedBundleNavigationAction::InjectedBundleNavigationAction):
+        * WebProcess/WebPage/Cocoa/WebPageCocoa.mm:
+        (WebKit::WebPage::performDictionaryLookupAtLocation):
+        * WebProcess/WebPage/WebFrame.cpp:
+        (WebKit::WebFrame::hitTest const):
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::handleContextMenuEvent):
+        (WebKit::WebPage::characterIndexForPointAsync):
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::WebPage::handleStylusSingleTapAtPoint):
+        (WebKit::textInteractionPositionInformation):
+        * WebProcess/WebPage/mac/WebPageMac.mm:
+        (WebKit::WebPage::shouldDelayWindowOrderingEvent):
+        (WebKit::WebPage::acceptsFirstMouse):
+        (WebKit::WebPage::performImmediateActionHitTestAtLocation):
+
 2019-07-12  Andy Estes  <aestes@apple.com>
 
         [Cocoa] -loadFileURL:allowingReadAccessToURL: should fully resolve file URLs
index 8ff4492..22f6873 100644 (file)
@@ -104,7 +104,7 @@ InjectedBundleNavigationAction::InjectedBundleNavigationAction(WebFrame* frame,
     , m_shouldTryAppLinks(navigationAction.shouldOpenExternalURLsPolicy() == ShouldOpenExternalURLsPolicy::ShouldAllow)
 {
     if (auto mouseEventData = navigationAction.mouseEventData()) {
-        m_hitTestResult = InjectedBundleHitTestResult::create(frame->coreFrame()->eventHandler().hitTestResultAtPoint(mouseEventData->absoluteLocation));
+        m_hitTestResult = InjectedBundleHitTestResult::create(frame->coreFrame()->eventHandler().hitTestResultAtPoint(mouseEventData->absoluteLocation, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowUserAgentShadowContent | HitTestRequest::AllowChildFrameContent));
         m_mouseButton = mouseButtonForMouseEventData(mouseEventData);
         m_syntheticClickType = syntheticClickTypeForNavigationAction(navigationAction);
         m_clickLocationInRootViewCoordinates = clickLocationInRootViewCoordinatesForNavigationAction(navigationAction);
index 4970cf5..d12b98a 100644 (file)
@@ -84,7 +84,7 @@ void WebPage::performDictionaryLookupAtLocation(const FloatPoint& floatPoint)
     }
     
     // Find the frame the point is over.
-    HitTestResult result = m_page->mainFrame().eventHandler().hitTestResultAtPoint(m_page->mainFrame().view()->windowToContents(roundedIntPoint(floatPoint)));
+    HitTestResult result = m_page->mainFrame().eventHandler().hitTestResultAtPoint(m_page->mainFrame().view()->windowToContents(roundedIntPoint(floatPoint)), HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowUserAgentShadowContent | HitTestRequest::AllowChildFrameContent);
     auto [range, options] = DictionaryLookup::rangeAtHitTestResult(result);
     if (!range)
         return;
index 4af495a..133bb3f 100644 (file)
@@ -644,7 +644,7 @@ RefPtr<InjectedBundleHitTestResult> WebFrame::hitTest(const IntPoint point) cons
     if (!m_coreFrame)
         return nullptr;
 
-    return InjectedBundleHitTestResult::create(m_coreFrame->eventHandler().hitTestResultAtPoint(point, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::IgnoreClipping | HitTestRequest::DisallowUserAgentShadowContent));
+    return InjectedBundleHitTestResult::create(m_coreFrame->eventHandler().hitTestResultAtPoint(point, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::IgnoreClipping | HitTestRequest::DisallowUserAgentShadowContent | HitTestRequest::AllowChildFrameContent));
 }
 
 bool WebFrame::getDocumentBackgroundColor(double* red, double* green, double* blue, double* alpha)
index 9bdb764..06c7316 100644 (file)
@@ -2628,7 +2628,7 @@ static bool isContextClick(const PlatformMouseEvent& event)
 static bool handleContextMenuEvent(const PlatformMouseEvent& platformMouseEvent, WebPage* page)
 {
     IntPoint point = page->corePage()->mainFrame().view()->windowToContents(platformMouseEvent.position());
-    HitTestResult result = page->corePage()->mainFrame().eventHandler().hitTestResultAtPoint(point);
+    HitTestResult result = page->corePage()->mainFrame().eventHandler().hitTestResultAtPoint(point, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowUserAgentShadowContent | HitTestRequest::AllowChildFrameContent);
 
     Frame* frame = &page->corePage()->mainFrame();
     if (result.innerNonSharedNode())
@@ -5217,7 +5217,7 @@ void WebPage::getSelectedRangeAsync(CallbackID callbackID)
 
 void WebPage::characterIndexForPointAsync(const WebCore::IntPoint& point, CallbackID callbackID)
 {
-    HitTestResult result = m_page->mainFrame().eventHandler().hitTestResultAtPoint(point);
+    HitTestResult result = m_page->mainFrame().eventHandler().hitTestResultAtPoint(point, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowUserAgentShadowContent | HitTestRequest::AllowChildFrameContent);
     Frame* frame = result.innerNonSharedNode() ? result.innerNodeFrame() : &m_page->focusController().focusedOrMainFrame();
     
     RefPtr<Range> range = frame->rangeForPoint(result.roundedPointInInnerNodeFrame());
index 873c9ff..7e2ada6 100644 (file)
@@ -1022,7 +1022,7 @@ void WebPage::handleStylusSingleTapAtPoint(const WebCore::IntPoint& point, uint6
     auto& frame = m_page->focusController().focusedOrMainFrame();
 
     auto pointInDocument = frame.view()->rootViewToContents(point);
-    HitTestResult hitTest = frame.eventHandler().hitTestResultAtPoint(pointInDocument, HitTestRequest::ReadOnly | HitTestRequest::Active);
+    HitTestResult hitTest = frame.eventHandler().hitTestResultAtPoint(pointInDocument, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::AllowChildFrameContent);
 
     Node* node = hitTest.innerNonSharedNode();
     if (!node)
@@ -2729,7 +2729,7 @@ static void textInteractionPositionInformation(WebPage& page, const HTMLInputEle
     if (!input.list())
         return;
 
-    HitTestResult result = page.corePage()->mainFrame().eventHandler().hitTestResultAtPoint(request.point, HitTestRequest::ReadOnly | HitTestRequest::Active);
+    HitTestResult result = page.corePage()->mainFrame().eventHandler().hitTestResultAtPoint(request.point, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::AllowChildFrameContent);
     if (result.innerNode() == input.dataListButtonElement())
         info.preventTextInteraction = true;
 }
index a07ca45..6be0582 100644 (file)
@@ -590,7 +590,7 @@ void WebPage::shouldDelayWindowOrderingEvent(const WebKit::WebMouseEvent& event,
 
     bool result = false;
 #if ENABLE(DRAG_SUPPORT)
-    HitTestResult hitResult = frame.eventHandler().hitTestResultAtPoint(frame.view()->windowToContents(event.position()), HitTestRequest::ReadOnly | HitTestRequest::Active);
+    HitTestResult hitResult = frame.eventHandler().hitTestResultAtPoint(frame.view()->windowToContents(event.position()), HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::AllowChildFrameContent);
     if (hitResult.isSelected())
         result = frame.eventHandler().eventMayStartDrag(platform(event));
 #endif
@@ -607,7 +607,7 @@ void WebPage::acceptsFirstMouse(int eventNumber, const WebKit::WebMouseEvent& ev
 
     auto& frame = m_page->focusController().focusedOrMainFrame();
 
-    HitTestResult hitResult = frame.eventHandler().hitTestResultAtPoint(frame.view()->windowToContents(event.position()), HitTestRequest::ReadOnly | HitTestRequest::Active);
+    HitTestResult hitResult = frame.eventHandler().hitTestResultAtPoint(frame.view()->windowToContents(event.position()), HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::AllowChildFrameContent);
     frame.eventHandler().setActivationEventNumber(eventNumber);
     bool result = false;
 #if ENABLE(DRAG_SUPPORT)
@@ -838,7 +838,7 @@ void WebPage::performImmediateActionHitTestAtLocation(WebCore::FloatPoint locati
     }
 
     IntPoint locationInContentCoordinates = mainFrame.view()->rootViewToContents(roundedIntPoint(locationInViewCoordinates));
-    HitTestResult hitTestResult = mainFrame.eventHandler().hitTestResultAtPoint(locationInContentCoordinates);
+    HitTestResult hitTestResult = mainFrame.eventHandler().hitTestResultAtPoint(locationInContentCoordinates, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowUserAgentShadowContent | HitTestRequest::AllowChildFrameContent);
 
     bool immediateActionHitTestPreventsDefault = false;
     Element* element = hitTestResult.targetElement();
@@ -946,7 +946,7 @@ std::tuple<RefPtr<WebCore::Range>, NSDictionary *> WebPage::lookupTextAtLocation
         return { nullptr, nil };
 
     auto point = roundedIntPoint(locationInViewCoordinates);
-    auto result = mainFrame.eventHandler().hitTestResultAtPoint(m_page->mainFrame().view()->windowToContents(point));
+    auto result = mainFrame.eventHandler().hitTestResultAtPoint(m_page->mainFrame().view()->windowToContents(point), HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowUserAgentShadowContent | HitTestRequest::AllowChildFrameContent);
     return DictionaryLookup::rangeAtHitTestResult(result);
 }
 
index 671f30a..f2653b2 100644 (file)
@@ -1,3 +1,20 @@
+2019-07-13  Zalan Bujtas  <zalan@apple.com>
+
+        Cannot bring up custom media controls at all on v.youku.com
+        https://bugs.webkit.org/show_bug.cgi?id=199699
+        <rdar://problem/51835327>
+
+        Reviewed by Simon Fraser.
+
+        * WebCoreSupport/WebFrameLoaderClient.mm:
+        (WebFrameLoaderClient::actionDictionary const):
+        * WebView/WebFrame.mm:
+        (-[WebFrame elementAtPoint:]):
+        * WebView/WebHTMLView.mm:
+        (-[WebHTMLView elementAtPoint:allowShadowContent:]):
+        * WebView/WebImmediateActionController.mm:
+        (-[WebImmediateActionController performHitTestAtPoint:]):
+
 2019-07-12  Alex Christensen  <achristensen@webkit.org>
 
         Begin unifying WebKitLegacy sources
index 7eba3a9..3dd50e7 100644 (file)
@@ -1584,7 +1584,7 @@ NSDictionary *WebFrameLoaderClient::actionDictionary(const NavigationAction& act
 
     if (auto mouseEventData = action.mouseEventData()) {
         WebElementDictionary *element = [[WebElementDictionary alloc]
-            initWithHitTestResult:core(m_webFrame.get())->eventHandler().hitTestResultAtPoint(mouseEventData->absoluteLocation)];
+            initWithHitTestResult:core(m_webFrame.get())->eventHandler().hitTestResultAtPoint(mouseEventData->absoluteLocation, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowUserAgentShadowContent | HitTestRequest::AllowChildFrameContent)];
         [result setObject:element forKey:WebActionElementKey];
         [element release];
 
index 585aea6..c67d6ad 100644 (file)
@@ -2361,7 +2361,7 @@ static WebFrameLoadType toWebFrameLoadType(FrameLoadType frameLoadType)
     Frame* coreFrame = _private->coreFrame;
     if (!coreFrame)
         return nil;
-    return [[[WebElementDictionary alloc] initWithHitTestResult:coreFrame->eventHandler().hitTestResultAtPoint(IntPoint(point), HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::IgnoreClipping | HitTestRequest::DisallowUserAgentShadowContent)] autorelease];
+    return [[[WebElementDictionary alloc] initWithHitTestResult:coreFrame->eventHandler().hitTestResultAtPoint(IntPoint(point), HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::IgnoreClipping | HitTestRequest::DisallowUserAgentShadowContent | HitTestRequest::AllowChildFrameContent)] autorelease];
 }
 
 - (NSURL *)_unreachableURL
index 4ca160e..d38817d 100644 (file)
@@ -7089,7 +7089,7 @@ static CGImageRef selectionImage(Frame* frame, bool forceBlackText)
     Frame* coreFrame = core([self _frame]);
     if (!coreFrame)
         return nil;
-    HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active
+    HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::AllowChildFrameContent
         | (allow ? 0 : HitTestRequest::DisallowUserAgentShadowContent);
     return [[[WebElementDictionary alloc] initWithHitTestResult:coreFrame->eventHandler().hitTestResultAtPoint(IntPoint(point), hitType)] autorelease];
 }
index f7936b5..cb33ec7 100644 (file)
@@ -149,7 +149,7 @@ using namespace WebCore;
     if (!coreFrame)
         return;
 
-    _hitTestResult = coreFrame->eventHandler().hitTestResultAtPoint(IntPoint(viewPoint));
+    _hitTestResult = coreFrame->eventHandler().hitTestResultAtPoint(IntPoint(viewPoint), HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowUserAgentShadowContent | HitTestRequest::AllowChildFrameContent);
     coreFrame->mainFrame().eventHandler().setImmediateActionStage(ImmediateActionStage::PerformedHitTest);
 
     if (Element* element = _hitTestResult.targetElement())
index 9ce27ce..43664dc 100644 (file)
@@ -1,3 +1,17 @@
+2019-07-13  Zalan Bujtas  <zalan@apple.com>
+
+        Cannot bring up custom media controls at all on v.youku.com
+        https://bugs.webkit.org/show_bug.cgi?id=199699
+        <rdar://problem/51835327>
+
+        Reviewed by Simon Fraser.
+
+        * WebActionPropertyBag.cpp:
+        (WebActionPropertyBag::Read):
+        * WebView.cpp:
+        (WebView::handleContextMenuEvent):
+        (WebView::elementAtPoint):
+
 2019-07-08  Fujii Hironori  <Hironori.Fujii@sony.com>
 
         [WinCairo] ASSERTION FAILED: info.bmBitsPixel == 32 in createCairoContextWithHDC
index 330b906..e8c47fe 100644 (file)
@@ -113,7 +113,7 @@ HRESULT WebActionPropertyBag::Read(LPCOLESTR pszPropName, VARIANT *pVar, IErrorL
     if (isEqual(pszPropName, WebActionElementKey)) {
         if (auto mouseEvent = m_action.mouseEventData()) {
             V_VT(pVar) = VT_UNKNOWN;
-            V_UNKNOWN(pVar) = WebElementPropertyBag::createInstance(m_frame->eventHandler().hitTestResultAtPoint(mouseEvent->absoluteLocation));
+            V_UNKNOWN(pVar) = WebElementPropertyBag::createInstance(m_frame->eventHandler().hitTestResultAtPoint(mouseEvent->absoluteLocation, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowUserAgentShadowContent | HitTestRequest::AllowChildFrameContent));
             return S_OK;
         }
     }
index 207a238..eac5a61 100644 (file)
@@ -1658,7 +1658,7 @@ bool WebView::handleContextMenuEvent(WPARAM wParam, LPARAM lParam)
     m_page->contextMenuController().clearContextMenu();
 
     IntPoint documentPoint(m_page->mainFrame().view()->windowToContents(logicalCoords));
-    HitTestResult result = m_page->mainFrame().eventHandler().hitTestResultAtPoint(documentPoint);
+    HitTestResult result = m_page->mainFrame().eventHandler().hitTestResultAtPoint(documentPoint, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowUserAgentShadowContent | HitTestRequest::AllowChildFrameContent);
     Frame* targetFrame = result.innerNonSharedNode() ? result.innerNonSharedNode()->document().frame() : &m_page->focusController().focusedOrMainFrame();
 
     targetFrame->view()->setCursor(pointerCursor());
@@ -4090,7 +4090,7 @@ HRESULT WebView::elementAtPoint(_In_ LPPOINT point, _COM_Outptr_opt_ IPropertyBa
     webCorePoint.scale(inverseScaleFactor, inverseScaleFactor);
     HitTestResult result = HitTestResult(webCorePoint);
     if (frame->contentRenderer())
-        result = frame->eventHandler().hitTestResultAtPoint(webCorePoint);
+        result = frame->eventHandler().hitTestResultAtPoint(webCorePoint, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowUserAgentShadowContent | HitTestRequest::AllowChildFrameContent);
     *elementDictionary = WebElementPropertyBag::createInstance(result);
     return S_OK;
 }