mortalis
mortalis

Reputation: 2151

Change found text highlight in a Firefox extension

I'm developing an extension for Firefox which searches terms in a page. And I'd like to change found text highlight color and background. For example, I search for a letter "s" and by default it's selected with a blue rectangle with white text color. So I want to change the blue to the red. How could I do this via JS?

Edit0:

To select a found text I use document.createRange() and selection.addRange() methods.
I don't know how the default finder selects a found term and applies background to it.
So maybe the 'range' method is not the best.
But I think I'm searching a way to highlight this created range...

Edit1:

Now I've partially resolved the color-changing preoblem. Just add a CSS rule with ::-moz-selection and red background when a text is found and selected. Then for document 'onmousedown' I remove this rule not to leave the default selection as red.

But a new problem is when I find say a digit and it gets a selection the background of that selection is gray (so it looks like a text selection of an inactive window). Then when I click with my mouse somewhere in the document text and press F3 the extension finds the next digit and selects it with the red background. And next findings work right (with red background).

So my purpose is change that initial gray background to red.
Maybe I should change the inactive selection color...

Edit2:

Now I updated my JS code:

var selection=w.getSelection()
var range=w.document.createRange()
range.setStart(foundNode,foundOffset)
range.setEnd(foundNode,foundOffset+foundLength)
selection.removeAllRanges()
selection.addRange(range)

var controller=gBrowser.docShell.QueryInterface(Ci.nsIInterfaceRequestor)
               .getInterface(Ci.nsISelectionDisplay)
               .QueryInterface(Ci.nsISelectionController);

controller.setDisplaySelection(controller.SELECTION_ATTENTION)
controller.repaintSelection(controller.SELECTION_NORMAL)

Thanks to Noitidart's answer I found some information on how to use nsISelectionController XPCOM interface to select found text with background. Still I can't set a custom color for this background so that it be different from the default color of found text in Firefox. But setting the ui.textSelectBackgroundAttention preference in about:config to desired color will work with both my extension and default find engine.

I've found that SELECTION_ATTENTION constant is responsible for that background color and the setDisplaySelection method links the color to the selected text. But I couldn't find any implementation of this method. I saw only nsISelectionController idl file with its structure but no correspondent .cpp or .js file implementing this .idl. So I don't have information on how the color is set.

Edit3:

Recently I added the "Highlight All" functionality to my extension. And a new question about color of this highlight has rised. Using the above tecnique will show all the matches with green find color (by default). But it's more comfortable to use a different color to distinguish the current match and others.

So I couldn't find another helpful nsISelectionController constant for the "Highlight All" selection. I simply set this selection to 'DISABLED' type and changed the ui.textSelectBackgroundDisabled about:config pref. This pref is obviously for the selected text background of an inactive window. And it worked for me.

controller.setDisplaySelection(controller.SELECTION_DISABLED)

Another thing is that I'm not sure that the controller.repaintSelection() in the previous Edit is necessary. I guess the selection didn't work without it when I started my experiments with this stuff. But now I removed that line and all still work.

Plus:

And some additional links if somebody will need:

Also I used some files from Firefox source archive: Firefox 33 Source:

 - nsISelectionController.idl          [\content\base\public\]
 - nsTypeAheadFind.cpp                 [\toolkit\components\typeaheadfind\]
 - Finder.jsm                          [\toolkit\modules\]
 - findbar.xml                         [\toolkit\content\widgets\]

Upvotes: 3

Views: 1629

Answers (1)

Noitidart
Noitidart

Reputation: 37238

I asked this question to quicksilver via email and this is what he told me:

You might find this one helpful: https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsISelectionController

I'm hardly the master you think I am, actually. :) To change those colors I just change the values for preferences:

ui.textHighlightBackground

ui.textHighlightForeground

ui.textSelectBackgroundAttention -> SELECTION_ATTENTION, it's not a highlight, it's a normal selection (as you would select some text with your mouse and it would turn the regular blue blackground, in windows at least) but it's given "attention", so it has the green background that the find operation reports. Basically it's a way of showing the user "Here I am!!" after firefox automatically selecs the text he searched for.

And I really don't know most of those contants, SELECTION_NORMAL is for normal text selection, like it would be when you select text with your mouse, SELECTION_FIND is for the highlights, and I only know the ON/HIDDEN/OFF/DISABLED ones which are self-explanatory. SELECTION_SPELLCHECK is probably for the auto-correct when you are typing in an editable content node, but I'm just guessing that one from the name.

Also, as far as I know, it's not possible to just create custom selection ranges/contants, as the code simply won't recognize them without editing the C++ code as well. Which is actually one of the reasons I haven't implemented https://github.com/Quicksaver/FindBar-Tweak/issues/76 yet.

Upvotes: 1

Related Questions