La creazione del menu di scelta rapida dinamico in Chrome Extension non funziona

Sto cercando di creare voci nel menu di scelta rapida di Chrome in base a ciò che è selezionato. Ho trovato diverse domande su StackOverflow, e per tutti loro la risposta è: utilizzare uno script di contenuto con un listener “mousedown” che guarda la selezione corrente e crea il menu di scelta rapida.

L’ho implementato, ma non sempre funziona. A volte tutti i messaggi di log dicono che il menu di scelta rapida è stato modificato come volevo, ma il menu di scelta rapida che appare non viene aggiornato.

Sulla base di questo ho sospettato che fosse una condizione di competizione: a volte chrome avvia il rendering del menu di scelta rapida prima che il codice fosse eseguito completamente.

Ho provato ad aggiungere un eventListener a “contextmenu” e “mouseup”. Il trigger successivo si verifica quando l’utente seleziona il testo con il mouse, quindi cambia il menu di contesto molto prima che venga visualizzato (anche in secondi). Anche con questa tecnica, vedo ancora lo stesso errore!

Ciò accade molto spesso in Chrome 22.0.1229.94 (Mac), occasionalmente in Chromium 20.0.1132.47 (linux) e non è successo in 2 minuti con Windows (Chrome 22.0.1229.94).

    Cosa sta succedendo esattamente? Come posso ripararlo? C’è qualche altra soluzione?


    Ecco una versione semplificata del mio codice (non così semplice perché sto mantenendo i messaggi di registro):

    manifest.json:

    { "name": "Test", "version": "0.1", "permissions": ["contextMenus"], "content_scripts": [{ "matches": ["http://*/*", "https://*/*"], "js": ["content_script.js"] }], "background": { "scripts": ["background.js"] }, "manifest_version": 2 } 

    content_script.js

     function loadContextMenu() { var selection = window.getSelection().toString().trim(); chrome.extension.sendMessage({request: 'loadContextMenu', selection: selection}, function (response) { console.log('sendMessage callback'); }); } document.addEventListener('mousedown', function(event){ if (event.button == 2) { loadContextMenu(); } }, true); 

    background.js

     function SelectionType(str) { if (str.match("^[0-9]+$")) return "number"; else if (str.match("^[az]+$")) return "lowercase string"; else return "other"; } chrome.extension.onMessage.addListener(function(msg, sender, sendResponse) { console.log("msg.request = " + msg.request); if (msg.request == "loadContextMenu") { var type = SelectionType(msg.selection); console.log("selection = " + msg.selection + ", type = " + type); if (type == "number" || type == "lowercase string") { console.log("Creating context menu with title = " + type); chrome.contextMenus.removeAll(function() { console.log("contextMenus.removeAll callback"); chrome.contextMenus.create( {"title": type, "contexts": ["selection"], "onclick": function(info, tab) {alert(1);}}, function() { console.log("ContextMenu.create callback! Error? " + chrome.extension.lastError);}); }); } else { console.log("Removing context menu") chrome.contextMenus.removeAll(function() { console.log("contextMenus.removeAll callback"); }); } console.log("handling message 'loadContextMenu' done."); } sendResponse({}); });