Some background to the problem: Reverse Engineering the DOM, Javascript events & "what's going on" ?
I'm writing something that will 'play' with the functionality of google's page preview on live search. Essentially, I'd like to add an event listener to the keyup event that will
- query the page preview results (send an ajax request to google)
- read that result in memory
- add it to your search page in realtime
This will essentially create a live page preview search result would of google.
To be fair, I've actually got about 95% of this working in various components and I'm at the stages of tweaking functionality to make it a bit more user friendly. If you're interested in the whys and hows of what I'm doing, please feel free to check out a my previous blog posts at http://chesser.ca or even look at the 'latest version of the code' at http://chesser.ca/gvs.marklet.0.3.js (currently very buggy as i'm a bit "between functionalities" at the moment.
The bookmarklet code for your browser is here:
javascript:(function{var head= document.getElementsByTagName('head')[0];var script= document.createElement('script');script.type= 'text/javascript';script.src= 'http://chesser.ca/gvs.marklet.0.3.js';head.appendChild(script);};)();
(the keyup event listener is currently set to off, essentially to make it work in its current state, you run a search on a page with live preview and click the bookmarklet once (to initiate queries), wait a second or two, then click it a second time (to display the page previews)
So I've got some changes to this to make:
In part 1 (for performance) I'm interested in only querying the first two elements. I imagine that will be easy and the only thing stopping me is that I haven't tried it yet (instead of all divs.length, just set it to 2)
function query_current_pages(){
var all_divs = document.getElementsByTagName('div');
for (i=0;i < all_divs.length; i++) {
if (all_divs[i].className == 'vsc') {
google.vs.ea(all_divs[i]);
}
}
}
The next problem (and the one that I'm a not sure about) is how I can set up an event listener and modify the add_previews function such that the previews are added when the request comes back, instead of the rather ham-fisted approach of looping through everything that is in the google.vs.ha
memory space rather I'd like to create something that will listen for the data to be there and then spring into action.
The reason i'm trying to do this is because I think it would be really really neat. That and I've learned a 'mountain' of stuff about coding while doing it.
For those interested in how the page previews get "chucked on the page" here's the function that loops through all the images in memory and put them up.
function add_previews(){
c=document.getElementById('ires');
nli=document.createElement('div');
cell = 0;
for(var Obj in google.vs.ha){
na=document.createElement('a');
na.href=Obj;
nd=document.createElement('div');
cldiv=document.createElement('div');
cldiv.style.clear = 'both';
nd.style.width=google.vs.ha[Obj].data.dim[0]+'px';
nd.style.height=google.vs.ha[Obj].data.dim[1]+'px';
nd.style.margin = '5px';
nd.style.padding = '5px';
nd.style.cssFloat = 'left';
nd.style.border = '1px solid #999999';
if (google.vs.ha[Obj].data.tbts.length) {
nilDiv = document.createElement('div');
for(i = 0; i < google.vs.ha[Obj].data.tbts.length; i++){
box = google.vs.ha[Obj].data.tbts[i].box;
newbox = document.createElement('div');
newbox.className = 'vsb vsbb';
newbox.style.position = 'relative';
newbox.style.top = (box.t)+'px';
newbox.style.left = box.l+'px';
newbox.style.height = box.h+'px';
newbox.style.width = box.w+'px';
nilDiv.appendChild(newbox);
newtext = document.createElement('div');
newtext.className = 'vsb vstb';
newtext.innerHTML = google.vs.ha[Obj].data.tbts[i].txt;
newtext.style.top = (box.t)+'px';
newtext.style.position = 'relative';
nilDiv.appendChild(newtext);
}
nilDiv.style.height = '0px';
nd.appendChild(nilDiv);
}
for(i = 0; i < google.vs.ha[Obj].data.ssegs.length; i++){
ni=document.createElement('img');
ni.src += google.vs.ha[Obj].data.ssegs[i];
ni.className+=' vsi';
na.appendChild(ni);
}
nd.appendChild(na);
nli.appendChild(nd);
};
c.insertBefore(nli,c.firstChild);
}
The obvious bit to change in there (with an event listener) is to fix for(var Obj in google.vs.ha){
to be a single google.vs.rs
object that is passed in.
If you've lasted this far into the question: thanks for reading :) - Alex
EDIT
As per the discussion below, google.vs.Ga seems to be responsible for querying the data (to which the answer is over-writing the function)
For informational purposes (and fun) here's the .Ga code.
google.vs.Ga = function (a, b, c) {
var d = google.vs.b.kfe.kfeHost,
g = google.vs.Ya(a),
i = a.getAttribute("sig");
if (i) {
var f = google.vs.qa(a);
if (f) {
d = [d ? "http://" + d : "", google.vs.b.kfe.kfeUrlPrefix, "&d=", encodeURIComponent(f), "&b=1", "&jsonp=google.vs.r"];
d.push("&a=");
d.push(encodeURIComponent(i));
if (i = a.getAttribute("blobref")) {
d.push("&bl=");
d.push(i)
}
d.push("&rs=");
i = 0;
for (var j; j = g[i++];) {
d.push(encodeURIComponent(j));
i < g.length && d.push("&rs=")
}
g = google.vs.m(a) || {
ub: a
};
g.G = c;
google.vs.ha[f] = g;
c = d.join("");
c = new google.vs.Ia(f, c, function () {
google.vs.P(a, h);
o(google.vs.k, f)
});
b ? p(google.vs.k, c) : q(google.vs.k, c)
}
}
};