Make lookup an immediate action instead of an action menu item
authorbdakin@apple.com <bdakin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 16 Dec 2014 00:51:31 +0000 (00:51 +0000)
committerbdakin@apple.com <bdakin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 16 Dec 2014 00:51:31 +0000 (00:51 +0000)
https://bugs.webkit.org/show_bug.cgi?id=139661
-and corresponding-
rdar://problem/19198414

Reviewed by Tim Horton.

Source/WebCore:

New SPI.
* platform/spi/mac/LookupSPI.h:

Source/WebKit/mac:

Remove the lookup menu items and non-unused static function associated with
lookup.
* WebView/WebActionMenuController.mm:
(-[WebActionMenuController _defaultMenuItemsForText]):
(-[WebActionMenuController _defaultMenuItemsForEditableText]):
(-[WebActionMenuController _defaultMenuItemsForEditableTextWithSuggestions]):
(-[WebActionMenuController _createActionMenuItemForTag:]):
(-[WebActionMenuController _lookupText:]): Deleted.
(performDictionaryLookupForSelection): Deleted.
(performDictionaryLookupForRange): Deleted.

Set the defaultAnimationController to the lookup-provided animation controller
when appropriate.
* WebView/WebImmediateActionController.mm:
(-[WebImmediateActionController _defaultAnimationController]):
(dictionaryPopupInfoForRange):
(-[WebImmediateActionController _animationControllerForText]):

New type.
* WebView/WebUIDelegatePrivate.h:

New function to get the lookup animation controller.
* WebView/WebView.mm:
(-[WebView _animationControllerForDictionaryLookupPopupInfo:]):
* WebView/WebViewInternal.h:

Source/WebKit2:

New type.
* Shared/API/c/WKImmediateActionTypes.h:

ActionMenuHitTestResult now includes a DictionaryPopupInfo.
* Shared/mac/ActionMenuHitTestResult.h:
* Shared/mac/ActionMenuHitTestResult.mm:
(WebKit::ActionMenuHitTestResult::encode):
(WebKit::ActionMenuHitTestResult::decode):

Remove all lookup menu items.
* UIProcess/mac/WKActionMenuController.mm:
(-[WKActionMenuController _defaultMenuItemsForText]):
(-[WKActionMenuController _defaultMenuItemsForEditableText]):
(-[WKActionMenuController _defaultMenuItemsForEditableTextWithSuggestions]):
(-[WKActionMenuController _createActionMenuItemForTag:]):
(-[WKActionMenuController _lookupText:]): Deleted.

Set the defaultAnimationController to the lookup-provided animation controller
when appropriate.
* UIProcess/mac/WKImmediateActionController.mm:
(-[WKImmediateActionController _defaultAnimationController]):
(-[WKImmediateActionController _animationControllerForText]):

Re-factor performDictionaryLookupForRange() so that most of the work is done in a
new function called dictionaryPopupInfoForRange(). This was that code can be used
for both performing a dictionary lookup and just getting the DictionaryPopupInfo
for the ActionMenuHitTest.
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/mac/WebPageMac.mm:
(WebKit::WebPage::dictionaryPopupInfoForRange):
(WebKit::WebPage::performDictionaryLookupForRange):
(WebKit::WebPage::performActionMenuHitTestAtLocation):
(WebKit::WebPage::lookupTextAtLocation):

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

16 files changed:
Source/WebCore/ChangeLog
Source/WebCore/platform/spi/mac/LookupSPI.h
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/WebView/WebActionMenuController.mm
Source/WebKit/mac/WebView/WebImmediateActionController.mm
Source/WebKit/mac/WebView/WebUIDelegatePrivate.h
Source/WebKit/mac/WebView/WebView.mm
Source/WebKit/mac/WebView/WebViewInternal.h
Source/WebKit2/ChangeLog
Source/WebKit2/Shared/API/c/WKImmediateActionTypes.h
Source/WebKit2/Shared/mac/ActionMenuHitTestResult.h
Source/WebKit2/Shared/mac/ActionMenuHitTestResult.mm
Source/WebKit2/UIProcess/mac/WKActionMenuController.mm
Source/WebKit2/UIProcess/mac/WKImmediateActionController.mm
Source/WebKit2/WebProcess/WebPage/WebPage.h
Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm

index 5b744d3..553e8c9 100644 (file)
@@ -1,3 +1,15 @@
+2014-12-15  Beth Dakin  <bdakin@apple.com>
+
+        Make lookup an immediate action instead of an action menu item
+        https://bugs.webkit.org/show_bug.cgi?id=139661
+        -and corresponding-
+        rdar://problem/19198414
+
+        Reviewed by Tim Horton.
+
+        New SPI.
+        * platform/spi/mac/LookupSPI.h:
+
 2014-12-12  Anders Carlsson  <andersca@apple.com>
 
         Get rid of the DONT_FINALIZE_ON_MAIN_THREAD #define
index 7b3b030..ad76e99 100644 (file)
@@ -47,4 +47,10 @@ SOFT_LINK_CLASS_OPTIONAL(Lookup, LULookupDefinitionModule)
 
 #endif // !USE(APPLE_INTERNAL_SDK)
 
