Title: [175474] trunk/Source/WebKit2
Revision
175474
Author
[email protected]
Date
2014-11-03 10:38:44 -0800 (Mon, 03 Nov 2014)

Log Message

Implement action menus for editable text
https://bugs.webkit.org/show_bug.cgi?id=138284
-and corresponding-
rdar://problem/18742323

Reviewed by Tim Horton.

New item type for paste.
* Shared/API/c/WKActionMenuItemTypes.h:

New menu type for editable text.
* Shared/API/c/WKActionMenuTypes.h:
* UIProcess/mac/WKActionMenuController.mm:

willOpenMenu should select text for both regular text menus and editable text 
menus. 
(-[WKActionMenuController willOpenMenu:withEvent:]):

Default items for editable text.
(-[WKActionMenuController _defaultMenuItemsForEditableText]):
(-[WKActionMenuController _paste:]):
(-[WKActionMenuController _createActionMenuItemForTag:]):

New method _hitTestResultForStage:(MenuUpdateStage)stage will figure out whether 
we can use the WebHitTestResult from the ActionMenuHitTestResult or if we have to 
use the potentially out-of-date WebHitTestResult that is cached on WebPageProxy. 
An important difference between these results is that the ActionMenuHitTest 
result, in addition to being more recent and accurate, also now includes shadow 
content, which affects some editable regions on important sites such as 
bugs.webkit.org and nytimes.com.
(-[WKActionMenuController _defaultMenuItems:]):
(-[WKActionMenuController _updateActionMenuItemsForStage:]):
(imageForResource:name::if): Deleted.

Allow shadow content in action menu hit testing.
* WebProcess/WebPage/mac/WebPageMac.mm:
(WebKit::WebPage::performActionMenuHitTestAtLocation):
(WebKit::WebPage::selectLookupTextAtLocation):

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (175473 => 175474)


--- trunk/Source/WebKit2/ChangeLog	2014-11-03 18:36:57 UTC (rev 175473)
+++ trunk/Source/WebKit2/ChangeLog	2014-11-03 18:38:44 UTC (rev 175474)
@@ -1,3 +1,44 @@
+2014-11-03  Beth Dakin  <[email protected]>
+
+        Implement action menus for editable text
+        https://bugs.webkit.org/show_bug.cgi?id=138284
+        -and corresponding-
+        rdar://problem/18742323
+
+        Reviewed by Tim Horton.
+
+        New item type for paste.
+        * Shared/API/c/WKActionMenuItemTypes.h:
+
+        New menu type for editable text.
+        * Shared/API/c/WKActionMenuTypes.h:
+        * UIProcess/mac/WKActionMenuController.mm:
+
+        willOpenMenu should select text for both regular text menus and editable text 
+        menus. 
+        (-[WKActionMenuController willOpenMenu:withEvent:]):
+
+        Default items for editable text.
+        (-[WKActionMenuController _defaultMenuItemsForEditableText]):
+        (-[WKActionMenuController _paste:]):
+        (-[WKActionMenuController _createActionMenuItemForTag:]):
+
+        New method _hitTestResultForStage:(MenuUpdateStage)stage will figure out whether 
+        we can use the WebHitTestResult from the ActionMenuHitTestResult or if we have to 
+        use the potentially out-of-date WebHitTestResult that is cached on WebPageProxy. 
+        An important difference between these results is that the ActionMenuHitTest 
+        result, in addition to being more recent and accurate, also now includes shadow 
+        content, which affects some editable regions on important sites such as 
+        bugs.webkit.org and nytimes.com.
+        (-[WKActionMenuController _defaultMenuItems:]):
+        (-[WKActionMenuController _updateActionMenuItemsForStage:]):
+        (imageForResource:name::if): Deleted.
+
+        Allow shadow content in action menu hit testing.
+        * WebProcess/WebPage/mac/WebPageMac.mm:
+        (WebKit::WebPage::performActionMenuHitTestAtLocation):
+        (WebKit::WebPage::selectLookupTextAtLocation):
+
 2014-11-03  Ada Chan  <[email protected]>
 
         Persist the page's muted state across web process crashes.

