Selecting text on a page causes a search button to pop up. It might be non-annoying enough to be useful.
Update: Turns out that Firebird has this same feature built in. Select some text, and right-click on the selection. One of the menu options is "web search." Dang, I'm dumb for not realizing this.
GWhen you select any text on this page, a little G should appear near the mouse cursor.
Click it to open up a Google search window for the selected text. All the javascript is in the source of this page. Some explanation is given below.
It is not the critic who counts,
not the man who points out how the strong man stumbled,
or where the doer of deeds could have done them better.
The credit belongs to the man who is actually in the arena;
whose face is marred by dust and sweat and blood;who strives valiantly;
who errs and comes short again and again;
who knows the great enthusiasms, the great devotions,
and spends himself in a worthy cause;
who, at the best knows the triumph of high achievement;
and who, at the worst, if he fails, at least fails while daring greatly,
so that his place shall never be with those cold and timid souls
who know neither victory nor defeat.
I first saw something like this at astrobio.net. I don't know who the original author is. The little "G" popup box is my own creation.
The version at astrobio.net opens up a search window automatically, with each selection. It also tries to do some intelligent filtering, to block very small or very large selections. But the filtering was pretty crude. Worse, it was annoying because I didn't want a search every time I selected something.
There needed to be some way to quickly trigger a search. Thus, the little "G" box. It's a stab at balancing the utility of quick search access against the distraction of interface clutter.
Right now, the little "G" box appears under the mouse cursor when the selection is completed. I wanted it to appear at the lower-right corner of the selection, but there doesn't appear to be a simple way to do this. There may be complicated ways. I tried a few.
IE uses the textrange object to provide bounding boxes for text selections. But it can't pinpoint the end of a selection, just the rightmost boundary. So if the selection were multiple lines, the box would appear at the far right of the longest line, not at the end of the highlighted text.
Mozilla uses the range object, and it doesn't automatically provide bounding boxes. It seems to give an entry point into the DOM tree, which a script can (hopefully?) use to calculate the text selection endpoint from the lower-level DOM node properties. Boy, that sounds like a ton of fun.
The first ingredient is a little "G" box:
<a id="g_box"
class="g_box"
style="position:absolute;visibility:hidden;"
href="javascript:google_search();"
onmouseover="google_search_mouseover_status();return true;"
onmouseout="window.status = 'Done';">
G
</a>
We also need to style the little "G" box:
a.g_box {
display:block;
margin:1px;
padding:1px;
color: #0000ff;
border: solid 1px;
background-color:#ffffff;
border-color: #00ff00 #ff0000 #00ff00 #0000ff;
font-family:Garamond,serif;
font-size:9pt;
font-weight:bold;
line-height:90%;
text-decoration:none;
z-index:1000;
}
When styled, it looks like: G
Notice that it's a link to javascript:google_search(). More about that function later.
The inline style is set to style="position:absolute;visibility:hidden;"
So it's actually invisible.
It's only going to become visible after the user makes a selection. For that, we need to detect mouseup and mousedown.
if (window.Event) {
document.captureEvents(Event.MOUSEUP);
document.captureEvents(Event.MOUSEDOWN);
}
document.onmouseup = mouseup;
document.onmousedown = mousedown;
function mousedown(e)
{
update_mouse_coords(e);
setTimeout('g_box_hide()',10); // hide the "G" after 10 ms.
// Doing it right away makes things not behave right (try it and see).
}
function mouseup(e)
{
update_mouse_coords(e); // get current mouse coordinates
var str = get_selection(); // see what's selected
if (str.length == 0) return; // if nothing is selected return
setTimeout('g_box_show()',10); // display a little "G" in 10 ms
// Doing it right away makes things not behave right (try it and see).
}
And when we detect mouseup and mousedown, we hide or show the box:
function g_box_hide()
{
var str = get_selection();
if (str.length != 0) return; // if nothing is selected
var g_box = document.getElementById("g_box");
g_box.style.visibility = "hidden";
}
function g_box_show()
{
var g_box = document.getElementById("g_box");
if (g_box.style.visibility == "visible") return;
if (window.getSelection) // Moz
{
g_box.style.left = mouse_x;
g_box.style.top = mouse_y;
}
else if (document.selection && document.selection.createRange) // IE
{
g_box.style.left = mouse_x;
g_box.style.top = mouse_y;
// experimental stuff for using IE textrange to put
// the G box at the end of the selection
//var range = document.selection.createRange();
//var corner_x=range.boundingLeft+range.boundingWidth;
//var corner_y=range.boundingTop+range.boundingHeight;
//alert("corner x: "+corner_x+" corner y: "+corner_y);
//g_box.style.left = corner_x;
//g_box.style.top = corner_y;
}
g_box.style.visibility = "visible";
}
Of course, we should figure out where to put the thing first.
function update_mouse_coords(e)
{
if (window.getSelection) { // Moz
mouse_x=e.layerX;
mouse_y=e.layerY;
} else if (document.selection && document.selection.createRange) { // IE
mouse_x=window.event.clientX+document.body.scrollLeft-4;
mouse_y=window.event.clientY+document.body.scrollTop-4;
} else { // out-of-luck below v.4
var str = "";
//alert("Sorry, event capture is not possible with your browser.");
return;
}
}
Actually doing the search is the easy part:
function google_search()
{
var target='http://www.google.com/search?hl=en&ie=UTF-8&q=';
var str = get_selection();
self.name = "body";
msgWindow = window.open(target + str, "displayWindow", "location=yes,menubar=yes,toolbar=yes,scrollbars=yes,resizable=yes,height=480,width=500,screenX=0,left=0,screenY=0,top=0");
}
function get_selection()
{
var str = new String("");
if (window.getSelection) // Moz
{
str = window.getSelection().toString();
}
else if (document.selection && document.selection.createRange) // IE
{
var range = document.selection.createRange();
str = range.text.toString();
}
else // out-of-luck below v.4
{
//alert("Sorry, event capture is not possible with your browser.");
}
// remove non-alphanumeric stuff from the string
str = str.replace(/[^a-zA-Z 0-9]+/g,'');
return str;
}
For consistency, we make the link show some information in the status bar when the cursor is over it.
function google_search_mouseover_status() // my_function_name_is_longer_than_your_function_name_ha_ha
{
var str = get_selection();
window.status = "Google search for \""+str+"\"";
return true;
}
Nice code, is there any way to stop an inverted comma within the selection truncating it? I assume you'd have to do this before the toString() method is used.