Skip to content

Commit ab04077

Browse files
author
Hosam Tageldin
committed
Remainder of review changes
1 parent 6ccbffe commit ab04077

1 file changed

Lines changed: 93 additions & 62 deletions

File tree

specs/ContextMenuRequested.md

Lines changed: 93 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,14 @@ The developer can add or remove entries to the default WebView context menu. For
3535
{
3636
wil::com_ptr<ICoreWebView2ContextMenuItemCollection> items;
3737
CHECK_FAILURE(args->get_MenuItems(&items));
38-
wil::com_ptr<ICoreWebView2ContextMenuInfo> info;
39-
CHECK_FAILURE(args->get_ContextMenuInfo(&info));
40-
COREWEBVIEW2_CONTEXT_KIND context;
41-
CHECK_FAILURE(info->get_ContextKind(&context));
38+
wil::com_ptr<ICoreWebView2ContextMenuTarget> target;
39+
CHECK_FAILURE(args->get_ContextMenuTarget(&target));
40+
COREWEBVIEW2_CONTEXT_MENU_TARGET_KIND context_kind;
41+
CHECK_FAILURE(target->get_Kind(&context_kind));
4242
UINT32 itemsCount;
4343
CHECK_FAILURE(items->get_Count(&itemsCount));
4444
// Removing the 'Save image as' context menu item for image context selections.
45-
if (context == COREWEBVIEW2_CONTEXT_KIND_IMAGE)
45+
if (context_kind == COREWEBVIEW2_CONTEXT_MENU_TARGET_KIND_IMAGE)
4646
{
4747
wil::com_ptr<ICoreWebView2ContextMenuItem> current;
4848
for(UINT32 i = 0; i < itemsCount; i++)
@@ -58,7 +58,7 @@ The developer can add or remove entries to the default WebView context menu. For
5858
}
5959
}
6060
// Adding a custom context menu item for the page that will display the page's URI.
61-
else if (context == COREWEBVIEW2_CONTEXT_KIND_PAGE)
61+
else if (context_kind == COREWEBVIEW2_CONTEXT_MENU_TARGET_KIND_PAGE)
6262
{
6363
wil::com_ptr<ICoreWebView2Environment5> webviewEnvironment;
6464
CHECK_FAILURE(m_appWindow->GetWebViewEnvironment()->QueryInterface(
@@ -113,11 +113,9 @@ The developer can use the data provided in the Event arguments to display a cust
113113
AddMenuItems(hPopupMenu, items);
114114
HWND hWnd;
115115
m_controller->get_ParentWindow(&hWnd);
116-
wil::com_ptr<ICoreWebView2ContextMenuInfo> info;
117-
CHECK_FAILURE(args->get_ContextMenuInfo(&info));
118116
POINT locationInControlCoordinates;
119117
POINT locationInScreenCoordinates;
120-
CHECK_FAILURE(info->get_Location(&locationInControlCoordinates));
118+
CHECK_FAILURE(args->get_Location(&locationInControlCoordinates));
121119
// get_Location returns coordinates in relation to upper left Bounds of the WebView2.Controller. Will need to convert to Screen coordinates to display the popup menu in the correct location.
122120
ConvertToScreenCoordinates(locationInControlCoordinates, locationInScreenCoordinates);
123121
UINT32 selectedCommandId = TrackPopupMenu(hPopupMenu, TPM_TOPALIGN | TPM_LEFTALIGN | TPM_RETURNCMD, locationInScreenCoordinates.x, locationInScreenCoordinates.y, 0, hWnd, NULL);
@@ -172,8 +170,17 @@ The developer can use the data provided in the Event arguments to display a cust
172170
HMENU newMenu = CHECK_POINTER(CreateMenu());
173171
wil::com_ptr<ICoreWebView2ContextMenuItemCollection> submenuItems;
174172
CHECK_FAILURE(current->get_Children(&submenuItems));
175-
AddMenuItems(newMenu, submenuItems);
176-
CHECK_BOOL(AppendMenu(hPopupMenu, MF_POPUP, (UINT_PTR)newMenu, labelString.c_str()));
173+
BOOL isEnabled;
174+
CHECK_FAILURE(current->get_IsEnabled(&isEnabled));
175+
if (isEnabled)
176+
{
177+
AddMenuItems(newMenu, submenuItems);
178+
CHECK_BOOL(AppendMenu(hPopupMenu, MF_POPUP, (UINT_PTR)newMenu, labelString.c_str()));
179+
}
180+
else
181+
{
182+
CHECK_BOOL(AppendMenu(hPopupMenu, MF_POPUP | MF_GRAYED, (UINT_PTR)newMenu, labelString.c_str()));
183+
}
177184
}
178185
else if (
179186
kind == COREWEBVIEW2_CONTEXT_MENU_ITEM_KIND_CHECK_BOX ||
@@ -223,8 +230,8 @@ The developer can use the data provided in the Event arguments to display a cust
223230
webView.CoreWebView2.ContextMenuRequested += delegate (object sender, CoreWebView2ContextMenuRequestedEventArgs args)
224231
{
225232
IList<CoreWebView2ContextMenuItem> menuList = args.MenuItems;
226-
CoreWebView2ContextKind context = args.ContextMenuInfo.ContextKind;
227-
if (context == CoreWebView2ContextKind.Image)
233+
CoreWebView2ContextMenuTargetKind context = args.ContextMenuTarget.Kind;
234+
if (context == CoreWebView2ContextMenuTargetKind.Image)
228235
{
229236
for (int index = 0; index < menuList.Count; index++)
230237
{
@@ -235,14 +242,14 @@ The developer can use the data provided in the Event arguments to display a cust
235242
}
236243
}
237244
}
238-
else if (context == CoreWebView2ContextKind.Page)
245+
else if (context == CoreWebView2ContextMenuTargetKind.Page)
239246
{
240247
// add new item to end of collection
241248
CoreWebView2ContextMenuItem newItem = webView.CoreWebView2.Environment.CreateContextMenuItem(
242249
"Display Page Uri", null, CoreWebView2ContextMenuItemKind.Command);
243250
newItem.CustomItemSelected += delegate (object send, Object ex)
244251
{
245-
string pageUri = args.ContextMenuInfo.PageUri;
252+
string pageUri = args.ContextMenuTarget.PageUri;
246253
System.Threading.SynchronizationContext.Current.Post((_) =>
247254
{
248255
MessageBox.Show(pageUri, "Page Uri", MessageBoxButton.OK);
@@ -312,6 +319,12 @@ The developer can use the data provided in the Event arguments to display a cust
312319

313320
2. Developers should never add an item as a child of itself, this will cause undefined results.
314321

322+
3. Forbidden usage of the IsEnabled property include setting the property for menu items that are not a custom menu item or of type separator.
323+
324+
4. Forbidden usage of the IsChecked property include setting the property for menu items that are not a custom context menu item or not of type Check Box and Radio.
325+
326+
5. The `ContextMenuTargetKind` will always represent the active element that caused the context menu request. If there is a selection with multiple images, audio and text, for example, the element that the user selects within this selection will still be the option represented by the `ContextMenuTargetKind` enum.
327+
315328
# API Notes
316329

317330
1. The `ContextMenuRequested` event will only be raised if the page allows the context menu to appear. If the settings option for `AreDefaultContextMenusEnabled` is set to false, then the `ContextMenuRequested` event will not be raised.
@@ -320,37 +333,39 @@ The developer can use the data provided in the Event arguments to display a cust
320333

321334
3. Command Ids will be unique for custom menu items and no guarantee they will be the same for each menu item case, must always use the command Id given by the event arg.
322335

336+
4. When creating a new custom context menu item using `CreateContextMenuItem`, the item's `IsEnabled` property will default to `TRUE` and `IsChecked` property will default to `FALSE`.
337+
323338
# API Details
324339
```cpp
325340
interface ICoreWebView2_4;
326341
interface ICoreWebView2Environment5;
327342
interface ICoreWebView2ContextMenuItem;
328343
interface ICoreWebView2ContextMenuItemCollection;
329-
interface ICoreWebView2ContextMenuInfo;
330344
interface ICoreWebView2ContextMenuRequestedEventArgs;
331345
interface ICoreWebView2ContextMenuRequestedEventHandler;
346+
interface ICoreWebView2ContextMenuTarget;
332347
interface ICoreWebView2CustomItemSelectedEventHandler;
333348

334349
/// Indicates the kind of context for which the context menu was created
335-
/// for the `ICoreWebView2ContextMenuInfo::get_ContextKind` method
350+
/// for the `ICoreWebView2ContextMenuTarget::get_Kind` method.
336351
[v1_enum]
337-
typedef enum COREWEBVIEW2_CONTEXT_KIND
352+
typedef enum COREWEBVIEW2_CONTEXT_MENU_TARGET_KIND
338353
{
339354
/// Indicates that the context menu was created for the page without any additional content.
340-
COREWEBVIEW2_CONTEXT_KIND_PAGE,
355+
COREWEBVIEW2_CONTEXT_MENU_TARGET_KIND_PAGE,
341356

342357
/// Indicates that the context menu was created for an image element.
343-
COREWEBVIEW2_CONTEXT_KIND_IMAGE,
358+
COREWEBVIEW2_CONTEXT_MENU_TARGET_KIND_IMAGE,
344359

345360
/// Indicates that the context menu was created for selected text.
346-
COREWEBVIEW2_CONTEXT_KIND_SELECTED_TEXT,
361+
COREWEBVIEW2_CONTEXT_MENU_TARGET_KIND_SELECTED_TEXT,
347362
348363
/// Indicates that the context menu was created for an audio element.
349-
COREWEBVIEW2_CONTEXT_KIND_AUDIO,
364+
COREWEBVIEW2_CONTEXT_MENU_TARGET_KIND_AUDIO,
350365
351366
/// Indicates that the context menu was created for a video element.
352-
COREWEBVIEW2_CONTEXT_KIND_VIDEO,
353-
} COREWEBVIEW2_CONTEXT_KIND;
367+
COREWEBVIEW2_CONTEXT_MENU_TARGET_KIND_VIDEO,
368+
} COREWEBVIEW2_CONTEXT_MENU_TARGET_KIND;
354369

355370
/// Specifies the menu item kind
356371
/// for the `ICoreWebView2StagingContextMenuItem::get_Kind` method
@@ -406,9 +421,17 @@ The developer can use the data provided in the Event arguments to display a cust
406421
/// Gets the `ContextMenuItem` kind.
407422
[propget] HRESULT Kind([out, retval] COREWEBVIEW2_CONTEXT_MENU_ITEM_KIND* value);
408423

424+
/// Sets the enabled property of the `ContextMenuItem`. Should only be used in the case of a
425+
/// custom context menu item. The default value for this is `TRUE`.
426+
[propput] HRESULT IsEnabled([in] BOOL value);
427+
409428
/// Gets the enabled property of the `ContextMenuItem`.
410429
[propget] HRESULT IsEnabled([out, retval] BOOL* value);
411430

431+
/// Sets the checked property of the `ContextMenuItem`. Should only used for custom context
432+
/// menu items that are of type Check box or Radio.
433+
[propput] HRESULT isChecked([in] BOOL value);
434+
412435
/// Gets the checked property of the `ContextMenuItem`, used if the kind is Check box or Radio.
413436
[propget] HRESULT IsChecked([out, retval] BOOL* value);
414437

@@ -511,9 +534,13 @@ The developer can use the data provided in the Event arguments to display a cust
511534
/// See `ICoreWebView2ContextMenuItemCollection` for more details.
512535
[propget] HRESULT MenuItems([out, retval] ICoreWebView2ContextMenuItemCollection** value);
513536

514-
/// Gets the information associated with the requested context menu.
515-
/// See `ICoreWebView2ContextMenuInfo` for more details.
516-
[propget] HRESULT ContextMenuInfo([out, retval] ICoreWebView2ContextMenuInfo** value);
537+
/// Gets the target information associated with the requested context menu.
538+
/// See `ICoreWebView2ContextMenuTarget` for more details.
539+
[propget] HRESULT ContextMenuTarget([out, retval] ICoreWebView2ContextMenuTarget** value);
540+
541+
/// Gets the coordinates where the context menu request occured in relation to the upper
542+
/// left corner of the webview bounds.
543+
[propget] HRESULT Location([out, retval] POINT* value);
517544

518545
/// Sets the selected command for the WebView to execute. The value is
519546
/// obtained via the `ContextMenuItem` CommandId property
@@ -540,46 +567,49 @@ The developer can use the data provided in the Event arguments to display a cust
540567
HRESULT GetDeferral([out, retval] ICoreWebView2Deferral** deferral);
541568
}
542569

543-
/// Represents the information regarding the context menu. Includes the location of the request,
544-
/// the context selected and the appropriate data used for the actions of a context menu.
570+
/// Represents the information regarding the context menu target.
571+
/// Includes the context selected and the appropriate data used for the actions of a context menu.
545572
[uuid(b8611d99-eed6-4f3f-902c-a198502ad472), object, pointer_default(unique)]
546-
interface ICoreWebView2ContextMenuInfo : IUnknown
573+
interface ICoreWebView2ContextMenuTarget : IUnknown
547574
{
548-
/// Gets the coordinates where the context menu request occured in relation to the upper left corner of the webview bounds.
549-
[propget] HRESULT Location([out, retval] POINT* value);
550-
551575
/// Gets the kind of context that the user selected.
552-
[propget] HRESULT ContextKind([out, retval] COREWEBVIEW2_CONTEXT_KIND* value);
553-
554-
/// Returns TRUE if the context menu was requested on the main frame and
555-
/// FALSE if invoked on another frame.
556-
[propget] HRESULT IsMainFrame([out, retval] BOOL* value);
557-
558-
/// Returns TRUE if the context menu is requested on a selection.
559-
[propget] HRESULT HasSelection([out, retval] BOOL* value);
576+
[propget] HRESULT Kind([out, retval] COREWEBVIEW2_CONTEXT_MENU_TARGET_KIND* value);
560577

561578
/// Returns TRUE if the context menu is requested on an editable component.
562579
[propget] HRESULT IsEditable([out, retval] BOOL* value);
563580

564-
/// Returns TRUE if the context menu is requested on a component that contains a link.
565-
[propget] HRESULT ContainsLink([out, retval] BOOL* value);
566-
581+
/// Returns TRUE if the context menu was requested on the main frame and
582+
/// FALSE if invoked on another frame.
583+
[propget] HRESULT IsRequestedForMainFrame([out, retval] BOOL* value);
584+
567585
/// Gets the uri of the page.
568586
[propget] HRESULT PageUri([out, retval] LPWSTR* value);
569587

570-
/// Gets the uri of the frame. Will match the PageUri if `get_IsMainFrame` is TRUE.
588+
/// Gets the uri of the frame. Will match the PageUri if `get_IsRequestedForMainFrame` is TRUE.
571589
[propget] HRESULT FrameUri([out, retval] LPWSTR* value);
572590

573-
/// Gets the source uri of element (if context menu requested on a media element, null otherwise).
574-
[propget] HRESULT SourceUri([out, retval] LPWSTR* value);
591+
/// Returns TRUE if the context menu is requested on HTML containing an anchor tag.
592+
[propget] HRESULT HasLinkUri([out, retval] BOOL* value);
575593

576-
/// Gets the uri of the link (if context menu requested on a link, null otherwise).
594+
/// Gets the uri of the link (if `HasLinkUri` is TRUE, null otherwise).
577595
[propget] HRESULT LinkUri([out, retval] LPWSTR* value);
578596

579-
/// Gets the text of the link (if context menu requested on a link, null otherwise).
597+
/// Returns TRUE if the context menu is requested on text element that contains an anchor tag.
598+
[propget] HRESULT HasLinkText([out, retval] BOOL* value);
599+
600+
/// Gets the text of the link (if `HasLinkText` is TRUE, null otherwise).
580601
[propget] HRESULT LinkText([out, retval] LPWSTR * value);
581602

582-
/// Gets the selected text (available when HasSelection is TRUE, null otherwise).
603+
/// Returns TRUE if the context menu is requested on HTML containing a source uri.
604+
[propget] HRESULT HasSourceUri([out, retval] BOOL* value);
605+
606+
/// Gets the active source uri of element (if `HasSourceUri` is TRUE, null otherwise).
607+
[propget] HRESULT SourceUri([out, retval] LPWSTR* value);
608+
609+
/// Returns TRUE if the context menu is requested on a selection.
610+
[propget] HRESULT HasSelection([out, retval] BOOL* value);
611+
612+
/// Gets the selected text (if `HasSelection` is TRUE, null otherwise).
583613
[propget] HRESULT SelectionText([out, retval] LPWSTR* value);
584614
}
585615
```
@@ -589,10 +619,10 @@ namespace Microsoft.Web.WebView2.Core
589619
{
590620
runtimeclass CoreWebView2Environment;
591621
runtimeclass CoreWebView2ContextMenuItem;
592-
runtimeclass CoreWebView2ContextMenuInfo;
593622
runtimeclass CoreWebView2ContextMenuRequestedEventArgs;
623+
runtimeclass CoreWebView2ContextMenuTarget;
594624
595-
enum CoreWebView2ContextKind
625+
enum CoreWebView2ContextMenuTargetKind
596626
{
597627
Page = 0,
598628
Image = 1,
@@ -613,25 +643,26 @@ namespace Microsoft.Web.WebView2.Core
613643
runtimeclass CoreWebView2ContextMenuRequestedEventArgs
614644
{
615645
Boolean Handled { get; set; }
616-
CoreWebView2ContextMenuInfo ContextMenuInfo { get; }
646+
CoreWebView2ContextMenuTarget ContextMenuTarget { get; }
617647
IVector<CoreWebView2ContextMenuItem> MenuItems { get; }
648+
Point Location { get; }
618649
Int32 SelectedCommandId { get; set; }
619650
Windows.Foundation.Deferral GetDeferral();
620651
};
621652
622-
runtimeclass CoreWebView2ContextMenuInfo
653+
runtimeclass CoreWebView2ContextMenuTarget
623654
{
624-
Point Location { get; }
625-
CoreWebView2ContextKind ContextKind { get; }
626-
Boolean IsMainFrame { get; }
627-
Boolean HasSelection { get; }
655+
CoreWebView2ContextMenuTargetKind Kind { get; }
628656
Boolean IsEditable { get; }
629-
Boolean ContainsLink { get; }
657+
Boolean IsRequestedForMainFrame { get; }
630658
String PageUri { get; }
631659
String FrameUri { get; }
632-
String SourceUri { get; }
660+
Boolean HasLink { get; }
633661
String LinkUri { get; }
634662
String LinkText { get; }
663+
Boolean HasSourceUri { get; }
664+
String SourceUri { get; }
665+
Boolean HasSelection { get; }
635666
String SelectionText { get; }
636667
};
637668
@@ -643,8 +674,8 @@ namespace Microsoft.Web.WebView2.Core
643674
Int32 CommandId { get; }
644675
Stream Icon { get; }
645676
CoreWebView2ContextMenuItemKind Kind { get; }
646-
Boolean IsEnabled { get; }
647-
Boolean IsChecked { get; }
677+
Boolean IsEnabled { get; set; }
678+
Boolean IsChecked { get; set; }
648679
IVector<CoreWebView2ContextMenuItem> Children { get; }
649680
650681
event Windows.Foundation.TypedEventHandler<CoreWebView2ContextMenuItem, Object> CustomItemSelected;

0 commit comments

Comments
 (0)