Dispatch AR event on the originating anchor element
authordino@apple.com <dino@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 21 Oct 2019 22:31:49 +0000 (22:31 +0000)
committerdino@apple.com <dino@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 21 Oct 2019 22:31:49 +0000 (22:31 +0000)
https://bugs.webkit.org/show_bug.cgi?id=203198
<rdar://55743929>

Reviewed by Simon Fraser.

Source/WebCore:

Expose an ElementContext on the SystemPreviewInfo, so that
when something happens in the AR QuickLook an event can be
fired on the originating <a> element.

* dom/Document.cpp:
(WebCore::Document::dispatchSystemPreviewActionEvent): Make sure
we dispatch only to the HTMLAnchorElement.
* dom/Document.h:
* html/HTMLAnchorElement.cpp:
(WebCore::HTMLAnchorElement::handleClick):
* loader/FrameLoaderTypes.h:
(WebCore::SystemPreviewInfo::encode const):
(WebCore::SystemPreviewInfo::decode):
* testing/Internals.cpp:
(WebCore::Internals::elementIdentifier const):
* testing/Internals.h:
* testing/Internals.idl:

Source/WebKit:

Use the ElementContext on SystemPreviewInfo.

* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _triggerSystemPreviewActionOnElement:frame:page:]):
(-[WKWebView _triggerSystemPreviewActionOnFrame:page:]): Deleted.
* UIProcess/API/Cocoa/WKWebViewPrivate.h:
* UIProcess/Cocoa/SystemPreviewControllerCocoa.mm:
* UIProcess/SystemPreviewController.h:
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::systemPreviewActionTriggered):

Tools:

Improve this test, most importantly so that it
actually works :)

Retrieve the ElementIdentifier for the <a> element,
and trigger a system preview action on it.

* TestWebKitAPI/Tests/WebKitCocoa/SystemPreview.mm:
(-[TestSystemPreviewTriggeredHandler userContentController:didReceiveScriptMessage:]):
(TestWebKitAPI::TEST):
* TestWebKitAPI/Tests/WebKitCocoa/system-preview-trigger.html:

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

17 files changed:
Source/WebCore/ChangeLog
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/html/HTMLAnchorElement.cpp
Source/WebCore/loader/FrameLoaderTypes.h
Source/WebCore/testing/Internals.cpp
Source/WebCore/testing/Internals.h
Source/WebCore/testing/Internals.idl
Source/WebKit/ChangeLog
Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm
Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h
Source/WebKit/UIProcess/Cocoa/SystemPreviewControllerCocoa.mm
Source/WebKit/UIProcess/SystemPreviewController.h
Source/WebKit/WebProcess/WebPage/WebPage.cpp
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WebKitCocoa/SystemPreview.mm
Tools/TestWebKitAPI/Tests/WebKitCocoa/system-preview-trigger.html

index f01b10e..969d412 100644 (file)
@@ -1,5 +1,31 @@
 2019-10-21  Dean Jackson  <dino@apple.com>
 
+        Dispatch AR event on the originating anchor element
+        https://bugs.webkit.org/show_bug.cgi?id=203198
+        <rdar://55743929>
+
+        Reviewed by Simon Fraser.
+
+        Expose an ElementContext on the SystemPreviewInfo, so that
+        when something happens in the AR QuickLook an event can be
+        fired on the originating <a> element.
+
+        * dom/Document.cpp:
+        (WebCore::Document::dispatchSystemPreviewActionEvent): Make sure
+        we dispatch only to the HTMLAnchorElement.
+        * dom/Document.h:
+        * html/HTMLAnchorElement.cpp:
+        (WebCore::HTMLAnchorElement::handleClick):
+        * loader/FrameLoaderTypes.h:
+        (WebCore::SystemPreviewInfo::encode const):
+        (WebCore::SystemPreviewInfo::decode):
+        * testing/Internals.cpp:
+        (WebCore::Internals::elementIdentifier const):
+        * testing/Internals.h:
+        * testing/Internals.idl:
+
+2019-10-21  Dean Jackson  <dino@apple.com>
+
         Move ElementContext from WebKit to WebCore
         https://bugs.webkit.org/show_bug.cgi?id=203210
         <rdar://problem/56475682>
