No menu pop-up when long pressing on a link in Firefox app
https://bugs.webkit.org/show_bug.cgi?id=199045
<rdar://problem/51422407>

Reviewed by Tim Horton.

Add a version check for linking on-or-after iOS 13. When
that isn't true, we don't use UIContextMenuInteraction
and instead fall back on the legacy UIPreviewItem API.

* UIProcess/Cocoa/VersionChecks.h: Add FirstThatHasUIContextMenuInteraction.
* UIProcess/ios/WKContentViewInteraction.h:
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView _shouldUseContextMenus]): New method to decide if we should
use context menus or preview items.
(-[WKContentView setupInteraction]): Make the decision at runtime rather than
compile time.
(-[WKContentView _contentsOfUserInterfaceItem:]): Ditto.
(-[WKContentView _registerPreview]): Ditto.
(-[WKContentView _unregisterPreview]): Ditto.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@246626 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WTF/wtf/spi/darwin/dyldSPI.h b/Source/WTF/wtf/spi/darwin/dyldSPI.h
index 805d65a..6564fcb 100644
--- a/Source/WTF/wtf/spi/darwin/dyldSPI.h
+++ b/Source/WTF/wtf/spi/darwin/dyldSPI.h
@@ -41,6 +41,10 @@
 #define DYLD_IOS_VERSION_12_0 0x000C0000
 #endif
 
+#ifndef DYLD_IOS_VERSION_13_0
+#define DYLD_IOS_VERSION_13_0 0x000D0000
+#endif
+
 #ifndef DYLD_MACOSX_VERSION_10_13
 #define DYLD_MACOSX_VERSION_10_13 0x000A0D00
 #endif
@@ -61,6 +65,7 @@
 #define DYLD_IOS_VERSION_11_0 0x000B0000
 #define DYLD_IOS_VERSION_11_3 0x000B0300
 #define DYLD_IOS_VERSION_12_0 0x000C0000
+#define DYLD_IOS_VERSION_13_0 0x000D0000
 
 #define DYLD_MACOSX_VERSION_10_11 0x000A0B00
 #define DYLD_MACOSX_VERSION_10_12 0x000A0C00
diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog
index 4d7c97f..59b8c97 100644
--- a/Source/WebKit/ChangeLog
+++ b/Source/WebKit/ChangeLog
@@ -1,3 +1,26 @@
+2019-06-19  Dean Jackson  <dino@apple.com>
+
+        No menu pop-up when long pressing on a link in Firefox app
+        https://bugs.webkit.org/show_bug.cgi?id=199045
+        <rdar://problem/51422407>
+
+        Reviewed by Tim Horton.
+
+        Add a version check for linking on-or-after iOS 13. When
+        that isn't true, we don't use UIContextMenuInteraction
+        and instead fall back on the legacy UIPreviewItem API.
+
+        * UIProcess/Cocoa/VersionChecks.h: Add FirstThatHasUIContextMenuInteraction.
+        * UIProcess/ios/WKContentViewInteraction.h: 
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView _shouldUseContextMenus]): New method to decide if we should
+        use context menus or preview items.
+        (-[WKContentView setupInteraction]): Make the decision at runtime rather than
+        compile time.
+        (-[WKContentView _contentsOfUserInterfaceItem:]): Ditto.
+        (-[WKContentView _registerPreview]): Ditto.
+        (-[WKContentView _unregisterPreview]): Ditto.
+
 2019-06-19  Andy Estes  <aestes@apple.com>
 
         [iOS] Fall back to taking a UIView snapshohot for UITargetedPreviews if InteractionInformationAtPosition does not have an image
diff --git a/Source/WebKit/UIProcess/Cocoa/VersionChecks.h b/Source/WebKit/UIProcess/Cocoa/VersionChecks.h
index d15521d..ed2ac70 100644
--- a/Source/WebKit/UIProcess/Cocoa/VersionChecks.h
+++ b/Source/WebKit/UIProcess/Cocoa/VersionChecks.h
@@ -72,6 +72,7 @@
     FirstThatDecidesPolicyBeforeLoadingQuickLookPreview = DYLD_IOS_VERSION_FIRST_THAT_DECIDES_POLICY_BEFORE_LOADING_QUICK_LOOK_PREVIEW,
     FirstWithExceptionsForRelatedWebViewsUsingDifferentDataStores = DYLD_IOS_VERSION_FIRST_WITH_EXCEPTIONS_FOR_RELATED_WEBVIEWS_USING_DIFFERENT_DATA_STORES,
     FirstWithModernCompabilityModeByDefault = DYLD_IOS_VERSION_FIRST_WITH_MODERN_COMPATIBILITY_MODE_BY_DEFAULT,
