Commit dc2dbcbd authored by Mike Dougherty's avatar Mike Dougherty Committed by Commit Bot

Enable post message context menu and remove flag.

This fully enables support for context menu in iFrames.

Bug: 873660, 873662
Cq-Include-Trybots: luci.chromium.try:ios-simulator-full-configs;master.tryserver.chromium.mac:ios-simulator-cronet
Change-Id: I3345f56f6812ef619c6ed5b7bcabd34e09de410f
Reviewed-on: https://chromium-review.googlesource.com/1174052
Commit-Queue: Mike Dougherty <michaeldo@chromium.org>
Reviewed-by: default avatarEugene But <eugenebut@chromium.org>
Cr-Commit-Position: refs/heads/master@{#583053}
parent 7755fb6c
...@@ -274,11 +274,6 @@ const flags_ui::FeatureEntry kFeatureEntries[] = { ...@@ -274,11 +274,6 @@ const flags_ui::FeatureEntry kFeatureEntries[] = {
{"infobars-ui-reboot", flag_descriptions::kInfobarsUIRebootName, {"infobars-ui-reboot", flag_descriptions::kInfobarsUIRebootName,
flag_descriptions::kInfobarsUIRebootDescription, flags_ui::kOsIos, flag_descriptions::kInfobarsUIRebootDescription, flags_ui::kOsIos,
FEATURE_VALUE_TYPE(kInfobarsUIReboot)}, FEATURE_VALUE_TYPE(kInfobarsUIReboot)},
{"context-menu-element-post-message",
flag_descriptions::kContextMenuElementPostMessageName,
flag_descriptions::kContextMenuElementPostMessageDescription,
flags_ui::kOsIos,
FEATURE_VALUE_TYPE(web::features::kContextMenuElementPostMessage)},
{"mailto-handling-google-ui", {"mailto-handling-google-ui",
flag_descriptions::kMailtoHandlingWithGoogleUIName, flag_descriptions::kMailtoHandlingWithGoogleUIName,
flag_descriptions::kMailtoHandlingWithGoogleUIDescription, flag_descriptions::kMailtoHandlingWithGoogleUIDescription,
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#import <XCTest/XCTest.h> #import <XCTest/XCTest.h>
#import "base/test/ios/wait_util.h" #import "base/test/ios/wait_util.h"
#include "base/test/scoped_feature_list.h"
#include "ios/chrome/browser/ui/ui_util.h" #include "ios/chrome/browser/ui/ui_util.h"
#include "ios/chrome/grit/ios_strings.h" #include "ios/chrome/grit/ios_strings.h"
#import "ios/chrome/test/app/chrome_test_util.h" #import "ios/chrome/test/app/chrome_test_util.h"
...@@ -21,7 +20,6 @@ ...@@ -21,7 +20,6 @@
#import "ios/chrome/test/earl_grey/chrome_matchers.h" #import "ios/chrome/test/earl_grey/chrome_matchers.h"
#import "ios/chrome/test/earl_grey/chrome_test_case.h" #import "ios/chrome/test/earl_grey/chrome_test_case.h"
#import "ios/testing/earl_grey/disabled_test_macros.h" #import "ios/testing/earl_grey/disabled_test_macros.h"
#import "ios/web/public/features.h"
#import "ios/web/public/test/earl_grey/web_view_matchers.h" #import "ios/web/public/test/earl_grey/web_view_matchers.h"
#include "ios/web/public/test/element_selector.h" #include "ios/web/public/test/element_selector.h"
#include "net/test/embedded_test_server/http_request.h" #include "net/test/embedded_test_server/http_request.h"
...@@ -183,33 +181,24 @@ void SelectTabAtIndexInCurrentMode(NSUInteger index) { ...@@ -183,33 +181,24 @@ void SelectTabAtIndexInCurrentMode(NSUInteger index) {
} }
// Tests that selecting "Open Image" from the context menu properly opens the // Tests that selecting "Open Image" from the context menu properly opens the
// image in the current tab. (With the kContextMenuElementPostMessage feature // image in the current tab.
// disabled.)
- (void)testOpenImageInCurrentTabFromContextMenu { - (void)testOpenImageInCurrentTabFromContextMenu {
base::test::ScopedFeatureList scopedFeatureList;
scopedFeatureList.InitAndDisableFeature(
web::features::kContextMenuElementPostMessage);
const GURL pageURL = self.testServer->GetURL(kLogoPagePath); const GURL pageURL = self.testServer->GetURL(kLogoPagePath);
[ChromeEarlGrey loadURL:pageURL]; [ChromeEarlGrey loadURL:pageURL];
[ChromeEarlGrey waitForWebViewContainingText:kLogoPageText]; [ChromeEarlGrey waitForWebViewContainingText:kLogoPageText];
LongPressElement(kLogoPageChromiumImageId); LongPressElement(kLogoPageChromiumImageId);
TapOnContextMenuButton(OpenImageButton()); TapOnContextMenuButton(OpenImageButton());
[ChromeEarlGrey waitForPageToFinishLoading]; [ChromeEarlGrey waitForPageToFinishLoading];
// Verify url and tab count. // Verify url.
GREYAssertEqual(chrome_test_util::GetMainTabCount(), 1,
@"Image should be opened in existing tab.");
const GURL imageURL = self.testServer->GetURL(kLogoPageImageSourcePath); const GURL imageURL = self.testServer->GetURL(kLogoPageImageSourcePath);
[[EarlGrey selectElementWithMatcher:OmniboxText(imageURL.GetContent())] [[EarlGrey selectElementWithMatcher:OmniboxText(imageURL.GetContent())]
assertWithMatcher:grey_notNil()]; assertWithMatcher:grey_notNil()];
} }
// Tests that selecting "Open Image in New Tab" from the context menu properly // Tests that selecting "Open Image in New Tab" from the context menu properly
// opens the image in a new background tab. (With the // opens the image in a new background tab.
// kContextMenuElementPostMessage feature disabled.)
// TODO(crbug.com/817810): Enable this test. // TODO(crbug.com/817810): Enable this test.
#if TARGET_IPHONE_SIMULATOR #if TARGET_IPHONE_SIMULATOR
#define MAYBE_testOpenImageInNewTabFromContextMenu \ #define MAYBE_testOpenImageInNewTabFromContextMenu \
...@@ -219,10 +208,6 @@ void SelectTabAtIndexInCurrentMode(NSUInteger index) { ...@@ -219,10 +208,6 @@ void SelectTabAtIndexInCurrentMode(NSUInteger index) {
FLAKY_testOpenImageInNewTabFromContextMenu FLAKY_testOpenImageInNewTabFromContextMenu
#endif #endif
- (void)MAYBE_testOpenImageInNewTabFromContextMenu { - (void)MAYBE_testOpenImageInNewTabFromContextMenu {
base::test::ScopedFeatureList scopedFeatureList;
scopedFeatureList.InitAndDisableFeature(
web::features::kContextMenuElementPostMessage);
const GURL pageURL = self.testServer->GetURL(kLogoPagePath); const GURL pageURL = self.testServer->GetURL(kLogoPagePath);
[ChromeEarlGrey loadURL:pageURL]; [ChromeEarlGrey loadURL:pageURL];
[ChromeEarlGrey waitForWebViewContainingText:kLogoPageText]; [ChromeEarlGrey waitForWebViewContainingText:kLogoPageText];
...@@ -240,8 +225,7 @@ void SelectTabAtIndexInCurrentMode(NSUInteger index) { ...@@ -240,8 +225,7 @@ void SelectTabAtIndexInCurrentMode(NSUInteger index) {
assertWithMatcher:grey_notNil()]; assertWithMatcher:grey_notNil()];
} }
// Tests "Open in New Tab" on context menu. (With the // Tests "Open in New Tab" on context menu.
// kContextMenuElementPostMessage feature disabled.)
// TODO(crbug.com/817810): Enable this test. // TODO(crbug.com/817810): Enable this test.
#if TARGET_IPHONE_SIMULATOR #if TARGET_IPHONE_SIMULATOR
#define MAYBE_testContextMenuOpenInNewTab testContextMenuOpenInNewTab #define MAYBE_testContextMenuOpenInNewTab testContextMenuOpenInNewTab
...@@ -249,10 +233,6 @@ void SelectTabAtIndexInCurrentMode(NSUInteger index) { ...@@ -249,10 +233,6 @@ void SelectTabAtIndexInCurrentMode(NSUInteger index) {
#define MAYBE_testContextMenuOpenInNewTab FLAKY_testContextMenuOpenInNewTab #define MAYBE_testContextMenuOpenInNewTab FLAKY_testContextMenuOpenInNewTab
#endif #endif
- (void)MAYBE_testContextMenuOpenInNewTab { - (void)MAYBE_testContextMenuOpenInNewTab {
base::test::ScopedFeatureList scopedFeatureList;
scopedFeatureList.InitAndDisableFeature(
web::features::kContextMenuElementPostMessage);
const GURL initialURL = self.testServer->GetURL(kInitialPageUrl); const GURL initialURL = self.testServer->GetURL(kInitialPageUrl);
[ChromeEarlGrey loadURL:initialURL]; [ChromeEarlGrey loadURL:initialURL];
[ChromeEarlGrey waitForWebViewContainingText:kInitialPageDestinationLinkText]; [ChromeEarlGrey waitForWebViewContainingText:kInitialPageDestinationLinkText];
...@@ -270,8 +250,7 @@ void SelectTabAtIndexInCurrentMode(NSUInteger index) { ...@@ -270,8 +250,7 @@ void SelectTabAtIndexInCurrentMode(NSUInteger index) {
assertWithMatcher:grey_notNil()]; assertWithMatcher:grey_notNil()];
} }
// Tests that the context menu is displayed for an image url. (With the // Tests that the context menu is displayed for an image url.
// kContextMenuElementPostMessage feature disabled.)
// TODO(crbug.com/817810): Enable this test. // TODO(crbug.com/817810): Enable this test.
#if TARGET_IPHONE_SIMULATOR #if TARGET_IPHONE_SIMULATOR
#define MAYBE_testContextMenuDisplayedOnImage testContextMenuDisplayedOnImage #define MAYBE_testContextMenuDisplayedOnImage testContextMenuDisplayedOnImage
...@@ -280,10 +259,6 @@ void SelectTabAtIndexInCurrentMode(NSUInteger index) { ...@@ -280,10 +259,6 @@ void SelectTabAtIndexInCurrentMode(NSUInteger index) {
FLAKY_testContextMenuDisplayedOnImage FLAKY_testContextMenuDisplayedOnImage
#endif #endif
- (void)MAYBE_testContextMenuDisplayedOnImage { - (void)MAYBE_testContextMenuDisplayedOnImage {
base::test::ScopedFeatureList scopedFeatureList;
scopedFeatureList.InitAndDisableFeature(
web::features::kContextMenuElementPostMessage);
const GURL imageURL = self.testServer->GetURL(kLogoPageImageSourcePath); const GURL imageURL = self.testServer->GetURL(kLogoPageImageSourcePath);
[ChromeEarlGrey loadURL:imageURL]; [ChromeEarlGrey loadURL:imageURL];
...@@ -309,161 +284,8 @@ void SelectTabAtIndexInCurrentMode(NSUInteger index) { ...@@ -309,161 +284,8 @@ void SelectTabAtIndexInCurrentMode(NSUInteger index) {
assertWithMatcher:grey_notNil()]; assertWithMatcher:grey_notNil()];
} }
// Tests that the element fetch duration is logged once with the // Tests that the element fetch duration is logged once.
// kContextMenuElementPostMessage feature disabled.
- (void)testContextMenuElementFetchDurationMetric { - (void)testContextMenuElementFetchDurationMetric {
base::test::ScopedFeatureList scopedFeatureList;
scopedFeatureList.InitAndDisableFeature(
web::features::kContextMenuElementPostMessage);
chrome_test_util::HistogramTester histogramTester;
const GURL pageURL = self.testServer->GetURL(kLogoPagePath);
[ChromeEarlGrey loadURL:pageURL];
[ChromeEarlGrey waitForWebViewContainingText:kLogoPageText];
LongPressElement(kLogoPageChromiumImageId);
TapOnContextMenuButton(OpenImageButton());
[ChromeEarlGrey waitForPageToFinishLoading];
histogramTester.ExpectTotalCount("ContextMenu.DOMElementFetchDuration", 1,
^(NSString* error) {
GREYFail(error);
});
}
// Tests that selecting "Open Image" from the context menu properly opens the
// image in the current tab. (With the kContextMenuElementPostMessage feature
// enabled.)
- (void)testOpenImageInCurrentTabFromContextMenuPostMessage {
base::test::ScopedFeatureList scopedFeatureList;
scopedFeatureList.InitAndEnableFeature(
web::features::kContextMenuElementPostMessage);
const GURL pageURL = self.testServer->GetURL(kLogoPagePath);
[ChromeEarlGrey loadURL:pageURL];
[ChromeEarlGrey waitForWebViewContainingText:kLogoPageText];
LongPressElement(kLogoPageChromiumImageId);
TapOnContextMenuButton(OpenImageButton());
[ChromeEarlGrey waitForPageToFinishLoading];
// Verify url.
const GURL imageURL = self.testServer->GetURL(kLogoPageImageSourcePath);
[[EarlGrey selectElementWithMatcher:OmniboxText(imageURL.GetContent())]
assertWithMatcher:grey_notNil()];
}
// Tests that selecting "Open Image in New Tab" from the context menu properly
// opens the image in a new background tab. (With the
// kContextMenuElementPostMessage feature enabled.)
// TODO(crbug.com/817810): Enable this test.
#if TARGET_IPHONE_SIMULATOR
#define MAYBE_testOpenImageInNewTabFromContextMenuPostMessage \
testOpenImageInNewTabFromContextMenuPostMessage
#else
#define MAYBE_testOpenImageInNewTabFromContextMenuPostMessage \
FLAKY_testOpenImageInNewTabFromContextMenuPostMessage
#endif
- (void)MAYBE_testOpenImageInNewTabFromContextMenuPostMessage {
base::test::ScopedFeatureList scopedFeatureList;
scopedFeatureList.InitAndEnableFeature(
web::features::kContextMenuElementPostMessage);
const GURL pageURL = self.testServer->GetURL(kLogoPagePath);
[ChromeEarlGrey loadURL:pageURL];
[ChromeEarlGrey waitForWebViewContainingText:kLogoPageText];
LongPressElement(kLogoPageChromiumImageId);
TapOnContextMenuButton(OpenImageInNewTabButton());
[ChromeEarlGrey waitForMainTabCount:2];
SelectTabAtIndexInCurrentMode(1U);
[ChromeEarlGrey waitForPageToFinishLoading];
// Verify url.
const GURL imageURL = self.testServer->GetURL(kLogoPageImageSourcePath);
[[EarlGrey selectElementWithMatcher:OmniboxText(imageURL.GetContent())]
assertWithMatcher:grey_notNil()];
}
// Tests "Open in New Tab" on context menu. (With the
// kContextMenuElementPostMessage feature enabled.)
// TODO(crbug.com/817810): Enable this test.
#if TARGET_IPHONE_SIMULATOR
#define MAYBE_testContextMenuOpenInNewTabPostMessage \
testContextMenuOpenInNewTabPostMessage
#else
#define MAYBE_testContextMenuOpenInNewTabPostMessage \
FLAKY_testContextMenuOpenInNewTabPostMessage
#endif
- (void)MAYBE_testContextMenuOpenInNewTabPostMessage {
base::test::ScopedFeatureList scopedFeatureList;
scopedFeatureList.InitAndEnableFeature(
web::features::kContextMenuElementPostMessage);
const GURL initialURL = self.testServer->GetURL(kInitialPageUrl);
[ChromeEarlGrey loadURL:initialURL];
[ChromeEarlGrey waitForWebViewContainingText:kInitialPageDestinationLinkText];
LongPressElement(kInitialPageDestinationLinkId);
TapOnContextMenuButton(OpenLinkInNewTabButton());
[ChromeEarlGrey waitForMainTabCount:2];
SelectTabAtIndexInCurrentMode(1U);
[ChromeEarlGrey waitForWebViewContainingText:kDestinationPageText];
// Verify url.
const GURL destinationURL = self.testServer->GetURL(kDestinationPageUrl);
[[EarlGrey selectElementWithMatcher:OmniboxText(destinationURL.GetContent())]
assertWithMatcher:grey_notNil()];
}
// Tests that the context menu is displayed for an image url. (With the
// kContextMenuElementPostMessage feature enabled.)
// TODO(crbug.com/817810): Enable this test.
#if TARGET_IPHONE_SIMULATOR
#define MAYBE_testContextMenuDisplayedOnImagePostMessage \
testContextMenuDisplayedOnImagePostMessage
#else
#define MAYBE_testContextMenuDisplayedOnImagePostMessage \
FLAKY_testContextMenuDisplayedOnImagePostMessage
#endif
- (void)MAYBE_testContextMenuDisplayedOnImagePostMessage {
base::test::ScopedFeatureList scopedFeatureList;
scopedFeatureList.InitAndEnableFeature(
web::features::kContextMenuElementPostMessage);
const GURL imageURL = self.testServer->GetURL(kLogoPageImageSourcePath);
[ChromeEarlGrey loadURL:imageURL];
// Calculate a point inside the displayed image. Javascript can not be used to
// find the element because no DOM exists.
CGPoint point = CGPointMake(
CGRectGetMidX([chrome_test_util::GetActiveViewController() view].bounds),
20.0);
id<GREYMatcher> web_view_matcher =
web::WebViewInWebState(chrome_test_util::GetCurrentWebState());
[[EarlGrey selectElementWithMatcher:web_view_matcher]
performAction:grey_longPressAtPointWithDuration(
point, kGREYLongPressDefaultDuration)];
TapOnContextMenuButton(OpenImageInNewTabButton());
[ChromeEarlGrey waitForMainTabCount:2];
SelectTabAtIndexInCurrentMode(1U);
[ChromeEarlGrey waitForPageToFinishLoading];
// Verify url.
[[EarlGrey selectElementWithMatcher:OmniboxText(imageURL.GetContent())]
assertWithMatcher:grey_notNil()];
}
// Tests that the element fetch duration is logged once with the
// kContextMenuElementPostMessage feature enabled.
- (void)testContextMenuElementFetchDurationMetricPostMessage {
base::test::ScopedFeatureList scopedFeatureList;
scopedFeatureList.InitAndEnableFeature(
web::features::kContextMenuElementPostMessage);
chrome_test_util::HistogramTester histogramTester; chrome_test_util::HistogramTester histogramTester;
const GURL pageURL = self.testServer->GetURL(kLogoPagePath); const GURL pageURL = self.testServer->GetURL(kLogoPagePath);
...@@ -481,11 +303,7 @@ void SelectTabAtIndexInCurrentMode(NSUInteger index) { ...@@ -481,11 +303,7 @@ void SelectTabAtIndexInCurrentMode(NSUInteger index) {
} }
// Tests that system touches are cancelled when the context menu is shown. // Tests that system touches are cancelled when the context menu is shown.
// (While the kContextMenuElementPostMessage feature is enabled.) - (void)testContextMenuCancelSystemTouchesMetric {
- (void)testContextMenuCancelSystemTouchesMetricPostMessage {
base::test::ScopedFeatureList scopedFeatureList;
scopedFeatureList.InitAndEnableFeature(
web::features::kContextMenuElementPostMessage);
chrome_test_util::HistogramTester histogramTester; chrome_test_util::HistogramTester histogramTester;
const GURL pageURL = self.testServer->GetURL(kLogoPagePath); const GURL pageURL = self.testServer->GetURL(kLogoPagePath);
...@@ -505,10 +323,7 @@ void SelectTabAtIndexInCurrentMode(NSUInteger index) { ...@@ -505,10 +323,7 @@ void SelectTabAtIndexInCurrentMode(NSUInteger index) {
// Tests that the system selected text callout is displayed instead of the // Tests that the system selected text callout is displayed instead of the
// context menu when user long presses on plain text. // context menu when user long presses on plain text.
- (void)testContextMenuSelectedTextCalloutPostMessage { - (void)testContextMenuSelectedTextCallout {
base::test::ScopedFeatureList scopedFeatureList;
scopedFeatureList.InitAndEnableFeature(
web::features::kContextMenuElementPostMessage);
chrome_test_util::HistogramTester histogramTester; chrome_test_util::HistogramTester histogramTester;
// Load the destination page directly because it has a plain text message on // Load the destination page directly because it has a plain text message on
......
...@@ -125,13 +125,6 @@ const char kContextualSearch[] = "Contextual Search"; ...@@ -125,13 +125,6 @@ const char kContextualSearch[] = "Contextual Search";
const char kContextualSearchDescription[] = const char kContextualSearchDescription[] =
"Whether or not Contextual Search is enabled."; "Whether or not Contextual Search is enabled.";
const char kContextMenuElementPostMessageName[] =
"Context Menu Element Post Message";
const char kContextMenuElementPostMessageDescription[] =
"When enabled, the DOM element for the Context Menu is returned using a "
"webkit postMessage call instead of directly returned from the JavaScript "
"function.";
const char kCopyImageName[] = "Copy Image"; const char kCopyImageName[] = "Copy Image";
const char kCopyImageDescription[] = const char kCopyImageDescription[] =
"Enable copying image to system pasteboard via context menu."; "Enable copying image to system pasteboard via context menu.";
......
...@@ -100,11 +100,6 @@ extern const char kCaptivePortalMetricsDescription[]; ...@@ -100,11 +100,6 @@ extern const char kCaptivePortalMetricsDescription[];
extern const char kContextualSearch[]; extern const char kContextualSearch[];
extern const char kContextualSearchDescription[]; extern const char kContextualSearchDescription[];
// Title and description for the flag to enable returning the DOM element for
// context menu using webkit postMessage API.
extern const char kContextMenuElementPostMessageName[];
extern const char kContextMenuElementPostMessageDescription[];
// Title and description for the flag to enable copying image. // Title and description for the flag to enable copying image.
extern const char kCopyImageName[]; extern const char kCopyImageName[];
extern const char kCopyImageDescription[]; extern const char kCopyImageDescription[];
......
...@@ -7,9 +7,6 @@ ...@@ -7,9 +7,6 @@
namespace web { namespace web {
namespace features { namespace features {
const base::Feature kContextMenuElementPostMessage{
"ContextMenuElementPostMessage", base::FEATURE_DISABLED_BY_DEFAULT};
const base::Feature kWebFrameMessaging{"WebFrameMessaging", const base::Feature kWebFrameMessaging{"WebFrameMessaging",
base::FEATURE_DISABLED_BY_DEFAULT}; base::FEATURE_DISABLED_BY_DEFAULT};
......
...@@ -10,9 +10,6 @@ ...@@ -10,9 +10,6 @@
namespace web { namespace web {
namespace features { namespace features {
// Used to enable asynchronous DOM element fetching for context menu.
extern const base::Feature kContextMenuElementPostMessage;
// Used to enable API to send messages directly to frames of a webpage. // Used to enable API to send messages directly to frames of a webpage.
extern const base::Feature kWebFrameMessaging; extern const base::Feature kWebFrameMessaging;
......
...@@ -7,15 +7,15 @@ ...@@ -7,15 +7,15 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
// Contains keys present in dictionary returned by __gCrWeb.getElementFromPoint // Contains keys present in dictionary created by __gCrWeb.findElementAtPoint
// and __gCrWeb.findElementAtPoint JS APIs. // to represent the DOM element.
namespace web { namespace web {
// Required in findElementAtPoint response. (Not used by getElementFromPoint.) // Required key. Represents a unique string request ID that is passed through
// Represents a unique string request ID that is passed through directly from a // directly from a call to findElementAtPoint to the response dictionary. The
// call to findElementAtPoint to the response dictionary. The request ID should // request ID should be used to correlate a response with a previous call to
// be used to correlate a response with a previous call to findElementAtPoint. // findElementAtPoint.
extern NSString* const kContextMenuElementRequestId; extern NSString* const kContextMenuElementRequestId;
// Optional key. Represents element's href attribute if present or parent's href // Optional key. Represents element's href attribute if present or parent's href
......
...@@ -10,18 +10,13 @@ ...@@ -10,18 +10,13 @@
#import <WebKit/WebKit.h> #import <WebKit/WebKit.h>
#include "base/macros.h" #include "base/macros.h"
#include "base/strings/stringprintf.h"
#include "base/strings/sys_string_conversions.h"
#import "base/test/ios/wait_util.h" #import "base/test/ios/wait_util.h"
#import "ios/web/public/test/js_test_util.h" #import "ios/web/public/test/js_test_util.h"
#include "ios/web/public/test/web_test.h" #include "ios/web/public/test/web_test.h"
#import "ios/web/public/test/web_test_with_web_state.h" #import "ios/web/public/test/web_test_with_web_state.h"
#import "ios/web/public/web_state/ui/crw_web_view_proxy.h"
#import "ios/web/public/web_state/ui/crw_web_view_scroll_view_proxy.h"
#import "ios/web/public/web_state/web_state.h" #import "ios/web/public/web_state/web_state.h"
#import "ios/web/public/web_view_creation_util.h" #import "ios/web/public/web_view_creation_util.h"
#import "ios/web/web_state/context_menu_constants.h" #import "ios/web/web_state/context_menu_constants.h"
#import "ios/web/web_state/ui/wk_web_view_configuration_provider.h"
#import "net/base/mac/url_conversions.h" #import "net/base/mac/url_conversions.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "testing/gtest_mac.h" #include "testing/gtest_mac.h"
...@@ -52,15 +47,6 @@ using base::test::ios::WaitUntilConditionOrTimeout; ...@@ -52,15 +47,6 @@ using base::test::ios::WaitUntilConditionOrTimeout;
namespace { namespace {
// Test coordinates and expected result for __gCrWeb.getElementFromPoint call.
struct TestCoordinatesAndExpectedValue {
TestCoordinatesAndExpectedValue(CGFloat x, CGFloat y, id expected_value)
: x(x), y(y), expected_value(expected_value) {}
CGFloat x = 0;
CGFloat y = 0;
id expected_value = nil;
};
// Request id used for __gCrWeb.findElementAtPoint call. // Request id used for __gCrWeb.findElementAtPoint call.
NSString* const kRequestId = @"UNIQUE_IDENTIFIER"; NSString* const kRequestId = @"UNIQUE_IDENTIFIER";
...@@ -80,362 +66,6 @@ NSString* kPageContentTemplate = ...@@ -80,362 +66,6 @@ NSString* kPageContentTemplate =
namespace web { namespace web {
// Test fixture to test __gCrWeb.getElementFromPoint function defined in
// context_menu.js.
class ContextMenuJsTest : public web::WebTestWithWebState {
protected:
// Verifies that __gCrWeb.getElementFromPoint returns |expected_value| for
// the given image |html|.
void ImageTesterHelper(NSString* html, NSDictionary* expected_value) {
NSString* page_content =
[NSString stringWithFormat:kPageContentTemplate, html];
TestCoordinatesAndExpectedValue test_data[] = {
// Point outside the document margins.
{0, 0, @{}},
// Point inside the <p> element.
{20, 20, expected_value},
// Point outside the <p> element.
{GetWebViewContentSize().width / 2, 50, @{}},
};
for (size_t i = 0; i < arraysize(test_data); i++) {
const TestCoordinatesAndExpectedValue& data = test_data[i];
LoadHtml(page_content);
ExecuteJavaScript(@"document.getElementsByTagName('p')"); // Force layout
id result = ExecuteGetElementFromPointJavaScript(data.x, data.y);
EXPECT_NSEQ(data.expected_value, result)
<< " in test " << i << ": (" << data.x << ", " << data.y << ")";
}
}
// Returns web view's content size from the current web state.
CGSize GetWebViewContentSize() {
return web_state()->GetWebViewProxy().scrollViewProxy.contentSize;
}
// Executes __gCrWeb.getElementFromPoint script and syncronously returns the
// result. |x| and |y| are points in web view coordinate system.
id ExecuteGetElementFromPointJavaScript(CGFloat x, CGFloat y) {
CGSize contentSize = GetWebViewContentSize();
NSString* const script = [NSString
stringWithFormat:@"__gCrWeb.getElementFromPoint(%g, %g, %g, %g)", x, y,
contentSize.width, contentSize.height];
return ExecuteJavaScript(script);
}
};
// Tests that __gCrWeb.getElementFromPoint function returns correct src.
TEST_F(ContextMenuJsTest, GetImageUrlAtPoint) {
NSString* html =
@"<img id='foo' style='width:200;height:200;' src='file:///bogus'/>";
NSDictionary* expected_value = @{
kContextMenuElementSource : @"file:///bogus",
kContextMenuElementReferrerPolicy : @"default",
};
ImageTesterHelper(html, expected_value);
}
// Tests that __gCrWeb.getElementFromPoint function returns correct title.
// TODO(crbug.com/796418): This test is flaky on devices.
#if TARGET_IPHONE_SIMULATOR
#define MAYBE_GetImageTitleAtPoint GetImageTitleAtPoint
#else
#define MAYBE_GetImageTitleAtPoint FLAKY_GetImageTitleAtPoint
#endif
TEST_F(ContextMenuJsTest, MAYBE_GetImageTitleAtPoint) {
NSString* html =
@"<img id='foo' title='Hello world!'"
"style='width:200;height:200;' src='file:///bogus'/>";
NSDictionary* expected_value = @{
kContextMenuElementSource : @"file:///bogus",
kContextMenuElementReferrerPolicy : @"default",
kContextMenuElementTitle : @"Hello world!",
};
ImageTesterHelper(html, expected_value);
}
// Tests that __gCrWeb.getElementFromPoint function returns correct href.
TEST_F(ContextMenuJsTest, GetLinkImageUrlAtPoint) {
NSString* html =
@"<a href='file:///linky'>"
"<img id='foo' style='width:200;height:200;' src='file:///bogus'/>"
"</a>";
NSDictionary* expected_value = @{
kContextMenuElementSource : @"file:///bogus",
kContextMenuElementReferrerPolicy : @"default",
kContextMenuElementHyperlink : @"file:///linky",
};
ImageTesterHelper(html, expected_value);
}
TEST_F(ContextMenuJsTest, TextAreaStopsProximity) {
NSString* html =
@"<html><body style='margin-left:10px;margin-top:10px;'>"
"<div style='width:100px;height:100px;'>"
"<img id='foo'"
" style='position:absolute;left:0px;top:0px;width:50px;height:50px'"
" src='file:///bogus' />"
"<input type='text' name='name'"
" style='position:absolute;left:5px;top:5px; "
"width:40px;height:40px'/>"
"</div></body> </html>";
NSDictionary* success = @{
kContextMenuElementSource : @"file:///bogus",
kContextMenuElementReferrerPolicy : @"default",
};
NSDictionary* failure = @{};
TestCoordinatesAndExpectedValue test_data[] = {
{2, 20, success}, {10, 10, failure},
};
for (size_t i = 0; i < arraysize(test_data); i++) {
const TestCoordinatesAndExpectedValue& data = test_data[i];
LoadHtml(html);
ExecuteJavaScript(@"document.getElementsByTagName('img')"); // Force layout
id result = ExecuteGetElementFromPointJavaScript(data.x, data.y);
EXPECT_NSEQ(data.expected_value, result)
<< " in test " << i << ": (" << data.x << ", " << data.y << ")";
}
}
// Tests the javascript of the url of the an image present in the DOM.
// TODO(crbug.com/796418): This test is flaky on devices.
#if TARGET_IPHONE_SIMULATOR
#define MAYBE_LinkOfImage LinkOfImage
#else
#define MAYBE_LinkOfImage FLAKY_LinkOfImage
#endif
TEST_F(ContextMenuJsTest, MAYBE_LinkOfImage) {
// A page with a large image surrounded by a link.
static const char image[] =
"<a href='%s'><img width=400 height=400 src='foo'></img></a>";
// A page with a link to a destination URL.
ASSERT_TRUE(LoadHtml(base::StringPrintf(image, "http://destination")));
ExecuteJavaScript(@"document.getElementsByTagName('img')"); // Force layout.
id result = ExecuteGetElementFromPointJavaScript(20, 20);
NSDictionary* expected_result = @{
kContextMenuElementSource :
[NSString stringWithFormat:@"%sfoo", BaseUrl().c_str()],
kContextMenuElementReferrerPolicy : @"default",
kContextMenuElementHyperlink : @"http://destination/",
};
EXPECT_NSEQ(expected_result, result);
// A page with a link with some JavaScript that does not result in a NOP.
ASSERT_TRUE(LoadHtml(
base::StringPrintf(image, "javascript:console.log('whatever')")));
result = ExecuteGetElementFromPointJavaScript(20, 20);
expected_result = @{
kContextMenuElementSource :
[NSString stringWithFormat:@"%sfoo", BaseUrl().c_str()],
kContextMenuElementReferrerPolicy : @"default",
kContextMenuElementHyperlink : @"javascript:console.log(",
};
EXPECT_NSEQ(expected_result, result);
// A list of JavaScripts that result in a NOP.
std::vector<std::string> nop_javascripts;
nop_javascripts.push_back(";");
nop_javascripts.push_back("void(0);");
nop_javascripts.push_back("void(0); void(0); void(0)");
for (auto js : nop_javascripts) {
// A page with a link with some JavaScript that results in a NOP.
const std::string javascript = std::string("javascript:") + js;
ASSERT_TRUE(LoadHtml(base::StringPrintf(image, javascript.c_str())));
result = ExecuteGetElementFromPointJavaScript(20, 20);
expected_result = @{
kContextMenuElementSource :
[NSString stringWithFormat:@"%sfoo", BaseUrl().c_str()],
kContextMenuElementReferrerPolicy : @"default",
};
// Make sure the returned JSON does not have an 'href' key.
EXPECT_NSEQ(expected_result, result);
}
}
// Tests context menu invoked on an image with "-webkit-touch-callout:none"
// style and parent link.
TEST_F(ContextMenuJsTest, LinkOfImageWithCalloutNone) {
// A page with an image surrounded by a link.
static const char image_html[] =
"<a href='%s'>"
"<img style='width:9;height:9;display:block;-webkit-touch-callout:none;'>"
"</a>";
// A page with a link to a destination URL.
ASSERT_TRUE(LoadHtml(base::StringPrintf(image_html, "http://destination")));
ExecuteJavaScript(@"document.getElementsByTagName('img')"); // Force layout.
id result = ExecuteGetElementFromPointJavaScript(5, 5);
NSDictionary* expected_result = @{
kContextMenuElementInnerText : @"",
kContextMenuElementReferrerPolicy : @"default",
kContextMenuElementHyperlink : @"http://destination/",
};
EXPECT_NSEQ(expected_result, result);
}
// Tests that the GetElementFromPoint script reports "never" as the referrer
// policy for pages that have an unsupported policy in a meta tag.
TEST_F(ContextMenuJsTest, UnsupportedReferrerPolicy) {
// A page with an unsupported referrer meta tag and a 400x400 image.
static const char kInvalidReferrerTag[] =
"<meta name=\"referrer\" content=\"unsupported-value\">"
"<img width=400 height=400 src='foo'></img>";
// Load the invalid meta tag
ASSERT_TRUE(LoadHtml(kInvalidReferrerTag));
ExecuteJavaScript(@"document.getElementsByTagName('img')"); // Force layout
id result = ExecuteGetElementFromPointJavaScript(20, 20);
ASSERT_TRUE([result isKindOfClass:[NSDictionary class]]);
EXPECT_NSEQ(@"never", result[kContextMenuElementReferrerPolicy]);
}
// Tests that getElementFromPoint finds an element at the bottom of a very long
// page.
// TODO(crbug.com/796418): This test is flaky on devices.
#if TARGET_IPHONE_SIMULATOR
#define MAYBE_LinkOfTextFromTallPage LinkOfTextFromTallPage
#else
#define MAYBE_LinkOfTextFromTallPage FLAKY_LinkOfTextFromTallPage
#endif
TEST_F(ContextMenuJsTest, MAYBE_LinkOfTextFromTallPage) {
const char kHtml[] =
"<html><body>"
" <div style='height:4000px'></div>"
" <div><a href='http://destination'>link</a></div>"
"</body></html>";
ASSERT_TRUE(LoadHtml(kHtml));
// Scroll the webView to the bottom to make the link accessible.
CGFloat content_height = GetWebViewContentSize().height;
CGFloat scroll_view_height =
CGRectGetHeight(web_state()->GetWebViewProxy().scrollViewProxy.frame);
CGFloat offset = content_height - scroll_view_height;
web_state()->GetWebViewProxy().scrollViewProxy.contentOffset =
CGPointMake(0.0, offset);
ExecuteJavaScript(@"document.getElementsByTagName('a')"); // Force layout.
// Link is at bottom of the page content.
id result = ExecuteGetElementFromPointJavaScript(1, content_height - 5.0);
NSDictionary* expected_result = @{
kContextMenuElementInnerText : @"link",
kContextMenuElementReferrerPolicy : @"default",
kContextMenuElementHyperlink : @"http://destination/",
};
EXPECT_NSEQ(expected_result, result);
}
// Tests that a callout information about a link is displayed when
// -webkit-touch-callout property is not specified. Please see:
// https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-touch-callout
TEST_F(ContextMenuJsTest, LinkOfTextWithoutCalloutProperty) {
const char kLinkHtml[] = "<a href='%s'>link</a>";
ASSERT_TRUE(LoadHtml(base::StringPrintf(kLinkHtml, "http://destination")));
ExecuteJavaScript(@"document.getElementsByTagName('a')"); // Force layout.
id result = ExecuteGetElementFromPointJavaScript(1, 1);
NSDictionary* expected_result = @{
kContextMenuElementInnerText : @"link",
kContextMenuElementReferrerPolicy : @"default",
kContextMenuElementHyperlink : @"http://destination/",
};
EXPECT_NSEQ(expected_result, result);
}
// Tests that a callout information about a link is displayed when
// -webkit-touch-callout property is set to default. Please see:
// https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-touch-callout
// TODO(crbug.com/796343): This test is flaky on iOS 11 device.
#if TARGET_IPHONE_SIMULATOR
#define MAYBE_LinkOfTextWithCalloutDefault LinkOfTextWithCalloutDefault
#else
#define MAYBE_LinkOfTextWithCalloutDefault FLAKY_LinkOfTextWithCalloutDefault
#endif
TEST_F(ContextMenuJsTest, MAYBE_LinkOfTextWithCalloutDefault) {
const char kLinkHtml[] =
"<a href='%s' style='-webkit-touch-callout:default;'>link</a>";
ASSERT_TRUE(LoadHtml(base::StringPrintf(kLinkHtml, "http://destination")));
ExecuteJavaScript(@"document.getElementsByTagName('a')"); // Force layout.
id result = ExecuteGetElementFromPointJavaScript(1, 1);
NSDictionary* expected_result = @{
kContextMenuElementInnerText : @"link",
kContextMenuElementReferrerPolicy : @"default",
kContextMenuElementHyperlink : @"http://destination/",
};
EXPECT_NSEQ(expected_result, result);
}
// Tests that no callout information about a link is displayed when
// -webkit-touch-callout property is set to none. Please see:
// https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-touch-callout
// TODO(crbug.com/873662): This test is flaky on iOS 11 device.
#if TARGET_IPHONE_SIMULATOR
#define MAYBE_LinkOfTextWithCalloutNone LinkOfTextWithCalloutNone
#else
#define MAYBE_LinkOfTextWithCalloutNone FLAKY_LinkOfTextWithCalloutNone
#endif
TEST_F(ContextMenuJsTest, MAYBE_LinkOfTextWithCalloutNone) {
const char kLinkHtml[] =
"<a href='%s' style='-webkit-touch-callout:none;'>link</a>";
ASSERT_TRUE(LoadHtml(base::StringPrintf(kLinkHtml, "http://destination")));
ExecuteJavaScript(@"document.getElementsByTagName('a')"); // Force layout.
id result = ExecuteGetElementFromPointJavaScript(1, 1);
EXPECT_NSEQ(@{}, result);
}
// Tests that -webkit-touch-callout property can be inherited from ancester if
// it's not specified. Please see:
// https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-touch-callout
TEST_F(ContextMenuJsTest, LinkOfTextWithCalloutFromAncester) {
const char kLinkHtml[] =
"<body style='-webkit-touch-callout: none'>"
" <a href='%s'>link</a>"
"</body>";
ASSERT_TRUE(LoadHtml(base::StringPrintf(kLinkHtml, "http://destination")));
ExecuteJavaScript(@"document.getElementsByTagName('a')"); // Force layout.
id result = ExecuteGetElementFromPointJavaScript(1, 1);
EXPECT_NSEQ(@{}, result);
}
// Tests that setting -webkit-touch-callout property can override the value
// inherited from ancester. Please see:
// https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-touch-callout
// TODO(crbug.com/873660): This test is flaky on iOS 11 device.
#if TARGET_IPHONE_SIMULATOR
#define MAYBE_LinkOfTextWithCalloutOverride LinkOfTextWithCalloutOverride
#else
#define MAYBE_LinkOfTextWithCalloutOverride FLAKY_LinkOfTextWithCalloutOverride
#endif
TEST_F(ContextMenuJsTest, MAYBE_LinkOfTextWithCalloutOverride) {
const char kLinkHtml[] =
"<body style='-webkit-touch-callout: none'>"
" <a href='%s' style='-webkit-touch-callout: default'>link</a>"
"</body>";
ASSERT_TRUE(LoadHtml(base::StringPrintf(kLinkHtml, "http://destination")));
ExecuteJavaScript(@"document.getElementsByTagName('a')"); // Force layout.
id result = ExecuteGetElementFromPointJavaScript(1, 1);
NSDictionary* expected_result = @{
kContextMenuElementInnerText : @"link",
kContextMenuElementReferrerPolicy : @"default",
kContextMenuElementHyperlink : @"http://destination/",
};
EXPECT_NSEQ(expected_result, result);
}
// Test fixture to test __gCrWeb.findElementAtPoint function defined in // Test fixture to test __gCrWeb.findElementAtPoint function defined in
// context_menu.js. // context_menu.js.
class ContextMenuJsFindElementAtPointTest : public web::WebTest { class ContextMenuJsFindElementAtPointTest : public web::WebTest {
...@@ -826,10 +456,9 @@ TEST_F(ContextMenuJsFindElementAtPointTest, UnsupportedReferrerPolicy) { ...@@ -826,10 +456,9 @@ TEST_F(ContextMenuJsFindElementAtPointTest, UnsupportedReferrerPolicy) {
// very long page. // very long page.
// TODO(crbug.com/796418): This test is flaky on devices. // TODO(crbug.com/796418): This test is flaky on devices.
#if TARGET_IPHONE_SIMULATOR #if TARGET_IPHONE_SIMULATOR
#define MAYBE_LinkOfTextFromTallPageFindElementAtPoint LinkOfTextFromTallPage #define MAYBE_LinkOfTextFromTallPage LinkOfTextFromTallPage
#else #else
#define MAYBE_LinkOfTextFromTallPageFindElementAtPoint \ #define MAYBE_LinkOfTextFromTallPage FLAKY_LinkOfTextFromTallPage
FLAKY_LinkOfTextFromTallPage
#endif #endif
TEST_F(ContextMenuJsFindElementAtPointTest, MAYBE_LinkOfTextFromTallPage) { TEST_F(ContextMenuJsFindElementAtPointTest, MAYBE_LinkOfTextFromTallPage) {
NSString* kHtml = NSString* kHtml =
...@@ -893,11 +522,9 @@ TEST_F(ContextMenuJsFindElementAtPointTest, ...@@ -893,11 +522,9 @@ TEST_F(ContextMenuJsFindElementAtPointTest,
// https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-touch-callout // https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-touch-callout
// TODO(crbug.com/796343): This test is flaky on iOS 11 device. // TODO(crbug.com/796343): This test is flaky on iOS 11 device.
#if TARGET_IPHONE_SIMULATOR #if TARGET_IPHONE_SIMULATOR
#define MAYBE_LinkOfTextWithCalloutDefaultFindElementAtPoint \ #define MAYBE_LinkOfTextWithCalloutDefault LinkOfTextWithCalloutDefault
LinkOfTextWithCalloutDefault
#else #else
#define MAYBE_LinkOfTextWithCalloutDefaultFindElementAtPoint \ #define MAYBE_LinkOfTextWithCalloutDefault FLAKY_LinkOfTextWithCalloutDefault
FLAKY_LinkOfTextWithCalloutDefault
#endif #endif
TEST_F(ContextMenuJsFindElementAtPointTest, TEST_F(ContextMenuJsFindElementAtPointTest,
MAYBE_LinkOfTextWithCalloutDefault) { MAYBE_LinkOfTextWithCalloutDefault) {
......
...@@ -14,59 +14,6 @@ goog.require('__crWeb.common'); ...@@ -14,59 +14,6 @@ goog.require('__crWeb.common');
/** Beginning of anonymous object */ /** Beginning of anonymous object */
(function() { (function() {
/**
* Returns an object representing the details of the given element.
* @param {number} x Horizontal center of the selected point in page
* coordinates.
* @param {number} y Vertical center of the selected point in page
* coordinates.
* @return {Object} An object of the same form as returned by
* {@code getResponseForLinkElement} or
* {@code getResponseForImageElement} or null if no element was
* found.
*/
__gCrWeb['getElementFromPointInPageCoordinates'] = function(x, y) {
var hitCoordinates = spiralCoordinates_(x, y);
for (var index = 0; index < hitCoordinates.length; index++) {
var coordinates = hitCoordinates[index];
var coordinateDetails = newCoordinate(coordinates.x, coordinates.y);
var element = elementsFromCoordinates(coordinateDetails);
if (!element || !element.tagName) {
// Nothing under the hit point. Try the next hit point.
continue;
}
// Also check element's ancestors. A bound on the level is used here to
// avoid large overhead when no links or images are found.
var level = 0;
while (++level < 8 && element && element != document) {
var tagName = element.tagName;
if (!tagName) continue;
tagName = tagName.toLowerCase();
if (tagName === 'input' || tagName === 'textarea' ||
tagName === 'select' || tagName === 'option') {
// If the element is a known input element, stop the spiral search and
// return empty results.
return {};
}
if (getComputedWebkitTouchCallout_(element) !== 'none') {
if (tagName === 'a' && element.href) {
return getResponseForLinkElement(element);
}
if (tagName === 'img' && element.src) {
return getResponseForImageElement(element);
}
}
element = element.parentNode;
}
}
return {};
};
/** /**
* Returns an object representing the details of a given link element. * Returns an object representing the details of a given link element.
* @param {HTMLElement} element The element whose details will be returned. * @param {HTMLElement} element The element whose details will be returned.
......
...@@ -18,7 +18,7 @@ goog.provide('__crWeb.mainFrameContextMenu'); ...@@ -18,7 +18,7 @@ goog.provide('__crWeb.mainFrameContextMenu');
* found element (or an empty object if no links or images are found) back to * found element (or an empty object if no links or images are found) back to
* the application by posting a 'FindElementResultHandler' message. * the application by posting a 'FindElementResultHandler' message.
* The object returned in the message is of the same form as * The object returned in the message is of the same form as
* {@code getElementFromPointInPageCoordinates} result. * {@code findElementAtPointInPageCoordinates} result.
* @param {string} requestId An identifier which be returned in the result * @param {string} requestId An identifier which be returned in the result
* dictionary of this request. * dictionary of this request.
* @param {number} x Horizontal center of the selected point in web view * @param {number} x Horizontal center of the selected point in web view
...@@ -36,23 +36,6 @@ __gCrWeb['findElementAtPoint'] = ...@@ -36,23 +36,6 @@ __gCrWeb['findElementAtPoint'] =
y * scale); y * scale);
}; };
/**
* Returns the url of the image or link under the selected point. Returns an
* empty object if no links or images are found.
* @param {number} x Horizontal center of the selected point in web view
* coordinates.
* @param {number} y Vertical center of the selected point in web view
* coordinates.
* @param {number} webViewWidth the width of web view.
* @param {number} webViewHeight the height of web view.
* @return {!Object} An object in the same form as
* {@code getElementFromPointInPageCoordinates} result.
*/
__gCrWeb['getElementFromPoint'] = function(x, y, webViewWidth, webViewHeight) {
var scale = getPageWidth() / webViewWidth;
return __gCrWeb.getElementFromPointInPageCoordinates(x * scale, y * scale);
};
/** /**
* Suppresses the next click such that they are not handled by JS click * Suppresses the next click such that they are not handled by JS click
* event handlers. * event handlers.
......
...@@ -178,10 +178,6 @@ struct ContextMenuInfo { ...@@ -178,10 +178,6 @@ struct ContextMenuInfo {
_delegate = delegate; _delegate = delegate;
_injectionEvaluator = injectionEvaluator; _injectionEvaluator = injectionEvaluator;
_pendingElementFetchRequests = [[NSMutableDictionary alloc] init]; _pendingElementFetchRequests = [[NSMutableDictionary alloc] init];
// Default to assuming all elements are from the main frame since this value
// will not be updated unless the
// |web::features::kContextMenuElementPostMessage| feature is enabled.
_contextMenuInfoForLastTouch.is_main_frame = YES;
// The system context menu triggers after 0.55 second. Add a gesture // The system context menu triggers after 0.55 second. Add a gesture
// recognizer with a shorter delay to be able to cancel the system menu if // recognizer with a shorter delay to be able to cancel the system menu if
...@@ -219,20 +215,17 @@ struct ContextMenuInfo { ...@@ -219,20 +215,17 @@ struct ContextMenuInfo {
} }
} }
if (base::FeatureList::IsEnabled( // Listen for fetched element response.
web::features::kContextMenuElementPostMessage)) { web::WKWebViewConfigurationProvider& configurationProvider =
// Listen for fetched element response. web::WKWebViewConfigurationProvider::FromBrowserState(browserState);
web::WKWebViewConfigurationProvider& configurationProvider = CRWWKScriptMessageRouter* messageRouter =
web::WKWebViewConfigurationProvider::FromBrowserState(browserState); configurationProvider.GetScriptMessageRouter();
CRWWKScriptMessageRouter* messageRouter = __weak CRWContextMenuController* weakSelf = self;
configurationProvider.GetScriptMessageRouter(); [messageRouter setScriptMessageHandler:^(WKScriptMessage* message) {
__weak CRWContextMenuController* weakSelf = self; [weakSelf didReceiveScriptMessage:message];
[messageRouter setScriptMessageHandler:^(WKScriptMessage* message) {
[weakSelf didReceiveScriptMessage:message];
}
name:kFindElementResultHandlerName
webView:webView];
} }
name:kFindElementResultHandlerName
webView:webView];
} }
return self; return self;
} }
...@@ -492,41 +485,20 @@ struct ContextMenuInfo { ...@@ -492,41 +485,20 @@ struct ContextMenuInfo {
CGFloat webViewContentWidth = webViewContentSize.width; CGFloat webViewContentWidth = webViewContentSize.width;
CGFloat webViewContentHeight = webViewContentSize.height; CGFloat webViewContentHeight = webViewContentSize.height;
NSString* formatString; NSString* requestID =
web::JavaScriptResultBlock completionHandler = nil; base::SysUTF8ToNSString(base::UnguessableToken::Create().ToString());
if (base::FeatureList::IsEnabled( HTMLElementFetchRequest* fetchRequest =
web::features::kContextMenuElementPostMessage)) { [[HTMLElementFetchRequest alloc] initWithFoundElementHandler:handler];
NSString* requestID = _pendingElementFetchRequests[requestID] = fetchRequest;
base::SysUTF8ToNSString(base::UnguessableToken::Create().ToString()); NSString* formatString = [NSString
HTMLElementFetchRequest* fetchRequest = stringWithFormat:
[[HTMLElementFetchRequest alloc] initWithFoundElementHandler:handler]; @"__gCrWeb.findElementAtPoint('%@', %%g, %%g, %%g, %%g);", requestID];
_pendingElementFetchRequests[requestID] = fetchRequest;
formatString =
[NSString stringWithFormat:
@"__gCrWeb.findElementAtPoint('%@', %%g, %%g, %%g, %%g);",
requestID];
} else {
formatString = @"__gCrWeb.getElementFromPoint(%g, %g, %g, %g);";
base::TimeTicks getElementStartTime = base::TimeTicks::Now();
__weak CRWContextMenuController* weakSelf = self;
completionHandler = ^(id element, NSError* error) {
[weakSelf logElementFetchDurationWithStartTime:getElementStartTime];
if (error.code == WKErrorWebContentProcessTerminated ||
error.code == WKErrorWebViewInvalidated) {
// Renderer was terminated or view deallocated.
handler(nil);
} else {
handler(base::mac::ObjCCastStrict<NSDictionary>(element));
}
};
}
NSString* getElementScript = NSString* getElementScript =
[NSString stringWithFormat:formatString, point.x + scrollOffset.x, [NSString stringWithFormat:formatString, point.x + scrollOffset.x,
point.y + scrollOffset.y, webViewContentWidth, point.y + scrollOffset.y, webViewContentWidth,
webViewContentHeight]; webViewContentHeight];
[self executeJavaScript:getElementScript completionHandler:completionHandler]; [self executeJavaScript:getElementScript completionHandler:nil];
} }
@end @end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment