~grubng-dev/grubng/website

« back to all changes in this revision

Viewing changes to search/index-js.html

  • Committer: thindil
  • Date: 2011-06-13 08:32:31 UTC
  • Revision ID: thindil2@gmail.com-20110613083231-kxtupywcmb2fski3
moved search interface to separate branch

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
 
<html>
3
 
<head>
4
 
 
5
 
        <title>grub (alpha)</title>
6
 
        <script type="text/javascript" src="prototype.js"></script>
7
 
        <link rel="stylesheet" type="text/css" href="grub.css"/>
8
 
        <link rel="icon" href="images/grub.ico" type="image/x-icon">
9
 
<script type="text/javascript">
10
 
 
11
 
// sets focus in search field   
12
 
window.onload = init;
13
 
 
14
 
// semaphore to lock loading of further results to often
15
 
var sem = 0;
16
 
 
17
 
var coargs = new Array();
18
 
var cogc = new Array();
19
 
// TODO get these from a config file, depending from the user agent language
20
 
var loadingString = "Loading..."
21
 
var endString = "End"
22
 
var winheight; // the window height
23
 
 
24
 
// TODO center output for 0 search results
25
 
// TODO add some links like "download source", project site, how can I help, forum?, FAQ?
26
 
// TODO add a max count for search results to load, should be temporarely here for damage limitation reasons of bad JavaScript 
27
 
// TODO make this site use the GET method instead of post, so we can give search URLs away
28
 
// TODO add "more results" link to end of the site, if JS does not work properly
29
 
 
30
 
/*
31
 
* TODO
32
 
*/
33
 
function callOut(func, url, arg) {
34
 
        // non-blocking jsonp fetcher
35
 
        var i = document.createElement('iframe');
36
 
        cogc[cogc.length] = i; // garbage collector
37
 
        i.style.display = "none";
38
 
        document.getElementsByTagName('head')[0].appendChild(i);
39
 
        var doc = null;
40
 
        
41
 
        if (i.contentDocument) { // Firefox, Opera
42
 
                doc = i.contentDocument;
43
 
        } else if(i.contentWindow) { // Internet Explorer
44
 
                doc = i.contentWindow.document;
45
 
        } else if(i.document) { // Others?
46
 
                doc = i.document;
47
 
        }
48
 
        if(doc == null) {
49
 
                throw "Document not initialized";
50
 
        }
51
 
        coargs[coargs.length] = arg;
52
 
        doc.open();
53
 
        doc.write("<script type=\"text/javascript\">function "+func+"(j){parent."+func+"(parent.coargs["+(coargs.length-1)+"],j);parent.setTimeout('cocleanup("+(cogc.length-1)+")',1);}</scr"+"ipt>");
54
 
        doc.write("<script type=\"text/javascript\" src=\""+url+"\" defer=\"defer\"></scr"+"ipt>");
55
 
        doc.close();
56
 
}
57
 
 
58
 
/*
59
 
TODO
60
 
*/
61
 
function cocleanup(id){
62
 
        cogc[id].parentNode.removeChild(cogc[id]);
63
 
        cogc[id] = 0;
64
 
}
65
 
 
66
 
/*
67
 
TODO
68
 
*/
69
 
function comma(number) {
70
 
  
71
 
  number = '' + number;
72
 
  
73
 
  if (number.length > 3) {  
74
 
    var mod = number.length % 3;
75
 
    var output = (mod > 0 ? (number.substring(0,mod)) : '');
76
 
      
77
 
    for (i=0 ; i < Math.floor(number.length / 3); i++) {
78
 
      if ((mod == 0) && (i == 0)) {
79
 
        output += number.substring(mod+ 3 * i, mod + 3 * i + 3);
80
 
      } else {
81
 
        output+= ',' + number.substring(mod + 3 * i, mod + 3 * i + 3);
82
 
      }
83
 
    }
84
 
  return (output);
85
 
  }
86
 
  else return number;
87
 
}
88
 
 
89
 
/*
90
 
returns month or months depending on what's needed
91
 
*/
92
 
function plural(num, word){
93
 
        return word = (num != 1) ? word+"s" : word;
94
 
}
95
 
 
96
 
/*
97
 
FIXME Why do we need this method?
98
 
*/
99
 
function getspan(i) {
100
 
        return i;
101
 
        }
102
 
 
103
 
/*returns friendly time difference
104
 
TODO get all String from variables that catch the correct language version
105
 
*/
106
 
