1// ---------------------------------------------------------------------------- 2// Zoom Search Engine 5.1 (13/11/2007) 3// 4// This file (search.js) is the JavaScript search front-end for client side 5// searches using index files created by the Zoom Search Engine Indexer. 6// 7// email: [email protected] 8// www: http://www.wrensoft.com 9// 10// Copyright (C) Wrensoft 2000-2007 11// 12// This script performs client-side searching with the index data file 13// (zoom_index.js) generated by the Zoom Search Engine Indexer. It allows you 14// to run searches on mediums such as CD-ROMs, or other local data, where a 15// web server is not available. 16// 17// We recommend against using client-side searches for online websites because 18// it requires the entire index data file to be downloaded onto the user's 19// local machine. This can be very slow for large websites, and our server-side 20// search scripts (available for PHP, ASP and CGI) are far better suited for this. 21// However, JavaScript is still an option for smaller websites in a limited 22// hosting situation (eg: your web host does not support PHP, ASP or CGI). 23// ---------------------------------------------------------------------------- 24 25// Include required files for index data, settings, etc. 26document.write("<script language=\"JavaScript\" src=\"zoom_index.js\" charset=\"" + Charset + "\"><\/script>"); 27document.write("<script language=\"JavaScript\" src=\"zoom_pageinfo.js\" charset=\"" + Charset + "\"><\/script>"); 28 29document.write("<meta http-equiv=\"content-type\" content=\"text/html; charset=" + Charset + "\">"); 30 31// ---------------------------------------------------------------------------- 32// Settings (change if necessary) 33// ---------------------------------------------------------------------------- 34 35// The options available in the dropdown menu for number of results 36// per page 37var PerPageOptions = new Array(10, 20, 50, 100); 38 39// Globals 40var SkippedWords = 0; 41var searchWords = new Array(); 42var RegExpSearchWords = new Array(); 43var SkippedOutputStr = ""; 44 45var months = new Array('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'); 46 47// Index format 48var PAGEDATA_URL = 0; 49var PAGEDATA_TITLE = 1; 50var PAGEDATA_DESC = 2; 51var PAGEDATA_IMG = 3; 52var PAGEINFO_DATETIME = 0; 53var PAGEINFO_FILESIZE = 1; 54var PAGEINFO_CAT = 2; 55 56// ---------------------------------------------------------------------------- 57// Helper Functions 58// ---------------------------------------------------------------------------- 59 60// This function will return the value of a GET parameter 61function getParam(paramName) 62{ 63 paramStr = document.location.search; 64 if (paramStr == "") 65 return ""; 66 67 // remove '?' in front of paramStr 68 if (paramStr.charAt(0) == "?") 69 paramStr = paramStr.substr(1); 70 71 arg = (paramStr.split("&")); 72 for (i=0; i < arg.length; i++) { 73 arg_values = arg[i].split("=") 74 if (unescape(arg_values[0]) == paramName) 75 { 76 if (paramName == "zoom_query") 77 arg_values[1] = arg_values[1].replace(/[\+]/g, " "); // replace the '+' with spaces 78 79 if (UseUTF8 == 1 && self.decodeURIComponent) // check if decodeURIComponent() is defined 80 ret = decodeURIComponent(arg_values[1]); 81 else 82 ret = unescape(arg_values[1]); // IE 5.0 and older does not have decodeURI 83 return ret; 84 } 85 } 86 return ""; 87} 88 89function getParamArrayInt(paramName) 90{ 91 paramStr = document.location.search; 92 93 var retArray = new Array(); 94 var retCount = 0; 95 96 if (paramStr == "") 97 return retArray; 98 99 // remove '?' in front of paramStr 100 if (paramStr.charAt(0) == "?") 101 paramStr = paramStr.substr(1); 102 103 arg = (paramStr.split("&")); 104 for (i=0; i < arg.length; i++) 105 { 106 arg_values = arg[i].split("=") 107 if (unescape(arg_values[0]) == paramName) 108 { 109 if (UseUTF8 == 1 && self.decodeURIComponent) // check if decodeURIComponent() is defined 110 ret = decodeURIComponent(arg_values[1]); 111 else 112 ret = unescape(arg_values[1]); // IE 5.0 and older does not have decodeURI 113 114 if (isNaN(ret) == false) 115 { 116 retArray[retCount] = ret; 117 retCount++; 118 } 119 } 120 } 121 return retArray; 122} 123 124// Compares the two values, used for sorting output results 125// Results that match all search terms are put first, highest score 126function SortCompare (a, b) 127{ 128 if (a[2] < b[2]) return 1; 129 else if (a[2] > b[2]) return -1; 130 else if (a[1] < b[1]) return 1; 131 else if (a[1] > b[1]) return -1; 132 else return 0; 133} 134 135function SortByDate(a, b) 136{ 137 if (pageinfo[a[0]][PAGEINFO_DATETIME] < pageinfo[b[0]][PAGEINFO_DATETIME]) return 1; 138 else if (pageinfo[a[0]][PAGEINFO_DATETIME] > pageinfo[b[0]][PAGEINFO_DATETIME]) return -1; 139 else return SortCompare(a, b); 140} 141 142function sw_compare(a, b) 143{ 144 if (a.charAt(0) == '-') 145 return 1; 146 147 if (b.charAt(0) == '-') 148 return -1; 149 150 return 0; 151} 152 153function pattern2regexp(pattern) 154{ 155 pattern = pattern.replace(/\#/g, "\\#"); 156 pattern = pattern.replace(/\$/g, "\\$"); 157 pattern = pattern.replace(/\./g, "\\."); 158 pattern = pattern.replace(/\*/g, "[\\d\\S]*"); 159 pattern = pattern.replace(/\?/g, ".?"); 160 return pattern; 161} 162 163function PrintHighlightDescription(line) 164{ 165 if (Highlighting == 0) 166 { 167 document.writeln(line); 168 return; 169 } 170 171 res = " " + line + " "; 172 for (i = 0; i < numwords; i++) { 173 if (RegExpSearchWords[i] == "") 174 continue; 175 176 if (SearchAsSubstring == 1) 177 res = res.replace(new RegExp("("+RegExpSearchWords[i]+")", "gi"), "[;:]$1[:;]"); 178 else 179 res = res.replace(new RegExp("(\\W|^|\\b)("+RegExpSearchWords[i]+")(\\W|$|\\b)", "gi"), "$1[;:]$2[:;]$3"); 180 } 181 // replace the marker text with the html text 182 // this is to avoid finding previous <span>'ed text. 183 res = res.replace(/\[;:\]/g, "<span class=\"highlight\">"); 184 res = res.replace(/\[:;
184\]/g, "</span>"); 185 document.writeln(res); 186} 187 188function PrintNumResults(num) 189{ 190 if (num == 0) 191 return STR_NO_RESULTS; 192 else if (num == 1) 193 return num + " " + STR_RESULT; 194 else 195 return num + " " + STR_RESULTS; 196} 197 198function AddParamToURL(url, paramStr) 199{ 200 // add GET parameters to URL depending on 201 // whether there are any existing parameters 202 if (url.indexOf("?") > -1) 203 return url + "&" + paramStr; 204 else 205 return url + "?" + paramStr; 206} 207 208function SkipSearchWord(sw) { 209 if (searchWords[sw] != "") { 210 if (SkippedWords > 0) 211 SkippedOutputStr += ", "; 212 SkippedOutputStr += "\"<b>" + searchWords[sw] + "</b>\""; 213 searchWords[sw] = ""; 214 } 215} 216 217function wordcasecmp(word1, word2) { 218 if (word1 == word2) 219 return 0; 220 else 221 return -1; 222} 223 224function htmlspecialchars(query) { 225 query = query.replace(/\&/g, "&"); 226 query = query.replace(/\</g, "<"); 227 query = query.replace(/\>/g, ">"); 228 query = query.replace(/\"/g, """); 229 query = query.replace(/\'/g, "'"); 230 return query; 231} 232 233function QueryEntities(query) { 234 query = query.replace(/\&/g, "&"); 235 query = query.replace(/\</g, "<"); 236 query = query.replace(/\>/g, ">"); 237 query = query.replace(/\'/g, "'"); 238 return query; 239} 240 241function FixQueryForAsianWords(query) { 242 currCharType = 0; 243 lastCharType = 0; // 0 is normal, 1 is hiragana, 2 is katakana, 3 is "han" 244 245 // check for hiragana/katakana splitting required 246 newquery = ""; 247 for (i = 0; i < query.length; i++) 248 { 249 ch = query.charAt(i); 250 chVal = query.charCodeAt(i); 251 252 if (chVal >= 12352 && chVal <= 12447) 253 currCharType = 1; 254 else if (chVal >= 12448 && chVal <= 12543) 255 currCharType = 2; 256 else if (chVal >= 13312 && chVal <= 44031) 257 currCharType = 3; 258 else 259 currCharType = 0; 260 261 if (lastCharType != currCharType && ch != " ") 262 newquery += " "; 263 lastCharType = currCharType; 264 newquery += ch; 265 } 266 return newquery; 267} 268 269// ---------------------------------------------------------------------------- 270// Parameters initialisation (globals) 271// ---------------------------------------------------------------------------- 272 273var query = getParam("zoom_query"); 274query = query.replace(/[\"]/g, " "); 275 276var per_page = parseInt(getParam("zoom_per_page")); 277if (isNaN(per_page)) per_page = 10; 278if (per_page < 1) per_page = 1; 279 280var page = parseInt(getParam("zoom_page")); 281if (isNaN(page)) page = 1; 282 283var andq = parseInt(getParam("zoom_and")); 284if (isNaN(andq)) 285{ 286 if (typeof(DefaultToAnd) != "undefined" && DefaultToAnd == 1) 287 andq = 1; 288 else 289 andq = 0; 290} 291 292var cat = getParamArrayInt("zoom_cat[]"); 293if (cat.length == 0) 294{ 295 cat[0] = parseInt(getParam("zoom_cat")); 296 if (isNaN(cat)) 297 cat[0] = -1; // search all categories 298} 299var num_zoom_cats = cat.length; 300 301 302// for sorting options. zero is default (relevance) 303// 1 is sort by date (if date/time is available) 304var sort = parseInt(getParam("zoom_sort")); 305if (isNaN(sort)) sort = 0; 306 307var SelfURL = ""; 308if (typeof(LinkBackURL) == "undefined") 309{ 310 SelfURL = document.location.href; 311 // strip off parameters and anchors 312 var paramIndex; 313 paramIndex = SelfURL.indexOf("?"); 314 if (paramIndex > -1) 315 SelfURL = SelfURL.substr(0, paramIndex); 316 paramIndex = SelfURL.indexOf("#"); 317 if (paramIndex > -1) 318 SelfURL = SelfURL.substr(0, paramIndex); 319} 320else 321 SelfURL = LinkBackURL; 322// encode invalid URL characters 323SelfURL = SelfURL.replace(/\</g, "<"); 324SelfURL = SelfURL.replace(/\"/g, """); 325 326var data = new Array(); 327var output = new Array(); 328 329target = ""; 330if (UseLinkTarget == 1) 331 target = " target=\"" + LinkTarget + "\" "; 332 333// ---------------------------------------------------------------------------- 334// Main search function starts here 335// ---------------------------------------------------------------------------- 336 337function ZoomSearch() 338{ 339 if (UseCats) 340 NumCats = catnames.length; 341 342 if (Timing == 1) { 343 timeStart = new Date(); 344 } 345 346 // Display the form 347 if (FormFormat > 0) { 348 document.writeln("<form method=\"get\" action=\"" + SelfURL + "\" class=\"zoom_searchform\">"); 349 document.writeln("<input type=\"text\" name=\"zoom_query\" size=\"20\" value=\"" + htmlspecialchars(query) + "\" class=\"zoom_searchbox\" />"); 350 document.writeln("<input type=\"submit\" value=\"" + STR_FORM_
350SUBMIT_BUTTON + "\" class=\"zoom_button\" />"); 351 if (FormFormat == 2) { 352 document.writeln("<span class=\"zoom_results_per_page\">" + STR_FORM_RESULTS_PER_PAGE + "\n"); 353 document.writeln("<select name=\"zoom_per_page\">"); 354 for (i = 0; i < PerPageOptions.length; i++) { 355 document.write("<option"); 356 if (PerPageOptions[i] == per_page) 357 document.write(" selected=\"selected\""); 358 document.writeln(">" + PerPageOptions[i] + "</option>"); 359 } 360 document.writeln("</select><br /><br /></span>"); 361 if (UseCats) { 362 document.writeln("<span class=\"zoom_categories\">"); 363 document.write(STR_FORM_CATEGORY + " "); 364 if (SearchMultiCats) 365 { 366 document.writeln("<ul>"); 367 document.write("<li><input type=\"checkbox\" name=\"zoom_cat[]\" value=\"-1\""); 368 if (cat[0] == -1) 369 document.write(" checked=\"checked\""); 370 document.writeln(">" + STR_FORM_CATEGORY_ALL + "</input></li>"); 371 for (i = 0; i < NumCats; i++) 372 { 373 document.write("<li><input type=\"checkbox\" name=\"zoom_cat[]\" value=\"" +i+ "\""); 374 if (cat[0] != -1) 375 { 376 for (catit = 0; catit < num_zoom_cats; catit++) 377 { 378 if (i == cat[catit]) 379 { 380 document.write(" checked=\"checked\""); 381 break; 382 } 383 } 384 } 385 document.writeln(">"+catnames[i]+"</input></li>"); 386 } 387 document.writeln("</ul><br /><br />"); 388 } 389 else 390 { 391 document.write("<select name='zoom_cat[]'>"); 392 // 'all cats option 393 document.write("<option value=\"-1\">" + STR_FORM_CATEGORY_ALL + "</option>"); 394 for (i = 0; i < NumCats; i++) { 395 document.write("<option value=\"" + i + "\""); 396 if (i == cat[0]) 397 document.write(" selected=\"selected\""); 398 document.writeln(">" + catnames[i] + "</option>"); 399 } 400 document.writeln("</select> "); 401 } 402 document.writeln("</span>"); 403 } 404 document.writeln("<span class=\"zoom_match\">" + STR_FORM_MATCH + " "); 405 if (andq == 0) { 406 document.writeln("<input type=\"radio\" name=\"zoom_and\" value=\"0\" checked=\"checked\" />" + STR_FORM_ANY_SEARCH_WORDS); 407 document.writeln("<input type=\"radio\" name=\"zoom_and\" value=\"1\" />" + STR_FORM_ALL_SEARCH_WORDS); 408 } else { 409 document.writeln("<input type=\"radio\" name=\"zoom_and\" value=\"0\" />" + STR_FORM_ANY_SEARCH_WORDS); 410 document.writeln("<input type=\"radio\" name=\"zoom_and\" value=\"1\" checked=\"checked\" />" + STR_FORM_ALL_SEARCH_WORDS); 411 } 412 document.writeln("<input type=\"hidden\" name=\"zoom_sort\" value=\"" + sort + "\" />"); 413 document.writeln("<br /><br /></span>"); 414 } 415 else 416 { 417 document.writeln("<input type=\"hidden\" name=\"zoom_per_page\" value=\"" + per_page + "\" />"); 418 document.writeln("<input type=\"hidden\" name=\"zoom_and\" value=\"" + andq + "\" />"); 419 document.writeln("<input type=\"hidden\" name=\"zoom_sort\" value=\"" + sort + "\" />"); 420 } 421 422 document.writeln("</form>"); 423 } 424 425 // give up early if no search words provided 426 if (query.length == 0) { 427 //document.writeln("No search query entered.<br />"); 428 if (ZoomInfo == 1) 429 document.writeln("<center><p><small>
429" + STR_POWEREDBY + " <a href=\"http://www.wrensoft.com/zoom/\" target=\"_blank\"><b>Zoom Search Engine</b></a></small></p></center>"); 430 return; 431 } 432 433 if (MapAccents == 1) 434 { 435 for (i = 0; i < NormalChars.length; i++) 436 query = query.replace(new RegExp(AccentChars[i], "g"), NormalChars[i]); 437 } 438 439 // Special query processing required when SearchAsSubstring is enabled 440 if (SearchAsSubstring == 1 && UseUTF8 == 1) 441 query = FixQueryForAsianWords(query); 442 443 // prepare search query, strip quotes, trim whitespace 444 if (WordJoinChars.indexOf(".") == -1) 445 query = query.replace(/[\.]/g, " "); 446 447 if (WordJoinChars.indexOf("-") == -1) 448 query = query.replace(/(\S)\-/g, "$1 "); 449 450 if (WordJoinChars.indexOf("#") == -1) 451 query = query.replace(/\#(\S)/g, " $1"); 452 453 if (WordJoinChars.indexOf("+") == -1) 454 { 455 query = query.replace(/[\+]+([^\+\s])/g, " $1"); 456 query = query.replace(/([^\+\s])\+\s/g, "$1 "); 457 } 458 459 if (WordJoinChars.indexOf("_") == -1) 460 query = query.replace(/[\_]/g, " "); 461 462 if (WordJoinChars.indexOf("'") == -1) 463 query = query.replace(/[\']/g, " "); 464 465 if (WordJoinChars.indexOf("$") == -1) 466 query = query.replace(/[\$]/g, " "); 467 468 if (WordJoinChars.indexOf("&") == -1) 469 query = query.replace(/[\&]/g, " "); 470 471 if (WordJoinChars.indexOf(":") == -1) 472 query = query.replace(/[\:]/g, " "); 473 474 if (WordJoinChars.indexOf(",") == -1) 475 query = query.replace(/[\,]/g, " "); 476 477 if (WordJoinChars.indexOf("/") == -1) 478 query = query.replace(/[\/]/g, " "); 479 480 if (WordJoinChars.indexOf("\\") == -1) 481 query = query.replace(/[\\]/g, " "); 482 483 // substitute multiple whitespace chars to single character 484 // also strip any of the wordjoinchars if followed immediately by a space 485 query = query.replace(/[\s\(\)\^\[\]\|\{\}\%]+|[\-._',:&\/\\\\](\s|$)/g, " "); 486 487 // trim trailing/leading whitespace 488 query = query.replace(/^\s*|\s*$/g,""); 489 490 var queryForHTML = htmlspecialchars(query); 491 var queryForSearch; 492 if (ToLowerSearchWords == 1) 493 queryForSearch = query.toLowerCase(); 494 else 495 queryForSearch = query; 496 queryForSearch = htmlspecialchars(queryForSearch); 497 498 // split search phrase into words 499 searchWords = queryForSearch.split(" "); // split by spaces. 500 501 // Sort search words if there are negative signs 502 if (queryForSearch.indexOf("-") != -1) 503 searchWords.sort(sw_compare); 504 505 var query_zoom_cats = ""; 506 507 document.write("<div class=\"searchheading\">" + STR_RESULTS_FOR + " " + queryForHTML); 508 if (UseCats) { 509 if (cat[0] == -1) 510 { 511 document.writeln(" " + STR_RESULTS_IN_ALL_CATEGORIES); 512 query_zoom_cats = "&zoom_cat%5B%5D=-1"; 513 } 514 else 515 { 516 document.writeln(" " + STR_RESULTS_IN_CATEGORY + " "); 517 for (catit = 0; catit < num_zoom_cats; catit++) 518 { 519 if (catit > 0) 520 document.write(", "); 521 document.write("\"" + catnames[cat[catit]] + "\""); 522 query_zoom_cats += "&zoom_cat%5B%5D="+cat[catit]; 523 } 524 } 525 } 526 document.writeln("<br /><br /></div>"); 527 528 document.writeln("<div class=\"results\">"); 529 530 numwords = searchWords.length; 531 kw_ptr = 0; 532 outputline = 0; 533 ipage = 0; 534 matches = 0; 535 var SWord; 536 pagesCount = NumPages; 537 538 exclude_count = 0; 539 ExcludeTerm = 0; 540 541 // Initialise a result table the size of all pages 542 res_table = new Array(pagesCount); 543 for (i = 0; i < pagesCount; i++) 544 { 545 res_table[i] = new Array(3); 546 res_table[i][0] = 0; 547 res_table[i][1] = 0; 548 res_table[i][2] = 0; 549 } 550 551 var UseWildCards = new Array(numwords); 552 553 for (sw = 0; sw < numwords; sw++) { 554 555 UseWildCards[sw] = 0; 556 557 if (skipwords) { 558 // check min length 559 if (searchWords[sw].length < MinWordLen) { 560 SkipSearchWord(sw); 561 continue; 562 } 563 // check skip word list 564 for (i = 0;
564 i < skipwords.length; i++) { 565 if (searchWords[sw] == skipwords[i]) { 566 SkipSearchWord(sw); 567 break; 568 } 569 } 570 } 571 572 if (searchWords[sw].indexOf("*") == -1 && searchWords[sw].indexOf("?") == -1) { 573 UseWildCards[sw] = 0; 574 } else { 575 UseWildCards[sw] = 1; 576 RegExpSearchWords[sw] = pattern2regexp(searchWords[sw]); 577 } 578 579 if (Highlighting == 1 && UseWildCards[sw] == 0) 580 RegExpSearchWords[sw] = searchWords[sw]; 581 } 582 583 // Begin searching... 584 for (sw = 0; sw < numwords; sw++) { 585 586 if (searchWords[sw] == "") { 587 SkippedWords++; 588 continue; 589 } 590 591 if (searchWords[sw].charAt(0) == '-') 592 { 593 searchWords[sw] = searchWords[sw].substr(1); 594 ExcludeTerm = 1; 595 exclude_count++; 596 } 597 598 if (UseWildCards[sw] == 1) { 599 if (SearchAsSubstring == 0) 600 pattern = "^" + RegExpSearchWords[sw] + "$"; 601 else 602 pattern = RegExpSearchWords[sw]; 603 re = new RegExp(pattern, "g"); 604 } 605 606 for (kw_ptr = 0; kw_ptr < dictwords.length; kw_ptr++) { 607 608 data = dictwords[kw_ptr].split(" "); 609 610 if (UseWildCards[sw] == 0) { 611 if (SearchAsSubstring == 0) 612 match_result = wordcasecmp(data[0], searchWords[sw]); 613 else 614 match_result = data[0].indexOf(searchWords[sw]); 615 } else 616 match_result = data[0].search(re); 617 618 619 if (match_result != -1) { 620 // keyword found, include it in the output list 621 for (kw = 1; kw < data.length; kw += 2) { 622 // check if page is already in output list 623 pageexists = 0; 624 ipage = data[kw]; 625 626 if (ExcludeTerm == 1) 627 { 628 // we clear out the score entry so that it'll be excluded in the filter stage 629 res_table[ipage][0] = 0; 630 } 631 else if (res_table[ipage][0] == 0) { 632 matches++; 633 res_table[ipage][0] += parseInt(data[kw+1]); 634 } 635 else { 636 637 if (res_table[ipage][0] > 10000) { 638 // take it easy if its too big to prevent gigantic scores 639 res_table[ipage][0] += 1; 640 } else { 641 res_table[ipage][0] += parseInt(data[kw+1]); // add in score 642 res_table[ipage][0] *= 2; // double score as we have two words matching 643 } 644 } 645 res_table[ipage][1] += 1; 646 // store the 'and' user search terms matched' value 647 if (res_table[ipage][2] == sw || res_table[ipage][2] == sw-SkippedWords-exclude_count) 648 res_table[ipage][2] += 1; 649 650 } 651 if (UseWildCards[sw] == 0 && SearchAsSubstring == 0) 652 break; // this search word was found, so skip to next 653 } 654 } 655 } 656 657 if (SkippedWords > 0) 658 document.writeln("<div class=\"summary\">" + STR_SKIPPED_FOLLOWING_WORDS + " " + SkippedOutputStr + ".<br /><br /></div>"); 659 660 // Count number of output lines that match ALL search terms 661 oline = 0; 662 fullmatches = 0; 663 output = new Array(); 664 var full_numwords = numwords - SkippedWords - exclude_count; 665 for (i = 0; i < pagesCount; i++) { 666 IsFiltered = false; 667 if (res_table[i][0] > 0) { 668 if (UseCats && cat[0] != -1) { 669 // using cats and not doing an "all cats" search 670 if (SearchMultiCats) { 671 for (cati = 0; cati < num_zoom_cats; cati++) { 672 if (pageinfo[i][PAGEINFO_CAT].charAt(cat[cati]) == "1") 673 break; 674 } 675 if (cati == num_zoom_cats) 676 IsFiltered = true; 677 } 678 else { 679 if (pageinfo[i][PAGEINFO_CAT].charAt(cat[0]) == "0") { 680 IsFiltered = true; 681 } 682 } 683 } 684 if (IsFiltered == false) { 685 if (res_table[i][2] >= full_numwords) { 686 fullmatches++; 687 } else { 688 if (andq == 1) 689 IsFiltered = true; 690 } 691 } 692 if (IsFiltered == false) { 693 // copy if not filtered out 694 output[oline] = new Array(3); 695 output[oline][0] = i; 696 output[oline][1] = res_table[i][0]; 697 output[oline][2] = res_table[i][1]; 698 oline++; 699 } 700 } 701 } 702 matches = oline; 703 704 // Sort results in order of score, use "SortCompare" function 705 if (matches > 1) 706 { 707 if (sort == 1 && UseDateTime == 1) 708 output.sort(SortByDate); // sort by date 709 else 710 output.sort(SortCompare); // sort by relevance 711 } 712 713 // prepare queryForURL 714 var queryForURL = query.replace(/\s/g, "+"); 715 if (UseUTF8 == 1 && self.encodeURIComponent) 716 queryForURL = encodeURIComponent(queryForURL); 717 else 718 queryForURL = escape(queryForURL); 719 720 //Display search result information 721 document.writeln("<div class=\"summary\">"); 722 if (matches == 0) 723 document.writeln(STR_SUMMARY_NO_RESULTS_FOUND + "<br />"); 724 else if (numwords > 1 && andq == 0) { 725 //OR 726 SomeTermMatches = matches - fullmatches; 727 document.writeln(PrintNumResults(fullmatches) + " " + STR_SUMMARY_FOUND_CONTAINING_ALL_TERMS + " "); 728 if (SomeTermMatches > 0) 729 document.writeln(PrintNumResults(SomeTermMatches) + " " + STR_SUMMARY_FOUND_CONTAINING_SOME_TERMS); 730 document.writeln("<br />"); 731 } 732 else if (numwords > 1 && andq == 1) //AND 733 document.writeln(PrintNumResults(fullmatches) + " " + STR_SUMMARY_FOUND_CONTAINING_ALL_TERMS + "<br />"); 734 else 735 document.writeln(PrintNumResults(matches) + " " + STR_SUMMARY_FOUND + "<br />"); 736 737 document.writeln("</div>\n"); 738 739 // number of pages of results 740 num_pages = Math.ceil(matches / per_page); 741 if (num_pages > 1) 742 document.writeln("<div class=\"result_pagescount\"><br />" + num_pages + " " + STR_PAGES_OF_RESULTS + "</div>\n"); 743 744 // Show recommended links if any 745 if (Recommended == 1) 746 { 747 num_recs_found = 0; 748 rec_count = recommended.length; 749 for (rl = 0; rl < rec_count && num_recs_found < RecommendedMax; rl++) 750 { 751 sep = recommended[rl].lastIndexOf(" "); 752 if (sep > -1) 753 { 754 rec_word = recommended[rl].slice(0, sep); 755 rec_idx = parseInt(recommended[rl].slice(sep)); 756 for (sw = 0; sw <= numwords; sw++) 757 { 758 if (sw == numwords) 759 { 760 match_result = wordcasecmp(rec_word, queryForSearch); 761 } 762 else 763 { 764 if (UseWildCards[sw] == 1) 765 { 766 if (SearchAsSubstring == 0) 767 pattern = "^" + RegExpSearchWords[sw] + "$"; 768 else 769 pattern = RegExpSearchWords[sw]; 770 re = new RegExp(pattern, "g"); 771 match_result = rec_word.search(re); 772 } 773 else if (SearchAsSubstring == 0) 774 { 775 match_result = wordcasecmp(rec_word, searchWords[sw]); 776 } 777 else 778 match_result = rec_word.indexOf(searchWords[sw]); 779 } 780 if (match_result != -1) 781 { 782 if (num_recs_found == 0) 783 { 784 document.writeln("<div class=\"recommended\">"); 785 document.writeln("<div class=\"recommended_heading\">" + STR_RECOMMENDED + "</div>"); 786 } 787 pgurl = pagedata[rec_idx][PAGEDATA_URL]; 788 pgtitle = pagedata[rec_idx][PAGEDATA_TITLE]; 789 pgdesc = pagedata[rec_idx][PAGEDATA_DESC]; 790 urlLink = pgurl; 791 if (GotoHighlight == 1) 792 { 793 if (SearchAsSubstring == 1) 794 urlLink = AddParamToURL(urlLink, "zoom_highlightsub=" + queryForURL); 795 else 796 urlLink = AddParamToURL(urlLink, "zoom_highlight=" + queryForURL); 797 } 798 if (PdfHighlight == 1) 799 { 800 if (urlLink.indexOf(".pdf") != -1) 801 urlLink = urlLink+"#search=""+query+"""; 802 } 803 document.writeln("<div class=\"recommend_block\">"); 804 document.writeln("<div class=\"recommend_title\">"); 805 document.writeln("<a href=\"" + urlLink + "\"" + target + ">"); 806 if (pgtitle.length > 1) 807 PrintHighlightDescription(pgtitle); 808 else 809 PrintHighlightDescription(pgurl); 810 document.writeln("</a></div>"); 811 document.writeln("<div class=\"recommend_description\">") 812 PrintHighlightDescription(pgdesc); 813 document.writeln("</div>"); 814 document.writeln("<div class=\"recommend_infoline\">" + pgurl + "</div>"); 815 document.writeln("</div>"); 816 num_recs_found++; 817 break; 818 } 819 } 820 } 821 } 822 if (num_recs_found > 0) 823 document.writeln("</div"); 824 } 825 826 // Show sorting options 827 if (matches > 1) 828 { 829 if (UseDateTime == 1) 830 { 831 document.writeln("<div class=\"sorting\">"); 832 if (sort == 1) 833 document.writeln("<a href=\"" + SelfURL + "?zoom_query=" + queryForURL + "&zoom_page=" + page + "&zoom_per_page=" + per_page + query_zoom_cats + "&zoom_and=" + andq + "&zoom_sort=0\">" + STR_SORTBY_RELEVANCE + "</a> / <b>" + STR_SORTEDBY_DATE + "</b>"); 834 else 835 document.writeln("<b>" + STR_SORTEDBY_RELEVANCE + "</b> / <a href=\"" + SelfURL + "?zoom_query=" + queryForURL + "&zoom_page=" + page + "&zoom_per_page=" + per_page + query_zoom_cats + "&zoom_and=" + andq + "&zoom_sort=1\">" + STR_SORTBY_DATE + "</a>"); 836 document.writeln("</div>"); 837 } 838 } 839 840 // determine current line of result from the output array 841 if (page == 1) { 842 arrayline = 0; 843 } else { 844 arrayline = ((page - 1) * per_page); 845 } 846 847 // the last result to show on this page 848 result_limit = arrayline + per_page; 849 850 // display the results 851 while (arrayline < matches && arrayline < result_limit) { 852 ipage = output[arrayline][0]; 853 score = output[arrayline][1]; 854 855 pgurl = pagedata[ipage][PAGEDATA_URL]; 856 pgtitle = pagedata[ipage][PAGEDATA_TITLE]; 857 pgdesc = pagedata[ipage][PAGEDATA_DESC]; 858 pgimage = pagedata[ipage][PAGEDATA_IMG]; 859 860 urlLink = pgurl; 861 if (GotoHighlight == 1) 862 { 863 if (SearchAsSubstring == 1) 864 urlLink = AddParamToURL(urlLink, "zoom_highlightsub=" + queryForURL); 865 else 866 urlLink = AddParamToURL(urlLink, "zoom_highlight=" + queryForURL); 867 } 868 if (PdfHighlight == 1) 869 { 870 if (urlLink.indexOf(".pdf") != -1) 871 urlLink = urlLink+"#search=""+query+"""; 872 } 873 874 if (arrayline % 2 == 0) 875 document.writeln("<div class=\"result_block\">"); 876 else 877 document.writeln("<div class=\"result_altblock\">"); 878 879 if (UseZoomImage == 1) 880 { 881 if (pgimage.length > 1) 882 { 883 document.writeln("<div class=\"result_image\">"); 884 document.writeln("<a href=\"" + urlLink + "\"" + target + "><img src=\"" + pgimage + "\" alt=\"\" class=\"result_image\"></a>"); 885 document.writeln("</div>"); 886 } 887 } 888 889 document.writeln("<div class=\"result_title\">"); 890 if (DisplayNumber == 1) 891 document.writeln("<b>" + (arrayline+1) + ".</b> "); 892 893 if (DisplayTitle == 1) 894 { 895 document.writeln("<a href=\"" + urlLink + "\"" + target + ">"); 896 PrintHighlightDescription(pgtitle); 897 document.writeln("</a>"); 898 } 899 else 900 document.writeln("<a href=\"" + urlLink + "\"" + target + ">" + pgurl + "</a>"); 901 902 if (UseCats) 903 { 904 catpage = pageinfo[ipage][PAGEINFO_CAT]; 905 document.write("<span class=\"category\">"); 906 for (cati = 0; cati < NumCats; cati++) 907 { 908 if (catpage.charAt(cati) == "1") 909 document.write(" ["+catnames[cati]+"]"); 910 } 911 document.writeln("</span>"); 912 } 913 document.writeln("</div>"); 914 915 if (DisplayMetaDesc == 1) 916 { 917 // print meta description 918 document.writeln("<div class=\"description\">"); 919 PrintHighlightDescription(pgdesc); 920 document.writeln("</div>\n"); 921 } 922 923 info_str = ""; 924 925 if (DisplayTerms == 1) 926 info_str += STR_RESULT_TERMS_MATCHED + " " + output[arrayline][2]; 927 928 if (DisplayScore == 1) { 929 if (info_str.length > 0) 930 info_str += " - "; 931 info_str += STR_RESULT_SCORE + " " + score; 932 } 933 934 if (DisplayDate == 1) 935 { 936 pgdate = pageinfo[ipage][PAGEINFO_DATETIME]; 937 if (pgdate > 0) 938 { 939 datetime = new Date(pgdate*1000); 940 if (info_str.length > 0) 941 info_str += " - "; 942 info_str += datetime.getDate() + " " + months[datetime.getMonth()] + " " + datetime.getFullYear(); 943 } 944 } 945 946 if (DisplayFilesize == 1) 947 { 948 filesize = pageinfo[ipage][PAGEINFO_FILESIZE];
949 filesize = Math.ceil(filesize / 1024); 950 if (filesize < 1) 951 filesize = 1; 952 953 if (info_str.length > 0) 954 info_str += " - "; 955 info_str += filesize + "k"; 956 } 957 958 if (DisplayURL == 1) { 959 if (info_str.length > 0) 960 info_str += " - "; 961 info_str += STR_RESULT_URL + " " + pgurl; 962 } 963 964 document.writeln("<div class=\"infoline\">"); 965 document.writeln(info_str); 966 document.writeln("</div></div>\n"); 967 arrayline++; 968 } 969 970 // Show links to other result pages 971 if (num_pages > 1) { 972 // 10 results to the left of the current page 973 start_range = page - 10; 974 if (start_range < 1) 975 start_range = 1; 976 977 // 10 to the right 978 end_range = page + 10; 979 if (end_range > num_pages) 980 end_range = num_pages; 981 982 document.writeln("<div class=\"result_pages\">" + STR_RESULT_PAGES + " "); 983 if (page > 1) 984 document.writeln("<a href=\"" + SelfURL + "?zoom_query=" + queryForURL + "&zoom_page=" + (page-1) + "&zoom_per_page=" + per_page + query_zoom_cats + "&zoom_and=" + andq + "&zoom_sort=" + sort + "\"><< " + STR_RESULT_PAGES_PREVIOUS + "</a> "); 985 for (i = start_range; i <= end_range; i++) 986 { 987 if (i == page) 988 document.writeln(page + " "); 989 else 990 document.writeln("<a href=\"" + SelfURL + "?zoom_query=" + queryForURL + "&zoom_page=" + i + "&zoom_per_page=" + per_page + query_zoom_cats + "&zoom_and=" + andq + "&zoom_sort=" + sort + "\">" + i + "</a> "); 991 } 992 if (page != num_pages) 993 document.writeln("<a href=\"" + SelfURL + "?zoom_query=" + queryForURL + "&zoom_page=" + (page+1) + "&zoom_per_page=" + per_page + query_zoom_cats + "&zoom_and=" + andq + "&zoom_sort=" + sort + "\">" + STR_RESULT_PAGES_NEXT + " >></a> "); 994 document.writeln("</div>"); 995 } 996 997 document.writeln("</div>"); // end results style tag 998 999 if (Timing == 1) { 1000 timeEnd = new Date(); 1001 timeDifference = timeEnd - timeStart; 1002 document.writeln("<div class=\"searchtime\"><br /><br />" + STR_SEARCH_TOOK + " " + (timeDifference/1000) + " " + STR_SECONDS + ".</div>\n"); 1003 } 1004 1005 if (ZoomInfo == 1) 1006 document.writeln("<center><p><small>" + STR_POWEREDBY + " <a href=\"http://www.wrensoft.com/zoom/\" target=\"_blank\"><b>Zoom Search Engine</b></a></small></p></center>"); 1007} 1008
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.