function contextMenuAction(info, tab) { switch (info.menuItemId) { case "1 Host Connect": browser.tabs.create({index: 1,url: "xyz://"+info.selectionText.trim()+"/"}); break; } }
That works well and as expected. Now I want to achieve the same thing with a shortcut using commands.
So I defined ALT+1 for the above context menu point action. But I’m having troubles making it work, passing the same information as with browser.contextMenus.onClicked.addListener(contextMenuAction), meaning tab,info.
How can I achieve the same result uPreformatted textsing commands? Doing something like this doesn’t work since info and tab are not defined:
function HotkeyContextMenuAction(info, tab) { browser.tabs.create({index: 1,url: "xyz://"+info.selectionText.trim()+"/"}); }
You can get the currently focused tab using the browser.tabs API, since that’s likely the tab the shortcut should be executed in. To get the selected text you will have to inject a script that gets the text and returns it to you. browser.tabs.execScript should be fine for that. You’ll also need the activeTab permission to do that easily.
Ok… So it actually does works just not where I need it to work!
If I execute the code via shortcut on a regular html page it works fine, the string is shown.
But I’ll be using the extension with an icinga2 (https://github.com/Icinga/icinga2) webpage. That’s where I was testing it before and there it doesn’t work!! Don’t know why though…
Maybe you guys have an idea???
I hinted at this before, but are you making the text selection in the same frame that you call window.getSelection().toString() in? If not, the returned string is expected to be empty.
Also, console.log() acceprs variable arguments and logs them all, you shouldn’t explicitly + them, which casts everything to strings (at least if one of them is a string).
Gosh… this was (for me) so much easier with SDK. The extension worked well without having to worry about different frames, code injection and all that.
So let me try to understand this…
A html page can have multiple frames… Top and child frames.
The shortcut and its selection works on a regular html page because it doesn’t have child frames… there is just a top frame!?
However, on my icinga page there are child frames, so making the selection on the same frame (the top frame?) would return an empty string because the actual selection is on a child frame?
How can I access those child frames?
I read that content scripts can be injected into all frames using something like:
Yes, that is a pretty precise description for a possible, and given the type of page you are working on I think likely, cause of what you encounter here.
How can I access those child frames?
You want to access the selected text in the background page, right?
Haven’t tested it, but this should work:
const pageSelection = (await Promise.all(
(await browser.webNavigation.getAllFrames({ tabId, }))
.map(({ frameId, }) =>
browser.tabs.executeScript(tabId, { frameId, code: `window.getSelection().toString()`, })
.catch(_ => '') //in production, avoid weird errors about uninitialized frames and stuff like that, but when debugging empty selection texts again, comment this line
)
)).reduce((a, b) => a || b, '') || '';
You wouldn’t want static content_scripts in the manifest for this.
Hi Niklas thank you once again!! I’m not getting an syntax errors anymore… but everything after const pageSelection doesn’t seem to fire…
If I simply implement a console.log('End host connect');
for // use pageSelection
I’ll get nothing in the console… noerror either. Any idea?