function whenAgo(t1, t2) {
107
 
        if(!t1 || !t2) return getspan("just now");
108
 
        var diff = t1 - t2;
109
 
        diff /= 1000;
110
 
        if(diff == 0) return getspan("just now");
111
 
        if(diff < 120) return getspan("moments ago");
112
 
        var months = Math.floor(diff / 2592000);
113
 
        if(months > 0) return months + " " + getspan(plural(months,"month")) + " " + getspan("ago");
114
 
        var days = Math.floor(diff / 86400);
115
 
        if(days > 0) return days + " " + getspan(plural(days,"day"))+" " + getspan("ago");
116
 
        var hours = Math.floor(diff / 3600);
117
 
        if(hours > 0) return hours + " " + getspan(plural(hours,"hour"))+" " + getspan("ago");
118
 
        var minutes = Math.floor(diff / 60);
119
 
        if(minutes > 0) return minutes + " " + getspan(plural(minutes, "minute")) + " "+getspan("ago");
120
 
}
121
 
 
122
 
/*
123
 
 * (re)calculates the window height and updates the variable winheight
124
 
 */
125
 
function calculateWinheight() {
126
 
        winheight = document.getElementById('results').offsetHeight;
127
 
}
128
 
 
129
 
/*
130
 
* detecs if we are at the end of the site and loads new results if true
131
 
*/
132
 
function isSiteEnd() {
133
 
        // determine scroll position
134
 
        var scrollTop = document.body.scrollTop;
135
 
        if (scrollTop == 0) {
136
 
        if (window.pageYOffset) {
137
 
                        scrollTop = window.pageYOffset;
138
 
                } else {
139
 
                        scrollTop = (document.body.parentElement) ? document.body.parentElement.scrollTop : 0;
140
 
                }
141
 
        }
142
 
        if (winheight - scrollTop < 1000) {
143
 
                // the semaphore prevents too many fetches
144
 
                if (sem == 1) {
145
 
                        return;
146
 
                } 
147
 
                sem = 1;
148
 
 
149
 
                var q = encodeURIComponent(document.forms[0].searchField.value);
150
 
                // fetch more search results
151
 
        callOut("scented", 
152
 
        "http://46.4.15.84:8080/solr/select?indent=on&version=2.2&q="+q+"&hl=true&hl.fl=body&hl.snippets=3&start="+nextres+"&rows=20&qt=dismax&debugQuery=on&wt=json&fl=url,ip,length,description,score,fetchedtime&json.wrf=scented",
153
 
        "");
154
 
        }
155
 
}
156
 
 
157
 
/*
158
 
* TODO
159
 
*/
160
 
var scents = new Object();
161
 
var doctitle = document.title;
162
 
 
163
 
/*
164
 
* submits search request to the server
165
 
*/
166
 
function smell() {
167
 
        // the semaphore prevents too many fetches
168
 
        if (sem == 1) {
169
 
                return;
170
 
        }
171
 
        sem = 1;
172
 
 
173
 
        scents = new Object();
174
 
        
175
 
        // show loading note
176
 
        $("loading").style.display = "block";
177
 
        
178
 
        var f = document.forms[0];
179
 
        var q = encodeURIComponent(f.searchField.value);
180
 
        callOut("scented", 
181
 
        "http://46.4.15.84:8080/solr/select?indent=on&version=2.2&q="+q+"&hl=true&hl.fl=body&hl.snippets=3&start=0&rows=20&qt=dismax&debugQuery=on&wt=json&fl=url,ip,length,description,score,fetchedtime&json.wrf=scented",
182
 
        "");
183
 
    document.title = doctitle + " - " + f.searchField.value;
184
 
        // FIXME does not seem to work properly
185
 
        // this is done to reset the scroll position of the user's browser on new searches
186
 
    scroll(0,0);
187
 
        // TODO decide to do this or not, pro: you can edit your seatch immidiately, con: you can not directly navigate using space 
188
 
    //f.searchField.blur();
189
 
        return false;
190
 
}
191
 
 
192
 
/*
193
 
prints the search results
194
 
*/
195
 
