You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							471 lines
						
					
					
						
							18 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							471 lines
						
					
					
						
							18 KiB
						
					
					
				| //*============================================================================== | |
| //*    ** DO NOT REMOVE OR MODIFY THIS COPYRIGHT MESSAGE ** | |
| //* | |
| //*    Helpware Search 1.1 | |
| //*    Copyright (c) 2004-2011 The Helpware Group | |
| //*    http://helpware.net/FAR/ | |
| //*    Requires a Modern Browser that supports JavaScript such as Firefox/IE4/GoogleChrome/Opera/Safari/Netscape | |
| //*    WARNING: You must purchase a copy of FAR HTML v4 or greater to use this file. | |
| //* | |
| //*============================================================================== | |
| //*  31-May-2005: RWC - Fixed Offby one error in highlighting. First word would not highlight.  | |
| //*  10-June-2009: RWC - All files now saved in UTF-8 file format. Search is now Unicode based. Previously ANSI based. | |
| //*     - Added reBreakChars to allow multiple text break chars. Was just space char (0x20). | |
| //*  12-Sept-2011: RWC - Search highlighting now works for all browsers (previously just Internet Explorer). | |
| //*  04-Sept-2012: RWC - Select first item when result list loads. | |
| //* | |
|  | |
| 
 | |
| //var SearchFiles = ["index.htm","Search_OzNet.html"... | |
| //var SearchTitles =["Molecular products","OzNet Web"... | |
| //var SearchIndexes = [["0-0",[128,129,256,257,323]]... | |
| // ...,["WATER;",[355,361]],["WATER-CIRCULATOR",[383]],... | |
|  | |
| 
 | |
| //Options | |
| var PARAM_PartialMatchOK = true; | |
| var PARAM_TargetWindow = 'content'; | |
| 
 | |
| //Globals - SearchResults is an array of Page Indexes | |
| var SearchResults = []; | |
| var gFindList = []; | |
| var gFirstFindCall = true; | |
| 
 | |
| //Chars that break words in an entry field   //RWC002 - Space, Ideographic Space | |
| var reBreakChars = new RegExp( "[\u0020\u3000]{1}", "gi" );     | |
| 
 | |
| //------------------------------------------------------------------------------ | |
| // Get Operator Type | |
| //   text should be Uppercase. Return 0 = normal search text | |
| //------------------------------------------------------------------------------ | |
| var OPT_AND = 1; | |
| var OPT_OR  = 2; | |
| var OPT_NOT = 3; | |
| function xxGetOpType(text) { | |
|   if ((text=="NOT")||(text=="!")) return OPT_NOT; | |
|   else if ((text=="AND")||(text== "&")||(text== "+")) return OPT_AND; | |
|   else if ((text=="OR")||(text== "|")) return OPT_OR; | |
|   else return(0); | |
|   } | |
| 
 | |
| 
 | |
| //---------------------------------------------------------------------------- | |
| // ProcessSearchTerms() | |
| //---------------------------------------------------------------------------- | |
| // Params | |
| //   ss -- string of terms to parse and find | |
| //   DefaultOp - Search Operator to default to for each list term (OPT_OR, OPT_AND, OPT_NOT) | |
| // Desc | |
| //   Parse ss string --> String list. Default Return. | |
| //   Items forced Uppercase (since Database and all calls use uppercase for speed) | |
| //   User can insert override 'AND', 'OR', 'NOT' into the list of terms to | |
| //   alter how the next item is searched. After that we go back to Defaultop. | |
| // Optimization | |
| //   Pass in SearchIndexes + SearchResults arrays (by ref) so no global lookups - speed up loops | |
| //---------------------------------------------------------------------------- | |
| function ProcessSearchTerms(ss, DefaultOp) { | |
|   //Parse string into array | |
|   var items = ss.split(reBreakChars); | |
| 
 | |
|   //---------------------------------------- | |
|   // Remove empty list entried due to multiple spaces passed to split() | |
|   // Force all items to Uppercase | |
|   //---------------------------------------- | |
|   var c = 0; | |
|   for (var i = 0; i < items.length; i++) | |
|     if (items[i] != "") { items[c] = items[i].toUpperCase(); c++; } | |
|   items.length = c; | |
| 
 | |
|   var CheckOp = true; | |
|   var otype = DefaultOp; | |
|   for (var i = 0; i < items.length; i++) { | |
| 
 | |
|     //---------------------------------------- | |
|     // Check for Override Operators. | |
|     // Don't allow Op override if working with NOT terms | |
|     //---------------------------------------- | |
|     if ((CheckOp) && (DefaultOp != OPT_NOT)) { | |
|       otype = xxGetOpType(items[i]); | |
|       CheckOp = (otype == 0); | |
|       if (CheckOp) otype = DefaultOp; | |
|       else continue; | |
|     } | |
|     CheckOp = true; | |
| 
 | |
|     //---------------------------------------- | |
|     // Find Text results ==> SearchResults | |
|     //---------------------------------------- | |
|     if (otype==OPT_OR)  FindText_OR(items[i], SearchIndexes, SearchResults); | |
|     if (otype==OPT_AND) FindText_AND(items[i], SearchIndexes, SearchResults); | |
|     if (otype==OPT_NOT) FindText_DEL(items[i], SearchIndexes, SearchResults); | |
| 
 | |
|     //build list of find words | |
|     if (DefaultOp!=OPT_NOT) | |
|       gFindList[gFindList.length] = items[i]; | |
| 
 | |
|     //Clear global flag | |
|     gFirstFindCall = false; | |
|   } | |
| } | |
| 
 | |
