It is desirable to allow a developer to perform an action when the context menu ("Back, Reload, etc") is invoked. The "oncontextmenu" event exists for this purpose. The event can captured and canceled using standard methods. However, if the context menu is allowed to display even once, it can no longer be canceled until the window is closed. Firefox and IE both allow the event to be canceled repeatedly, even if the menu has been shown before.
Created attachment 12651 [details] Test case reduction. 1) Open test case. 2) Mark the checkbox labeled "prevent default context menu". 3) Attempt to open the default context menu by right-clicking or ctrl-clicking. Event data will be captured. The context menu will NOT be displayed. This is correct. 4) Unmark the checkbox labeled "prevent default context menu". 5) Right-click or ctrl-click to open the context menu. Event data will be captured. The context menu will be displayed. This is correct. 6) Clear the context menu. 7) Mark the checkbox labeled "prevent default context menu". 8) Attempt to open the default context menu by right-clicking or ctrl-clicking. Event data will be captured. The context menu WILL be displayed. This is NOT correct. After this, any right-click (or ctrl-click) will cause the context menu to be displayed, regardless of whether or not the event is canceled. This will occur until the window is closed.
This bug was introduced sometime between revisions 18554 and 18597, with 18592 being suspect ("turned on webcore context menus").
Confirmed. I think I know how to fix this . . .
Created attachment 13329 [details] Clear the controller's context menu before sending the event through the DOM This problem appeared because of two facets of the current context menu design. First, all context menu events are now considered to be "swallowed" since we take care of building up the regular context menu through the defaultEventHandler(). Second, the context menu controller holds onto it's context menu until a new one is created. There would be logistical problems changing this since AppKit relies on the menu being around for as long as it is visible on the screen and we don't get any notification once the menu is popped-down. There are a few different ways to fix this problem, but I think this is simplest. This solution does not change either of the two thing described above. It just clears out the controller's context menu before a new event is propagated through the DOM.
Comment on attachment 13329 [details] Clear the controller's context menu before sending the event through the DOM + page->contextMenuController()->clearContextMenu(); It's probably worth a comment here saying why we have to do this. I wish we had a way to test this under DRT. r=me
Comment on attachment 13329 [details] Clear the controller's context menu before sending the event through the DOM You should also add the testcase as a manual test.
rdar://5017416
Fixed with r19810.