Modified: trunk/Source/WebKit2/Shared/API/c/WKActionMenuItemTypes.h (175473 => 175474)


--- trunk/Source/WebKit2/Shared/API/c/WKActionMenuItemTypes.h	2014-11-03 18:36:57 UTC (rev 175473)
+++ trunk/Source/WebKit2/Shared/API/c/WKActionMenuItemTypes.h	2014-11-03 18:38:44 UTC (rev 175474)
@@ -42,7 +42,8 @@
     kWKContextActionItemTagSaveImageToDownloads,
     kWKContextActionItemTagShareImage,
     kWKContextActionItemTagCopyText,
-    kWKContextActionItemTagLookupText
+    kWKContextActionItemTagLookupText,
+    kWKContextActionItemTagPaste
 };
 
 #ifdef __cplusplus

Modified: trunk/Source/WebKit2/Shared/API/c/WKActionMenuTypes.h (175473 => 175474)


--- trunk/Source/WebKit2/Shared/API/c/WKActionMenuTypes.h	2014-11-03 18:36:57 UTC (rev 175473)
+++ trunk/Source/WebKit2/Shared/API/c/WKActionMenuTypes.h	2014-11-03 18:38:44 UTC (rev 175474)
@@ -37,7 +37,8 @@
     kWKActionMenuLink,
     kWKActionMenuImage,
     kWKActionMenuDataDetectedItem,
-    kWKActionMenuReadOnlyText
+    kWKActionMenuReadOnlyText,
+    kWKActionMenuEditableText
 };
 typedef uint32_t _WKActionMenuType;
 

Modified: trunk/Source/WebKit2/UIProcess/mac/WKActionMenuController.mm (175473 => 175474)


--- trunk/Source/WebKit2/UIProcess/mac/WKActionMenuController.mm	2014-11-03 18:36:57 UTC (rev 175473)
+++ trunk/Source/WebKit2/UIProcess/mac/WKActionMenuController.mm	2014-11-03 18:38:44 UTC (rev 175474)
@@ -115,12 +115,12 @@
     if (menu != _wkView.actionMenu)
         return;
 
-    if (_type != kWKActionMenuReadOnlyText)
+    if (_type != kWKActionMenuReadOnlyText && _type != kWKActionMenuEditableText)
         return;
 
     // Action menus for text should highlight the text so that it is clear what the action menu actions
     // will apply to. If the text is already selected, the menu will use the existing selection.
-    WebHitTestResult* hitTestResult = _page->lastMouseMoveHitTestResult();
+    RefPtr<WebHitTestResult> hitTestResult = [self _hitTestResultForStage:MenuUpdateStage::MenuNeedsUpdate];
     if (!hitTestResult->isSelected())
         _page->selectLookupTextAtLocation([_wkView convertPoint:event.locationInWindow fromView:nil]);
 }
@@ -314,6 +314,17 @@
 
 #pragma mark Text actions
 
+- (NSArray *)_defaultMenuItemsForDataDetectedText
+{
+    DDActionContext *actionContext = _hitTestResult.actionContext.get();
+    if (!actionContext)
+        return @[ ];
+
+    WKSetDDActionContextIsForActionMenu(actionContext);
+    actionContext.highlightFrame = [_wkView.window convertRectToScreen:[_wkView convertRect:_hitTestResult.actionBoundingBox toView:nil]];
+    return [[getDDActionsManagerClass() sharedManager] menuItemsForResult:[_hitTestResult.actionContext mainResult] actionContext:actionContext];
+}
+
 - (NSArray *)_defaultMenuItemsForText
 {
     RetainPtr<NSMenuItem> copyTextItem = [self _createActionMenuItemForTag:kWKContextActionItemTagCopyText];
@@ -322,11 +333,25 @@
     return @[ copyTextItem.get(), lookupTextItem.get() ];
 }
 