| //------------------------------------------------------------------------------ | |
| // s1 - Any words (OR) -->> one or more words present in a document is a result. Ie. Get the OR of all word search results. | |
| // s2 - All words (AND) -->> all words must be present in each result document. Ie. Get the AND of all word search results. | |
| // s3 - Not these words (NOT) -->> Only makes sense when used with the above. Knock out Topics containing these words. | |
| // b4 - Partial Word matching is ok - otherwise we match exaclty what is entered | |
| // s5 - target window -- default = 'content' | |
| // ---------------------------------------------- | |
| // -- To match similar spellings in a full-text search, select the Match similar words check box. | |
| //    eg  "add", "adds", and "added". | |
| // -- To search for words in document titles only, select the Search titles only check box. | |
| // -- To highlight words in searched topics | |
| //------------------------------------------------------------------------------ | |
| //  Notes | |
| //  - DoSearch(s1, s2, s3. partial) | |
| //     S1 is a string of words separated by spaces. Words are OR'd together | |
| //     S2 is a string of words separated by spaces. Words are AND'd together | |
| //     S3 is a string of words separated by spaces. Words are Deleted from other results | |
| //  - User can override default properties of S1 and S2 by using the following keywords | |
| //    "OR","|" the next word is OR'd | |
| //    "AND","&","+" the next word is AND'd | |
| //    "NOT","!" the next word is removed | |
| // | |
| //------------------------------------------------------------------------------ | |
| function DoSearch(s1, s2, s3, b4, s5) | |
| { | |
|   //---------------------------------------------------------------------------- | |
|   // Init | |
|   //   - Reset First AND call flag. The first time must be an OR. | |
|   //   - Clear SearchResults list | |
|   //   - Clear target list control | |
|   //---------------------------------------------------------------------------- | |
|   gFirstFindCall = true; | |
|   SearchResults.length = 0; | |
|   gFindList.length = 0; | |
|   if (document.forms['searchform'].SearchResultList) | |
|     document.forms['searchform'].SearchResultList.length = 0; | |
|   PARAM_PartialMatchOK = b4; | |
|   if (s5 == '') PARAM_TargetWindow = 'content'; | |
|     else PARAM_TargetWindow = s5; | |
| 
 | |
|   //---------------------------------------------------------------------------- | |
|   //1. (OR) Find documents with "Any of these Words"  ==> SearchResults | |
|   //2. (AND) Find documents with "All these Words"  ==> SearchResults | |
|   //3. (NOT) SearchResults must NOT files containing these words ==> Remove from SearchResults | |
|   //---------------------------------------------------------------------------- | |
|   ProcessSearchTerms(s1, OPT_OR); | |
|   ProcessSearchTerms(s2, OPT_AND); | |
|   ProcessSearchTerms(s3, OPT_NOT); | |
|    | |
|   //---------------------------------------------------------------------------- | |
|   // Display SearchResults | |
|   //---------------------------------------------------------------------------- | |
|   if (SearchResults.length == 0) { | |
|     alert("No matches found!"); | |
|     return(0); } | |
| 
 | |
|   //Search Results list exists   | |
|   if (document.forms['searchform'].SearchResultList) | |
|   { | |
|     //Fill SearchResults List -- 500 item limit same as H1.x and H2.x | |
|     for(var i=0;((i<SearchResults.length) && (i<500));i++) { | |
|       var new_option = document.createElement('option'); | |
|       new_option.text = SearchTitles[SearchResults[i]]; | |
|       new_option.text= new_option.text.replace(/\&/g,'&'); | |
|       new_option.value = SearchFiles[SearchResults[i]]; | |
|       document.forms['searchform'].SearchResultList[i]=new_option; | |
|     } | |
| 
 | |
|     //open the first file | |
|     // ** Comment this line out if you don't want the first Search result displayed automatically **  | |
|     OpenResultListDoc(); | |
| 
 | |
|   } | |
|   else { | |
|     ShowSearchResultsWindow(); | |
|   } | |
| 
 | |
|   return(SearchResults.length); | |
| 
 | |
| } | |
| 
 | |
