<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[191520] trunk/Source/WebKit/mac</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/191520">191520</a></dd>
<dt>Author</dt> <dd>andersca@apple.com</dd>
<dt>Date</dt> <dd>2015-10-23 17:26:21 -0700 (Fri, 23 Oct 2015)</dd>
</dl>
<h3>Log Message</h3>
<pre>Invoke the context menu delegate callback right before we return the menu
https://bugs.webkit.org/show_bug.cgi?id=150521
Reviewed by Tim Horton.
Move the getCustomMenuFromDefaultItems to WebHTMLView wholesale. This will allow us to get rid of the ContextMenuClient function from WebCore.
* WebCoreSupport/WebContextMenuClient.mm:
(WebContextMenuClient::getCustomMenuFromDefaultItems):
(isPreVersion3Client): Deleted.
(isPreInspectElementTagClient): Deleted.
(fixMenusToSendToOldClients): Deleted.
(fixMenusReceivedFromOldClients): Deleted.
* WebView/WebHTMLView.mm:
(isPreVersion3Client):
(isPreInspectElementTagClient):
(fixMenusToSendToOldClients):
(fixMenusReceivedFromOldClients):
(customMenuFromDefaultItems):
(-[WebHTMLView menuForEvent:]):</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebKitmacChangeLog">trunk/Source/WebKit/mac/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitmacWebCoreSupportWebContextMenuClientmm">trunk/Source/WebKit/mac/WebCoreSupport/WebContextMenuClient.mm</a></li>
<li><a href="#trunkSourceWebKitmacWebViewWebHTMLViewmm">trunk/Source/WebKit/mac/WebView/WebHTMLView.mm</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebKitmacChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/ChangeLog (191519 => 191520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/ChangeLog        2015-10-24 00:24:53 UTC (rev 191519)
+++ trunk/Source/WebKit/mac/ChangeLog        2015-10-24 00:26:21 UTC (rev 191520)
</span><span class="lines">@@ -1,5 +1,28 @@
</span><span class="cx"> 2015-10-23 Anders Carlsson <andersca@apple.com>
</span><span class="cx">
</span><ins>+ Invoke the context menu delegate callback right before we return the menu
+ https://bugs.webkit.org/show_bug.cgi?id=150521
+
+ Reviewed by Tim Horton.
+
+ Move the getCustomMenuFromDefaultItems to WebHTMLView wholesale. This will allow us to get rid of the ContextMenuClient function from WebCore.
+
+ * WebCoreSupport/WebContextMenuClient.mm:
+ (WebContextMenuClient::getCustomMenuFromDefaultItems):
+ (isPreVersion3Client): Deleted.
+ (isPreInspectElementTagClient): Deleted.
+ (fixMenusToSendToOldClients): Deleted.
+ (fixMenusReceivedFromOldClients): Deleted.
+ * WebView/WebHTMLView.mm:
+ (isPreVersion3Client):
+ (isPreInspectElementTagClient):
+ (fixMenusToSendToOldClients):
+ (fixMenusReceivedFromOldClients):
+ (customMenuFromDefaultItems):
+ (-[WebHTMLView menuForEvent:]):
+
+2015-10-23 Anders Carlsson <andersca@apple.com>
+
</ins><span class="cx"> More context menu simplification
</span><span class="cx"> https://bugs.webkit.org/show_bug.cgi?id=150519
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebKitmacWebCoreSupportWebContextMenuClientmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/WebCoreSupport/WebContextMenuClient.mm (191519 => 191520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/WebCoreSupport/WebContextMenuClient.mm        2015-10-24 00:24:53 UTC (rev 191519)
+++ trunk/Source/WebKit/mac/WebCoreSupport/WebContextMenuClient.mm        2015-10-24 00:26:21 UTC (rev 191520)
</span><span class="lines">@@ -89,237 +89,9 @@
</span><span class="cx"> delete this;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-static BOOL isPreVersion3Client(void)
-{
- static BOOL preVersion3Client = !WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_3_0_CONTEXT_MENU_TAGS);
- return preVersion3Client;
-}
-
-static BOOL isPreInspectElementTagClient(void)
-{
- static BOOL preInspectElementTagClient = !WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_INSPECT_ELEMENT_MENU_TAG);
- return preInspectElementTagClient;
-}
-
-static RetainPtr<NSArray> fixMenusToSendToOldClients(NSMutableArray *defaultMenuItems)
-{
- auto savedItems = adoptNS([[NSMutableArray alloc] init]);
-
- unsigned defaultItemsCount = [defaultMenuItems count];
-
- if (isPreInspectElementTagClient() && defaultItemsCount >= 2) {
- NSMenuItem *secondToLastItem = [defaultMenuItems objectAtIndex:defaultItemsCount - 2];
- NSMenuItem *lastItem = [defaultMenuItems objectAtIndex:defaultItemsCount - 1];
-
- if ([secondToLastItem isSeparatorItem] && [lastItem tag] == WebMenuItemTagInspectElement) {
- savedItems = adoptNS([[NSMutableArray alloc] initWithCapacity:2]);
- [savedItems addObject:secondToLastItem];
- [savedItems addObject:lastItem];
-
- [defaultMenuItems removeObject:secondToLastItem];
- [defaultMenuItems removeObject:lastItem];
- defaultItemsCount -= 2;
- }
- }
-
- BOOL preVersion3Client = isPreVersion3Client();
- if (!preVersion3Client)
- return savedItems;
-
- for (NSMenuItem *item in defaultMenuItems) {
- int tag = item.tag;
- int oldStyleTag = tag;
-
- if (tag >= WEBMENUITEMTAG_WEBKIT_3_0_SPI_START) {
- // Change all editing-related SPI tags listed in WebUIDelegatePrivate.h to WebMenuItemTagOther
- // to match our old WebKit context menu behavior.
- oldStyleTag = WebMenuItemTagOther;
- } else {
- // All items are expected to have useful tags coming into this method.
- ASSERT(tag != WebMenuItemTagOther);
-
- // Use the pre-3.0 tags for the few items that changed tags as they moved from SPI to API. We
- // do this only for old clients; new Mail already expects the new symbols in this case.
- if (preVersion3Client) {
- switch (tag) {
- case WebMenuItemTagSearchInSpotlight:
- oldStyleTag = OldWebMenuItemTagSearchInSpotlight;
- break;
- case WebMenuItemTagSearchWeb:
- oldStyleTag = OldWebMenuItemTagSearchWeb;
- break;
- case WebMenuItemTagLookUpInDictionary:
- oldStyleTag = OldWebMenuItemTagLookUpInDictionary;
- break;
- default:
- break;
- }
- }
- }
-
- item.tag = oldStyleTag;
- }
-
- return savedItems;
-}
-
-// FIXME: This should return NSArray.
-static RetainPtr<NSMutableArray> fixMenusReceivedFromOldClients(NSArray *delegateSuppliedItems, NSArray *savedItems)
-{
- auto newMenuItems = adoptNS([delegateSuppliedItems mutableCopy]);
-
- if (savedItems)
- [newMenuItems addObjectsFromArray:savedItems];
-
- BOOL preVersion3Client = isPreVersion3Client();
- if (!preVersion3Client)
- return newMenuItems;
-
- // Restore the modern tags to the menu items whose tags we altered in fixMenusToSendToOldClients.
- unsigned newItemsCount = [newMenuItems count];
- for (unsigned i = 0; i < newItemsCount; ++i) {
- NSMenuItem *item = [newMenuItems objectAtIndex:i];
-
- int tag = [item tag];
- int modernTag = tag;
-
- if (tag == WebMenuItemTagOther) {
- // Restore the specific tag for items on which we temporarily set WebMenuItemTagOther to match old behavior.
- NSString *title = [item title];
- if ([title isEqualToString:contextMenuItemTagOpenLink()])
- modernTag = WebMenuItemTagOpenLink;
- else if ([title isEqualToString:contextMenuItemTagIgnoreGrammar()])
- modernTag = WebMenuItemTagIgnoreGrammar;
- else if ([title isEqualToString:contextMenuItemTagSpellingMenu()])
- modernTag = WebMenuItemTagSpellingMenu;
- else if ([title isEqualToString:contextMenuItemTagShowSpellingPanel(true)]
- || [title isEqualToString:contextMenuItemTagShowSpellingPanel(false)])
- modernTag = WebMenuItemTagShowSpellingPanel;
- else if ([title isEqualToString:contextMenuItemTagCheckSpelling()])
- modernTag = WebMenuItemTagCheckSpelling;
- else if ([title isEqualToString:contextMenuItemTagCheckSpellingWhileTyping()])
- modernTag = WebMenuItemTagCheckSpellingWhileTyping;
- else if ([title isEqualToString:contextMenuItemTagCheckGrammarWithSpelling()])
- modernTag = WebMenuItemTagCheckGrammarWithSpelling;
- else if ([title isEqualToString:contextMenuItemTagFontMenu()])
- modernTag = WebMenuItemTagFontMenu;
- else if ([title isEqualToString:contextMenuItemTagShowFonts()])
- modernTag = WebMenuItemTagShowFonts;
- else if ([title isEqualToString:contextMenuItemTagBold()])
- modernTag = WebMenuItemTagBold;
- else if ([title isEqualToString:contextMenuItemTagItalic()])
- modernTag = WebMenuItemTagItalic;
- else if ([title isEqualToString:contextMenuItemTagUnderline()])
- modernTag = WebMenuItemTagUnderline;
- else if ([title isEqualToString:contextMenuItemTagOutline()])
- modernTag = WebMenuItemTagOutline;
- else if ([title isEqualToString:contextMenuItemTagStyles()])
- modernTag = WebMenuItemTagStyles;
- else if ([title isEqualToString:contextMenuItemTagShowColors()])
- modernTag = WebMenuItemTagShowColors;
- else if ([title isEqualToString:contextMenuItemTagSpeechMenu()])
- modernTag = WebMenuItemTagSpeechMenu;
- else if ([title isEqualToString:contextMenuItemTagStartSpeaking()])
- modernTag = WebMenuItemTagStartSpeaking;
- else if ([title isEqualToString:contextMenuItemTagStopSpeaking()])
- modernTag = WebMenuItemTagStopSpeaking;
- else if ([title isEqualToString:contextMenuItemTagWritingDirectionMenu()])
- modernTag = WebMenuItemTagWritingDirectionMenu;
- else if ([title isEqualToString:contextMenuItemTagDefaultDirection()])
- modernTag = WebMenuItemTagDefaultDirection;
- else if ([title isEqualToString:contextMenuItemTagLeftToRight()])
- modernTag = WebMenuItemTagLeftToRight;
- else if ([title isEqualToString:contextMenuItemTagRightToLeft()])
- modernTag = WebMenuItemTagRightToLeft;
- else if ([title isEqualToString:contextMenuItemTagInspectElement()])
- modernTag = WebMenuItemTagInspectElement;
- else if ([title isEqualToString:contextMenuItemTagCorrectSpellingAutomatically()])
- modernTag = WebMenuItemTagCorrectSpellingAutomatically;
- else if ([title isEqualToString:contextMenuItemTagSubstitutionsMenu()])
- modernTag = WebMenuItemTagSubstitutionsMenu;
- else if ([title isEqualToString:contextMenuItemTagShowSubstitutions(true)]
- || [title isEqualToString:contextMenuItemTagShowSubstitutions(false)])
- modernTag = WebMenuItemTagShowSubstitutions;
- else if ([title isEqualToString:contextMenuItemTagSmartCopyPaste()])
- modernTag = WebMenuItemTagSmartCopyPaste;
- else if ([title isEqualToString:contextMenuItemTagSmartQuotes()])
- modernTag = WebMenuItemTagSmartQuotes;
- else if ([title isEqualToString:contextMenuItemTagSmartDashes()])
- modernTag = WebMenuItemTagSmartDashes;
- else if ([title isEqualToString:contextMenuItemTagSmartLinks()])
- modernTag = WebMenuItemTagSmartLinks;
- else if ([title isEqualToString:contextMenuItemTagTextReplacement()])
- modernTag = WebMenuItemTagTextReplacement;
- else if ([title isEqualToString:contextMenuItemTagTransformationsMenu()])
- modernTag = WebMenuItemTagTransformationsMenu;
- else if ([title isEqualToString:contextMenuItemTagMakeUpperCase()])
- modernTag = WebMenuItemTagMakeUpperCase;
- else if ([title isEqualToString:contextMenuItemTagMakeLowerCase()])
- modernTag = WebMenuItemTagMakeLowerCase;
- else if ([title isEqualToString:contextMenuItemTagCapitalize()])
- modernTag = WebMenuItemTagCapitalize;
- else {
- // We don't expect WebMenuItemTagOther for any items other than the ones we explicitly handle.
- // There's nothing to prevent an app from applying this tag, but they are supposed to only
- // use tags in the range starting with WebMenuItemBaseApplicationTag=10000
- ASSERT_NOT_REACHED();
- }
- } else if (preVersion3Client) {
- // Restore the new API tag for items on which we temporarily set the old SPI tag. The old SPI tag was
- // needed to avoid confusing clients linked against earlier WebKits; the new API tag is needed for
- // WebCore to handle the menu items appropriately (without needing to know about the old SPI tags).
- switch (tag) {
- case OldWebMenuItemTagSearchInSpotlight:
- modernTag = WebMenuItemTagSearchInSpotlight;
- break;
- case OldWebMenuItemTagSearchWeb:
- modernTag = WebMenuItemTagSearchWeb;
- break;
- case OldWebMenuItemTagLookUpInDictionary:
- modernTag = WebMenuItemTagLookUpInDictionary;
- break;
- default:
- break;
- }
- }
-
- if (modernTag != tag)
- [item setTag:modernTag];
- }
-
- return newMenuItems;
-}
-
</del><span class="cx"> NSMutableArray* WebContextMenuClient::getCustomMenuFromDefaultItems(ContextMenu* defaultMenu)
</span><span class="cx"> {
</span><del>- id delegate = [m_webView UIDelegate];
- SEL selector = @selector(webView:contextMenuItemsForElement:defaultMenuItems:);
- if (![delegate respondsToSelector:selector])
- return defaultMenu->platformDescription();
-
- NSDictionary *element = [[[WebElementDictionary alloc] initWithHitTestResult:[m_webView page]->contextMenuController().hitTestResult()] autorelease];
-
- BOOL preVersion3Client = isPreVersion3Client();
- if (preVersion3Client) {
- DOMNode *node = [element objectForKey:WebElementDOMNodeKey];
- if ([node isKindOfClass:[DOMHTMLInputElement class]] && [(DOMHTMLInputElement *)node _isTextField])
- return defaultMenu->platformDescription();
- if ([node isKindOfClass:[DOMHTMLTextAreaElement class]])
- return defaultMenu->platformDescription();
- }
-
- NSMutableArray *defaultMenuItems = defaultMenu->platformDescription();
-
- for (NSMenuItem *menuItem in defaultMenuItems) {
- if (!menuItem.representedObject)
- menuItem.representedObject = element;
- }
-
- auto savedItems = fixMenusToSendToOldClients(defaultMenuItems);
-
- NSArray *delegateSuppliedItems = CallUIDelegate(m_webView, selector, element, defaultMenuItems);
-
- return fixMenusReceivedFromOldClients(delegateSuppliedItems, savedItems.get()).autorelease();
</del><ins>+ return defaultMenu->platformDescription();
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void WebContextMenuClient::contextMenuItemSelected(ContextMenuItem* item, const ContextMenu* parentMenu)
</span></span></pre></div>
<a id="trunkSourceWebKitmacWebViewWebHTMLViewmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/WebView/WebHTMLView.mm (191519 => 191520)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/WebView/WebHTMLView.mm        2015-10-24 00:24:53 UTC (rev 191519)
+++ trunk/Source/WebKit/mac/WebView/WebHTMLView.mm        2015-10-24 00:26:21 UTC (rev 191520)
</span><span class="lines">@@ -106,6 +106,7 @@
</span><span class="cx"> #import <WebCore/Image.h>
</span><span class="cx"> #import <WebCore/KeyboardEvent.h>
</span><span class="cx"> #import <WebCore/LegacyWebArchive.h>
</span><ins>+#import <WebCore/LocalizedStrings.h>
</ins><span class="cx"> #import <WebCore/MIMETypeRegistry.h>
</span><span class="cx"> #import <WebCore/MainFrame.h>
</span><span class="cx"> #import <WebCore/NSURLFileTypeMappingsSPI.h>
</span><span class="lines">@@ -3329,6 +3330,236 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+static BOOL isPreVersion3Client(void)
+{
+ static BOOL preVersion3Client = !WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_3_0_CONTEXT_MENU_TAGS);
+ return preVersion3Client;
+}
+
+static BOOL isPreInspectElementTagClient(void)
+{
+ static BOOL preInspectElementTagClient = !WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_INSPECT_ELEMENT_MENU_TAG);
+ return preInspectElementTagClient;
+}
+
+static RetainPtr<NSArray> fixMenusToSendToOldClients(NSMutableArray *defaultMenuItems)
+{
+ auto savedItems = adoptNS([[NSMutableArray alloc] init]);
+
+ unsigned defaultItemsCount = [defaultMenuItems count];
+
+ if (isPreInspectElementTagClient() && defaultItemsCount >= 2) {
+ NSMenuItem *secondToLastItem = [defaultMenuItems objectAtIndex:defaultItemsCount - 2];
+ NSMenuItem *lastItem = [defaultMenuItems objectAtIndex:defaultItemsCount - 1];
+
+ if ([secondToLastItem isSeparatorItem] && [lastItem tag] == WebMenuItemTagInspectElement) {
+ savedItems = adoptNS([[NSMutableArray alloc] initWithCapacity:2]);
+ [savedItems addObject:secondToLastItem];
+ [savedItems addObject:lastItem];
+
+ [defaultMenuItems removeObject:secondToLastItem];
+ [defaultMenuItems removeObject:lastItem];
+ defaultItemsCount -= 2;
+ }
+ }
+
+ BOOL preVersion3Client = isPreVersion3Client();
+ if (!preVersion3Client)
+ return savedItems;
+
+ for (NSMenuItem *item in defaultMenuItems) {
+ int tag = item.tag;
+ int oldStyleTag = tag;
+
+ if (tag >= WEBMENUITEMTAG_WEBKIT_3_0_SPI_START) {
+ // Change all editing-related SPI tags listed in WebUIDelegatePrivate.h to WebMenuItemTagOther
+ // to match our old WebKit context menu behavior.
+ oldStyleTag = WebMenuItemTagOther;
+ } else {
+ // All items are expected to have useful tags coming into this method.
+ ASSERT(tag != WebMenuItemTagOther);
+
+ // Use the pre-3.0 tags for the few items that changed tags as they moved from SPI to API. We
+ // do this only for old clients; new Mail already expects the new symbols in this case.
+ if (preVersion3Client) {
+ switch (tag) {
+ case WebMenuItemTagSearchInSpotlight:
+ oldStyleTag = OldWebMenuItemTagSearchInSpotlight;
+ break;
+ case WebMenuItemTagSearchWeb:
+ oldStyleTag = OldWebMenuItemTagSearchWeb;
+ break;
+ case WebMenuItemTagLookUpInDictionary:
+ oldStyleTag = OldWebMenuItemTagLookUpInDictionary;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ item.tag = oldStyleTag;
+ }
+
+ return savedItems;
+}
+
+static RetainPtr<NSArray> fixMenusReceivedFromOldClients(NSArray *delegateSuppliedItems, NSArray *savedItems)
+{
+ auto newMenuItems = adoptNS([delegateSuppliedItems mutableCopy]);
+
+ if (savedItems)
+ [newMenuItems addObjectsFromArray:savedItems];
+
+ BOOL preVersion3Client = isPreVersion3Client();
+ if (!preVersion3Client)
+ return newMenuItems;
+
+ // Restore the modern tags to the menu items whose tags we altered in fixMenusToSendToOldClients.
+ unsigned newItemsCount = [newMenuItems count];
+ for (unsigned i = 0; i < newItemsCount; ++i) {
+ NSMenuItem *item = [newMenuItems objectAtIndex:i];
+
+ int tag = [item tag];
+ int modernTag = tag;
+
+ if (tag == WebMenuItemTagOther) {
+ // Restore the specific tag for items on which we temporarily set WebMenuItemTagOther to match old behavior.
+ NSString *title = [item title];
+ if ([title isEqualToString:contextMenuItemTagOpenLink()])
+ modernTag = WebMenuItemTagOpenLink;
+ else if ([title isEqualToString:contextMenuItemTagIgnoreGrammar()])
+ modernTag = WebMenuItemTagIgnoreGrammar;
+ else if ([title isEqualToString:contextMenuItemTagSpellingMenu()])
+ modernTag = WebMenuItemTagSpellingMenu;
+ else if ([title isEqualToString:contextMenuItemTagShowSpellingPanel(true)] || [title isEqualToString:contextMenuItemTagShowSpellingPanel(false)])
+ modernTag = WebMenuItemTagShowSpellingPanel;
+ else if ([title isEqualToString:contextMenuItemTagCheckSpelling()])
+ modernTag = WebMenuItemTagCheckSpelling;
+ else if ([title isEqualToString:contextMenuItemTagCheckSpellingWhileTyping()])
+ modernTag = WebMenuItemTagCheckSpellingWhileTyping;
+ else if ([title isEqualToString:contextMenuItemTagCheckGrammarWithSpelling()])
+ modernTag = WebMenuItemTagCheckGrammarWithSpelling;
+ else if ([title isEqualToString:contextMenuItemTagFontMenu()])
+ modernTag = WebMenuItemTagFontMenu;
+ else if ([title isEqualToString:contextMenuItemTagShowFonts()])
+ modernTag = WebMenuItemTagShowFonts;
+ else if ([title isEqualToString:contextMenuItemTagBold()])
+ modernTag = WebMenuItemTagBold;
+ else if ([title isEqualToString:contextMenuItemTagItalic()])
+ modernTag = WebMenuItemTagItalic;
+ else if ([title isEqualToString:contextMenuItemTagUnderline()])
+ modernTag = WebMenuItemTagUnderline;
+ else if ([title isEqualToString:contextMenuItemTagOutline()])
+ modernTag = WebMenuItemTagOutline;
+ else if ([title isEqualToString:contextMenuItemTagStyles()])
+ modernTag = WebMenuItemTagStyles;
+ else if ([title isEqualToString:contextMenuItemTagShowColors()])
+ modernTag = WebMenuItemTagShowColors;
+ else if ([title isEqualToString:contextMenuItemTagSpeechMenu()])
+ modernTag = WebMenuItemTagSpeechMenu;
+ else if ([title isEqualToString:contextMenuItemTagStartSpeaking()])
+ modernTag = WebMenuItemTagStartSpeaking;
+ else if ([title isEqualToString:contextMenuItemTagStopSpeaking()])
+ modernTag = WebMenuItemTagStopSpeaking;
+ else if ([title isEqualToString:contextMenuItemTagWritingDirectionMenu()])
+ modernTag = WebMenuItemTagWritingDirectionMenu;
+ else if ([title isEqualToString:contextMenuItemTagDefaultDirection()])
+ modernTag = WebMenuItemTagDefaultDirection;
+ else if ([title isEqualToString:contextMenuItemTagLeftToRight()])
+ modernTag = WebMenuItemTagLeftToRight;
+ else if ([title isEqualToString:contextMenuItemTagRightToLeft()])
+ modernTag = WebMenuItemTagRightToLeft;
+ else if ([title isEqualToString:contextMenuItemTagInspectElement()])
+ modernTag = WebMenuItemTagInspectElement;
+ else if ([title isEqualToString:contextMenuItemTagCorrectSpellingAutomatically()])
+ modernTag = WebMenuItemTagCorrectSpellingAutomatically;
+ else if ([title isEqualToString:contextMenuItemTagSubstitutionsMenu()])
+ modernTag = WebMenuItemTagSubstitutionsMenu;
+ else if ([title isEqualToString:contextMenuItemTagShowSubstitutions(true)] || [title isEqualToString:contextMenuItemTagShowSubstitutions(false)])
+ modernTag = WebMenuItemTagShowSubstitutions;
+ else if ([title isEqualToString:contextMenuItemTagSmartCopyPaste()])
+ modernTag = WebMenuItemTagSmartCopyPaste;
+ else if ([title isEqualToString:contextMenuItemTagSmartQuotes()])
+ modernTag = WebMenuItemTagSmartQuotes;
+ else if ([title isEqualToString:contextMenuItemTagSmartDashes()])
+ modernTag = WebMenuItemTagSmartDashes;
+ else if ([title isEqualToString:contextMenuItemTagSmartLinks()])
+ modernTag = WebMenuItemTagSmartLinks;
+ else if ([title isEqualToString:contextMenuItemTagTextReplacement()])
+ modernTag = WebMenuItemTagTextReplacement;
+ else if ([title isEqualToString:contextMenuItemTagTransformationsMenu()])
+ modernTag = WebMenuItemTagTransformationsMenu;
+ else if ([title isEqualToString:contextMenuItemTagMakeUpperCase()])
+ modernTag = WebMenuItemTagMakeUpperCase;
+ else if ([title isEqualToString:contextMenuItemTagMakeLowerCase()])
+ modernTag = WebMenuItemTagMakeLowerCase;
+ else if ([title isEqualToString:contextMenuItemTagCapitalize()])
+ modernTag = WebMenuItemTagCapitalize;
+ else {
+ // We don't expect WebMenuItemTagOther for any items other than the ones we explicitly handle.
+ // There's nothing to prevent an app from applying this tag, but they are supposed to only
+ // use tags in the range starting with WebMenuItemBaseApplicationTag=10000
+ ASSERT_NOT_REACHED();
+ }
+ } else if (preVersion3Client) {
+ // Restore the new API tag for items on which we temporarily set the old SPI tag. The old SPI tag was
+ // needed to avoid confusing clients linked against earlier WebKits; the new API tag is needed for
+ // WebCore to handle the menu items appropriately (without needing to know about the old SPI tags).
+ switch (tag) {
+ case OldWebMenuItemTagSearchInSpotlight:
+ modernTag = WebMenuItemTagSearchInSpotlight;
+ break;
+ case OldWebMenuItemTagSearchWeb:
+ modernTag = WebMenuItemTagSearchWeb;
+ break;
+ case OldWebMenuItemTagLookUpInDictionary:
+ modernTag = WebMenuItemTagLookUpInDictionary;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (modernTag != tag)
+ [item setTag:modernTag];
+ }
+
+ return newMenuItems;
+}
+
+static RetainPtr<NSArray> customMenuFromDefaultItems(WebView *webView, const ContextMenu& defaultMenu)
+{
+ id delegate = [webView UIDelegate];
+ SEL selector = @selector(webView:contextMenuItemsForElement:defaultMenuItems:);
+ if (![delegate respondsToSelector:selector])
+ return defaultMenu.platformDescription();
+
+ auto element = adoptNS([[WebElementDictionary alloc] initWithHitTestResult:[webView page]->contextMenuController().hitTestResult()]);
+
+ BOOL preVersion3Client = isPreVersion3Client();
+ if (preVersion3Client) {
+ DOMNode *node = [element objectForKey:WebElementDOMNodeKey];
+ if ([node isKindOfClass:[DOMHTMLInputElement class]] && [(DOMHTMLInputElement *)node _isTextField])
+ return defaultMenu.platformDescription();
+ if ([node isKindOfClass:[DOMHTMLTextAreaElement class]])
+ return defaultMenu.platformDescription();
+ }
+
+ NSMutableArray *defaultMenuItems = defaultMenu.platformDescription();
+
+ for (NSMenuItem *menuItem in defaultMenuItems) {
+ if (!menuItem.representedObject)
+ menuItem.representedObject = element.get();
+ }
+
+ auto savedItems = fixMenusToSendToOldClients(defaultMenuItems);
+
+ NSArray *delegateSuppliedItems = CallUIDelegate(webView, selector, element.get(), defaultMenuItems);
+
+ return fixMenusReceivedFromOldClients(delegateSuppliedItems, savedItems.get()).autorelease();
+}
+
</ins><span class="cx"> - (NSMenu *)menuForEvent:(NSEvent *)event
</span><span class="cx"> {
</span><span class="cx"> // There's a chance that if we run a nested event loop the event will be released.
</span><span class="lines">@@ -3361,21 +3592,17 @@
</span><span class="cx"> if (!page)
</span><span class="cx"> return nil;
</span><span class="cx">
</span><del>- ContextMenu* coreMenu = page->contextMenuController().contextMenu();
- if (!coreMenu)
</del><ins>+ ContextMenu* contextMenu = page->contextMenuController().contextMenu();
+ if (!contextMenu)
</ins><span class="cx"> return nil;
</span><span class="cx">
</span><del>- NSArray* menuItems = coreMenu->platformDescription();
- if (!menuItems)
</del><ins>+ auto menuItems = customMenuFromDefaultItems([self _webView], *contextMenu);
+ if (![menuItems count])
</ins><span class="cx"> return nil;
</span><span class="cx">
</span><del>- NSUInteger count = [menuItems count];
- if (!count)
- return nil;
-
</del><span class="cx"> auto menu = adoptNS([[NSMenu alloc] init]);
</span><span class="cx">
</span><del>- for (NSMenuItem *item in menuItems) {
</del><ins>+ for (NSMenuItem *item in menuItems.get()) {
</ins><span class="cx"> [menu addItem:item];
</span><span class="cx">
</span><span class="cx"> if (item.tag == ContextMenuItemTagShareMenu) {
</span><span class="lines">@@ -3384,8 +3611,8 @@
</span><span class="cx"> _private->currentSharingServicePickerController = adoptNS([[WebSharingServicePickerController alloc] initWithSharingServicePicker:item.representedObject client:static_cast<WebContextMenuClient&>(page->contextMenuController().client())]);
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><ins>+ }
</ins><span class="cx">
</span><del>- }
</del><span class="cx"> setMenuTargets(menu.get());
</span><span class="cx">
</span><span class="cx"> [[WebMenuTarget sharedMenuTarget] setMenuController:&page->contextMenuController()];
</span></span></pre>
</div>
</div>
</body>
</html>