Whamcloud - gitweb
LUDOC-120 presentation: build bits for webhelp.
[doc/manual.git] / webhelp / template / search / nwSearchFnt.js
1 /*----------------------------------------------------------------------------\r
2  * JavaScript for webhelp search\r
3  *----------------------------------------------------------------------------\r
4  This file is part of the webhelpsearch plugin for DocBook WebHelp\r
5  Copyright (c) 2007-2008 NexWave Solutions All Rights Reserved.\r
6  www.nexwave.biz Nadege Quaine\r
7  http://kasunbg.blogspot.com/ Kasun Gajasinghe\r
8  */\r
9 \r
10 //string initialization\r
11 var htmlfileList = "htmlFileInfoList.js";\r
12 var htmlfileinfoList = "htmlFileInfoList.js";\r
13 var useCJKTokenizing = false;\r
14 \r
15 var w = new Object();\r
16 var scoring = new Object();\r
17 \r
18 var searchTextField = '';\r
19 var no = 0;\r
20 var noWords = 0;\r
21 var partialSearch = "<font class=\"highlightText\">There is no page containing all the search terms.<br>Partial results:</font>";\r
22 var warningMsg = '<div style="padding: 5px;margin-right:5px;;background-color:#FFFF00;">';\r
23 warningMsg+='<b>Please note that due to security settings, Google Chrome does not highlight';\r
24 warningMsg+=' the search results in the right frame.</b><br>';\r
25 warningMsg+='This happens only when the WebHelp files are loaded from the local file system.<br>';\r
26 warningMsg+='Workarounds:';\r
27 warningMsg+='<ul>';\r
28 warningMsg+='<li>Try using another web browser.</li>';\r
29 warningMsg+='<li>Deploy the WebHelp files on a web server.</li>';\r
30 warningMsg+='</div>';\r
31 txt_filesfound = 'Results';\r
32 txt_enter_at_least_1_char = "You must enter at least one character.";\r
33 txt_enter_more_than_10_words = "Only first 10 words will be processed.";\r
34 txt_browser_not_supported = "Your browser is not supported. Use of Mozilla Firefox is recommended.";\r
35 txt_please_wait = "Please wait. Search in progress...";\r
36 txt_results_for = "Results for: ";\r
37 \r
38 /* This function verify the validity of search input by the user\r
39   Cette fonction verifie la validite de la recherche entrre par l utilisateur */\r
40 function Verifie(searchForm) {\r
41 \r
42     // Check browser compatibility\r
43     if (navigator.userAgent.indexOf("Konquerer") > -1) {\r
44 \r
45         alert(txt_browser_not_supported);\r
46         return;\r
47     }\r
48 \r
49     searchTextField = trim(document.searchForm.textToSearch.value);\r
50     searchTextField = searchTextField.replace(/['"]/g,'');\r
51         var expressionInput = searchTextField;\r
52     $.cookie('textToSearch', expressionInput);\r
53 \r
54     if (expressionInput.length < 1) {\r
55 \r
56         // expression is invalid\r
57         alert(txt_enter_at_least_1_char);\r
58         // reactive la fenetre de search (utile car cadres)\r
59 \r
60         document.searchForm.textToSearch.focus();\r
61     }\r
62     else {\r
63     var splitSpace = searchTextField.split(" ");\r
64        var splitWords = [];\r
65         for (var i = 0 ; i < splitSpace.length ; i++) {     \r
66           var splitDot = splitSpace[i].split(".");\r
67           \r
68           if(!(splitDot.length == 1)){\r
69             splitWords.push(splitSpace[i]);\r
70           }\r
71           \r
72           for (var i1 = 0; i1 < splitDot.length; i1++) {\r
73                var splitColon = splitDot[i1].split(":");\r
74             for (var i2 = 0; i2 < splitColon.length; i2++) {\r
75                 var splitDash = splitColon[i2].split("-");\r
76                  for (var i3 = 0; i3 < splitDash.length; i3++) {\r
77                      if (splitDash[i3].split("").length > 0) {\r
78                            splitWords.push(splitDash[i3]);\r
79                        }\r
80                  }\r
81             }\r
82           }\r
83        }\r
84        noWords = splitWords;\r
85         if (noWords.length > 9){\r
86           // Allow to search maximum 10 words\r
87                 alert(txt_enter_more_than_10_words);\r
88                 expressionInput = '';\r
89                 for (var x = 0 ; x < 10 ; x++){\r
90                         expressionInput = expressionInput + " " + noWords[x]; \r
91                 }               \r
92                 Effectuer_recherche(expressionInput);\r
93                 document.searchForm.textToSearch.focus();\r
94         } else {\r
95                 // Effectuer la recherche\r
96              expressionInput = '';\r
97           for (var x = 0 ; x < noWords.length ; x++) {\r
98                  expressionInput = expressionInput + " " + noWords[x]; \r
99              }\r
100                 Effectuer_recherche(expressionInput);\r
101                 // reactive la fenetre de search (utile car cadres)\r
102                 document.searchForm.textToSearch.focus();        \r
103         }\r
104     }\r
105 }\r
106 \r
107 var stemQueryMap = new Array();  // A hashtable which maps stems to query words\r
108 \r
109 /* This function parses the search expression, loads the indices and displays the results*/\r
110 function Effectuer_recherche(expressionInput) {\r
111 \r
112     /* Display a waiting message */\r
113     //DisplayWaitingMessage();\r
114 \r
115     /*data initialisation*/\r
116     var searchFor = "";       // expression en lowercase et sans les caracte    res speciaux\r
117     //w = new Object();  // hashtable, key=word, value = list of the index of the html files\r
118     scriptLetterTab = new Scriptfirstchar(); // Array containing the first letter of each word to look for\r
119     var wordsList = new Array(); // Array with the words to look for\r
120     var finalWordsList = new Array(); // Array with the words to look for after removing spaces\r
121     var linkTab = new Array();\r
122     var fileAndWordList = new Array();\r
123     var txt_wordsnotfound = "";\r
124 \r
125 \r
126     // --------------------------------------\r
127     // Begin Thu's patch \r
128     /*nqu: expressionInput, la recherche est lower cased, plus remplacement des char speciaux*/\r
129     //The original replacement expression is: \r
130     //searchFor = expressionInput.toLowerCase().replace(/<\//g, "_st_").replace(/\$_/g, "_di_").replace(/\.|%2C|%3B|%21|%3A|@|\/|\*/g, " ").replace(/(%20)+/g, " ").replace(/_st_/g, "</").replace(/_di_/g, "%24_");\r
131     //The above expression was error prone because it did not deal with words that have a . as part of the word correctly, for example, document.txt\r
132     \r
133     //Do not automatically replace a . with a space\r
134     searchFor = expressionInput.toLowerCase().replace(/<\//g, "_st_").replace(/\$_/g, "_di_").replace(/%2C|%3B|%21|%3A|@|\/|\*/g, " ").replace(/(%20)+/g, " ").replace(/_st_/g, "</").replace(/_di_/g, "%24_");\r
135     \r
136     //If it ends with a period, replace it with a space\r
137     searchFor = searchFor.replace(/[.]$/,"");\r
138     // End Thu's Patch\r
139     // ------------------------------------------\r
140 \r
141     searchFor = searchFor.replace(/  +/g, " ");\r
142     searchFor = searchFor.replace(/ $/, "").replace(/^ /, "");\r
143 \r
144     wordsList = searchFor.split(" ");\r
145     wordsList.sort();\r
146 \r
147     //set the tokenizing method\r
148     useCJKTokenizing = typeof indexerLanguage != "undefined" && (indexerLanguage == "zh" || indexerLanguage == "ja" || indexerLanguage == "ko");\r
149     //If Lucene CJKTokenizer was used as the indexer, then useCJKTokenizing will be true. Else, do normal tokenizing.\r
150     // 2-gram tokenizinghappens in CJKTokenizing, \r
151     //If doStem then make tokenize with Stemmer\r
152     var finalArray;\r
153     if (doStem){\r
154             if(useCJKTokenizing){\r
155                 finalWordsList = cjkTokenize(wordsList);\r
156           finalArray = finalWordsList;\r
157             } else { \r
158                 finalWordsList = tokenize(wordsList);\r
159           finalArray = finalWordsList;\r
160             }\r
161     } else if(useCJKTokenizing){\r
162           finalWordsList = cjkTokenize(wordsList);\r
163           finalArray = finalWordsList;\r
164          } else{\r
165 \r
166     //load the scripts with the indices: the following lines do not work on the server. To be corrected\r
167     /*if (IEBrowser) {\r
168      scriptsarray = loadTheIndexScripts (scriptLetterTab);\r
169      } */\r
170 \r
171     /**\r
172      * Compare with the indexed words (in the w[] array), and push words that are in it to tempTab.\r
173      */\r
174     var tempTab = new Array();\r
175         \r
176     // ---------------------------------------\r
177     // Thu's patch\r
178     //Do not use associative array in for loop, for example:\r
179     //for(var t in finalWordsList)\r
180     //it causes errors when finalWordList contains \r
181     //stemmed words such as: kei from the stemmed word: key\r
182     for(var t=0;t<finalWordsList.length;++t){\r
183         var aWord=finalWordsList[t];\r
184         //w is a Map like Object, use the current word in finalWordList as the key\r
185         if(w[aWord] == undefined){\r
186             txt_wordsnotfound += aWord + " ";\r
187                 }\r
188         else{\r
189             tempTab.push(aWord);\r
190                 }\r
191         }\r
192         finalWordsList = tempTab;               \r
193     //Check all the inputs to see if the root words are in the finalWordsList, if not add them there\r
194     var inputs = expressionInput.split(' ');\r
195     // Thu's Patch \r
196     // -------------------------------------------\r
197 \r
198     \r
199     txt_wordsnotfound = expressionInput;\r
200         finalWordsList = removeDuplicate(finalWordsList);\r
201     \r
202    }\r
203     if (finalWordsList.length) {\r
204       //search 'and' and 'or' one time\r
205       fileAndWordList = SortResults(finalWordsList);\r
206       \r
207       if (fileAndWordList == undefined){\r
208                 var cpt = 0;\r
209       } else {\r
210           var cpt = fileAndWordList.length;\r
211                   var maxNumberOfWords = fileAndWordList[0][0].motsnb;\r
212       }\r
213           if (cpt > 0){\r
214                 var searchedWords = noWords.length;\r
215                 var foundedWords  = fileAndWordList[0][0].motslisteDisplay.split(",").length;\r
216                 //console.info("search : " + noWords.length + "   found : " + fileAndWordList[0][0].motslisteDisplay.split(",").length);\r
217                 if (searchedWords != foundedWords){\r
218                         linkTab.push(partialSearch);\r
219                 }\r
220           }\r
221           \r
222       \r
223       for (var i = 0; i < cpt; i++) {\r
224                         \r
225                         var hundredProcent = fileAndWordList[i][0].scoring + 100 * fileAndWordList[i][0].motsnb;\r
226                         var ttScore_first = fileAndWordList[i][0].scoring;\r
227                         var numberOfWords = fileAndWordList[i][0].motsnb;\r
228                         \r
229             if (fileAndWordList[i] != undefined) {\r
230                 linkTab.push("<p>" + txt_results_for + " " + "<span class=\"searchExpression\">" + fileAndWordList[i][0].motslisteDisplay + "</span>" + "</p>");\r
231 \r
232                 linkTab.push("<ul class='searchresult'>");\r
233                 for (t in fileAndWordList[i]) {\r
234                     //linkTab.push("<li><a href=\"../"+fl[fileAndWordList[i][t].filenb]+"\">"+fl[fileAndWordList[i][t].filenb]+"</a></li>");\r
235                                                         \r
236                     var ttInfo = fileAndWordList[i][t].filenb;\r
237                     // Get scoring\r
238                     var ttScore = fileAndWordList[i][t].scoring;\r
239                     var tempInfo = fil[ttInfo];\r
240                                     \r
241                     var pos1 = tempInfo.indexOf("@@@");\r
242                     var pos2 = tempInfo.lastIndexOf("@@@");\r
243                     var tempPath = tempInfo.substring(0, pos1);\r
244                     var tempTitle = tempInfo.substring(pos1 + 3, pos2);\r
245                     var tempShortdesc = tempInfo.substring(pos2 + 3, tempInfo.length);\r
246 \r
247                     \r
248                     // toc.html will not be displayed on search result\r
249                     if (tempPath == 'toc.html'){\r
250                         continue;\r
251                     }\r
252                     /*\r
253                     //file:///home/kasun/docbook/WEBHELP/webhelp-draft-output-format-idea/src/main/resources/web/webhelp/installation.html\r
254                     var linkString = "<li><a href=" + tempPath + ">" + tempTitle + "</a>";\r
255                     // var linkString = "<li><a href=\"installation.html\">" + tempTitle + "</a>";\r
256                     */\r
257                     var split = fileAndWordList[i][t].motsliste.split(",");\r
258                     // var splitedValues = expressionInput.split(" ");\r
259                                         // var finalArray = split.concat(splitedValues);                                        \r
260                                         \r
261                     arrayString = 'Array(';\r
262                     for(var x in finalArray){\r
263                       if (finalArray[x].length > 2 || useCJKTokenizing){\r
264                                 arrayString+= "'" + finalArray[x] + "',";\r
265                         } \r
266                     }\r
267                     arrayString = arrayString.substring(0,arrayString.length - 1) + ")";\r
268                     var idLink = 'foundLink' + no;\r
269                     var linkString = '<li><a id="' + idLink + '" href="' + tempPath + '" class="foundResult">' + tempTitle + '</a>';\r
270                     var starWidth = (ttScore * 100/ hundredProcent)/(ttScore_first/hundredProcent) * (numberOfWords/maxNumberOfWords);\r
271                     starWidth = starWidth < 10 ? (starWidth + 5) : starWidth;\r
272                     // Keep the 5 stars format\r
273                     if (starWidth > 85){\r
274                                                 starWidth = 85;\r
275                                         }\r
276                                         /*\r
277                                         var noFullStars = Math.ceil(starWidth/17);\r
278                                         var fullStar  = "curr";\r
279                                         var emptyStar = "";\r
280                                         if (starWidth % 17 == 0){\r
281                                                 // am stea plina\r
282                                                 \r
283                                         } else {\r
284                                                 \r
285                                         }\r
286                                         console.info(noFullStars);\r
287                                         */\r
288                     // Also check if we have a valid description\r
289                     if ((tempShortdesc != "null" && tempShortdesc != '...')) {\r
290                     \r
291                         linkString += "\n<div class=\"shortdesclink\">" + tempShortdesc + "</div>";\r
292                     }\r
293                     linkString += "</li>";\r
294                     \r
295                     // Add rating values for scoring at the list of matches     \r
296                                         linkString += "<div id=\"rightDiv\">";\r
297                                         linkString += "<div id=\"star\">";\r
298                                         //linkString += "<div style=\"color: rgb(136, 136, 136);\" id=\"starUser0\" class=\"user\">" \r
299                                         //                              + ((ttScore * 100/ hundredProcent)/(ttScore_first/hundredProcent)) * 1 + "</div>";\r
300                         linkString += "<ul id=\"star0\" class=\"star\">";\r
301                                         linkString += "<li id=\"starCur0\" class=\"curr\" style=\"width: " + starWidth + "px;\"></li>";\r
302                         linkString += "</ul>";\r
303                         \r
304                         linkString += "<br style=\"clear: both;\">";\r
305                         linkString += "</div>";\r
306                                         linkString += "</div>";\r
307                     //linkString += '<b>Rating: ' + ttScore + '</b>';\r
308                                            \r
309                     linkTab.push(linkString);\r
310                     no++;\r
311                 }\r
312                 linkTab.push("</ul>");\r
313             }\r
314         }\r
315     }\r
316 \r
317     var results = "";\r
318     if (linkTab.length > 0) { \r
319         /*writeln ("<p>" + txt_results_for + " " + "<span class=\"searchExpression\">"  + cleanwordsList + "</span>" + "<br/>"+"</p>");*/\r
320         results = "<p>";\r
321         //write("<ul class='searchresult'>");\r
322         for (t in linkTab) {\r
323             results += linkTab[t].toString();\r
324         }\r
325         results += "</p>";\r
326     } else {\r
327         results = "<p>" + localeresource.search_no_results + " <span class=\"searchExpression\">" + txt_wordsnotfound + "</span>" + "</p>";\r
328     }\r
329     \r
330     \r
331     // Verify if the browser is Google Chrome and the WebHelp is used on a local machine\r
332     // If browser is Google Chrome and WebHelp is used on a local machine a warning message will appear\r
333     // Highlighting will not work in this conditions. There is 2 workarounds\r
334     if (verifyBrowser()){\r
335         document.getElementById('searchResults').innerHTML = results;\r
336     } else {\r
337         document.getElementById('searchResults').innerHTML = warningMsg + results;\r
338     }\r
339     \r
340 }\r
341 \r
342 \r
343 // Verify if the stemmed word is aproximately the same as the searched word\r
344 function verifyWord(word, arr){\r
345         for (var i = 0 ; i < arr.length ; i++){\r
346                 if (word[0] == arr[i][0] \r
347                         && word[1] == arr[i][1] \r
348                         //&& word[2] == arr[i][2]\r
349                         ){\r
350                         return true;\r
351                 }\r
352         }\r
353         return false;\r
354 }\r
355 \r
356 // Look for elements that start with searchedValue.\r
357 function wordsStartsWith(searchedValue){\r
358         var toReturn = '';\r
359         for (var sv in w){\r
360                 if (searchedValue.length < 3){\r
361                         continue;\r
362                 } else {\r
363                         if (sv.toLowerCase().indexOf(searchedValue.toLowerCase()) == 0){\r
364                                 toReturn+=sv + ","; \r
365                         }\r
366                 }\r
367         }\r
368         return toReturn.length > 0 ? toReturn : undefined;\r
369 }\r
370 \r
371 \r
372 function tokenize(wordsList){\r
373     var stemmedWordsList = new Array(); // Array with the words to look for after removing spaces\r
374     var cleanwordsList = new Array(); // Array with the words to look for\r
375     // -------------------------------------------------\r
376     // Thu's patch\r
377     for(var j=0;j<wordsList.length;++j){\r
378         var word = wordsList[j];\r
379         var originalWord=word;\r
380         if(typeof stemmer != "undefined" ){\r
381             var stemmedWord=stemmer(word);\r
382             if(w[stemmedWord]!=undefined){\r
383             stemQueryMap[stemmer(word)] = word;\r
384             }\r
385             else{\r
386                 stemQueryMap[originalWord]=originalWord;\r
387             }\r
388         } else {\r
389             if(w[word]!=undefined){\r
390             stemQueryMap[word] = word;\r
391         }\r
392             else{\r
393                 stemQueryMap[originalWord]=originalWord;\r
394             }\r
395         }\r
396     } \r
397      //stemmedWordsList is the stemmed list of words separated by spaces.\r
398     for (var t=0;t<wordsList.length;++t) {\r
399         wordsList[t] = wordsList[t].replace(/(%22)|^-/g, "");\r
400         if (wordsList[t] != "%20") {\r
401             scriptLetterTab.add(wordsList[t].charAt(0));\r
402             cleanwordsList.push(wordsList[t]);\r
403         }\r
404     }\r
405 \r
406     if(typeof stemmer != "undefined" ){\r
407         //Do the stemming using Porter's stemming algorithm\r
408         for (var i = 0; i < cleanwordsList.length; i++) {                       \r
409             var stemWord = stemmer(cleanwordsList[i]);                  \r
410             if(w[stemWord]!=undefined){\r
411             stemmedWordsList.push(stemWord);\r
412         }\r
413             else{\r
414                 stemmedWordsList.push(cleanwordsList[i]);               \r
415             }\r
416         }\r
417     // End Thu's patch\r
418     // -------------------------------------------\r
419     } else {\r
420         stemmedWordsList = cleanwordsList;\r
421     }\r
422     return stemmedWordsList;\r
423 }\r
424 \r
425 //Invoker of CJKTokenizer class methods.\r
426 function cjkTokenize(wordsList){\r
427     var allTokens= new Array();\r
428     var notCJKTokens= new Array();\r
429     var j=0;\r
430     for(j=0;j<wordsList.length;j++){\r
431         var word = wordsList[j];\r
432         if(getAvgAsciiValue(word) < 127){\r
433             notCJKTokens.push(word);\r
434         } else { \r
435             var tokenizer = new CJKTokenizer(word);\r
436             var tokensTmp = tokenizer.getAllTokens();\r
437             allTokens = allTokens.concat(tokensTmp);\r
438         }\r
439     }\r
440     allTokens = allTokens.concat(tokenize(notCJKTokens));\r
441     return allTokens;\r
442 }\r
443 \r
444 //A simple way to determine whether the query is in english or not.\r
445 function getAvgAsciiValue(word){\r
446     var tmp = 0;\r
447     var num = word.length < 5 ? word.length:5;\r
448     for(var i=0;i<num;i++){\r
449         if(i==5) break;\r
450         tmp += word.charCodeAt(i);\r
451     }\r
452     return tmp/num;\r
453 }\r
454 \r
455 //CJKTokenizer\r
456 function CJKTokenizer(input){\r
457     this.input = input;\r
458     this.offset=-1;\r
459     this.tokens = new Array(); \r
460     this.incrementToken = incrementToken;\r
461     this.tokenize = tokenize;\r
462     this.getAllTokens = getAllTokens;\r
463     this.unique = unique;\r
464 \r
465     function incrementToken(){\r
466                 if(this.input.length - 2 <= this.offset){\r
467                 //      console.log("false "+offset);\r
468                         return false;\r
469                 }\r
470                 else {\r
471                         this.offset+=1;\r
472                         return true;\r
473                 }\r
474         }\r
475 \r
476         function tokenize(){\r
477                 //document.getElementById("content").innerHTML += x.substring(offset,offset+2)+"<br>";\r
478                 return this.input.substring(this.offset,this.offset+2);\r
479         }\r
480 \r
481         function getAllTokens(){\r
482                 while(this.incrementToken()){\r
483                         var tmp = this.tokenize();\r
484                         this.tokens.push(tmp);\r
485                 }\r
486         return this.unique(this.tokens);\r
487 //              document.getElementById("content").innerHTML += tokens+" ";\r
488 //              document.getElementById("content").innerHTML += "<br>dada"+sortedTokens+" ";\r
489 //              console.log(tokens.length+"dsdsds");\r
490                 /*for(i=0;i<tokens.length;i++){\r
491                         console.log(tokens[i]);\r
492                         var ss = tokens[i] == sortedTokens[i];\r
493 \r
494 //                      document.getElementById("content").innerHTML += "<br>dada"+un[i]+"- "+stems[i]+"&nbsp;&nbsp;&nbsp;"+ ss;\r
495                         document.getElementById("content").innerHTML += "<br>"+sortedTokens[i];\r
496                 }*/\r
497         }\r
498 \r
499         function unique(a)\r
500         {\r
501            var r = new Array();\r
502            o:for(var i = 0, n = a.length; i < n; i++)\r
503            {\r
504               for(var x = 0, y = r.length; x < y; x++)\r
505               {\r
506                  if(r[x]==a[i]) continue o;\r
507               }\r
508               r[r.length] = a[i];\r
509            }\r
510            return r;\r
511         } \r
512 }\r
513 \r
514 \r
515 /* Scriptfirstchar: to gather the first letter of index js files to upload */\r
516 function Scriptfirstchar() {\r
517     this.strLetters = "";\r
518     this.add = addLettre;\r
519 }\r
520 \r
521 function addLettre(caract) {\r
522 \r
523     if (this.strLetters == 'undefined') {\r
524         this.strLetters = caract;\r
525     } else if (this.strLetters.indexOf(caract) < 0) {\r
526         this.strLetters += caract;\r
527     }\r
528 \r
529     return 0;\r
530 }\r
531 /* end of scriptfirstchar */\r
532 \r
533 /*main loader function*/\r
534 /*tab contains the first letters of each word looked for*/\r
535 function loadTheIndexScripts(tab) {\r
536 \r
537     //alert (tab.strLetters);\r
538     var scriptsarray = new Array();\r
539 \r
540     for (var i = 0; i < tab.strLetters.length; i++) {\r
541 \r
542         scriptsarray[i] = "..\/search" + "\/" + tab.strLetters.charAt(i) + ".js";\r
543     }\r
544     // add the list of html files\r
545     i++;\r
546     scriptsarray[i] = "..\/search" + "\/" + htmlfileList;\r
547 \r
548     //debug\r
549     for (var t in scriptsarray) {\r
550         //alert (scriptsarray[t]);\r
551     }\r
552 \r
553     tab = new ScriptLoader();\r
554     for (t in scriptsarray) {\r
555         tab.add(scriptsarray[t]);\r
556     }\r
557     tab.load();\r
558     //alert ("scripts loaded");\r
559     return (scriptsarray);\r
560 }\r
561 \r
562 /* ScriptLoader: to load the scripts and wait that it's finished */\r
563 function ScriptLoader() {\r
564     this.cpt = 0;\r
565     this.scriptTab = new Array();\r
566     this.add = addAScriptInTheList;\r
567     this.load = loadTheScripts;\r
568     this.onScriptLoaded = onScriptLoadedFunc;\r
569 }\r
570 \r
571 function addAScriptInTheList(scriptPath) {\r
572     this.scriptTab.push(scriptPath);\r
573 }\r
574 \r
575 function loadTheScripts() {\r
576     var script;\r
577     var head;\r
578 \r
579     head = document.getElementsByTagName('head').item(0);\r
580 \r
581     //script = document.createElement('script');\r
582 \r
583     for (var el in this.scriptTab) {\r
584         //alert (el+this.scriptTab[el]);\r
585         script = document.createElement('script');\r
586         script.src = this.scriptTab[el];\r
587         script.type = 'text/javascript';\r
588         script.defer = false;\r
589 \r
590         head.appendChild(script);\r
591     }\r
592 \r
593 }\r
594 \r
595 function onScriptLoadedFunc(e) {\r
596     e = e || window.event;\r
597     var target = e.target || e.srcElement;\r
598     var isComplete = true;\r
599     if (typeof target.readyState != undefined) {\r
600 \r
601         isComplete = (target.readyState == "complete" || target.readyState == "loaded");\r
602     }\r
603     if (isComplete) {\r
604         ScriptLoader.cpt++;\r
605         if (ScriptLoader.cpt == ScriptLoader.scripts.length) {\r
606             ScriptLoader.onLoadComplete();\r
607         }\r
608     }\r
609 }\r
610 \r
611 /*\r
612 function onLoadComplete() {\r
613     alert("loaded !!");\r
614 } */\r
615 \r
616 /* End of scriptloader functions */\r
617  \r
618 // Array.unique( strict ) - Remove duplicate values\r
619 function unique(tab) {\r
620     var a = new Array();\r
621     var i;\r
622     var l = tab.length;\r
623 \r
624     if (tab[0] != undefined) {\r
625         a[0] = tab[0];\r
626     }\r
627     else {\r
628         return -1;\r
629     }\r
630 \r
631     for (i = 1; i < l; i++) {\r
632         if (indexof(a, tab[i], 0) < 0) {\r
633             a.push(tab[i]);\r
634         }\r
635     }\r
636     return a;\r
637 }\r
638 function indexof(tab, element, begin) {\r
639     for (var i = begin; i < tab.length; i++) {\r
640         if (tab[i] == element) {\r
641             return i;\r
642         }\r
643     }\r
644     return -1;\r
645 \r
646 }\r
647 /* end of Array functions */\r
648 \r
649 \r
650 /*\r
651  Param: mots= list of words to look for.\r
652  This function creates an hashtable:\r
653  - The key is the index of a html file which contains a word to look for.\r
654  - The value is the list of all words contained in the html file.\r
655 \r
656  Return value: the hashtable fileAndWordList\r
657  */\r
658 function SortResults(mots) {\r
659 \r
660     var fileAndWordList = new Object();\r
661     if (mots.length == 0 || mots[0].length == 0) {\r
662         return null;\r
663     }\r
664     \r
665     \r
666     // In generated js file we add scoring at the end of the word\r
667     // Example word1*scoringForWord1,word2*scoringForWord2 and so on\r
668     // Split after * to obtain the right values\r
669     var scoringArr = Array();\r
670     for (var t in mots) {\r
671         // get the list of the indices of the files.\r
672         var listNumerosDesFicStr = w[mots[t].toString()];\r
673 \r
674         if (listNumerosDesFicStr != undefined) {\r
675 \r
676             //alert ("listNumerosDesFicStr "+listNumerosDesFicStr);\r
677             var tab = listNumerosDesFicStr.split(",");\r
678             //for each file (file's index):\r
679             for (var t2 in tab) {\r
680                 var tmp = '';\r
681                 var idx = '';\r
682                 var temp = tab[t2].toString();\r
683                 if (temp.indexOf('*') != -1) {\r
684                     idx = temp.indexOf('*');\r
685                     tmp = temp.substring(idx + 3, temp.length);\r
686                     temp = temp.substring(0, idx);\r
687                 }\r
688                 scoringArr.push(tmp);\r
689                 if (fileAndWordList[temp] == undefined) {\r
690                     fileAndWordList[temp] = "" + mots[t];\r
691                 } else {\r
692                     fileAndWordList[temp] += "," + mots[t];\r
693                 }\r
694                 //console.info("fileAndWordList[" + temp + "]=" + fileAndWordList[temp] + " : " + tmp);\r
695             }\r
696 \r
697         }\r
698     }\r
699     var fileAndWordListValuesOnly = new Array();\r
700     // sort results according to values\r
701     var temptab = new Array();\r
702     finalObj = new Array();\r
703     for (t in fileAndWordList) {        \r
704         finalObj.push(new newObj(t,fileAndWordList[t]));\r
705     }\r
706 \r
707     if ( finalObj.length == 0 ) {   // None of the queried words are not in the index (stemmed or not)\r
708         return null;\r
709     }\r
710     finalObj = removeDerivates(finalObj);\r
711     for (t in finalObj) {\r
712         tab = finalObj[t].wordList.split(',');\r
713         var tempDisplay = new Array();\r
714         for (var x in tab) {                    \r
715             if(stemQueryMap[tab[x]] != undefined && doStem){\r
716                 tempDisplay.push(stemQueryMap[tab[x]]); //get the original word from the stem word.                \r
717             } else {\r
718                 tempDisplay.push(tab[x]); //no stem is available. (probably a CJK language)\r
719             }\r
720         }\r
721         var tempDispString = tempDisplay.join(", ");\r
722                                 var index;\r
723                                 for (x in fileAndWordList) {\r
724                                         if (x === finalObj[t].filesNo) {\r
725                                                 index = x;\r
726                                                 break;\r
727                                         }\r
728                                 }\r
729                                 var scoring = findRating(fileAndWordList[index], index);        \r
730         temptab.push(new resultPerFile(finalObj[t].filesNo, finalObj[t].wordList, tab.length, tempDispString, scoring));\r
731         fileAndWordListValuesOnly.push(finalObj[t].wordList);        \r
732     }\r
733     fileAndWordListValuesOnly = unique(fileAndWordListValuesOnly);\r
734     fileAndWordListValuesOnly = fileAndWordListValuesOnly.sort(compare_nbMots);\r
735 \r
736     var listToOutput = new Array();\r
737     for (var fawlvoIdx in fileAndWordListValuesOnly) {\r
738         for (t in temptab) {\r
739             if (temptab[t].motsliste == fileAndWordListValuesOnly[fawlvoIdx]) {\r
740                 if (listToOutput[fawlvoIdx] == undefined) {\r
741                     listToOutput[fawlvoIdx] = new Array(temptab[t]);\r
742                 } else {\r
743                     listToOutput[fawlvoIdx].push(temptab[t]);\r
744                 }\r
745             }\r
746         }\r
747     }           \r
748   // Sort results by scoring, descending on the same group\r
749         for (var ltoIdx in listToOutput) {\r
750             listToOutput[ltoIdx].sort(function(a, b){\r
751                         return b.scoring - a.scoring;\r
752                 });\r
753         }\r
754         // If we have groups with same number of words, \r
755         // will sort groups by higher scoring of each group\r
756         for (var i = 0; i < listToOutput.length - 1; i++) {\r
757                 for (var j = i + 1; j < listToOutput.length; j++) {\r
758                         if (listToOutput[i][0].motsnb < listToOutput[j][0].motsnb \r
759                                 || (listToOutput[i][0].motsnb == listToOutput[j][0].motsnb\r
760                                 && listToOutput[i][0].scoring < listToOutput[j][0].scoring)\r
761                                 ) {\r
762                                 var x = listToOutput[i];\r
763                                 listToOutput[i] = listToOutput[j];\r
764                                 listToOutput[j] = x;\r
765                         }\r
766                 }\r
767         }\r
768 \r
769     return listToOutput;\r
770 }\r
771 \r
772 // Remove derivates words from the list of words\r
773 function removeDerivates(obj){\r
774         var toResultObject = new Array();       \r
775         for (i in obj){\r
776                 var filesNo  = obj[i].filesNo;\r
777                 var wordList = obj[i].wordList;\r
778                 var wList = wordList.split(",");                \r
779                 var searchedWords = searchTextField.toLowerCase().split(" ");\r
780                 for (var k = 0 ; k < searchedWords.length ; k++){\r
781                         for (var j = 0 ; j < wList.length ; j++){                               \r
782                                 if (wList[j].startsWith(searchedWords[k])){\r
783                                         wList[j] = searchedWords[k];\r
784                                 }\r
785                         }\r
786                 }\r
787                 wList = removeDuplicate(wList);\r
788                 var recreateList = '';\r
789                 for(var x in wList){\r
790                         recreateList+=wList[x] + ",";\r
791                 }\r
792                 recreateList = recreateList.substr(0, recreateList.length - 1);\r
793                 toResultObject.push(new newObj(filesNo, recreateList));\r
794         }\r
795         return toResultObject;\r
796 }\r
797 \r
798 function newObj(filesNo, wordList){\r
799         this.filesNo = filesNo;\r
800         this.wordList = wordList;\r
801 }\r
802 \r
803 // Add a new parameter. Scoring.\r
804 function resultPerFile(filenb, motsliste, motsnb, motslisteDisplay, scoring, group) {\r
805         //10 - spring,time - 2 - spring, time - 55 - 3\r
806     this.filenb = filenb;\r
807     this.motsliste = motsliste;\r
808     this.motsnb = motsnb;\r
809     this.motslisteDisplay= motslisteDisplay;\r
810     \r
811     this.scoring = scoring;\r
812     \r
813 }\r
814 \r
815 \r
816 function findRating(words, nr){\r
817     var sum = 0;\r
818     var xx = words.split(',');\r
819     for (jj = 0 ; jj < xx.length ; jj++){\r
820         var wrd = w[xx[jj]].split(',');\r
821         for (var ii = 0 ; ii < wrd.length ; ii++){\r
822             var wrdno = wrd[ii].split('*');\r
823             if (wrdno[0] == nr){\r
824                 sum+=parseInt(wrdno[1]);\r
825             }\r
826         }\r
827     }\r
828     return sum;\r
829 }\r
830 \r
831 function compare_nbMots(s1, s2) {\r
832     var t1 = s1.split(',');\r
833     var t2 = s2.split(',');\r
834     //alert ("s1:"+t1.length + " " +t2.length)\r
835     if (t1.length == t2.length) {\r
836         return 0;\r
837     } else if (t1.length > t2.length) {\r
838         return 1;\r
839     } else {\r
840         return -1;\r
841     }\r
842     //return t1.length - t2.length);\r
843 }\r
844 \r
845 // return false if browser is Google Chrome and WebHelp is used on a local machine, not a web server \r
846 function verifyBrowser(){\r
847     var returnedValue = true;    \r
848     var browser = BrowserDetect.browser;\r
849     var addressBar = window.location.href;\r
850     if (browser == 'Chrome' && addressBar.indexOf('file://') === 0){\r
851         returnedValue = false;\r
852     }\r
853     \r
854     return returnedValue;\r
855 }\r
856 \r
857 // Remove duplicate values from an array\r
858 function removeDuplicate(arr) {\r
859    var r = new Array();\r
860    o:for(var i = 0, n = arr.length; i < n; i++) {\r
861       for(var x = 0, y = r.length; x < y; x++) {\r
862          if(r[x]==arr[i]) continue o;\r
863       }\r
864       r[r.length] = arr[i];\r
865    }\r
866    return r;\r
867 }\r
868 \r
869 // Create startsWith method\r
870 String.prototype.startsWith = function(str) {\r
871         return (this.match("^"+str)==str);\r
872 }\r
873 \r
874 function trim(str, chars) {\r
875         return ltrim(rtrim(str, chars), chars);\r
876 }\r
877  \r
878 function ltrim(str, chars) {\r
879         chars = chars || "\\s";\r
880         return str.replace(new RegExp("^[" + chars + "]+", "g"), "");\r
881 }\r
882  \r
883 function rtrim(str, chars) {\r
884         chars = chars || "\\s";\r
885         return str.replace(new RegExp("[" + chars + "]+$", "g"), "");\r
886 }\r