+@interface LULookupDefinitionModule (AnimationController)
+
++ (id<NSImmediateActionAnimationController>)lookupAnimationControllerForTerm:(NSAttributedString *)term atLocation:(NSPoint)screenPoint options:(NSDictionary *)options;
+
+@end
+
 #endif // PLATFORM(MAC)
index e69c29e..157f079 100644 (file)
@@ -1,3 +1,38 @@
+2014-12-15  Beth Dakin  <bdakin@apple.com>
+
+        Make lookup an immediate action instead of an action menu item
+        https://bugs.webkit.org/show_bug.cgi?id=139661
+        -and corresponding-
+        rdar://problem/19198414
+
+        Reviewed by Tim Horton.
+
+        Remove the lookup menu items and non-unused static function associated with 
+        lookup.
+        * WebView/WebActionMenuController.mm:
+        (-[WebActionMenuController _defaultMenuItemsForText]):
+        (-[WebActionMenuController _defaultMenuItemsForEditableText]):
+        (-[WebActionMenuController _defaultMenuItemsForEditableTextWithSuggestions]):
+        (-[WebActionMenuController _createActionMenuItemForTag:]):
+        (-[WebActionMenuController _lookupText:]): Deleted.
+        (performDictionaryLookupForSelection): Deleted.
+        (performDictionaryLookupForRange): Deleted.
+
+        Set the defaultAnimationController to the lookup-provided animation controller 
+        when appropriate.
+        * WebView/WebImmediateActionController.mm:
+        (-[WebImmediateActionController _defaultAnimationController]):
+        (dictionaryPopupInfoForRange):
+        (-[WebImmediateActionController _animationControllerForText]):
+
+        New type.
+        * WebView/WebUIDelegatePrivate.h:
+
+        New function to get the lookup animation controller.
+        * WebView/WebView.mm:
+        (-[WebView _animationControllerForDictionaryLookupPopupInfo:]):
+        * WebView/WebViewInternal.h:
+
 2014-12-15  Timothy Horton  <timothy_horton@apple.com>
 
         Implement Data Detectors immediate actions for Legacy WebKit
index bedf2d9..ec5f2fa 100644 (file)
@@ -30,7 +30,6 @@
 #import "DOMElementInternal.h"
 #import "DOMNodeInternal.h"
 #import "DOMRangeInternal.h"
-#import "DictionaryPopupInfo.h"
 #import "WebDocumentInternal.h"
 #import "WebElementDictionary.h"
 #import "WebFrameInternal.h"
@@ -53,7 +52,6 @@
 #import <WebCore/Frame.h>
 #import <WebCore/FrameView.h>
 #import <WebCore/HTMLConverter.h>
-#import <WebCore/LookupSPI.h>
 #import <WebCore/NSMenuSPI.h>
 #import <WebCore/NSSharingServicePickerSPI.h>
 #import <WebCore/NSSharingServiceSPI.h>
@@ -463,20 +461,18 @@ static NSString *pathToPhotoOnDisk(NSString *suggestedFilename)
 - (NSArray *)_defaultMenuItemsForText
 {
     RetainPtr<NSMenuItem> copyTextItem = [self _createActionMenuItemForTag:WebActionMenuItemTagCopyText];
-    RetainPtr<NSMenuItem> lookupTextItem = [self _createActionMenuItemForTag:WebActionMenuItemTagLookupText];
     RetainPtr<NSMenuItem> pasteItem = [self _createActionMenuItemForTag:WebActionMenuItemTagPaste];
     [pasteItem setEnabled:NO];
 
-    return @[ copyTextItem.get(), lookupTextItem.get(), pasteItem.get() ];
+    return @[ copyTextItem.get(), [NSMenuItem separatorItem], pasteItem.get() ];
 }
 
 - (NSArray *)_defaultMenuItemsForEditableText
 {
     RetainPtr<NSMenuItem> copyTextItem = [self _createActionMenuItemForTag:WebActionMenuItemTagCopyText];
-    RetainPtr<NSMenuItem> lookupTextItem = [self _createActionMenuItemForTag:WebActionMenuItemTagLookupText];
     RetainPtr<NSMenuItem> pasteItem = [self _createActionMenuItemForTag:WebActionMenuItemTagPaste];
 
-    return @[ copyTextItem.get(), lookupTextItem.get(), pasteItem.get() ];
+    return @[ copyTextItem.get(), [NSMenuItem separatorItem], pasteItem.get() ];
 }
 
 - (NSArray *)_defaultMenuItemsForEditableTextWithSuggestions
@@ -513,13 +509,12 @@ static NSString *pathToPhotoOnDisk(NSString *suggestedFilename)
     }
 
     RetainPtr<NSMenuItem> copyTextItem = [self _createActionMenuItemForTag:WebActionMenuItemTagCopyText];
-    RetainPtr<NSMenuItem> lookupTextItem = [self _createActionMenuItemForTag:WebActionMenuItemTagLookupText];
     RetainPtr<NSMenuItem> pasteItem = [self _createActionMenuItemForTag:WebActionMenuItemTagPaste];
     RetainPtr<NSMenuItem> textSuggestionsItem = [self _createActionMenuItemForTag:WebActionMenuItemTagTextSuggestions];
 
     [textSuggestionsItem setSubmenu:spellingSubMenu.get()];
 