| 
 | |
| 
 | |
| //---------------------------------------------------------------------------- | |
| // OR -- Add only Unique items to the SearchResults Array | |
| //   items - array of Idxs to OR into SearchResults | |
| //   SearchResults - Pass in by ref to to optomize global scope access | |
| //---------------------------------------------------------------------------- | |
| function OR_WithSearchResults(items, SearchResults) { | |
|   var found; | |
|   for (var i = 0; i < items.length; i++) { | |
| 
 | |
|     //Already in list? | |
|     found = false; | |
|     for (var k = 0; (k < SearchResults.length) && (!found); k++) | |
|       if (items[i] == SearchResults[k]) | |
|         found = true; | |
| 
 | |
|     //Not in list? Then Add it! | |
|     if (!found) | |
|       SearchResults[SearchResults.length] = items[i]; | |
|   } | |
| } | |
| 
 | |
| //---------------------------------------------------------------------------- | |
| // AND -- Keep only the intersection of items and SearchResults | |
| //   items - array of Idxs to AND into SearchResults | |
| //   SearchResults - Pass in by ref to to optomize global scope access | |
| //---------------------------------------------------------------------------- | |
| function AND_WithSearchResults(items, SearchResults) { | |
|   var count = 0; | |
|   for (var i = 0; i < SearchResults.length; i++) | |
|     for (var k = 0; k < items.length; k++) { | |
|       if (items[k] == SearchResults[i]) { | |
|         SearchResults[count] = SearchResults[i]; | |
|         count++; | |
|         break; | |
|       } | |
|     } | |
|   SearchResults.length = count; | |
| } | |
| 
 | |
| //---------------------------------------------------------------------------- | |
| // DEL -- Remove items from SearchResults list | |
| //   items - array of Idxs to DEL from SearchResults | |
| //   SearchResults - Pass in by ref to to optomize global scope access | |
| //---------------------------------------------------------------------------- | |
| function DEL_WithSearchResults(items, SearchResults) { | |
|   var count = 0; | |
|   var found;  | |
|   for (var i = 0; i < SearchResults.length; i++) { | |
| 
 | |
|     //Its Delete Item in the Result list? | |
|     found = false; | |
|     for (var k = 0; (k < items.length) && (!found); k++) | |
|       if (items[k] == SearchResults[i]) { | |
|         found = true; | |
|         break; | |
|       } | |
| 
 | |
|     //Not Found in delete list? then keep Result | |
|     if (!found) { | |
|       SearchResults[count] = SearchResults[i]; | |
|       count++; | |
|       } | |
|   } | |
|   SearchResults.length = count; | |
| } | |
| 
 | |
| 
 | |
| //---------------------------------------------------------------------------- | |
| // Find Database Text | |
| // By this stage all strings are Uppercase | |
| // Optimization | |
| //   - String Compare - check length the same, and check first char match before | |
| //     going on to actually do a string compare. | |
| //   - Pass Global SearchIndexes in instead of accessing out of scope many times | |
| //---------------------------------------------------------------------------- | |
|  | |
| //Find Text (in SearchIndex passed in by ref) and OR matches into SearchResults list | |
| function FindText_OR(SrchText, SearchIndexes, SearchResults) | |
| { | |
|   if (PARAM_PartialMatchOK) { | |
|     for(var i=0;i<SearchIndexes.length;i++) | |
|       if((SearchIndexes[i][0].length >= SrchText.length) | |
|       && (SearchIndexes[i][0].indexOf(SrchText) >= 0)) { | |
|         OR_WithSearchResults(SearchIndexes[i][1], SearchResults); | |
|       } | |
|   } | |
|   else { | |
|     //Not Partial - Fast - Find exact match and break out   | |
|     for(var i=0;i<SearchIndexes.length;i++) | |
|       if((SearchIndexes[i][0].length == SrchText.length) | |
|       && (SearchIndexes[i][0] == SrchText)) { | |
|         OR_WithSearchResults(SearchIndexes[i][1], SearchResults); | |
|         break; | |
|       } | |
|   } | |
| } | |
| 
 | |
