Selecting content with getSelection

Talk about add-ons and extension development.
Post Reply
Lumox
Posts: 27
Joined: November 25th, 2007, 11:12 pm

Selecting content with getSelection

Post by Lumox »

My legacy XUL add-on "Save Images" is dying a slow death with the changes that are occurring to Firefox but I am trying to keep it going as long as possible. And with the reduced API functionality in WebExtensions, I will not be able to port it over.

One of the features I use is to check if content is selected and to retrieve the links in the selected content. I used to use

Code: Select all

document.commandDispatcher.focusedWindow.getSelection();
but that no longer works so I tried to change over to

Code: Select all

window.getSelection();
which is supposed to be the latest method, but I get nothing back.

I have been testing with Firefox v51.0.1 32 bit and developer edition v53.0a2 and they both fail to return any selected content.
Running the following in Scratchpad

Code: Select all

console.log(window.getSelection());
or the following in the Browser Console

Code: Select all

window.getSelection();
I get the following output

Code: Select all

Selection { anchorNode: null, anchorOffset: 0, focusNode: null, focusOffset: 0, isCollapsed: true, rangeCount: 0, caretBidiLevel: null, interlinePosition: false, type: 1 }
And yet if I look in the Web Developer Web Console, there is the following output (content selected in Wikipedia)

Code: Select all

Selection { anchorNode: #text " on Rodrigues. Around 40 centimetres (16 in) long, Newton's parakeet was roughly the size of the ", anchorOffset: 43, focusNode: #text " in 1708, and was mentioned only a few times by other writers. The bird became scarce due to deforestation and perhaps hunting, and was probably wiped out by a series of ", focusOffset: 9, isCollapsed: false, rangeCount: 1, caretBidiLevel: 0 }
So it appears to function, but not in my add-on.

Trying it in Firefox v47.0.2, everything works correctly.

Could someone please advise as to how to get this working correctly.
lithopsian
Posts: 3664
Joined: September 15th, 2010, 9:03 am

Re: Selecting content with getSelection

Post by lithopsian »

You are almost certainly hitting multiprocess issues. Your addon (by default) runs in chrome and the content is in an entirely different process. There are automatic shims that allow synchronous access to properties of objects in the content process as if they were local javascript objects. They are disabled if you set the multiprocess compatible flag in your install manifest. Then everything you try to access in content will just be null instead.

window (I assume the content window) is an object in the content process. It is replicated in the chrome process, for example as a property of several chrome objects, but its properties are not local javascript objects. So getSelection() is a function in the content process. With the compatible flag not set, that is not even in the manifest, getSelection should be a shim that behaves like calling a javascript function but actually performs synchronous inter-process messaging for you, returning the selection object. Slow but effective. And of course synchronous IO is necessary in many cases such as inside a popup handler.

The "full" solution is to implement a frame script which runs in the content process, accesses what you need from content, and communicates with the rest of your addon using the message manager. Given that your addon is dead in a few months time, you might want a more quick-and-dirty fix?

If you are doing this inside the global content context menu, then there is a selectionInfo object already populated for your convenience on gContextMenuContentData. Is that any use?
Lumox
Posts: 27
Joined: November 25th, 2007, 11:12 pm

Re: Selecting content with getSelection

Post by Lumox »

Thanks for the quick reply lithopsian.
Unfortunately, gContextMenuContentData only gets populated if the context menu is used. My add-on also has popup menus for a toolbar button and from Firefox's main menu system which then can't use gContextMenuContentData selectionInfo object. I also need to use the function containsNode but can't get this to work using the returned selectionInfo object.

I will look at using frame script messages and window.getSelection(), but I don't know if it is worth the effort.
Post Reply