+    FirstThatHasUIContextMenuInteraction = DYLD_IOS_VERSION_13_0,
 #elif PLATFORM(MAC)
     FirstWithNetworkCache = DYLD_MACOSX_VERSION_10_11,
     FirstWithExceptionsForDuplicateCompletionHandlerCalls = DYLD_MACOSX_VERSION_10_13,
diff --git a/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h b/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h
index 27dadb8..e96dedb 100644
--- a/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h
+++ b/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h
@@ -251,9 +251,8 @@
     RetainPtr<UIMenu> _contextMenuLegacyMenu;
     BOOL _contextMenuHasRequestedLegacyData;
     RetainPtr<UITargetedPreview> _contextMenuInteractionTargetedPreview;
-#else
-    RetainPtr<UIPreviewItemController> _previewItemController;
 #endif
+    RetainPtr<UIPreviewItemController> _previewItemController;
 #endif
 
     std::unique_ptr<WebKit::SmartMagnificationController> _smartMagnificationController;
@@ -537,10 +536,11 @@
 
 #if HAVE(LINK_PREVIEW)
 #if USE(UICONTEXTMENU)
-@interface WKContentView (WKInteractionPreview) <UIContextMenuInteractionDelegate>
+@interface WKContentView (WKInteractionPreview) <UIContextMenuInteractionDelegate, UIPreviewItemDelegate>
 #else
 @interface WKContentView (WKInteractionPreview) <UIPreviewItemDelegate>
 #endif
+- (bool)_shouldUseContextMenus;
 - (void)_registerPreview;
 - (void)_unregisterPreview;
 @end
diff --git a/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm b/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm
index 0398202..3111a48 100644
--- a/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm
+++ b/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm
@@ -42,6 +42,7 @@
 #import "SmartMagnificationController.h"
 #import "TextInputSPI.h"
 #import "UIKitSPI.h"
+#import "VersionChecks.h"
 #import "WKActionSheetAssistant.h"
 #import "WKContextMenuElementInfoInternal.h"
 #import "WKDatePickerViewController.h"
@@ -768,9 +769,11 @@
     [_highlightLongPressGestureRecognizer setDelay:highlightDelay];
     [_highlightLongPressGestureRecognizer setDelegate:self];
 
-#if HAVE(LINK_PREVIEW) && !USE(UICONTEXTMENU)
-    [self addGestureRecognizer:_highlightLongPressGestureRecognizer.get()];
-    [self _createAndConfigureLongPressGestureRecognizer];
+#if HAVE(LINK_PREVIEW)
+    if (![self _shouldUseContextMenus]) {
+        [self addGestureRecognizer:_highlightLongPressGestureRecognizer.get()];
+        [self _createAndConfigureLongPressGestureRecognizer];
+    }
 #endif
 
 #if ENABLE(DATA_INTERACTION)
@@ -7367,12 +7370,11 @@
 
 #if HAVE(LINK_PREVIEW)
     if ([userInterfaceItem isEqualToString:@"linkPreviewPopoverContents"]) {
-#if USE(UICONTEXTMENU)
-        return @{ userInterfaceItem: @{ @"pageURL": WTF::userVisibleString(_positionInformation.url) } };
-#else
+        if ([self _shouldUseContextMenus])
+            return @{ userInterfaceItem: @{ @"pageURL": WTF::userVisibleString(_positionInformation.url) } };
+
         NSString *url = [_previewItemController previewData][UIPreviewDataLink];
         return @{ userInterfaceItem: @{ @"pageURL": url } };
-#endif
     }
 #endif
 
@@ -7411,35 +7413,68 @@
     return nil;
 }
 
-#if USE(UICONTEXTMENU)
-
 @implementation WKContentView (WKInteractionPreview)
 