-    return @[ copyTextItem.get(), lookupTextItem.get(), pasteItem.get(), textSuggestionsItem.get() ];
+    return @[ copyTextItem.get(), [NSMenuItem separatorItem], pasteItem.get(), textSuggestionsItem.get() ];
 }
 
 - (void)_selectDataDetectedText
@@ -579,16 +574,6 @@ static NSString *pathToPhotoOnDisk(NSString *suggestedFilename)
     [_webView copy:self];
 }
 
-- (void)_lookupText:(id)sender
-{
-    Frame* frame = core([_webView _selectedOrMainFrame]);
-    if (!frame)
-        return;
-
-    DictionaryPopupInfo popupInfo = performDictionaryLookupForSelection(frame, frame->selection().selection());
-    [_webView _showDictionaryLookupPopup:popupInfo];
-}
-
 - (void)_paste:(id)sender
 {
     [_webView paste:self];
@@ -620,56 +605,6 @@ static NSString *pathToPhotoOnDisk(NSString *suggestedFilename)
     [documentView _changeSpellingToWord:selectedCorrection];
 }
 
-static DictionaryPopupInfo performDictionaryLookupForSelection(Frame* frame, const VisibleSelection& selection)
-{
-    NSDictionary *options = nil;
-    DictionaryPopupInfo popupInfo;
-    RefPtr<Range> selectedRange = rangeForDictionaryLookupForSelection(selection, &options);
-    if (selectedRange)
-        popupInfo = performDictionaryLookupForRange(frame, *selectedRange, options, TextIndicatorPresentationTransition::BounceAndCrossfade);
-    return popupInfo;
-}
-
-static DictionaryPopupInfo performDictionaryLookupForRange(Frame* frame, Range& range, NSDictionary *options, TextIndicatorPresentationTransition presentationTransition)
-{
-    DictionaryPopupInfo popupInfo;
-    if (range.text().stripWhiteSpace().isEmpty())
-        return popupInfo;
-    
-    RenderObject* renderer = range.startContainer()->renderer();
-    const RenderStyle& style = renderer->style();
-
-    Vector<FloatQuad> quads;
-    range.textQuads(quads);
-    if (quads.isEmpty())
-        return popupInfo;
-
-    IntRect rangeRect = frame->view()->contentsToWindow(quads[0].enclosingBoundingBox());
-
-    popupInfo.origin = NSMakePoint(rangeRect.x(), rangeRect.y() + (style.fontMetrics().descent() * frame->page()->pageScaleFactor()));
-    popupInfo.options = options;
-
-    NSAttributedString *nsAttributedString = editingAttributedStringFromRange(range, IncludeImagesInAttributedString::No);
-    RetainPtr<NSMutableAttributedString> scaledNSAttributedString = adoptNS([[NSMutableAttributedString alloc] initWithString:[nsAttributedString string]]);
-    NSFontManager *fontManager = [NSFontManager sharedFontManager];
-
-    [nsAttributedString enumerateAttributesInRange:NSMakeRange(0, [nsAttributedString length]) options:0 usingBlock:^(NSDictionary *attributes, NSRange range, BOOL *stop) {
-        RetainPtr<NSMutableDictionary> scaledAttributes = adoptNS([attributes mutableCopy]);
-
-        NSFont *font = [scaledAttributes objectForKey:NSFontAttributeName];
-        if (font) {
-            font = [fontManager convertFont:font toSize:[font pointSize] * frame->page()->pageScaleFactor()];
-            [scaledAttributes setObject:font forKey:NSFontAttributeName];
-        }
-
-        [scaledNSAttributedString addAttributes:scaledAttributes.get() range:range];
-    }];
-
-    popupInfo.attributedString = scaledNSAttributedString.get();
-    popupInfo.textIndicator = TextIndicator::createWithRange(range, presentationTransition);
-    return popupInfo;
-}
-
 #pragma mark Whitespace actions
 
 - (NSArray *)_defaultMenuItemsForWhitespaceInEditableArea
@@ -737,13 +672,6 @@ static DictionaryPopupInfo performDictionaryLookupForRange(Frame* frame, Range&
         enabled = _hitTestResult.allowsCopy();
         break;
 
-    case WebActionMenuItemTagLookupText:
-        selector = @selector(_lookupText:);
-        title = WEB_UI_STRING_KEY("Look Up", "Look Up (action menu item)", "action menu item");
-        image = [NSImage imageNamed:@"NSActionMenuLookup"];
-        enabled = getLULookupDefinitionModuleClass() && _hitTestResult.allowsCopy();
-        break;
-
     case WebActionMenuItemTagPaste:
         selector = @selector(_paste:);
         title = WEB_UI_STRING_KEY("Paste", "Paste (action menu item)", "action menu item");
index 3746ab7..18a2a47 100644 (file)
@@ -30,6 +30,7 @@
 #import "DOMElementInternal.h"
 #import "DOMNodeInternal.h"
 #import "DOMRangeInternal.h"
+#import "DictionaryPopupInfo.h"
 #import "WebElementDictionary.h"
 #import "WebFrameInternal.h"
 #import "WebHTMLView.h"
 #import "WebViewInternal.h"
 #import <WebCore/DataDetection.h>
 #import <WebCore/DataDetectorsSPI.h>
+#import <WebCore/DictionaryLookup.h>
 #import <WebCore/EventHandler.h>
 #import <WebCore/Frame.h>
+#import <WebCore/FrameView.h>
+#import <WebCore/HTMLConverter.h>
+#import <WebCore/LookupSPI.h>
 #import <WebCore/NSMenuSPI.h>
+#import <WebCore/Page.h>
+#import <WebCore/RenderObject.h>
 #import <WebCore/SoftLinking.h>
 #import <WebCore/TextIndicator.h>
 #import <objc/objc-class.h>
@@ -176,6 +183,11 @@ using namespace WebCore;
             _type = WebImmediateActionDataDetectedItem;
             return (id<NSImmediateActionAnimationController>)immediateActionItem;
         }