--(void)_copyText:(id)sender
+- (NSArray *)_defaultMenuItemsForEditableText
 {
+    RetainPtr<NSMenuItem> copyTextItem = [self _createActionMenuItemForTag:kWKContextActionItemTagCopyText];
+    RetainPtr<NSMenuItem> lookupTextItem = [self _createActionMenuItemForTag:kWKContextActionItemTagLookupText];
+    RetainPtr<NSMenuItem> pasteItem = [self _createActionMenuItemForTag:kWKContextActionItemTagPaste];
+
+    return @[ copyTextItem.get(), lookupTextItem.get(), pasteItem.get() ];
+}
+
+-(void)_copySelection:(id)sender
+{
     _page->executeEditCommand("copy");
 }
 
+-(void)_paste:(id)sender
+{
+    _page->executeEditCommand("paste");
+}
+
 -(void)_lookupText:(id)sender
 {
     _page->performDictionaryLookupOfCurrentSelection();
@@ -430,7 +455,7 @@
         break;
 
     case kWKContextActionItemTagCopyText:
-        selector = @selector(_copyText:);
+        selector = @selector(_copySelection:);
         title = @"Copy";
         image = [NSImage imageNamed:@"NSActionMenuCopy"];
         break;
@@ -441,6 +466,12 @@
         image = [NSImage imageNamed:@"NSActionMenuLookup"];
         break;
 
+    case kWKContextActionItemTagPaste:
+        selector = @selector(_paste:);
+        title = @"Paste";
+        image = [NSImage imageNamed:@"NSActionMenuPaste"];
+        break;
+
     default:
         ASSERT_NOT_REACHED();
         return nil;
@@ -458,32 +489,56 @@
     return [[NSBundle bundleForClass:[WKView class]] imageForResource:name];
 }
 