| //Find Text (in SearchIndex passed in by ref) and AND matches into SearchResults list | |
| function FindText_AND(SrchText, SearchIndexes, SearchResults) | |
| { | |
|   //Optimization: Take copy to minimize global out of scope lookups | |
|   var FirstFindCall = gFirstFindCall; | |
| 
 | |
|   //If 2nd or 3rd... item and No SearchResults then Nothing to AND with | |
|   if ((!FirstFindCall) && (SearchResults.length == 0)) | |
|     return; | |
| 
 | |
|   var tempList = []; | |
|   if (PARAM_PartialMatchOK) { | |
|     for(var i=0;i<SearchIndexes.length;i++) | |
|       if((SearchIndexes[i][0].length >= SrchText.length) | |
|       && (SearchIndexes[i][0].indexOf(SrchText) >= 0)) | |
|         OR_WithSearchResults(SearchIndexes[i][1], tempList); | |
|   } | |
|   else { | |
|     //Not Partial - Fast - Find exact match and break out | |
|     for(var i=0;i<SearchIndexes.length;i++) | |
|       if((SearchIndexes[i][0].length == SrchText.length) | |
|       && (SearchIndexes[i][0] == SrchText)) { | |
|         OR_WithSearchResults(SearchIndexes[i][1], tempList); | |
|         //Exact match - we are done | |
|         break; | |
|       } | |
|   } | |
| 
 | |
|   //Add Results | |
|   //1st call wont have results yet -- We must OR into SearchResults as AND would not do nothing | |
|   if (tempList.length >= 0) { | |
|     if (FirstFindCall) | |
|       OR_WithSearchResults(tempList, SearchResults); | |
|     else | |
|       AND_WithSearchResults(tempList, SearchResults); | |
|   } | |
|   else | |
|     //No Results + not first call -- AND will wipe out all results | |
|     if (!FirstFindCall) | |
|       SearchResults.length = 0; | |
| } | |
| 
 | |
| 
 | |
| //Find Text (in SearchIndex passed in by ref) and DELETE matches from SearchResults list | |
| function FindText_DEL(SrchText, SearchIndexes, SearchResults) | |
| { | |
|   //first check there is something to delete from | |
|   if (SearchResults.length) | |
|     for(var i=0;i<SearchIndexes.length;i++) | |
|       if((SearchIndexes[i][0].length == SrchText.length) | |
|       &&(SearchIndexes[i][0]==SrchText)) { | |
| 
 | |
|         //Send match words idx array off to be deleted from SearchResults | |
|         DEL_WithSearchResults(SearchIndexes[i][1], SearchResults); | |
| 
 | |
|         //We found the word and its idx array data -- Jobs done | |
|         break; | |
|       } | |
| } | |
| 
 | |
| 
 | |
| 
 | |
| //------------------------------------------------------------------------------ | |
| // Highlight search hits | |
| //------------------------------------------------------------------------------ | |
|  | |
| var targetWin = null; | |
| var highlightStartTag = "<span style='background-color:#FFFF00;color:#222222;'>";  //yellow highlight | |
| var highlightEndTag = "</span>"; | |
| 
 | |
