0

I have some code that updates a context menu when a selection is made. My content code is:

document.addEventListener('selectionchange', function() {
    var selection = window.getSelection().toString().trim();
    chrome.runtime.sendMessage({
        request: 'selectionChanged',
        selection: selection
    });
});

and the background code catches the message and updates the context menu.

This works fine if I select text by using the left-mouse button (drag to highlight, double click, etc) and then bringing up the context menu, but does not work if I right-click on a word that is not already highlighted. From what I can tell the problem is that the context menu is brought up before the selection change message is handled and the menu updated.

How can I update the context menu with the right-click selection before the menu is displayed?

  • how do you get selection without event?... switching to a tab with already selected text? maybe you should listen for that and on every activated tab test if there is an selection already. But it looks to me like overkill. Simply leave it like that and user should select text again in those situations. – Wolf War Mar 18 '16 at 14:04
  • @Wolf the selection happens whenever the user right-clicks on an item, but the menu appears before the selection event is processed which is why the menu does not have the correct information. –  Mar 18 '16 at 14:10
  • 1
    Do you really need to programmatically update the menu? If you want to include the selection in the menu text you can use `%s`. – rsanchez Mar 18 '16 at 15:26
  • yes, that's how it goes. contextMenu item must be prepared, because there is no time in moment of menu creation to update it – Wolf War Mar 18 '16 at 15:27
  • you updating your menu on *selectionChange*. And it works fine (no menu triggered yet). But when there is already selection, there is no update – Wolf War Mar 18 '16 at 15:29
  • @rsanchez I was hoping for more control over the text rather than just putting the selection directly in to the menu item, but this might be the closest that can be managed. Looks like bug crbug.com/60758 is related to this and still open. –  Mar 18 '16 at 15:54
  • @wolf it looks like the bug I referenced in the earlier comment is the root cause of the problem, where there is no way of synchronously providing updates prior to the context menu being shown. –  Mar 18 '16 at 16:06
  • @jgm Did you ever manage to get this working? I'm looking to do something very similar, not only including the highlighted text in the context menu but also another string derived from the highlighted word... – Mark Stickley Apr 18 '19 at 20:54

1 Answers1

0

Simply have an interval running and checking for a change in the selection using window.getSelection().toString().trim() instead.

Here's a rough example of what I mean:

var selection="";
setInterval(function(){
    if(selection!=window.getSelection().toString().trim()){
        selection=window.getSelection().toString().trim();
        chrome.runtime.sendMessage({
            request: 'selectionChanged',
            selection: selection
        });
    }
},500);

optionally you could do what this guy suggested: Javascript: How to detect if a word is highlighted

Community
  • 1
  • 1
Marc Guiselin
  • 3,442
  • 2
  • 25
  • 37
  • Thanks for the answer. Unfortunately neither of these ideas appear to work because the menu is generated as soon as the right-click occurs, which means that although the menu is updated the updates do not show until the next time the menu is displayed. –  Mar 18 '16 at 14:11
  • @jgm Sorry, I guess I misunderstood what you asked. – Marc Guiselin Mar 18 '16 at 16:23