Diff
Modified: trunk/Source/WebKit2/ChangeLog (175375 => 175376)
--- trunk/Source/WebKit2/ChangeLog 2014-10-30 19:04:29 UTC (rev 175375)
+++ trunk/Source/WebKit2/ChangeLog 2014-10-30 19:38:27 UTC (rev 175376)
@@ -1,3 +1,63 @@
+2014-10-30 Beth Dakin <[email protected]>
+
+ Implement action menus for text
+ https://bugs.webkit.org/show_bug.cgi?id=138220
+ -and corresponding-
+ rdar://problem/18742297
+
+ Reviewed by Tim Horton.
+
+ Two new types of actions for the two text actions.
+ * Shared/API/c/WKActionMenuItemTypes.h:
+
+ One new type of menu.
+ * Shared/API/c/WKActionMenuTypes.h:
+
+ Pass willOpenMenu on to the WKActionMenuController.
+ * UIProcess/API/mac/WKView.mm:
+ (-[WKView willOpenMenu:withEvent:]):
+
+ Two new WebPageProxy functions that will pass messages along to the web process.
+ * UIProcess/WebPageProxy.cpp:
+ (WebKit::WebPageProxy::selectLookupTextAtLocation):
+ * UIProcess/WebPageProxy.h:
+
+ At willOpenMenu time, text menus should select text so that it is clear what the
+ menu actions will apply to.
+ * UIProcess/mac/WKActionMenuController.h:
+ * UIProcess/mac/WKActionMenuController.mm:
+
+ Menu items for text menus.
+ (-[WKActionMenuController willOpenMenu:withEvent:]):
+ (-[WKActionMenuController _defaultMenuItemsForText]):
+ (-[WKActionMenuController _copyText:]):
+ (-[WKActionMenuController _lookupText:]):
+ (-[WKActionMenuController _createActionMenuItemForTag:]):
+ (imageForResource:name::if):
+
+ New messages to the web process.
+ * UIProcess/mac/WebPageProxyMac.mm:
+ (WebKit::WebPageProxy::performDictionaryLookupOfCurrentSelection):
+ * WebProcess/WebPage/WebPage.h:
+ * WebProcess/WebPage/WebPage.messages.in:
+
+ Re-factor performDictionaryLookupAtLocation() to re-use the code that finds the
+ Range for the dictionary lookup. That code now lives in
+ rangeForDictionaryLookupAtHitTestResult() and can be used by
+ performDictionaryLookupAtLocation() and our new function
+ selectLookupTextAtLocation().
+ * WebProcess/WebPage/mac/WebPageMac.mm:
+ (WebKit::WebPage::rangeForDictionaryLookupAtHitTestResult):
+ (WebKit::WebPage::performDictionaryLookupAtLocation):
+
+ Since the action menu text is always selected, when the lookup action is chosen,
+ we can just lookup the current selection.
+ (WebKit::WebPage::performDictionaryLookupOfCurrentSelection):
+
+ Uses the new function rangeForDictionaryLookupAtHitTestResult() to get a lookup
+ range and then select it.
+ (WebKit::WebPage::selectLookupTextAtLocation):
+
2014-10-30 Dan Bernstein <[email protected]>
When a client certificate is rejected, Safari says the website didn’t accept the certificate “unknown” instead of naming the certificate
Modified: trunk/Source/WebKit2/Shared/API/c/WKActionMenuItemTypes.h (175375 => 175376)
--- trunk/Source/WebKit2/Shared/API/c/WKActionMenuItemTypes.h 2014-10-30 19:04:29 UTC (rev 175375)
+++ trunk/Source/WebKit2/Shared/API/c/WKActionMenuItemTypes.h 2014-10-30 19:38:27 UTC (rev 175376)
@@ -40,7 +40,9 @@
kWKContextActionItemTagCopyImage,
kWKContextActionItemTagAddImageToPhotos,
kWKContextActionItemTagSaveImageToDownloads,
- kWKContextActionItemTagShareImage
+ kWKContextActionItemTagShareImage,
+ kWKContextActionItemTagCopyText,
+ kWKContextActionItemTagLookupText
};
#ifdef __cplusplus
Modified: trunk/Source/WebKit2/Shared/API/c/WKActionMenuTypes.h (175375 => 175376)
--- trunk/Source/WebKit2/Shared/API/c/WKActionMenuTypes.h 2014-10-30 19:04:29 UTC (rev 175375)
+++ trunk/Source/WebKit2/Shared/API/c/WKActionMenuTypes.h 2014-10-30 19:38:27 UTC (rev 175376)
@@ -36,7 +36,8 @@
kWKActionMenuNone = 0,
kWKActionMenuLink,
kWKActionMenuImage,
- kWKActionMenuDataDetectedItem
+ kWKActionMenuDataDetectedItem,
+ kWKActionMenuReadOnlyText
};
typedef uint32_t _WKActionMenuType;
Modified: trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm (175375 => 175376)
--- trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm 2014-10-30 19:04:29 UTC (rev 175375)
+++ trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm 2014-10-30 19:38:27 UTC (rev 175376)
@@ -3643,6 +3643,11 @@
[_data->_actionMenuController prepareForMenu:menu withEvent:event];
}
+- (void)willOpenMenu:(NSMenu *)menu withEvent:(NSEvent *)event
+{
+ [_data->_actionMenuController willOpenMenu:menu withEvent:event];
+}
+
- (void)didCloseMenu:(NSMenu *)menu withEvent:(NSEvent *)event
{
[_data->_actionMenuController didCloseMenu:menu withEvent:event];
Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp (175375 => 175376)
--- trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp 2014-10-30 19:04:29 UTC (rev 175375)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp 2014-10-30 19:38:27 UTC (rev 175376)
@@ -5274,6 +5274,11 @@
m_process->send(Messages::WebPage::PerformActionMenuHitTestAtLocation(point), m_pageID);
}
+void WebPageProxy::selectLookupTextAtLocation(FloatPoint point)
+{
+ m_process->send(Messages::WebPage::SelectLookupTextAtLocation(point), m_pageID);
+}
+
void WebPageProxy::didPerformActionMenuHitTest(const ActionMenuHitTestResult& result)
{
m_pageClient.didPerformActionMenuHitTest(result);
Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.h (175375 => 175376)
--- trunk/Source/WebKit2/UIProcess/WebPageProxy.h 2014-10-30 19:04:29 UTC (rev 175375)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.h 2014-10-30 19:38:27 UTC (rev 175376)
@@ -690,6 +690,7 @@
#if PLATFORM(COCOA)
// Dictionary.
void performDictionaryLookupAtLocation(const WebCore::FloatPoint&);
+ void performDictionaryLookupOfCurrentSelection();
#endif
void receivedPolicyDecision(WebCore::PolicyAction, WebFrameProxy*, uint64_t listenerID, uint64_t navigationID);
@@ -925,6 +926,7 @@
WebHitTestResult* lastMouseMoveHitTestResult() const { return m_lastMouseMoveHitTestResult.get(); }
void performActionMenuHitTestAtLocation(WebCore::FloatPoint);
+ void selectLookupTextAtLocation(WebCore::FloatPoint);
#endif
#if PLATFORM(EFL) && HAVE(ACCESSIBILITY) && defined(HAVE_ECORE_X)
Modified: trunk/Source/WebKit2/UIProcess/mac/WKActionMenuController.h (175375 => 175376)
--- trunk/Source/WebKit2/UIProcess/mac/WKActionMenuController.h 2014-10-30 19:04:29 UTC (rev 175375)
+++ trunk/Source/WebKit2/UIProcess/mac/WKActionMenuController.h 2014-10-30 19:38:27 UTC (rev 175376)
@@ -59,6 +59,7 @@
- (void)willDestroyView:(WKView *)view;
- (void)prepareForMenu:(NSMenu *)menu withEvent:(NSEvent *)event;
+- (void)willOpenMenu:(NSMenu *)menu withEvent:(NSEvent *)event;
- (void)didCloseMenu:(NSMenu *)menu withEvent:(NSEvent *)event;
- (void)didPerformActionMenuHitTest:(const WebKit::ActionMenuHitTestResult&)hitTestResult;
Modified: trunk/Source/WebKit2/UIProcess/mac/WKActionMenuController.mm (175375 => 175376)
--- trunk/Source/WebKit2/UIProcess/mac/WKActionMenuController.mm 2014-10-30 19:04:29 UTC (rev 175375)
+++ trunk/Source/WebKit2/UIProcess/mac/WKActionMenuController.mm 2014-10-30 19:38:27 UTC (rev 175376)
@@ -104,6 +104,21 @@
[self _updateActionMenuItems];
}
+- (void)willOpenMenu:(NSMenu *)menu withEvent:(NSEvent *)event
+{
+ if (menu != _wkView.actionMenu)
+ return;
+
+ if (_type != kWKActionMenuReadOnlyText)
+ 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();
+ if (!hitTestResult->isSelected())
+ _page->selectLookupTextAtLocation([_wkView convertPoint:event.locationInWindow fromView:nil]);
+}
+
- (void)didCloseMenu:(NSMenu *)menu withEvent:(NSEvent *)event
{
if (menu != _wkView.actionMenu)
@@ -290,6 +305,26 @@
});
}
+#pragma mark Text actions
+
+- (NSArray *)_defaultMenuItemsForText
+{
+ RetainPtr<NSMenuItem> copyTextItem = [self _createActionMenuItemForTag:kWKContextActionItemTagCopyText];
+ RetainPtr<NSMenuItem> lookupTextItem = [self _createActionMenuItemForTag:kWKContextActionItemTagLookupText];
+
+ return @[ copyTextItem.get(), lookupTextItem.get() ];
+}
+
+-(void)_copyText:(id)sender
+{
+ _page->executeEditCommand("copy");
+}
+
+-(void)_lookupText:(id)sender
+{
+ _page->performDictionaryLookupOfCurrentSelection();
+}
+
#pragma mark NSMenuDelegate implementation
- (void)menuNeedsUpdate:(NSMenu *)menu
@@ -374,6 +409,18 @@
image = webKitBundleImageNamed(@"ShareImageTemplate");
break;
+ case kWKContextActionItemTagCopyText:
+ selector = @selector(_copyText:);
+ title = @"Copy";
+ image = [NSImage imageNamed:@"NSActionMenuCopy"];
+ break;
+
+ case kWKContextActionItemTagLookupText:
+ selector = @selector(_lookupText:);
+ title = @"Lookup";
+ image = [NSImage imageNamed:@"NSActionMenuLookup"];
+ break;
+
default:
ASSERT_NOT_REACHED();
return nil;
@@ -414,6 +461,8 @@
return dataDetectorMenuItems;
}
}
+ _type = kWKActionMenuReadOnlyText;
+ return [self _defaultMenuItemsForText];
}
}
Modified: trunk/Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm (175375 => 175376)
--- trunk/Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm 2014-10-30 19:04:29 UTC (rev 175375)
+++ trunk/Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm 2014-10-30 19:38:27 UTC (rev 175376)
@@ -408,6 +408,14 @@
process().send(Messages::WebPage::PerformDictionaryLookupAtLocation(point), m_pageID);
}
+void WebPageProxy::performDictionaryLookupOfCurrentSelection()
+{
+ if (!isValid())
+ return;
+
+ process().send(Messages::WebPage::PerformDictionaryLookupOfCurrentSelection(), m_pageID);
+}
+
// Complex text input support for plug-ins.
void WebPageProxy::sendComplexTextInputToPlugin(uint64_t pluginComplexTextInputIdentifier, const String& textInput)
{
Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h (175375 => 175376)
--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h 2014-10-30 19:04:29 UTC (rev 175375)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h 2014-10-30 19:38:27 UTC (rev 175376)
@@ -973,6 +973,8 @@
#if PLATFORM(COCOA)
void performDictionaryLookupAtLocation(const WebCore::FloatPoint&);
void performDictionaryLookupForRange(WebCore::Frame*, WebCore::Range&, NSDictionary *options);
+ PassRefPtr<WebCore::Range> rangeForDictionaryLookupAtHitTestResult(const WebCore::HitTestResult&, NSDictionary **);
+ void performDictionaryLookupOfCurrentSelection();
void windowAndViewFramesChanged(const WebCore::FloatRect& windowFrameInScreenCoordinates, const WebCore::FloatRect& windowFrameInUnflippedScreenCoordinates, const WebCore::FloatRect& viewFrameInWindowCoordinates, const WebCore::FloatPoint& accessibilityViewCoordinates);
@@ -1047,6 +1049,7 @@
#if PLATFORM(MAC)
void performActionMenuHitTestAtLocation(WebCore::FloatPoint);
+ void selectLookupTextAtLocation(WebCore::FloatPoint);
#endif
uint64_t m_pageID;
Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in (175375 => 175376)
--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in 2014-10-30 19:04:29 UTC (rev 175375)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in 2014-10-30 19:38:27 UTC (rev 175376)
@@ -158,6 +158,7 @@
#if PLATFORM(COCOA)
# Dictionary support.
PerformDictionaryLookupAtLocation(WebCore::FloatPoint point)
+ PerformDictionaryLookupOfCurrentSelection()
#endif
PreferencesDidChange(WebKit::WebPreferencesStore store)
@@ -390,5 +391,6 @@
TakeSnapshot(WebCore::IntRect snapshotRect, WebCore::IntSize bitmapSize, uint32_t options, uint64_t callbackID)
#if PLATFORM(MAC)
PerformActionMenuHitTestAtLocation(WebCore::FloatPoint location)
+ SelectLookupTextAtLocation(WebCore::FloatPoint location)
#endif
}
Modified: trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm (175375 => 175376)
--- trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm 2014-10-30 19:04:29 UTC (rev 175375)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm 2014-10-30 19:38:27 UTC (rev 175376)
@@ -529,50 +529,63 @@
return makeRange(contextStart, contextEnd);
}
-void WebPage::performDictionaryLookupAtLocation(const FloatPoint& floatPoint)
+PassRefPtr<Range> WebPage::rangeForDictionaryLookupAtHitTestResult(const WebCore::HitTestResult& hitTestResult, NSDictionary **options)
{
- if (PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame())) {
- if (pluginView->performDictionaryLookupAtLocation(floatPoint))
- return;
- }
+ Node* node = hitTestResult.innerNonSharedNode();
+ if (!node)
+ return nullptr;
- // Find the frame the point is over.
- IntPoint point = roundedIntPoint(floatPoint);
- HitTestResult result = m_page->mainFrame().eventHandler().hitTestResultAtPoint(m_page->mainFrame().view()->windowToContents(point));
- Frame* frame = result.innerNonSharedNode() ? result.innerNonSharedNode()->document().frame() : &m_page->focusController().focusedOrMainFrame();
+ auto renderer = node->renderer();
+ if (!renderer)
+ return nullptr;
- IntPoint translatedPoint = frame->view()->windowToContents(point);
+ Frame* frame = node->document().frame();
+ if (!frame)
+ return nullptr;
// Don't do anything if there is no character at the point.
- if (!frame->rangeForPoint(translatedPoint))
- return;
+ if (!frame->rangeForPoint(hitTestResult.roundedPointInInnerNodeFrame()))
+ return nullptr;
- VisiblePosition position = frame->visiblePositionForPoint(translatedPoint);
+ VisiblePosition position = renderer->positionForPoint(hitTestResult.localPoint(), nullptr);
+ if (position.isNull())
+ position = firstPositionInOrBeforeNode(node);
+
VisibleSelection selection = m_page->focusController().focusedOrMainFrame().selection().selection();
if (shouldUseSelection(position, selection)) {
performDictionaryLookupForSelection(frame, selection);
- return;
+ return nullptr;
}
- NSDictionary *options = nil;
-
// As context, we are going to use four lines of text before and after the point. (Dictionary can sometimes look up things that are four lines long)
RefPtr<Range> fullCharacterRange = rangeExpandedAroundPosition(position, 4);
NSRange rangeToPass = NSMakeRange(TextIterator::rangeLength(makeRange(fullCharacterRange->startPosition(), position).get()), 0);
String fullPlainTextString = plainText(fullCharacterRange.get());
- NSRange extractedRange = WKExtractWordDefinitionTokenRangeFromContextualString(fullPlainTextString, rangeToPass, &options);
+ NSRange extractedRange = WKExtractWordDefinitionTokenRangeFromContextualString(fullPlainTextString, rangeToPass, options);
// This function sometimes returns {NSNotFound, 0} if it was unable to determine a good string.
if (extractedRange.location == NSNotFound)
- return;
+ return nullptr;
- RefPtr<Range> finalRange = TextIterator::subrange(fullCharacterRange.get(), extractedRange.location, extractedRange.length);
- if (!finalRange)
- return;
+ return TextIterator::subrange(fullCharacterRange.get(), extractedRange.location, extractedRange.length);
+}
- performDictionaryLookupForRange(frame, *finalRange, options);
+void WebPage::performDictionaryLookupAtLocation(const FloatPoint& floatPoint)
+{
+ if (PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame())) {
+ if (pluginView->performDictionaryLookupAtLocation(floatPoint))
+ return;
+ }
+
+ // Find the frame the point is over.
+ IntPoint point = roundedIntPoint(floatPoint);
+ HitTestResult result = m_page->mainFrame().eventHandler().hitTestResultAtPoint(m_page->mainFrame().view()->windowToContents(point));
+ Frame* frame = result.innerNonSharedNode() ? result.innerNonSharedNode()->document().frame() : &m_page->focusController().focusedOrMainFrame();
+ NSDictionary *options = nil;
+ RefPtr<Range> range = rangeForDictionaryLookupAtHitTestResult(result, &options);
+ performDictionaryLookupForRange(frame, *range, options);
}
void WebPage::performDictionaryLookupForSelection(Frame* frame, const VisibleSelection& selection)
@@ -602,6 +615,12 @@
performDictionaryLookupForRange(frame, *selectedRange, options);
}
+void WebPage::performDictionaryLookupOfCurrentSelection()
+{
+ Frame* frame = &m_page->focusController().focusedOrMainFrame();
+ performDictionaryLookupForSelection(frame, frame->selection().selection());
+}
+
void WebPage::performDictionaryLookupForRange(Frame* frame, Range& range, NSDictionary *options)
{
if (range.text().stripWhiteSpace().isEmpty())
@@ -1151,6 +1170,21 @@
send(Messages::WebPageProxy::DidPerformActionMenuHitTest(actionMenuResult));
}
+void WebPage::selectLookupTextAtLocation(FloatPoint locationInWindowCooordinates)
+{
+ MainFrame& mainFrame = corePage()->mainFrame();
+ if (!mainFrame.view() || !mainFrame.view()->renderView())
+ return;
+
+ IntPoint point = roundedIntPoint(locationInWindowCooordinates);
+ HitTestResult result = m_page->mainFrame().eventHandler().hitTestResultAtPoint(m_page->mainFrame().view()->windowToContents(point));
+ Frame* frame = result.innerNonSharedNode() ? result.innerNonSharedNode()->document().frame() : &m_page->focusController().focusedOrMainFrame();
+ NSDictionary *options = nil;
+ RefPtr<Range> lookupRange = rangeForDictionaryLookupAtHitTestResult(result, &options);
+ if (lookupRange)
+ frame->selection().setSelectedRange(lookupRange.get(), DOWNSTREAM, true);
+}
+
} // namespace WebKit
#endif // PLATFORM(MAC)