Skip to content

Commit

Permalink
Show the Chrome context menu when running on iOS 11.
Browse files Browse the repository at this point in the history
Bring back an old hack to prioritize our gesture recognizer over
WKWebView's when running on iOS 11 or later. The hack was previously
removed in
https://codereview.chromium.org/2627093003/patch/160001/170008.

Bug: 736330, 736480
Change-Id: I669a3d530942e39db246f9b298a5f7a797e9754b
Reviewed-on: https://chromium-review.googlesource.com/585672
Reviewed-by: Eugene But <eugenebut@chromium.org>
Commit-Queue: Mike Dougherty <michaeldo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#491040}
  • Loading branch information
michaeldo1 authored and Commit Bot committed Aug 1, 2017
1 parent 2b78b7f commit 3700a08
Showing 1 changed file with 40 additions and 0 deletions.
40 changes: 40 additions & 0 deletions ios/web/web_state/ui/crw_context_menu_controller.mm
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#import <objc/runtime.h>
#include <stddef.h>

#include "base/ios/ios_util.h"
#include "base/logging.h"
#include "base/mac/foundation_util.h"
#include "base/metrics/histogram_macros.h"
Expand Down Expand Up @@ -54,6 +55,9 @@ @interface CRWContextMenuController ()<UIGestureRecognizerDelegate>
// Returns the x, y offset the content has been scrolled.
@property(nonatomic, readonly) CGPoint scrollPosition;

// Returns a gesture recognizers with |fragment| in it's description.
- (UIGestureRecognizer*)gestureRecognizerWithDescriptionFragment:
(NSString*)fragment;
// Called when the window has determined there was a long-press and context menu
// must be shown.
- (void)showContextMenu:(UIGestureRecognizer*)gestureRecognizer;
Expand Down Expand Up @@ -107,10 +111,46 @@ - (instancetype)initWithWebView:(WKWebView*)webView
[_contextMenuRecognizer setAllowableMovement:kLongPressMoveDeltaPixels];
[_contextMenuRecognizer setDelegate:self];
[_webView addGestureRecognizer:_contextMenuRecognizer];

if (base::ios::IsRunningOnIOS11OrLater()) {
// WKWebView's default context menu gesture recognizer interferes with
// the detection of a long press by |_contextMenuRecognizer|. WKWebView's
// context menu gesture recognizer should fail if |_contextMenuRecognizer|
// detects a long press.
NSString* fragment = @"action=_longPressRecognized:";
UIGestureRecognizer* systemContextMenuRecognizer =
[self gestureRecognizerWithDescriptionFragment:fragment];
if (systemContextMenuRecognizer) {
[systemContextMenuRecognizer
requireGestureRecognizerToFail:_contextMenuRecognizer];
// requireGestureRecognizerToFail: doesn't retain the recognizer, so it
// is possible for |iRecognizer| to outlive |recognizer| and end up with
// a dangling pointer. Add a retaining associative reference to ensure
// that the lifetimes work out.
// Note that normally using the value as the key wouldn't make any
// sense, but here it's fine since nothing needs to look up the value.
void* associated_object_key = (__bridge void*)_contextMenuRecognizer;
objc_setAssociatedObject(systemContextMenuRecognizer.view,
associated_object_key, _contextMenuRecognizer,
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
}
}
return self;
}

- (UIGestureRecognizer*)gestureRecognizerWithDescriptionFragment:
(NSString*)fragment {
for (UIView* view in [[_webView scrollView] subviews]) {
for (UIGestureRecognizer* recognizer in [view gestureRecognizers]) {
if ([recognizer.description rangeOfString:fragment].length) {
return recognizer;
}
}
}
return nil;
}

- (UIScrollView*)webScrollView {
return [_webView scrollView];
}
Expand Down

0 comments on commit 3700a08

Please sign in to comment.