+
+        if (id<NSImmediateActionAnimationController> defaultTextController = [self _animationControllerForText]) {
+            _type = WebImmediateActionText;
+            return defaultTextController;
+        }
     }
 
     return nil;
@@ -277,6 +289,71 @@ using namespace WebCore;
     return menuItems.lastObject;
 }
 
+#pragma mark Text action
+
+static DictionaryPopupInfo dictionaryPopupInfoForRange(Frame* frame, Range& range, NSDictionary *options, TextIndicatorPresentationTransition presentationTransition)
+{
+    DictionaryPopupInfo popupInfo;
+    if (range.text().stripWhiteSpace().isEmpty())
+        return popupInfo;
+    
+    RenderObject* renderer = range.startContainer()->renderer();
+    const RenderStyle& style = renderer->style();
+
+    Vector<FloatQuad> quads;
+    range.textQuads(quads);
+    if (quads.isEmpty())
+        return popupInfo;
+
+    IntRect rangeRect = frame->view()->contentsToWindow(quads[0].enclosingBoundingBox());
+
+    popupInfo.origin = NSMakePoint(rangeRect.x(), rangeRect.y() + (style.fontMetrics().descent() * frame->page()->pageScaleFactor()));
+    popupInfo.options = options;
+
+    NSAttributedString *nsAttributedString = editingAttributedStringFromRange(range, IncludeImagesInAttributedString::No);
+    RetainPtr<NSMutableAttributedString> scaledNSAttributedString = adoptNS([[NSMutableAttributedString alloc] initWithString:[nsAttributedString string]]);
+    NSFontManager *fontManager = [NSFontManager sharedFontManager];
+
+    [nsAttributedString enumerateAttributesInRange:NSMakeRange(0, [nsAttributedString length]) options:0 usingBlock:^(NSDictionary *attributes, NSRange range, BOOL *stop) {
+        RetainPtr<NSMutableDictionary> scaledAttributes = adoptNS([attributes mutableCopy]);
+
+        NSFont *font = [scaledAttributes objectForKey:NSFontAttributeName];
+        if (font) {
+            font = [fontManager convertFont:font toSize:[font pointSize] * frame->page()->pageScaleFactor()];
+            [scaledAttributes setObject:font forKey:NSFontAttributeName];
+        }
+
+        [scaledNSAttributedString addAttributes:scaledAttributes.get() range:range];
+    }];
+
+    popupInfo.attributedString = scaledNSAttributedString.get();
+    popupInfo.textIndicator = TextIndicator::createWithRange(range, presentationTransition);
+    return popupInfo;
+}
+
+- (id<NSImmediateActionAnimationController>)_animationControllerForText
+{
+    if (!getLULookupDefinitionModuleClass())
+        return nil;
+
+    Node* node = _hitTestResult.innerNode();
+    if (!node)
+        return nil;
+
+    Frame* frame = node->document().frame();
+    if (!frame)
+        return nil;
+
+    NSDictionary *options = nil;
+    RefPtr<Range> dictionaryRange = rangeForDictionaryLookupAtHitTestResult(_hitTestResult, &options);
+
+    DictionaryPopupInfo dictionaryPopupInfo = dictionaryPopupInfoForRange(frame, *dictionaryRange, options, TextIndicatorPresentationTransition::Bounce);
+    if (!dictionaryPopupInfo.attributedString)
+        return nil;
+
+    return [_webView _animationControllerForDictionaryLookupPopupInfo:dictionaryPopupInfo];
+}
+
 #pragma mark Text Indicator
 
 - (void)_showTextIndicator