-- (NSArray *)_defaultMenuItems
+- (PassRefPtr<WebHitTestResult>)_hitTestResultForStage:(MenuUpdateStage)stage
 {
-    if (WebHitTestResult* hitTestResult = _page->lastMouseMoveHitTestResult()) {
-        if (!hitTestResult->absoluteImageURL().isEmpty() && _hitTestResult.image) {
-            _type = kWKActionMenuImage;
-            return [self _defaultMenuItemsForImage];
+    RefPtr<WebHitTestResult> hitTestResult;
+    switch (stage) {
+    case MenuUpdateStage::PrepareForMenu:
+        hitTestResult = _page->lastMouseMoveHitTestResult();
+        break;
+    case MenuUpdateStage::MenuNeedsUpdate:
+        if (_state == ActionMenuState::Ready)
+            hitTestResult = WebHitTestResult::create(_hitTestResult.hitTestResult);
+        else
+            hitTestResult = _page->lastMouseMoveHitTestResult();
+        break;
+    }
+
+    return hitTestResult.release();
+}
+
+- (NSArray *)_defaultMenuItems:(MenuUpdateStage)stage
+{
+    RefPtr<WebHitTestResult> hitTestResult = [self _hitTestResultForStage:stage];
+    if (!hitTestResult) {
+        _type = kWKActionMenuNone;
+        return _state != ActionMenuState::Ready ? @[ [NSMenuItem separatorItem] ] : @[ ];
+    }
+
+    if (!hitTestResult->absoluteImageURL().isEmpty() && _hitTestResult.image) {
+        _type = kWKActionMenuImage;
+        return [self _defaultMenuItemsForImage];
+    }
+
+    if (!hitTestResult->absoluteLinkURL().isEmpty()) {
+        _type = kWKActionMenuLink;
+        return [self _defaultMenuItemsForLink];
+    }
+
+    if (hitTestResult->isTextNode()) {
+        NSArray *dataDetectorMenuItems = [self _defaultMenuItemsForDataDetectedText];
+        if (dataDetectorMenuItems.count) {
+            _type = kWKActionMenuDataDetectedItem;
+            return dataDetectorMenuItems;
         }
 
-        if (!hitTestResult->absoluteLinkURL().isEmpty()) {
-            _type = kWKActionMenuLink;
-            return [self _defaultMenuItemsForLink];
+        if (hitTestResult->isContentEditable()) {
+            _type = kWKActionMenuEditableText;
+            return [self _defaultMenuItemsForEditableText];
         }
 
-        if (hitTestResult->isTextNode()) {
-            if (DDActionContext *actionContext = _hitTestResult.actionContext.get()) {
-                WKSetDDActionContextIsForActionMenu(actionContext);
-                actionContext.highlightFrame = [_wkView.window convertRectToScreen:[_wkView convertRect:_hitTestResult.actionBoundingBox toView:nil]];
-                NSArray *dataDetectorMenuItems = [[getDDActionsManagerClass() sharedManager] menuItemsForResult:[_hitTestResult.actionContext mainResult] actionContext:actionContext];
-                if (dataDetectorMenuItems.count) {
-                    _type = kWKActionMenuDataDetectedItem;
-                    return dataDetectorMenuItems;
-                }
-            }
-            _type = kWKActionMenuReadOnlyText;
-            return [self _defaultMenuItemsForText];
-        }
+        _type = kWKActionMenuReadOnlyText;
+        return [self _defaultMenuItemsForText];
     }
 
     _type = kWKActionMenuNone;
@@ -494,19 +549,8 @@
 {
     [_wkView.actionMenu removeAllItems];
 
-    NSArray *menuItems = [self _defaultMenuItems];
-    RefPtr<WebHitTestResult> hitTestResult;
-    switch (stage) {
-    case MenuUpdateStage::PrepareForMenu:
-        hitTestResult = _page->lastMouseMoveHitTestResult();
-        break;
-    case MenuUpdateStage::MenuNeedsUpdate:
-        if (_state == ActionMenuState::Ready)
-            hitTestResult = WebHitTestResult::create(_hitTestResult.hitTestResult);
-        else
-            hitTestResult = _page->lastMouseMoveHitTestResult();
-        break;
-    }
+    NSArray *menuItems = [self _defaultMenuItems:stage];
+    RefPtr<WebHitTestResult> hitTestResult = [self _hitTestResultForStage:stage];
 
     if ([_wkView respondsToSelector:@selector(_actionMenuItemsForHitTestResult:defaultActionMenuItems:)])
         menuItems = [_wkView _actionMenuItemsForHitTestResult:toAPI(hitTestResult.get()) defaultActionMenuItems:menuItems];

Modified: trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm (175473 => 175474)


--- trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm	2014-11-03 18:36:57 UTC (rev 175473)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm	2014-11-03 18:38:44 UTC (rev 175474)
@@ -1142,7 +1142,7 @@
 
     RenderView& mainRenderView = *mainFrame.view()->renderView();
 
-    HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::AllowChildFrameContent | HitTestRequest::IgnoreClipping | HitTestRequest::DisallowShadowContent);
+    HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::AllowChildFrameContent | HitTestRequest::IgnoreClipping);
 
     IntPoint locationInContentCoordinates = mainFrame.view()->rootViewToContents(roundedIntPoint(locationInViewCooordinates));
     HitTestResult hitTestResult(locationInContentCoordinates);
@@ -1179,7 +1179,7 @@
         return;
 
     IntPoint point = roundedIntPoint(locationInWindowCooordinates);
-    HitTestResult result = m_page->mainFrame().eventHandler().hitTestResultAtPoint(m_page->mainFrame().view()->windowToContents(point));
+    HitTestResult result = m_page->mainFrame().eventHandler().hitTestResultAtPoint(m_page->mainFrame().view()->windowToContents(point), HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::AllowChildFrameContent | HitTestRequest::IgnoreClipping);
     Frame* frame = result.innerNonSharedNode() ? result.innerNonSharedNode()->document().frame() : &m_page->focusController().focusedOrMainFrame();
     NSDictionary *options = nil;
     RefPtr<Range> lookupRange = rangeForDictionaryLookupAtHitTestResult(result, &options);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to