index 8855786..73f3faf 100644 (file)
@@ -8314,11 +8314,18 @@ MessagePortChannelProvider& Document::messagePortChannelProvider()
 }
 
 #if USE(SYSTEM_PREVIEW)
-void Document::dispatchSystemPreviewActionEvent(const String& message)
+void Document::dispatchSystemPreviewActionEvent(const SystemPreviewInfo& systemPreviewInfo, const String& message)
 {
+    auto* element = searchForElementByIdentifier(systemPreviewInfo.element.elementIdentifier);
+    if (!element)
+        return;
+
+    if (!is<HTMLAnchorElement>(element))
+        return;
+
     auto event = MessageEvent::create(message, origin());
     UserGestureIndicator gestureIndicator(ProcessingUserGesture, this);
-    dispatchWindowEvent(event, domWindow());
+    element->dispatchEvent(event);
 }
 #endif
 
index a65dd4b..9d498b0 100644 (file)
@@ -38,6 +38,7 @@
 #include "FocusDirection.h"
 #include "FontSelectorClient.h"
 #include "FrameDestructionObserver.h"
+#include "FrameLoaderTypes.h"
 #include "GenericTaskQueue.h"
 #include "GraphicsTypes.h"
 #include "MediaProducer.h"
@@ -1549,7 +1550,7 @@ public:
     MessagePortChannelProvider& messagePortChannelProvider();
 
 #if USE(SYSTEM_PREVIEW)
-    WEBCORE_EXPORT void dispatchSystemPreviewActionEvent(const String& message);
+    WEBCORE_EXPORT void dispatchSystemPreviewActionEvent(const SystemPreviewInfo&, const String& message);
 #endif
 
 #if ENABLE(PICTURE_IN_PICTURE_API)
index 597accb..a7ffb15 100644 (file)
@@ -486,8 +486,9 @@ void HTMLAnchorElement::handleClick(Event& event)
     systemPreviewInfo.isPreview = isSystemPreviewLink() && RuntimeEnabledFeatures::sharedFeatures().systemPreviewEnabled();
 
     if (systemPreviewInfo.isPreview) {
-        systemPreviewInfo.globalFrameID.frameID = document().frame()->loader().client().frameID().valueOr(FrameIdentifier { });
-        systemPreviewInfo.globalFrameID.pageID = document().frame()->loader().client().pageID().valueOr(PageIdentifier { });
+        systemPreviewInfo.element.elementIdentifier = document().identifierForElement(*this);
+        systemPreviewInfo.element.documentIdentifier = document().identifier();
+        systemPreviewInfo.element.webPageIdentifier = document().frame()->loader().client().pageID().valueOr(PageIdentifier { });
         if (auto* child = firstElementChild())
             systemPreviewInfo.previewRect = child->boundsInRootViewSpace();
     }
index 5406984..8d8628a 100644 (file)
@@ -28,7 +28,7 @@
 
 #pragma once
 
-#include "GlobalFrameIdentifier.h"
+#include "ElementContext.h"
 #include "IntRect.h"
 #include "ProcessIdentifier.h"
 