index e94a48e..cf65a88 100644 (file)
@@ -147,7 +147,8 @@ typedef enum {
 typedef enum {
     WebImmediateActionNone = 0,
     WebImmediateActionLinkPreview,
-    WebImmediateActionDataDetectedItem
+    WebImmediateActionDataDetectedItem,
+    WebImmediateActionText
 } WebImmediateActionType;
 
 // Message Sources.
index 990e258..61555e0 100644 (file)
@@ -8659,6 +8659,33 @@ static void glibContextIterationCallback(CFRunLoopObserverRef, CFRunLoopActivity
         [getLULookupDefinitionModuleClass() showDefinitionForTerm:dictionaryPopupInfo.attributedString.get() atLocation:textBaselineOrigin options:dictionaryPopupInfo.options.get()];
 }
 
+- (id)_animationControllerForDictionaryLookupPopupInfo:(const DictionaryPopupInfo&)dictionaryPopupInfo
+{
+    if (!dictionaryPopupInfo.attributedString)
+        return nil;
+
+    NSPoint textBaselineOrigin = dictionaryPopupInfo.origin;
+
+    // Convert to screen coordinates.
+    textBaselineOrigin = [self.window convertRectToScreen:NSMakeRect(textBaselineOrigin.x, textBaselineOrigin.y, 0, 0)].origin;
+
+    if (canLoadLUTermOptionDisableSearchTermIndicator() && canLoadLUNotificationPopoverWillClose()) {
+        if (!_private->hasInitializedLookupObserver) {
+            [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_dictionaryLookupPopoverWillClose:) name:getLUNotificationPopoverWillClose() object:nil];
+            _private->hasInitializedLookupObserver = YES;
+        }
+
+        RetainPtr<NSMutableDictionary> mutableOptions = adoptNS([dictionaryPopupInfo.options mutableCopy]);
+        if (!mutableOptions)
+            mutableOptions = adoptNS([[NSMutableDictionary alloc] init]);
+        [mutableOptions setObject:@YES forKey:getLUTermOptionDisableSearchTermIndicator()];
+        [self _setTextIndicator:dictionaryPopupInfo.textIndicator.get() fadeOut:NO animationCompletionHandler:[] { }];
+        return [getLULookupDefinitionModuleClass() lookupAnimationControllerForTerm:dictionaryPopupInfo.attributedString.get() atLocation:textBaselineOrigin options:mutableOptions.get()];
+    }
+
+    return [getLULookupDefinitionModuleClass() lookupAnimationControllerForTerm:dictionaryPopupInfo.attributedString.get() atLocation:textBaselineOrigin options:dictionaryPopupInfo.options.get()];
+}
+
 - (void)_dictionaryLookupPopoverWillClose:(NSNotification *)notification
 {
     [self _setTextIndicator:nullptr fadeOut:NO animationCompletionHandler:[] { }];
index 097870c..03d4049 100644 (file)
@@ -262,6 +262,7 @@ OBJC_CLASS NSTextAlternatives;
 - (void)_setTextIndicator:(WebCore::TextIndicator*)textIndicator fadeOut:(BOOL)fadeOut animationCompletionHandler:(std::function<void ()>)completionHandler;
 - (void)_clearTextIndicator;
 - (void)_showDictionaryLookupPopup:(const DictionaryPopupInfo&)dictionaryPopupInfo;
+- (id)_animationControllerForDictionaryLookupPopupInfo:(const DictionaryPopupInfo&)dictionaryPopupInfo;
 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
 - (WebActionMenuController *)_actionMenuController;
 - (WebImmediateActionController *)_immediateActionController;
index 1568405..d5d0ab9 100644 (file)
@@ -1,3 +1,46 @@
+2014-12-15  Beth Dakin  <bdakin@apple.com>
+
+        Make lookup an immediate action instead of an action menu item
+        https://bugs.webkit.org/show_bug.cgi?id=139661
+        -and corresponding-
+        rdar://problem/19198414
+
+        Reviewed by Tim Horton.
+
+        New type.
+        * Shared/API/c/WKImmediateActionTypes.h:
+
+        ActionMenuHitTestResult now includes a DictionaryPopupInfo.
+        * Shared/mac/ActionMenuHitTestResult.h:
+        * Shared/mac/ActionMenuHitTestResult.mm:
+        (WebKit::ActionMenuHitTestResult::encode):
+        (WebKit::ActionMenuHitTestResult::decode):
+
+        Remove all lookup menu items.
+        * UIProcess/mac/WKActionMenuController.mm:
+        (-[WKActionMenuController _defaultMenuItemsForText]):
+        (-[WKActionMenuController _defaultMenuItemsForEditableText]):
+        (-[WKActionMenuController _defaultMenuItemsForEditableTextWithSuggestions]):
+        (-[WKActionMenuController _createActionMenuItemForTag:]):
+        (-[WKActionMenuController _lookupText:]): Deleted.
+
+        Set the defaultAnimationController to the lookup-provided animation controller 
+        when appropriate.
+        * UIProcess/mac/WKImmediateActionController.mm:
+        (-[WKImmediateActionController _defaultAnimationController]):
+        (-[WKImmediateActionController _animationControllerForText]):
+
+        Re-factor performDictionaryLookupForRange() so that most of the work is done in a 
+        new function called dictionaryPopupInfoForRange(). This was that code can be used 
+        for both performing a dictionary lookup and just getting the DictionaryPopupInfo 
+        for the ActionMenuHitTest.
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/mac/WebPageMac.mm:
+        (WebKit::WebPage::dictionaryPopupInfoForRange):
+        (WebKit::WebPage::performDictionaryLookupForRange):
+        (WebKit::WebPage::performActionMenuHitTestAtLocation):
+        (WebKit::WebPage::lookupTextAtLocation):
+
 2014-12-15  Matt Baker  <mattbaker@apple.com>
 
         Web Inspector: Docked inspector repositioned incorrectly when dragging frame borders
index 8c2db4d..d380077 100644 (file)
@@ -36,6 +36,7 @@ enum {
     kWKImmediateActionNone = 0,
     kWKImmediateActionLinkPreview,
     kWKImmediateActionDataDetectedItem,
+    kWKImmediateActionLookupText,
 };
 typedef uint32_t _WKImmediateActionType;
 
index 702c56e..54c8d4d 100644 (file)
@@ -27,6 +27,7 @@
 #define ActionMenuHitTestResult_h
 
 #include "DataReference.h"
+#include "DictionaryPopupInfo.h"
 #include "ShareableBitmap.h"
 #include "SharedMemory.h"
 #include "WebHitTestResult.h"
@@ -59,6 +60,8 @@ struct ActionMenuHitTestResult {
     WebCore::FloatRect detectedDataBoundingBox;
     RefPtr<WebCore::TextIndicator> detectedDataTextIndicator;
     WebCore::PageOverlay::PageOverlayID detectedDataOriginatingPageOverlay;
+
+    DictionaryPopupInfo dictionaryPopupInfo;
 };
 
 } // namespace WebKit