+- (bool)_shouldUseContextMenus
+{
+#if USE(UICONTEXTMENU)
+    return linkedOnOrAfter(WebKit::SDKVersion::FirstThatHasUIContextMenuInteraction);
+#endif
+    return false;
+}
+
 - (void)_registerPreview
 {
     if (!_webView.allowsLinkPreview)
         return;
 
-    _contextMenuInteraction = adoptNS([[UIContextMenuInteraction alloc] initWithDelegate:self]);
-    _contextMenuHasRequestedLegacyData = NO;
-    [self addInteraction:_contextMenuInteraction.get()];
+#if USE(UICONTEXTMENU)
+    if ([self _shouldUseContextMenus]) {
+        _contextMenuInteraction = adoptNS([[UIContextMenuInteraction alloc] initWithDelegate:self]);
+        _contextMenuHasRequestedLegacyData = NO;
+        [self addInteraction:_contextMenuInteraction.get()];
 
-    [self _showLinkPreviewsPreferenceChanged:nil];
+        [self _showLinkPreviewsPreferenceChanged:nil];
 
-    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_showLinkPreviewsPreferenceChanged:) name:webkitShowLinkPreviewsPreferenceChangedNotification object:nil];
+        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_showLinkPreviewsPreferenceChanged:) name:webkitShowLinkPreviewsPreferenceChangedNotification object:nil];
+
+        return;
+    }
+#endif
+
+    if (!_webView.allowsLinkPreview)
+        return;
+
+    _previewItemController = adoptNS([[UIPreviewItemController alloc] initWithView:self]);
+    [_previewItemController setDelegate:self];
+    _previewGestureRecognizer = _previewItemController.get().presentationGestureRecognizer;
+    if ([_previewItemController respondsToSelector:@selector(presentationSecondaryGestureRecognizer)])
+        _previewSecondaryGestureRecognizer = _previewItemController.get().presentationSecondaryGestureRecognizer;
 }
 
 - (void)_unregisterPreview
 {
-    if (!_contextMenuInteraction)
+#if USE(UICONTEXTMENU)
+    if ([self _shouldUseContextMenus]) {
+        if (!_contextMenuInteraction)
+            return;
+
+        [self removeInteraction:_contextMenuInteraction.get()];
+        _contextMenuInteraction = nil;
+
+        [[NSNotificationCenter defaultCenter] removeObserver:self name:webkitShowLinkPreviewsPreferenceChangedNotification object:nil];
         return;
+    }
+#endif
 
-    [self removeInteraction:_contextMenuInteraction.get()];
-    _contextMenuInteraction = nil;
-
-    [[NSNotificationCenter defaultCenter] removeObserver:self name:webkitShowLinkPreviewsPreferenceChangedNotification object:nil];
+    [_previewItemController setDelegate:nil];
+    _previewGestureRecognizer = nil;
+    _previewSecondaryGestureRecognizer = nil;
+    _previewItemController = nil;
 }
 
+#if USE(UICONTEXTMENU)
+
 - (void)_showLinkPreviewsPreferenceChanged:(NSNotification *)notification
 {
     Boolean keyExistsAndHasValidFormat = false;
@@ -8004,31 +8039,7 @@
     _contextMenuInteractionTargetedPreview = nil;
 }
 
-@end
-
-#else
-
-@implementation WKContentView (WKInteractionPreview)
-
-- (void)_registerPreview
-{
-    if (!_webView.allowsLinkPreview)
-        return;
-
-    _previewItemController = adoptNS([[UIPreviewItemController alloc] initWithView:self]);
-    [_previewItemController setDelegate:self];
-    _previewGestureRecognizer = _previewItemController.get().presentationGestureRecognizer;
-    if ([_previewItemController respondsToSelector:@selector(presentationSecondaryGestureRecognizer)])
-        _previewSecondaryGestureRecognizer = _previewItemController.get().presentationSecondaryGestureRecognizer;
-}
-
-- (void)_unregisterPreview
-{
-    [_previewItemController setDelegate:nil];
-    _previewGestureRecognizer = nil;
-    _previewSecondaryGestureRecognizer = nil;
-    _previewItemController = nil;
-}
+#endif // USE(UICONTEXTMENU)
 
 - (BOOL)_interactionShouldBeginFromPreviewItemController:(UIPreviewItemController *)controller forPosition:(CGPoint)position
 {
@@ -8354,8 +8365,6 @@
 
 @end
 
-#endif // USE(UICONTEXTMENU)
-
 #endif // HAVE(LINK_PREVIEW)
 
 // UITextRange, UITextPosition and UITextSelectionRect implementations for WK2