function scented(s, j) {
196
 
        /* hide loading note as it is completed now */
197
 
    $("loading").style.display = "none";
198
 
        var div = document.createElement("div");
199
 
        var now = new Date();
200
 
    var nowsecs = now.getTime();
201
 
    if (parseInt(j.responseHeader.params.start) == 0) {
202
 
                // show how much results we found
203
 
                // TODO get this translated and for plural and singular
204
 
        $("results").innerHTML = 
205
 
                                        "<h5>" + comma(j.response.numFound) + " results found for </h5>" + 
206
 
                                        "<h2>" + document.forms[0].searchField.value + "</h2>";
207
 
    }
208
 
 
209
 
        for(var i = 0; i < j.response.docs.length; i++) {
210
 
                var d = j.response.docs[i];
211
 
                var h = j.highlighting[d.url];
212
 
                var e = j.debug;
213
 
                var fetchdate = String(d.fetchedtime);
214
 
                var year = fetchdate.substr(0,4);
215
 
                var month = fetchdate.substr(4,2);
216
 
                var day = fetchdate.substr(6,2);
217
 
                var hour = fetchdate.substr(8,2);
218
 
                var minutes = fetchdate.substr(10,2);
219
 
                var seconds = fetchdate.substr(12);
220
 
                var sp = document.createElement("div");
221
 
        var fetchtime = new Date(year, (month - 1), day, hour, minutes, seconds, 0);
222
 
                var fetchtimesecs = fetchtime.getTime();
223
 
                var retrievetime = whenAgo(nowsecs, fetchtimesecs);
224
 
                sp.className="sr";
225
 
                var a = document.createElement("a");
226
 
                a.className = "title";
227
 
                // FIXME is there a limit for title length specified somewhere?
228
 
                a.title = d.description.substr(0,100);
229
 
                a.href = d.url;
230
 
                if (d.description.length > 50) {
231
 
                    a.innerHTML = d.description.substr(0,50) + "...";
232
 
        } else if (d.description.length == 0) {
233
 
            a.innerHTML = d.url;
234
 
        } else {
235
 
            a.innerHTML = d.description;
236
 
        }
237
 
                sp.appendChild(a);
238
 
                sp.innerHTML += "<br />"
239
 
                                
240
 
        var length = Math.ceil(d.length / 1024);
241
 
        var strbytes;
242
 
        if (length > 1024) {
243
 
            length = Math.ceil(d.length / 1024);
244
 
            strbytes = "MB";
245
 
        } else {
246
 
            strbytes = "kB";
247
 
        }
248
 
                sp.innerHTML += "<font color=\"#1a831c\"><strong class=\"info\">" + d.url + "<span> IP:" + d.ip + "</span></strong><strong> " + length + " " + strbytes + " (" + retrievetime + ")</strong></font><br />";
249
 
                var temp = 0;
250
 
                var explainscore;
251
 
                for (var urls in e.explain) {
252
 
                    if (temp == i) {
253
 
                        explainscore = e.explain[urls];
254
 
                        explainscore = explainscore.replace("\n", "<br />");
255
 
                    }
256
 
                    temp++;
257
 
                }
258
 
                sp.innerHTML += "<strong class=\"info\">Score: " + d.score + "<span>" + explainscore + "</span></strong>";
259
 
                if(h && h.body && h.body.length > 0) sp.innerHTML += "<br /> - " + h.body.join("...<br />...");
260
 
                div.appendChild(sp);
261
 
        }
262
 
    nextres = parseInt(j.responseHeader.params.rows) + parseInt(j.responseHeader.params.start);
263
 
    if (nextres < parseInt(j.response.numFound)) {
264
 
                // enable "polling" to see if user reached the site's end
265
 
            //var intervalid = setInterval( "howlow()" , 1000);
266
 
                var intervalid = setInterval( "isPrefetchNeeded()" , 1000);
267
 
    } else {
268
 
                // disable "polling" if there are no more results to fetch
269
 
            clearInterval(intervalid);
270
 
                // don't print "end" if no results were found
271
 
                if (parseInt(j.response.numFound) != 0) {
272
 
                        var sp2 = document.createElement("h3");
273
 
                        sp2.innerHTML = endString;
274
 
                }
275
 
                div.appendChild(sp2);
276
 
    }
277
 
        $("results").appendChild(div);
278
 
        // update the window height variable; needed to load new results when the bottom is reached
279
 
        calculateWinheight();
280
 
        // reset semaphore
281
 
        sem = 0;
282
 
}
283
 
 
284
 
/*
285
 
* sets focus to search field
286
 
*/
287
 
function init() {
288
 
        document.getElementById("searchFieldID").focus();
289
 
        // TODO read the GET arguments if there are any, write them here and start a search
290
 
        document.getElementById("searchFieldID").value = "";
291
 
         Event.observe(window, 'scroll', isSiteEnd);
292
 
}
293
 
 
294
 
</script>
295
 
</head>
296
 
 
297
 
<body>
298
 
    <div class="suma">
299
 
        <a href="http://suma-ev.de"><img src="images/sumalogo.jpg" alt="suma logo" title="suma logo" border="0"></a><br>
300
 
        This node is sponsored by <a href="http://suma-ev.de">SuMa e.V.</a>
301
 
    </div>
302
 
    <div class="grublogo"><img src="images/logo.png" alt="grub logo" title="grub logo"></div>
303
 
 
304
 
<!-- This shows the "loading..." note while fetching the results from the server -->
305
 
<div id="loading" class="loading">
306
 
    <strong>
307
 
    <script type="text/javascript">document.write(loadingString)</script>
308
 
    </strong><br />
309
 
    <img src="images/spinner.gif" border="0" alt="loading">
310
 
</div>
311
 
 
312
 
<!-- The input field for the search submit -->
313
 
<div id="top" class="searchField">
314
 
    <form action="javascript:" method="post" onsubmit="return smell()">
315
 
            <input name="searchField" id="searchFieldID"/>
316
 
        </form>
317
 
</div>
318
 
 
319
 
<!-- divs which include the single search results will go here -->
320
 
<div id="results" class="results"></div>
321
 
 
322
 
</body>
323
 
</html>