index 95c534b..5723c91 100644 (file)
@@ -68,6 +68,8 @@ void ActionMenuHitTestResult::encode(IPC::ArgumentEncoder& encoder) const
         if (hasTextIndicator)
             encoder << detectedDataTextIndicator->data();
     }
+
+    encoder << dictionaryPopupInfo;
 }
 
 bool ActionMenuHitTestResult::decode(IPC::ArgumentDecoder& decoder, ActionMenuHitTestResult& actionMenuHitTestResult)
@@ -130,6 +132,9 @@ bool ActionMenuHitTestResult::decode(IPC::ArgumentDecoder& decoder, ActionMenuHi
         }
     }
 
+    if (!decoder.decode(actionMenuHitTestResult.dictionaryPopupInfo))
+        return false;
+
     return true;
 }
     
index 4c10f23..00ed77a 100644 (file)
@@ -41,7 +41,6 @@
 #import <ImageKit/ImageKit.h>
 #import <WebCore/DataDetectorsSPI.h>
 #import <WebCore/LocalizedStrings.h>
-#import <WebCore/LookupSPI.h>
 #import <WebCore/NSMenuSPI.h>
 #import <WebCore/NSSharingServiceSPI.h>
 #import <WebCore/NSSharingServicePickerSPI.h>
@@ -408,20 +407,18 @@ static NSString *pathToPhotoOnDisk(NSString *suggestedFilename)
 - (NSArray *)_defaultMenuItemsForText
 {
     RetainPtr<NSMenuItem> copyTextItem = [self _createActionMenuItemForTag:kWKContextActionItemTagCopyText];
-    RetainPtr<NSMenuItem> lookupTextItem = [self _createActionMenuItemForTag:kWKContextActionItemTagLookupText];
     RetainPtr<NSMenuItem> pasteItem = [self _createActionMenuItemForTag:kWKContextActionItemTagPaste];
     [pasteItem setEnabled:NO];
 
-    return @[ copyTextItem.get(), lookupTextItem.get(), pasteItem.get() ];
+    return @[ copyTextItem.get(), [NSMenuItem separatorItem], pasteItem.get() ];
 }
 
 - (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() ];
+    return @[ copyTextItem.get(), [NSMenuItem separatorItem], pasteItem.get() ];
 }
 
 - (NSArray *)_defaultMenuItemsForEditableTextWithSuggestions
@@ -448,13 +445,12 @@ static NSString *pathToPhotoOnDisk(NSString *suggestedFilename)
     }
 
     RetainPtr<NSMenuItem> copyTextItem = [self _createActionMenuItemForTag:kWKContextActionItemTagCopyText];
-    RetainPtr<NSMenuItem> lookupTextItem = [self _createActionMenuItemForTag:kWKContextActionItemTagLookupText];
     RetainPtr<NSMenuItem> pasteItem = [self _createActionMenuItemForTag:kWKContextActionItemTagPaste];
     RetainPtr<NSMenuItem> textSuggestionsItem = [self _createActionMenuItemForTag:kWKContextActionItemTagTextSuggestions];
 
     [textSuggestionsItem setSubmenu:spellingSubMenu.get()];
 
-    return @[ copyTextItem.get(), lookupTextItem.get(), pasteItem.get(), textSuggestionsItem.get() ];
+    return @[ copyTextItem.get(), [NSMenuItem separatorItem], pasteItem.get(), textSuggestionsItem.get() ];
 }
 
 - (void)_copySelection:(id)sender
@@ -467,11 +463,6 @@ static NSString *pathToPhotoOnDisk(NSString *suggestedFilename)
     _page->executeEditCommand("paste");
 }
 