@@ -186,7 +186,8 @@ enum class AllowNavigationToInvalidURL : bool { No, Yes };
 enum class HasInsecureContent : bool { No, Yes };
 
 struct SystemPreviewInfo {
-    GlobalFrameIdentifier globalFrameID;
+    ElementContext element;
+
     IntRect previewRect;
     bool isPreview { false };
 
@@ -197,15 +198,15 @@ struct SystemPreviewInfo {
 template<class Encoder>
 void SystemPreviewInfo::encode(Encoder& encoder) const
 {
-    encoder << globalFrameID << previewRect << isPreview;
+    encoder << element << previewRect << isPreview;
 }
 
 template<class Decoder>
 Optional<SystemPreviewInfo> SystemPreviewInfo::decode(Decoder& decoder)
 {
-    Optional<GlobalFrameIdentifier> globalFrameID;
-    decoder >> globalFrameID;
-    if (!globalFrameID)
+    Optional<ElementContext> element;
+    decoder >> element;
+    if (!element)
         return WTF::nullopt;
 
     Optional<IntRect> previewRect;
@@ -218,7 +219,7 @@ Optional<SystemPreviewInfo> SystemPreviewInfo::decode(Decoder& decoder)
     if (!isPreview)
         return WTF::nullopt;
 
-    return { { WTFMove(*globalFrameID), WTFMove(*previewRect), WTFMove(*isPreview) } };
+    return { { WTFMove(*element), WTFMove(*previewRect), WTFMove(*isPreview) } };
 }
 
 enum class LoadCompletionType : uint8_t {
index 9bc3641..a5042e5 100644 (file)
@@ -2516,6 +2516,11 @@ bool Internals::isDocumentAlive(uint64_t documentIdentifier) const
     return Document::allDocumentsMap().contains(makeObjectIdentifier<DocumentIdentifierType>(documentIdentifier));
 }
 
+uint64_t Internals::elementIdentifier(Element& element) const
+{
+    return element.document().identifierForElement(element).toUInt64();
+}
+
 uint64_t Internals::frameIdentifier(const Document& document) const
 {
     if (auto* page = document.page())
index 116fe89..e195bc8 100644 (file)
@@ -418,6 +418,7 @@ public:
     uint64_t documentIdentifier(const Document&) const;
     bool isDocumentAlive(uint64_t documentIdentifier) const;
 
+    uint64_t elementIdentifier(Element&) const;
     uint64_t frameIdentifier(const Document&) const;
     uint64_t pageIdentifier(const Document&) const;
 
index d5ec9fe..28902ff 100644 (file)
@@ -721,6 +721,7 @@ enum CompositingPolicy {
     unsigned long long documentIdentifier(Document document);
     boolean isDocumentAlive(unsigned long long documentIdentifier);
 
+    unsigned long long elementIdentifier(Element element);
     unsigned long long frameIdentifier(Document document);
     unsigned long long pageIdentifier(Document document);
 
index 8e19626..323b237 100644 (file)
@@ -1,5 +1,24 @@
 2019-10-21  Dean Jackson  <dino@apple.com>
 
+        Dispatch AR event on the originating anchor element
+        https://bugs.webkit.org/show_bug.cgi?id=203198
+        <rdar://55743929>
+
+        Reviewed by Simon Fraser.
+
+        Use the ElementContext on SystemPreviewInfo.
+
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView _triggerSystemPreviewActionOnElement:frame:page:]):
+        (-[WKWebView _triggerSystemPreviewActionOnFrame:page:]): Deleted.
+        * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+        * UIProcess/Cocoa/SystemPreviewControllerCocoa.mm:
+        * UIProcess/SystemPreviewController.h:
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::systemPreviewActionTriggered):
+
+2019-10-21  Dean Jackson  <dino@apple.com>
+
         Move ElementContext from WebKit to WebCore
         https://bugs.webkit.org/show_bug.cgi?id=203210
         <rdar://problem/56475682>
index e6f9d69..b7abfdf 100644 (file)
@@ -7541,12 +7541,12 @@ static WebCore::UserInterfaceLayoutDirection toUserInterfaceLayoutDirection(UISe
 }
 
 #if PLATFORM(IOS_FAMILY)
-- (void)_triggerSystemPreviewActionOnFrame:(uint64_t)frameID page:(uint64_t)pageID
+- (void)_triggerSystemPreviewActionOnElement:(uint64_t)elementID document:(uint64_t)documentID page:(uint64_t)pageID
 {
 #if USE(SYSTEM_PREVIEW)
     if (_page) {
         if (auto* previewController = _page->systemPreviewController())
-            previewController->triggerSystemPreviewActionWithTargetForTesting(frameID, pageID);
+            previewController->triggerSystemPreviewActionWithTargetForTesting(elementID, documentID, pageID);
     }
 #endif
 }
index 094fe25..ce16082 100644 (file)
@@ -506,7 +506,7 @@ typedef NS_OPTIONS(NSUInteger, _WKRectEdge) {
 - (void)_accessibilityClearSelection WK_API_AVAILABLE(ios(11.3));
 - (UIView *)_fullScreenPlaceholderView WK_API_AVAILABLE(ios(12.0));
 
-- (void)_triggerSystemPreviewActionOnFrame:(uint64_t)frameID page:(uint64_t)pageID WK_API_AVAILABLE(ios(13.0));
+- (void)_triggerSystemPreviewActionOnElement:(uint64_t)elementID document:(uint64_t)documentID page:(uint64_t)pageID WK_API_AVAILABLE(ios(WK_IOS_TBA));
 
 @property (nonatomic, readonly) BOOL _contentViewIsFirstResponder WK_API_AVAILABLE(ios(12.2));
 #else
index 0d27d6b..6435b3e 100644 (file)
@@ -301,10 +301,12 @@ void SystemPreviewController::triggerSystemPreviewAction()
     page().systemPreviewActionTriggered(m_systemPreviewInfo, "_apple_ar_quicklook_button_tapped");
 }
 
-void SystemPreviewController::triggerSystemPreviewActionWithTargetForTesting(uint64_t frameID, uint64_t pageID)
+void SystemPreviewController::triggerSystemPreviewActionWithTargetForTesting(uint64_t elementID, uint64_t documentID, uint64_t pageID)
 {
-    m_systemPreviewInfo.globalFrameID.frameID = makeObjectIdentifier<WebCore::FrameIdentifierType>(frameID);
-    m_systemPreviewInfo.globalFrameID.pageID = makeObjectIdentifier<WebCore::PageIdentifierType>(pageID);
+    m_systemPreviewInfo.isPreview = true;
+    m_systemPreviewInfo.element.elementIdentifier = makeObjectIdentifier<WebCore::ElementIdentifierType>(elementID);
+    m_systemPreviewInfo.element.documentIdentifier = makeObjectIdentifier<WebCore::DocumentIdentifierType>(documentID);
+    m_systemPreviewInfo.element.webPageIdentifier = makeObjectIdentifier<WebCore::PageIdentifierType>(pageID);
     triggerSystemPreviewAction();
 }
 
index 1aa4017..2edb041 100644 (file)
@@ -61,7 +61,7 @@ public:
 
     void triggerSystemPreviewAction();
 
-    void triggerSystemPreviewActionWithTargetForTesting(uint64_t frameID, uint64_t pageID);
+    void triggerSystemPreviewActionWithTargetForTesting(uint64_t elementID, uint64_t frameID, uint64_t pageID);
 
 private:
     WebPageProxy& m_webPageProxy;
index 901ba06..8a65c2e 100644 (file)
@@ -6621,19 +6621,15 @@ void WebPage::simulateDeviceOrientationChange(double alpha, double beta, double
 #if USE(SYSTEM_PREVIEW)
 void WebPage::systemPreviewActionTriggered(WebCore::SystemPreviewInfo previewInfo, const String& message)
 {
-    WebFrame* frame = WebProcess::singleton().webFrame(previewInfo.globalFrameID.frameID);
-    if (!frame)
-        return;
-
-    auto* document = frame->coreFrame()->document();
+    auto* document = Document::allDocumentsMap().get(previewInfo.element.documentIdentifier);
     if (!document)
         return;
 
     auto pageID = document->pageID();
-    if (!pageID || previewInfo.globalFrameID.pageID != pageID.value())
+    if (!pageID || previewInfo.element.webPageIdentifier != pageID.value())
         return;
 
-    document->dispatchSystemPreviewActionEvent(message);
+    document->dispatchSystemPreviewActionEvent(previewInfo, message);
 }
 #endif
 
index d8168c0..3f574af 100644 (file)
@@ -1,3 +1,22 @@
+2019-10-21  Dean Jackson  <dino@apple.com>
+
+        Dispatch AR event on the originating anchor element
+        https://bugs.webkit.org/show_bug.cgi?id=203198
+        <rdar://55743929>
+
+        Reviewed by Simon Fraser.
+
+        Improve this test, most importantly so that it
+        actually works :)
+
+        Retrieve the ElementIdentifier for the <a> element,
+        and trigger a system preview action on it.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/SystemPreview.mm:
+        (-[TestSystemPreviewTriggeredHandler userContentController:didReceiveScriptMessage:]):
+        (TestWebKitAPI::TEST):
+        * TestWebKitAPI/Tests/WebKitCocoa/system-preview-trigger.html:
+
 2019-10-21  Alex Christensen  <achristensen@webkit.org>
 
         ServiceWorker tests should use TCPServer instead of WKURLSchemeHandler
index 279e342..d9adef4 100644 (file)
 #import <WebKit/WKWebViewPrivate.h>
 #import <WebKit/WebKit.h>
 
-static bool isLoaded;
-static bool isTriggered;
-static uint64_t frameID;
+static bool hasTriggerInfo;
+static bool wasTriggered;
+static uint64_t elementID;
+static uint64_t documentID;
 static uint64_t pageID;
 
 @interface TestSystemPreviewTriggeredHandler : NSObject <WKScriptMessageHandler>
@@ -47,12 +48,13 @@ static uint64_t pageID;
 - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
 {
     if ([message.body[@"message"] isEqualToString:@"loaded"]) {
-        frameID = [message.body[@"frameID"] unsignedIntValue];
+        elementID = [message.body[@"elementID"] unsignedIntValue];
+        documentID = [message.body[@"documentID"] unsignedIntValue];
         pageID = [message.body[@"pageID"] unsignedIntValue];
-        isLoaded = true;
+        hasTriggerInfo = true;
     } else if ([message.body[@"message"] isEqualToString:@"triggered"]) {
         EXPECT_TRUE([message.body[@"action"] isEqualToString:@"_apple_ar_quicklook_button_tapped"]);
-        isTriggered = true;
+        wasTriggered = true;
     }
 }
 
@@ -60,19 +62,19 @@ static uint64_t pageID;
 
 namespace TestWebKitAPI {
 
-TEST(WebKit, DISABLED_SystemPreviewTriggered)
+TEST(WebKit, SystemPreviewTriggered)
 {
+    auto *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES];
     auto messageHandler = adoptNS([[TestSystemPreviewTriggeredHandler alloc] init]);
+    [[configuration userContentController] addScriptMessageHandler:messageHandler.get() name:@"testSystemPreview"];
 
-    WKWebViewConfiguration *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals"];
-    [configuration.userContentController addScriptMessageHandler:messageHandler.get() name:@"testSystemPreview"];
+    auto webView = [[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration];
+    [webView synchronouslyLoadTestPageNamed:@"system-preview-trigger"];
+    Util::run(&hasTriggerInfo);
 
-    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration]);
-    [webView loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"system-preview-trigger" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]];
-    Util::run(&isLoaded);
+    [webView _triggerSystemPreviewActionOnElement:elementID document:documentID page:pageID];
+    Util::run(&wasTriggered);
 
-    [webView _triggerSystemPreviewActionOnFrame:frameID page:pageID];
-    Util::run(&isTriggered);
 }
 
 }
index b6c5bc7..b6ab6e2 100644 (file)
@@ -1,16 +1,23 @@
 <!DOCTYPE html>
 <body>
+<a rel="ar"></a>
 <script>
-window.addEventListener("message", function (event) {
-    window.webkit.messageHandlers.testSystemPreview.postMessage({ message: "triggered", action: event.data });
-});
-
 window.addEventListener("load", function () {
-    let pageID = internals.pageIdentifier(document);
-    let frameID = internals.frameIdentifier(document);
-    let msg = { message: "loaded", pageID, frameID };
+    const a = document.querySelector("a");
+
+    const elementID = internals.elementIdentifier(a);
+    const pageID = internals.pageIdentifier(document);
+    const documentID = internals.documentIdentifier(document);
+
+    a.addEventListener("message", function (event) {
+        window.webkit.messageHandlers.testSystemPreview.postMessage({ message: "triggered", action: event.data });
+    });
+
+    const msg = { message: "loaded", elementID, pageID, documentID };
     window.webkit.messageHandlers.testSystemPreview.postMessage(msg);
 });
 
+
+
 </script>