Changeset 275491 in webkit
- Timestamp:
- Apr 5, 2021 9:31:13 PM (3 years ago)
- Location:
- trunk/Source/WebKit
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit/ChangeLog
r275487 r275491 1 2021-04-05 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 [macOS] Image preview context menu action should be shown conditionally 4 https://bugs.webkit.org/show_bug.cgi?id=224126 5 <rdar://problem/76162272> 6 7 Reviewed by Devin Rousso. 8 9 Add a page client hook to return whether or not the "reveal image" context menu item should be enabled, given 10 the image URL and decoded image bitmap; we then use this method to conditionally insert a context menu item for 11 revealing the image in context menu data. 12 13 * UIProcess/Cocoa/WebViewImpl.h: 14 * UIProcess/PageClient.h: 15 (WebKit::PageClient::computeCanRevealImage): 16 * UIProcess/WebPageProxy.cpp: 17 (WebKit::WebPageProxy::computeCanRevealImage): 18 * UIProcess/WebPageProxy.h: 19 * UIProcess/mac/PageClientImplMac.h: 20 * UIProcess/mac/PageClientImplMac.mm: 21 (WebKit::PageClientImpl::computeCanRevealImage): 22 * UIProcess/mac/WebContextMenuProxyMac.mm: 23 (WebKit::createMenuActionItem): 24 25 Pull logic for mapping a `WebContextMenuItemData` of type `ActionType` or `CheckableActionType` to a platform 26 `NSMenuItem` out into a separate helper function. Use this helper in `getContextMenuItem`, as well as the 27 completion handler for the call to `computeCanRevealImage`. Note that this also requires moving the 28 `menuItemIdentifier` function up above `getContextMenuFromItems`. 29 30 (WebKit::WebContextMenuProxyMac::getContextMenuFromItems): 31 32 Special case the `ContextMenuItemTagRevealImage` item; instead of adding this item to the context menu right 33 away, we hide it by default, and only reinsert it if the page client indicates that we require the item (via 34 `computeCanRevealImage`). 35 36 (WebKit::WebContextMenuProxyMac::getContextMenuItem): 37 1 38 2021-04-05 Alex Christensen <achristensen@webkit.org> 2 39 -
trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.h
r274148 r275491 45 45 #include <wtf/WeakObjCPtr.h> 46 46 #include <wtf/WeakPtr.h> 47 #include <wtf/WorkQueue.h> 47 48 #include <wtf/text/WTFString.h> 48 49 … … 586 587 #if ENABLE(IMAGE_EXTRACTION) 587 588 void requestImageExtraction(const URL& imageURL, const ShareableBitmap::Handle& imageData, CompletionHandler<void(WebCore::ImageExtractionResult&&)>&&); 589 void computeCanRevealImage(const URL& imageURL, ShareableBitmap& imageBitmap, CompletionHandler<void(bool)>&&); 588 590 #endif 589 591 -
trunk/Source/WebKit/UIProcess/PageClient.h
r275485 r275491 528 528 #if ENABLE(IMAGE_EXTRACTION) 529 529 virtual void requestImageExtraction(const URL& imageURL, const ShareableBitmap::Handle& imageData, CompletionHandler<void(WebCore::ImageExtractionResult&&)>&& completion) { completion({ }); } 530 virtual void computeCanRevealImage(const URL&, ShareableBitmap&, CompletionHandler<void(bool)>&& completion) { completion(false); } 530 531 #endif 531 532 -
trunk/Source/WebKit/UIProcess/WebPageProxy.cpp
r275485 r275491 8259 8259 } 8260 8260 8261 void WebPageProxy::computeCanRevealImage(const URL& imageURL, ShareableBitmap& imageBitmap, CompletionHandler<void(bool)>&& completion) 8262 { 8263 pageClient().computeCanRevealImage(imageURL, imageBitmap, WTFMove(completion)); 8264 } 8265 8261 8266 void WebPageProxy::updateWithImageExtractionResult(ImageExtractionResult&& results, const ElementContext& context, const FloatPoint& location, CompletionHandler<void(bool textExistsAtLocation)>&& completionHandler) 8262 8267 { -
trunk/Source/WebKit/UIProcess/WebPageProxy.h
r275485 r275491 1640 1640 void requestImageExtraction(const URL& imageURL, const ShareableBitmap::Handle& imageData, CompletionHandler<void(WebCore::ImageExtractionResult&&)>&&); 1641 1641 void updateWithImageExtractionResult(WebCore::ImageExtractionResult&&, const WebCore::ElementContext&, const WebCore::FloatPoint& location, CompletionHandler<void(bool textExistsAtLocation)>&&); 1642 void computeCanRevealImage(const URL& imageURL, ShareableBitmap& imageBitmap, CompletionHandler<void(bool)>&&); 1642 1643 #endif 1643 1644 -
trunk/Source/WebKit/UIProcess/mac/PageClientImplMac.h
r275485 r275491 133 133 #if ENABLE(IMAGE_EXTRACTION) 134 134 void requestImageExtraction(const URL& imageURL, const ShareableBitmap::Handle& imageData, CompletionHandler<void(WebCore::ImageExtractionResult&&)>&&) override; 135 void computeCanRevealImage(const URL&, ShareableBitmap&, CompletionHandler<void(bool)>&&) override; 135 136 #endif 136 137 -
trunk/Source/WebKit/UIProcess/mac/PageClientImplMac.mm
r275485 r275491 489 489 } 490 490 491 void PageClientImpl::computeCanRevealImage(const URL& imageURL, ShareableBitmap& imageBitmap, CompletionHandler<void(bool)>&& completion) 492 { 493 m_impl->computeCanRevealImage(imageURL, imageBitmap, WTFMove(completion)); 494 } 495 491 496 #endif 492 497 -
trunk/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.mm
r274521 r275491 35 35 #import "ShareableBitmap.h" 36 36 #import "WKMenuItemIdentifiersPrivate.h" 37 #import "WKNSURLExtras.h" 37 38 #import "WKSharingServicePickerDelegate.h" 38 39 #import "WebContextMenuItem.h" … … 374 375 } 375 376 376 void WebContextMenuProxyMac::getContextMenuFromItems(const Vector<WebContextMenuItemData>& items, CompletionHandler<void(NSMenu *)>&& completionHandler)377 {378 auto menu = adoptNS([[NSMenu alloc] initWithTitle:@""]);379 [menu setAutoenablesItems:NO];380 381 if (items.isEmpty()) {382 completionHandler(menu.get());383 return;384 }385 386 auto filteredItems = items;387 auto webView = m_webView.get();388 389 bool isPopover = webView.get().window._childWindowOrderingPriority == NSWindowChildOrderingPriorityPopover;390 bool isLookupDisabled = [NSUserDefaults.standardUserDefaults boolForKey:@"LULookupDisabled"];391 392 if (isLookupDisabled || isPopover) {393 filteredItems.removeAllMatching([] (auto& item) {394 return item.action() == WebCore::ContextMenuItemTagLookUpInDictionary;395 });396 }397 398 #if HAVE(TRANSLATION_UI_SERVICES)399 if (!page()->canHandleContextMenuTranslation() || isPopover) {400 filteredItems.removeAllMatching([] (auto& item) {401 return item.action() == ContextMenuItemTagTranslate;402 });403 }404 #endif405 406 auto sparseMenuItems = retainPtr([NSPointerArray strongObjectsPointerArray]);407 auto insertMenuItem = makeBlockPtr([completionHandler = WTFMove(completionHandler), itemsRemaining = filteredItems.size(), menu = WTFMove(menu), sparseMenuItems](NSMenuItem *item, NSUInteger index) mutable {408 ASSERT(index < [sparseMenuItems count]);409 ASSERT(![sparseMenuItems pointerAtIndex:index]);410 [sparseMenuItems replacePointerAtIndex:index withPointer:item];411 if (--itemsRemaining)412 return;413 414 [menu setItemArray:[sparseMenuItems allObjects]];415 completionHandler(menu.get());416 });417 418 for (size_t i = 0; i < filteredItems.size(); ++i) {419 [sparseMenuItems addPointer:nullptr];420 getContextMenuItem(filteredItems[i], [insertMenuItem, i](NSMenuItem *menuItem) {421 insertMenuItem(menuItem, i);422 });423 }424 }425 426 377 static NSString *menuItemIdentifier(const WebCore::ContextMenuAction action) 427 378 { … … 516 467 } 517 468 469 static RetainPtr<NSMenuItem> createMenuActionItem(const WebContextMenuItemData& item) 470 { 471 auto type = item.type(); 472 ASSERT_UNUSED(type, type == WebCore::ActionType || type == WebCore::CheckableActionType); 473 474 auto menuItem = adoptNS([[NSMenuItem alloc] initWithTitle:item.title() action:@selector(forwardContextMenuAction:) keyEquivalent:@""]); 475 476 [menuItem setTag:item.action()]; 477 [menuItem setEnabled:item.enabled()]; 478 [menuItem setState:item.checked() ? NSControlStateValueOn : NSControlStateValueOff]; 479 [menuItem setIndentationLevel:item.indentationLevel()]; 480 [menuItem setTarget:[WKMenuTarget sharedMenuTarget]]; 481 [menuItem setIdentifier:menuItemIdentifier(item.action())]; 482 483 if (item.userData()) { 484 auto wrapper = adoptNS([[WKUserDataWrapper alloc] initWithUserData:item.userData()]); 485 [menuItem setRepresentedObject:wrapper.get()]; 486 } 487 488 return menuItem; 489 } 490 491 void WebContextMenuProxyMac::getContextMenuFromItems(const Vector<WebContextMenuItemData>& items, CompletionHandler<void(NSMenu *)>&& completionHandler) 492 { 493 auto menu = adoptNS([[NSMenu alloc] initWithTitle:@""]); 494 [menu setAutoenablesItems:NO]; 495 496 if (items.isEmpty()) { 497 completionHandler(menu.get()); 498 return; 499 } 500 501 auto filteredItems = items; 502 auto webView = m_webView.get(); 503 504 bool isPopover = webView.get().window._childWindowOrderingPriority == NSWindowChildOrderingPriorityPopover; 505 bool isLookupDisabled = [NSUserDefaults.standardUserDefaults boolForKey:@"LULookupDisabled"]; 506 507 if (isLookupDisabled || isPopover) { 508 filteredItems.removeAllMatching([] (auto& item) { 509 return item.action() == WebCore::ContextMenuItemTagLookUpInDictionary; 510 }); 511 } 512 513 Optional<WebContextMenuItemData> revealImageItem; 514 515 #if ENABLE(IMAGE_EXTRACTION) 516 filteredItems.removeFirstMatching([&] (auto& item) { 517 if (item.action() != WebCore::ContextMenuItemTagRevealImage) 518 return false; 519 520 revealImageItem = { item }; 521 return true; 522 }); 523 #endif 524 525 #if HAVE(TRANSLATION_UI_SERVICES) 526 if (!page()->canHandleContextMenuTranslation() || isPopover) { 527 filteredItems.removeAllMatching([] (auto& item) { 528 return item.action() == ContextMenuItemTagTranslate; 529 }); 530 } 531 #endif 532 533 auto imageURL = URL([NSURL _web_URLWithWTFString:m_context.webHitTestResultData().absoluteImageURL]); 534 auto imageBitmap = m_context.webHitTestResultData().imageBitmap; 535 536 auto sparseMenuItems = retainPtr([NSPointerArray strongObjectsPointerArray]); 537 auto insertMenuItem = makeBlockPtr([protectedThis = makeRef(*this), weakPage = makeWeakPtr(page()), imageURL = WTFMove(imageURL), imageBitmap = WTFMove(imageBitmap), revealImageItem = WTFMove(revealImageItem), completionHandler = WTFMove(completionHandler), itemsRemaining = filteredItems.size(), menu = WTFMove(menu), sparseMenuItems](NSMenuItem *item, NSUInteger index) mutable { 538 ASSERT(index < [sparseMenuItems count]); 539 ASSERT(![sparseMenuItems pointerAtIndex:index]); 540 [sparseMenuItems replacePointerAtIndex:index withPointer:item]; 541 if (--itemsRemaining) 542 return; 543 544 [menu setItemArray:[sparseMenuItems allObjects]]; 545 546 auto page = makeRefPtr(weakPage.get()); 547 if (revealImageItem && page && imageBitmap) { 548 #if ENABLE(IMAGE_EXTRACTION) 549 page->computeCanRevealImage(imageURL, *imageBitmap, [protectedThis = WTFMove(protectedThis), revealImageItem = WTFMove(*revealImageItem)] (bool canRevealImage) mutable { 550 if (!canRevealImage) 551 return; 552 553 auto nsMenuItem = createMenuActionItem(revealImageItem); 554 [protectedThis->m_menu addItem:nsMenuItem.get()]; 555 }); 556 #else 557 UNUSED_PARAM(imageURL); 558 #endif 559 } 560 561 completionHandler(menu.get()); 562 }); 563 564 for (size_t i = 0; i < filteredItems.size(); ++i) { 565 [sparseMenuItems addPointer:nullptr]; 566 getContextMenuItem(filteredItems[i], [insertMenuItem, i](NSMenuItem *menuItem) { 567 insertMenuItem(menuItem, i); 568 }); 569 } 570 } 571 518 572 void WebContextMenuProxyMac::getContextMenuItem(const WebContextMenuItemData& item, CompletionHandler<void(NSMenuItem *)>&& completionHandler) 519 573 { … … 528 582 case WebCore::ActionType: 529 583 case WebCore::CheckableActionType: { 530 auto menuItem = adoptNS([[NSMenuItem alloc] initWithTitle:item.title() action:@selector(forwardContextMenuAction:) keyEquivalent:@""]); 531 532 [menuItem setTag:item.action()]; 533 [menuItem setEnabled:item.enabled()]; 534 [menuItem setState:item.checked() ? NSControlStateValueOn : NSControlStateValueOff]; 535 [menuItem setIndentationLevel:item.indentationLevel()]; 536 [menuItem setTarget:[WKMenuTarget sharedMenuTarget]]; 537 [menuItem setIdentifier:menuItemIdentifier(item.action())]; 538 539 if (item.userData()) { 540 auto wrapper = adoptNS([[WKUserDataWrapper alloc] initWithUserData:item.userData()]); 541 [menuItem setRepresentedObject:wrapper.get()]; 542 } 543 544 completionHandler(menuItem.get()); 584 auto nsMenuItem = createMenuActionItem(item); 585 completionHandler(nsMenuItem.get()); 545 586 return; 546 587 }
Note: See TracChangeset
for help on using the changeset viewer.