-- (void)_lookupText:(id)sender
-{
-    _page->performDictionaryLookupOfCurrentSelection();
-}
-
 - (void)_changeSelectionToSuggestion:(id)sender
 {
     NSString *selectedCorrection = [sender representedObject];
@@ -627,13 +618,6 @@ static NSString *pathToPhotoOnDisk(NSString *suggestedFilename)
         enabled = hitTestResult->allowsCopy();
         break;
 
-    case kWKContextActionItemTagLookupText:
-        selector = @selector(_lookupText:);
-        title = WEB_UI_STRING_KEY("Look Up", "Look Up (action menu item)", "action menu item");
-        image = [NSImage imageNamed:@"NSActionMenuLookup"];
-        enabled = getLULookupDefinitionModuleClass() && hitTestResult->allowsCopy();
-        break;
-
     case kWKContextActionItemTagPaste:
         selector = @selector(_paste:);
         title = WEB_UI_STRING_KEY("Paste", "Paste (action menu item)", "action menu item");
index eb4fd96..3d504b5 100644 (file)
@@ -37,6 +37,7 @@
 #import "WebProcessProxy.h"
 #import <WebCore/DataDetectorsSPI.h>
 #import <WebCore/GeometryUtilities.h>
+#import <WebCore/LookupSPI.h>
 #import <WebCore/NSMenuSPI.h>
 #import <WebCore/QuickLookMacSPI.h>
 #import <WebCore/SoftLinking.h>
@@ -44,6 +45,7 @@
 
 SOFT_LINK_FRAMEWORK_IN_UMBRELLA(Quartz, QuickLookUI)
 SOFT_LINK_CLASS(QuickLookUI, QLPreviewMenuItem)
+SOFT_LINK_CONSTANT_MAY_FAIL(Lookup, LUTermOptionDisableSearchTermIndicator, NSString *)
 
 using namespace WebCore;
 using namespace WebKit;
@@ -235,6 +237,11 @@ using namespace WebKit;
             _type = kWKImmediateActionDataDetectedItem;
             return (id<NSImmediateActionAnimationController>)immediateActionItem;
         }
+
+        if (id<NSImmediateActionAnimationController> textAnimationController = [self _animationControllerForText]) {
+            _type = kWKImmediateActionLookupText;
+            return textAnimationController;
+        }
     }
 
     return nil;
@@ -485,6 +492,34 @@ static bool targetSizeFitsInAvailableSpace(NSSize targetSize, NSSize availableSp
     return menuItems.lastObject;
 }
 
+#pragma mark Text action
+
+- (id<NSImmediateActionAnimationController>)_animationControllerForText
+{
+    if (_state != ImmediateActionState::Ready)
+        return nil;
+
+    if (!getLULookupDefinitionModuleClass())
+        return nil;
+
+    DictionaryPopupInfo dictionaryPopupInfo = _hitTestResult.dictionaryPopupInfo;
+    if (!dictionaryPopupInfo.attributedString.string)
+        return nil;
+
+    // Convert baseline to screen coordinates.
+    NSPoint textBaselineOrigin = dictionaryPopupInfo.origin;
+    textBaselineOrigin = [_wkView convertPoint:textBaselineOrigin toView:nil];
+    textBaselineOrigin = [_wkView.window convertRectToScreen:NSMakeRect(textBaselineOrigin.x, textBaselineOrigin.y, 0, 0)].origin;
+
+    RetainPtr<NSMutableDictionary> mutableOptions = adoptNS([(NSDictionary *)dictionaryPopupInfo.options.get() mutableCopy]);
+    if (canLoadLUTermOptionDisableSearchTermIndicator() && dictionaryPopupInfo.textIndicator.contentImage) {
+        [_wkView _setTextIndicator:TextIndicator::create(dictionaryPopupInfo.textIndicator) fadeOut:NO animationCompletionHandler:[]{ }];
+        [mutableOptions setObject:@YES forKey:getLUTermOptionDisableSearchTermIndicator()];
+        return [getLULookupDefinitionModuleClass() lookupAnimationControllerForTerm:dictionaryPopupInfo.attributedString.string.get() atLocation:textBaselineOrigin options:mutableOptions.get()];
+    }
+    return [getLULookupDefinitionModuleClass() lookupAnimationControllerForTerm:dictionaryPopupInfo.attributedString.string.get() atLocation:textBaselineOrigin options:mutableOptions.get()];
+}
+
 @end
 
 #endif // PLATFORM(MAC)
index 23cfce8..8e58222 100644 (file)
@@ -29,6 +29,7 @@
 #include "APIInjectedBundleFormClient.h"
 #include "APIInjectedBundlePageUIClient.h"
 #include "APIObject.h"
+#include "DictionaryPopupInfo.h"
 #include "FindController.h"
 #include "GeolocationPermissionRequestManager.h"
 #include "ImageOptions.h"
@@ -994,6 +995,7 @@ private:
     void performDictionaryLookupAtLocation(const WebCore::FloatPoint&);
     void performDictionaryLookupOfCurrentSelection();
     void performDictionaryLookupForRange(WebCore::Frame*, WebCore::Range&, NSDictionary *options, WebCore::TextIndicatorPresentationTransition);
+    DictionaryPopupInfo dictionaryPopupInfoForRange(WebCore::Frame* frame, WebCore::Range& range, NSDictionary **options, WebCore::TextIndicatorPresentationTransition presentationTransition);
 
     void windowAndViewFramesChanged(const WebCore::FloatRect& windowFrameInScreenCoordinates, const WebCore::FloatRect& windowFrameInUnflippedScreenCoordinates, const WebCore::FloatRect& viewFrameInWindowCoordinates, const WebCore::FloatPoint& accessibilityViewCoordinates);
 
@@ -1072,7 +1074,7 @@ private:
 
 #if PLATFORM(MAC)
     void performActionMenuHitTestAtLocation(WebCore::FloatPoint);
-    PassRefPtr<WebCore::Range> lookupTextAtLocation(WebCore::FloatPoint);
+    PassRefPtr<WebCore::Range> lookupTextAtLocation(WebCore::FloatPoint, NSDictionary **options);
     void selectLastActionMenuRange();
     void focusAndSelectLastActionMenuHitTestResult();
 