| //------------------------------------------------------------------------------ | |
| // Highlight text by adding HTML tags before and after all occurrences of the search term. | |
| // Acknowledgments: Thank you Sujit Kumar Shah - http://www.sks.com.np/article/14/pure-javascript-search-and-text-highlighting.html | |
| //------------------------------------------------------------------------------ | |
| function doHighlight(bodyText, searchTerm)  | |
| { | |
|   var newText = ""; | |
|   var i = -1; | |
|   var lcSearchTerm = searchTerm.toLowerCase(); | |
|   var lcBodyText = bodyText.toLowerCase(); | |
|      | |
|   while (bodyText.length > 0) { | |
|     i = lcBodyText.indexOf(lcSearchTerm, i+1); | |
|     if (i < 0) { | |
|       newText += bodyText; | |
|       bodyText = ""; | |
|     } else { | |
|       // skip anything inside an HTML tag | |
|       if (bodyText.lastIndexOf(">", i) >= bodyText.lastIndexOf("<", i)) { | |
|         // skip anything inside a <script> block | |
|         if (lcBodyText.lastIndexOf("/script>", i) >= lcBodyText.lastIndexOf("<script", i)) { | |
|           newText += bodyText.substring(0, i) + highlightStartTag + bodyText.substr(i, searchTerm.length) + highlightEndTag; | |
|           bodyText = bodyText.substr(i + searchTerm.length); | |
|           lcBodyText = bodyText.toLowerCase(); | |
|           i = -1; | |
|         } | |
|       } | |
|     } | |
|   } | |
|   return newText; | |
| } | |
| 
 | |
| // Highlight search terms | |
| function HighlightTopic() { | |
|   var bodyText = targetWin.document.body.innerHTML; | |
|   for(var k = 0; k < gFindList.length; k++) { | |
|     bodyText = doHighlight(bodyText, gFindList[k]); | |
|   } | |
|   targetWin.document.body.innerHTML = bodyText; | |
| } | |
| 
 | |
| //------------------------------------------------------------------------------ | |
| // Open List item in Browser - Target = PARAM_TargetWindow | |
| //------------------------------------------------------------------------------ | |
| function OpenResultListDoc() { | |
|   //Something selected in the search result list? | |
|   var iSelect = document.forms['searchform'].SearchResultList.selectedIndex; | |
|   if (iSelect < 0) { | |
|     iSelect = 0; | |
|     document.forms['searchform'].SearchResultList.selectedIndex = 0; | |
|   } | |
| 
 | |
|   //Open the selected file | |
|   if (window.navigator.userAgent.indexOf("Netscape") > 0) { | |
|     top.right.location.href = document.forms['searchform'].SearchResultList.options[iSelect].value; | |
|     targetWin = top.right.window; | |
|   } | |
|   else //all other browsers | |
|     targetWin = open(document.forms['searchform'].SearchResultList.options[iSelect].value, PARAM_TargetWindow); | |
| 
 | |
|   //Highlight search hits on a delay | |
|   if (targetWin) | |
|     setTimeout('HighlightTopic()',1000); | |
| } | |
| 
 | |
| 
 | |
| //------------------------------------------------------------------------------ | |
| // Search Results Window -- called if user does not | |
| //  -- 500 item limit same as H1.x and H2.x | |
| //------------------------------------------------------------------------------ | |
| function ShowSearchResultsWindow() { | |
|   var newWindow = window.open("about:blank", "searchValue", "width=500, height=300, resizable=yes, maximizable=no, status=yes, scrollbars=yes"); | |
|   newWindow.document.write('<html>\n<head>\n<title>Search Results</title>\n'); | |
|   newWindow.document.write('</head>\n'); | |
|   newWindow.document.write('<body>\n'); | |
| 
 | |
|   //Fill SearchResults List | |
|   for(var i=0;((i<SearchResults.length) && (i<500));i++) { | |
|     //Search Topic Title | |
|     var aTitle = SearchTitles[SearchResults[i]]; | |
|     //URL | |
|     var aURL = SearchFiles[SearchResults[i]]; | |
| 
 | |
|     newWindow.document.write('<p>Title: '+ aTitle +'<br>\n'); | |
|     newWindow.document.write('URL: <a href="'+ aURL +'">'+aURL+'</a></p>\n'); | |
|   } | |
| 
 | |
|   newWindow.document.write("</body>\n"); | |
|   newWindow.document.write("</html>\n"); | |
|   newWindow.document.close(); | |
| //  self.name = "main"; | |
| } | |
| 
 | |
| //------------------------------------------------------------------------------ | |
| // Other Script | |
| //------------------------------------------------------------------------------ | |
| function CloseNavPane() { | |
|   if ((top.content.location == null) || (top.content.location == undefined) || (typeof(top.content.location.href) != "string") || (top.content.location.href == "")) | |
|     top.location="index.htm";   //can't work out the current content file - return home | |
|   else | |
|     top.location=top.content.location; | |
| } | |
| 
 | |
| 
 | |
| //------------------------------------------------------------------------------ | |
| // | |
| //------------------------------------------------------------------------------ | |
|  | |
| 
 | |
| 
 | |
| 
 |