index c944f0e..6eacb93 100644 (file)
@@ -511,10 +511,11 @@ void WebPage::performDictionaryLookupOfCurrentSelection()
     performDictionaryLookupForSelection(frame, frame->selection().selection(), TextIndicatorPresentationTransition::BounceAndCrossfade);
 }
 
-void WebPage::performDictionaryLookupForRange(Frame* frame, Range& range, NSDictionary *options, TextIndicatorPresentationTransition presentationTransition)
+DictionaryPopupInfo WebPage::dictionaryPopupInfoForRange(Frame* frame, Range& range, NSDictionary **options, TextIndicatorPresentationTransition presentationTransition)
 {
+    DictionaryPopupInfo dictionaryPopupInfo;
     if (range.text().stripWhiteSpace().isEmpty())
-        return;
+        return dictionaryPopupInfo;
     
     RenderObject* renderer = range.startContainer()->renderer();
     const RenderStyle& style = renderer->style();
@@ -522,13 +523,12 @@ void WebPage::performDictionaryLookupForRange(Frame* frame, Range& range, NSDict
     Vector<FloatQuad> quads;
     range.textQuads(quads);
     if (quads.isEmpty())
-        return;
+        return dictionaryPopupInfo;
 
     IntRect rangeRect = frame->view()->contentsToWindow(quads[0].enclosingBoundingBox());
 
-    DictionaryPopupInfo dictionaryPopupInfo;
     dictionaryPopupInfo.origin = FloatPoint(rangeRect.x(), rangeRect.y() + (style.fontMetrics().ascent() * pageScaleFactor()));
-    dictionaryPopupInfo.options = (CFDictionaryRef)options;
+    dictionaryPopupInfo.options = (CFDictionaryRef)*options;
 
     NSAttributedString *nsAttributedString = editingAttributedStringFromRange(range, IncludeImagesInAttributedString::No);
 
@@ -550,11 +550,17 @@ void WebPage::performDictionaryLookupForRange(Frame* frame, Range& range, NSDict
 
     RefPtr<TextIndicator> textIndicator = TextIndicator::createWithRange(range, presentationTransition);
     if (!textIndicator)
-        return;
+        return dictionaryPopupInfo;
 
     dictionaryPopupInfo.textIndicator = textIndicator->data();
     dictionaryPopupInfo.attributedString.string = scaledNSAttributedString;
 
+    return dictionaryPopupInfo;
+}
+
+void WebPage::performDictionaryLookupForRange(Frame* frame, Range& range, NSDictionary *options, TextIndicatorPresentationTransition presentationTransition)
+{
+    DictionaryPopupInfo dictionaryPopupInfo = dictionaryPopupInfoForRange(frame, range, &options, presentationTransition);
     send(Messages::WebPageProxy::DidPerformDictionaryLookup(dictionaryPopupInfo));
 }
 
@@ -989,8 +995,16 @@ void WebPage::performActionMenuHitTestAtLocation(WebCore::FloatPoint locationInV
     actionMenuResult.hitTestLocationInViewCooordinates = locationInViewCooordinates;
     actionMenuResult.hitTestResult = WebHitTestResult::Data(hitTestResult);
 
-    RefPtr<WebCore::Range> lookupRange = lookupTextAtLocation(locationInViewCooordinates);
+    NSDictionary *options = nil;
+    RefPtr<WebCore::Range> lookupRange = lookupTextAtLocation(locationInViewCooordinates, &options);
     actionMenuResult.lookupText = lookupRange ? lookupRange->text() : String();
+    if (lookupRange) {
+        if (Node* node = hitTestResult.innerNode()) {
+            if (Frame* hitTestResultFrame = node->document().frame())
+                actionMenuResult.dictionaryPopupInfo = dictionaryPopupInfoForRange(hitTestResultFrame, *lookupRange.get(), &options, TextIndicatorPresentationTransition::Bounce);
+        }
+    }
+
     m_lastActionMenuRangeForSelection = lookupRange;
     m_lastActionMenuHitTestResult = hitTestResult;
 
@@ -1052,7 +1066,7 @@ void WebPage::performActionMenuHitTestAtLocation(WebCore::FloatPoint locationInV
     send(Messages::WebPageProxy::DidPerformActionMenuHitTest(actionMenuResult, InjectedBundleUserMessageEncoder(userData.get())));
 }
 
-PassRefPtr<WebCore::Range> WebPage::lookupTextAtLocation(FloatPoint locationInViewCooordinates)
+PassRefPtr<WebCore::Range> WebPage::lookupTextAtLocation(FloatPoint locationInViewCooordinates, NSDictionary **options)
 {
     MainFrame& mainFrame = corePage()->mainFrame();
     if (!mainFrame.view() || !mainFrame.view()->renderView())
@@ -1060,8 +1074,7 @@ PassRefPtr<WebCore::Range> WebPage::lookupTextAtLocation(FloatPoint locationInVi
 
     IntPoint point = roundedIntPoint(locationInViewCooordinates);
     HitTestResult result = mainFrame.eventHandler().hitTestResultAtPoint(m_page->mainFrame().view()->windowToContents(point));
-    NSDictionary *options = nil;
-    return rangeForDictionaryLookupAtHitTestResult(result, &options);
+    return rangeForDictionaryLookupAtHitTestResult(result, options);
 }
 
 void WebPage::selectLastActionMenuRange()