home *** CD-ROM | disk | FTP | other *** search
/ ftp6.securdisc.net / ftp6.securdisc.net.tar / ftp6.securdisc.net / SecurDiscViewer_Chs.chm / scripts / common.searchengine.js < prev    next >
Text File  |  2010-08-08  |  22KB  |  920 lines

  1. if ( !this["Schema"] )
  2.     Schema = function ( ) {};
  3.  
  4. Schema.Search = function ( init ) 
  5. {
  6.     var self = this;
  7.     var fulltextindex = null;
  8.     var parseTree = [];
  9.     var metaOptions;
  10.     var metaRegex;
  11.     var options;
  12.     
  13.     var _ID;
  14.     var _TITLE;
  15.     var _FILENAME;
  16.     var _FILESIZE;
  17.     var _META;
  18.     var _CONTENT;
  19.     var defaultLocations;
  20.     
  21.     
  22.     this.CreateExpressionTree = function ( obj, options )
  23.     {
  24.         for ( var i = 0; i < obj.length; i++ )
  25.         {
  26.             if ( obj[i].type == 'AND' )
  27.             {
  28.                 if ( obj[i].what && obj[i].what.length > 0 )
  29.                 {
  30.                     obj[i].regex = Schema.Regex.Create ( obj[i].what, options );
  31.                     if ( obj[i].metaOptions || obj[i].metaOptions == 0 )
  32.                         obj[i].metaRegex = Schema.Regex.Create ( obj[i].what, obj[i].metaOptions );
  33.                     else
  34.                         obj[i].metaRegex = Schema.Regex.Create ( obj[i].what, metaOptions );
  35.                 }
  36.             }
  37.             else
  38.             {
  39.                 for ( var j = 0; j < obj[i].expr.length; j++ )
  40.                 {
  41.                     if ( obj[i].expr[j].what && obj[i].expr[j].what.length > 0 )
  42.                     {
  43.                         obj[i].expr[j].regex = Schema.Regex.Create ( obj[i].expr[j].what, options );
  44.                         if ( obj[i].expr[j].metaOptions || obj[i].expr[j].metaOptions == 0 )
  45.                             obj[i].expr[j].metaRegex = Schema.Regex.Create ( obj[i].expr[j].what, obj[i].expr[j].metaOptions );
  46.                         else
  47.                             obj[i].expr[j].metaRegex = Schema.Regex.Create ( obj[i].expr[j].what, metaOptions );
  48.                     }
  49.                 }
  50.             }
  51.         }
  52.         
  53.         return ( obj );
  54.     };
  55.  
  56.  
  57.  
  58.     this.Execute = function ( tokenStream )
  59.     {    
  60.         var result = [];
  61.  
  62.         parseTree = Parse ( tokenStream );
  63.         
  64.         var expressionTree = self.CreateExpressionTree ( parseTree, options );
  65.         if ( expressionTree.length == 0 )
  66.             return ( result );
  67.     
  68.         for ( var i = 0; i < fulltextindex.length; i++ )
  69.         {
  70.             var item = fulltextindex[i];
  71.             
  72.             var itemIsResult = true;
  73.             for ( var j = 0; j < expressionTree.length; j++ )
  74.             {
  75.                 if ( !self.Search(expressionTree[j], item) )
  76.                 {
  77.                     itemIsResult = false;
  78.                     break;
  79.                 }
  80.             }
  81.             
  82.             if ( itemIsResult )
  83.                 result.push ( i );
  84.         }
  85.         
  86.         return ( result );
  87.     };
  88.  
  89.  
  90.  
  91.     this.GetExpressions = function ( )
  92.     {
  93.         return ( parseTree );
  94.     };
  95.  
  96.      
  97.     this.GetFulltextIndex = function ( )
  98.      {
  99.          return ( fulltextindex );
  100.      };
  101.      
  102.  
  103.     this.GetMetaOptions = function ( )
  104.     {
  105.         return ( metaOptions );
  106.     };
  107.  
  108.      
  109.      this.GetOptions = function ( )
  110.      {
  111.          return ( options );
  112.      };
  113.      
  114.  
  115.     var Initialize = function ( init )
  116.     {
  117.         fulltextindex = init.fulltextindex;
  118.         if ( init.options )
  119.             options = init.options;
  120.         else
  121.             options = Schema.Regex.Options.IgnoreCase;
  122.             
  123.         if ( init.metaOptions )
  124.             metaOptions = init.metaOptions;
  125.         else
  126.             metaOptions = Schema.Regex.Options.IgnoreCase;
  127.  
  128.         _ID = Schema.Search.Location.Id;
  129.         _TITLE = Schema.Search.Location.Title;
  130.         _FILENAME = Schema.Search.Location.Filename;
  131.         _FILESIZE = Schema.Search.Location.Filesize;
  132.         _META = Schema.Search.Location.Meta;
  133.         _CONTENT = Schema.Search.Location.Content;
  134.         
  135.         if ( init.defaultLocations )
  136.             defaultLocations = init.defaultLocations;
  137.         else
  138.             defaultLocations = [_TITLE, _CONTENT];
  139.     };
  140.  
  141.  
  142.     this.Search = function ( info, item )
  143.     {
  144.         if ( info.type == 'AND' )
  145.         {
  146.             return ( self.SearchAnd(info, item) );
  147.         }
  148.         else
  149.         {
  150.             for ( var i = 0; i < info.expr.length; i++ )
  151.             {
  152.                 if ( self.SearchAnd(info.expr[i], item) )
  153.                     return ( true );
  154.             }
  155.             return ( false );
  156.         }
  157.     }; 
  158.     
  159.     
  160.     this.SearchAnd = function ( info, item )
  161.     {
  162.         for ( var i = 0; i < info.where.length; i++ )
  163.         {
  164.             if ( info.where[i] == _ID )
  165.             {
  166.                 if ( item[_ID] == info.what )
  167.                     return ( !info.invert );
  168.             }
  169.             else if ( info.where[i] == _META )
  170.             {
  171.                 if ( self.SearchMeta(info, item) )
  172.                     return ( !info.invert );
  173.             }
  174.             else
  175.             {
  176.                 if ( info.regex.exec(item[info.where[i]]) )
  177.                     return ( !info.invert );
  178.             }
  179.         }
  180.         return ( info.invert );
  181.     };
  182.     
  183.     
  184.     this.SearchMeta = function ( info, item )
  185.     {
  186.         var metaexp = info.metaRegex ? info.metaRegex : metaRegex; 
  187.     
  188.         if ( !item[_META] || item[_META].length <= 0 )
  189.             return ( false );
  190.         
  191.         if ( !info.constraints || info.constraints.length <= 0 )
  192.         {
  193.             if ( !info.what || info.what == "" )
  194.             {
  195.                 for ( var name in item[_META] )
  196.                     return ( true );
  197.                 return ( false );
  198.             }
  199.             else
  200.             {
  201.                 for ( var name in item[_META] )
  202.                 {
  203.                     if ( metaexp.exec(item[_META][name]) )
  204.                         return ( true ); 
  205.                 }
  206.                 return ( false );
  207.             }
  208.         }
  209.         else
  210.         {
  211.             for ( var i = 0; i < info.constraints.length; i++ )
  212.             {
  213.                 if ( !info.what || info.what == "" )
  214.                 {
  215.                     if ( item[_META][info.constraints[i]] )
  216.                         return ( true );
  217.                 }
  218.                 else
  219.                 {    
  220.                     var entry = item[_META][info.constraints[i]];
  221.                     if ( entry && metaexp.exec(entry) )
  222.                         return ( true );
  223.                 }
  224.             } 
  225.             return ( false );
  226.         }
  227.     };
  228.  
  229.  
  230.     var Parse = function ( tokenStream )
  231.     {   
  232.         var tree = [];
  233.         
  234.         var tokens = Tokenize ( tokenStream );
  235.  
  236.         for ( var i = 0; i < tokens.length; i++ )
  237.         {
  238.             if ( tokens[i].type == 'OR' )
  239.             {
  240.                 var orToken = {'type': 'OR', 'expr': []};
  241.                 for ( var j = 0; j < tokens[i].value.length; j++ )
  242.                 {
  243.                     var info = self.ParseToken(tokens[i].value[j]);
  244.                     if ( info )
  245.                         orToken.expr.push ( info );
  246.                 }
  247.                     
  248.                 tree.push ( orToken );
  249.             }
  250.             else
  251.             {
  252.                 var info = self.ParseToken(tokens[i].value[0]);
  253.                 if ( info )
  254.                     tree.push ( info );
  255.             }
  256.         }
  257.         
  258.         return ( tree );
  259.     };
  260.     
  261.  
  262.  
  263.     var ParseMeta = function ( token, info )
  264.     {
  265.         info.where = [_META];
  266.         token = token.substr(4);
  267.                 
  268.         if ( token.substr(0,1) == '[' )
  269.         {
  270.             var inner = false;
  271.             var lastIsEscape = false;
  272.             
  273.             var pos = 1;
  274.             while ( pos < token.length )
  275.             {
  276.                 var c = token.substr(pos,1);
  277.                 if ( c == ']' && !inner )
  278.                     break;
  279.                 else if ( c == '\\' && inner )
  280.                     lastIsEscape = !lastIsEscape;
  281.                 else if ( c == '"' && !lastIsEscape )
  282.                     inner = false;
  283.                 else
  284.                     lastIsEscape = false;
  285.                     
  286.                 pos++;
  287.             }
  288.             
  289.             if ( pos >= token.length )
  290.                 throw _("Search.Error.ResultWriter.InvalidConstraints", token);
  291.  
  292.  
  293.             var temp = token.substr(1, pos-1).split(",");
  294.             var constraints = [];
  295.             for ( var i = 0; i < temp.length; i++ )
  296.             {
  297.                 var value = Prepare(temp[i]);
  298.                 if ( value != "" )
  299.                     constraints.push ( value ); 
  300.             }
  301.             
  302.             if ( constraints.length > 0 )
  303.                 info.constraints = constraints;
  304.  
  305.             if ( token.substr(pos+1,1) == '(' )
  306.                 pos = ParseMetaOption ( token, pos+1, info );
  307.  
  308.             if ( !pos )
  309.             {
  310.                 throw _("Search.Error.Parser.InvalidOptions", token);
  311.                 return ( null );
  312.             }
  313.                 
  314.             
  315.             if ( token.substr(pos+1,1) == ':' )
  316.                 info.what = Prepare( token.substr(pos+2) );
  317.         }
  318.         else if ( token.substr(0,1) == '(' )
  319.         {
  320.             var pos = ParseMetaOption ( token, 0, info );
  321.             
  322.             if ( token.substr(pos+1,1) == ':' )
  323.                 info.what = Prepare( token.substr(pos+2) );
  324.         }
  325.         else
  326.         {
  327.             info.what = Prepare ( token.substr(1) );
  328.         }
  329.         
  330.         return ( info );
  331.     };
  332.     
  333.  
  334.     var ParseMetaOption = function ( token, pos, info )
  335.     {
  336.         var len = token.length;
  337.         var end;
  338.         var st = pos;
  339.  
  340.         
  341.         while ( pos < len )
  342.         {
  343.             if ( token.substr(pos,1) == ')' )
  344.             {
  345.                 end = pos;
  346.                 break;     
  347.             }
  348.             pos++;
  349.         }
  350.         
  351.         if ( end )
  352.         {
  353.             var item = token.substr(st+1, end-st-1);
  354.             if ( !item || item.length == 0 || parseInt(item) == NaN )
  355.                 throw _("Search.Error.Parser.InvalidOptions", token);
  356.                 
  357.             info.metaOptions = parseInt(item); 
  358.         }
  359.         else
  360.             throw _("Search.Error.Parser.InvalidOptions", token);
  361.             
  362.         return ( end );
  363.     };
  364.     
  365.     
  366.     
  367.     this.ParseToken = function ( token )
  368.     {
  369.         var info = {'type': 'AND', 'invert': false};
  370.         if ( token.substr(0,1) == '-' )
  371.         {
  372.             info.invert = true;
  373.             token = token.substr(1);
  374.         }
  375.         
  376.         if ( token.substr(0,5) == 'meta:' || token.substr(0,5) == 'meta[' || token.substr(0,5) == 'meta(' )
  377.             ParseMeta ( token, info );
  378.         else if ( token.substr(0,6) == 'title:' )
  379.         {
  380.             info.where = [_TITLE];
  381.             info.what = Prepare ( token.substr(6) );
  382.         }
  383.         else if ( token.substr(0,3) == 'id:' )
  384.         {
  385.             info.where = [_ID];
  386.             info.what = Prepare ( token.substr(3) );
  387.         }
  388.         else if ( token.substr(0,8) == 'content:' )
  389.         {
  390.             info.where = [_CONTENT];
  391.             info.what = Prepare ( token.substr(8) );
  392.         }
  393.         else if ( token.substr(0,14) == 'x-set-options:' )
  394.         {
  395.             options = parseInt(token.substr(14));
  396.             info = null;
  397.         }
  398.         else if ( token.substr(0,18) == 'x-set-metaoptions:' )
  399.         {
  400.             metaOptions = parseInt(token.substr(18));
  401.             info = null;
  402.         }
  403.         else 
  404.         {
  405.             info.where = defaultLocations;
  406.             info.what = Prepare ( token );
  407.         }
  408.         
  409.         return ( info );
  410.     };
  411.     
  412.     
  413.     var Prepare = function ( input )
  414.     {
  415.         if ( !input )
  416.             return ( "" );
  417.             
  418.         if ( input.substr(0,1) == '"' )
  419.             input = input.substr(1);
  420.         if ( input.substr(input.length-1, 1) == '"' )
  421.             input = input.substr(0, input.length-1);
  422.         return ( input );
  423.     };
  424.  
  425.  
  426.     this.SetMetaOptions = function ( opts )
  427.     {
  428.         metaOptions = opts;
  429.     };
  430.  
  431.  
  432.      this.SetOptions = function ( opts ) 
  433.     {
  434.          options = opts;
  435.      };
  436.  
  437.  
  438.     var Tokenize = function ( tokenStream )
  439.     {
  440.         tokenStream = tokenStream.replace(/\s+/g, " ");
  441.         var tokens = [];
  442.         var isOrActive = false;
  443.         var pos = 0;
  444.         
  445.         while ( pos < tokenStream.length )
  446.         {
  447.             var token = Schema.String.TokenizeNext ( tokenStream, pos );
  448.             if ( !token )
  449.                 break;
  450.  
  451.             if ( token.value.toUpperCase() == "OR" )
  452.             {
  453.                 if ( tokens.length > 0 )
  454.                 {
  455.                     tokens[tokens.length-1].type = 'OR';
  456.                     isOrActive = true;
  457.                 }
  458.             }                
  459.             else
  460.             {
  461.                 if ( tokens.length == 0 || !isOrActive )
  462.                     tokens.push ( {'type': 'AND', 'value': [token.value]} );
  463.                 else
  464.                     tokens[tokens.length-1].value.push(token.value);
  465.                     
  466.                 isOrActive = false;
  467.             }
  468.  
  469.             pos = token.end+1;
  470.         }
  471.         
  472.         return ( tokens );
  473.     };
  474.  
  475.  
  476.     Initialize ( init );
  477. };
  478.  
  479.  
  480.  
  481. Schema.Search.Location = function ( ) { };
  482. Schema.Search.Location.Id = 0;
  483. Schema.Search.Location.Title = 1;
  484. Schema.Search.Location.Filename = 2;
  485. Schema.Search.Location.Filesize = 3;
  486. Schema.Search.Location.Meta = 4;
  487. Schema.Search.Location.Content = 5;
  488.  
  489.  
  490.  
  491. Schema.Search.ResultWriter = function ( init )
  492. {
  493.     var self = this;
  494.     var element = null;
  495.     var elementName = null;
  496.     this.expressionTree = [];
  497.     var environment = 3;
  498.     var pageSize = 10;
  499.     var boundaryRegex = new RegExp ( "[" + Schema.Regex.Unicode.Separator + Schema.Regex.Unicode.Punctuation + "]" );
  500.     var propertyName = "writer";
  501.     var result;
  502.  
  503.     var CheckHighlight = function ( expr, section )
  504.     {
  505.         var doHighlight = false;
  506.         for ( var j = 0; j < section.length; j++ )
  507.         {
  508.             if ( ContainsValue(expr.where, section[j]) )
  509.             {
  510.                 doHighlight = true;
  511.                 break;
  512.             }
  513.         }
  514.         
  515.         return ( doHighlight );
  516.     };
  517.  
  518.  
  519.  
  520.     this.Clear = function ( )
  521.     {
  522.         if ( element )
  523.             element.innerHTML = "";
  524.     };
  525.  
  526.  
  527.  
  528.     var ContainsValue = function ( ary, value )
  529.     {
  530.         for ( var i = 0; i < ary.length; i++ )
  531.         {
  532.             if ( ary[i] == value )
  533.                 return ( true );
  534.         }
  535.         
  536.         return ( false );
  537.     };
  538.  
  539.  
  540.  
  541.     this.Execute = function ( resultSet )
  542.     {
  543.         if ( !element )
  544.         {
  545.             if ( !document.getElementById(elementName) )
  546.                 throw _("Search.Error.ResultWriter.NoElement");
  547.                 
  548.             element = document.getElementById ( elementName );
  549.         }
  550.  
  551.         result = resultSet;
  552.         self.expressionTree = search.CreateExpressionTree ( search.GetExpressions(), search.GetOptions() | Schema.Regex.Options.AllMatches );
  553.         
  554.         self.ShowPage ( 1 );
  555.     };
  556.  
  557.     
  558.     
  559.     var GetEnvironment = function ( page )
  560.     {
  561.         var maxPage = GetMaxPage ( );
  562.  
  563.         if ( page <= environment+1 )
  564.             return ( {'start': 1, 'end': Math.min(environment+environment+1, maxPage)} );
  565.             
  566.  
  567.         if ( maxPage <= environment+environment+1 )
  568.             return ( {'start': 1, 'end': maxPage} );
  569.             
  570.         if ( maxPage - page < environment )
  571.             return ( {'start': Math.max(1, maxPage-environment-environment), 'end': maxPage} );
  572.         
  573.         return ( {'start': page-environment, 'end': Math.min(page+environment, maxPage)} );
  574.     };
  575.         
  576.         
  577.     var GetEnvironmentSize = function ( )
  578.     {
  579.         return ( environment );
  580.     };
  581.  
  582.  
  583.     var GetMaxPage = function ( )
  584.     {
  585.         if ( !result || result.length <= 0 )
  586.             return ( 0 );
  587.         if ( pageSize <= 0 )
  588.             return ( 1 );
  589.             
  590.         var len = result.length;
  591.         var count = 0;
  592.         
  593.         while ( len > 0 )
  594.         {
  595.             count++;
  596.             len -= pageSize;
  597.         }
  598.         
  599.         return ( count );
  600.     };
  601.     
  602.     
  603.  
  604.     this.GetPageLink = function ( page, text )
  605.     {
  606.         return ( '<a href="javascript:' + propertyName + ".ShowPage(" + page + ');" class="searchResultPagingLink">' + text + '</a>' ); 
  607.     };
  608.  
  609.     
  610.     
  611.     var GetPageRegion = function ( page )
  612.     {
  613.         if ( pageSize <= 0 )
  614.             return ( {'start': 0, 'end': result.length - 1} );
  615.             
  616.         var st = (page-1) * pageSize;
  617.         var end = Math.min ( st+pageSize-1, result.length-1 );
  618.         if ( st > result.length )
  619.             return ( null );
  620.             
  621.         return ( {'start': st, 'end': end} );
  622.     };
  623.     
  624.     
  625.     
  626.     this.GetPageSize = function ( )
  627.     {
  628.         return ( pageSize );
  629.     };
  630.  
  631.  
  632.     
  633.     this.Highlight = function ( text, section )
  634.     {
  635.         var include = (section ? section : [Schema.Search.Location.Content]);
  636.         
  637.         for ( var i = 0; i < self.expressionTree.length; i++ )
  638.         {
  639.             if ( self.expressionTree[i].type == 'AND' )
  640.             {
  641.                 if ( CheckHighlight(self.expressionTree[i], include) )
  642.                     text = text.replace(self.expressionTree[i].regex, self.HighlightFunction);
  643.             }
  644.             else
  645.             {
  646.                 for ( var j = 0; j < self.expressionTree[i].expr.length; j++ )
  647.                 {
  648.                     if ( CheckHighlight(self.expressionTree[i].expr[j], include) )
  649.                         text = text.replace(self.expressionTree[i].expr[j].regex, self.HighlightFunction);
  650.                 }
  651.             }
  652.         }
  653.         
  654.         return ( text );
  655.     };
  656.         
  657.     
  658.     
  659.     this.HighlightFunction = function ( match )
  660.     {
  661.         var st = "";
  662.         var end = "";
  663.         if ( boundaryRegex.test(match.substr(0,1)) )
  664.         {
  665.             st = match.substr(0,1);
  666.             match = match.substr(1);
  667.         }
  668.         if ( boundaryRegex.test(match.substr(match.length-1,1)) )
  669.         {
  670.             end = match.substr(match.length-1,1); 
  671.             match = match.substr(0, match.length-1);
  672.         }
  673.             
  674.         return ( st + '<span class="searchEntryHighlight">'+match+'</span>' + end );
  675.     };
  676.  
  677.  
  678.  
  679.     var Initialize = function ( init )
  680.     {
  681.         elementName = init.element;
  682.         
  683.         if ( init.pageSize && parseInt(init.pageSize) > 0 )
  684.             pageSize = parseInt(init.pageSize);
  685.         if ( init.environment && parseInt(init.environment) > 0 )
  686.             environment = parseInt(init.environment);
  687.         if ( init.propertyName )
  688.             propertyName = init.propertyName;
  689.     };
  690.  
  691.     
  692.     this.SetEnvironmentSize = function ( size )
  693.     {
  694.         environment = size;
  695.     };
  696.     
  697.     
  698.     this.SetPageSize = function ( size )
  699.     {
  700.         pageSize = size;
  701.     };
  702.     
  703.     
  704.     this.ShowPage = function ( page )
  705.     {
  706.         self.Clear ( );
  707.     
  708.         self.WritePagingAndCount ( page );
  709.         if ( result && result.length > 0 )
  710.         {
  711.             var region = GetPageRegion ( page );
  712.             if ( region )
  713.             {
  714.                 var fulltextindex = search.GetFulltextIndex();
  715.                 for ( var i = region.start; i <= region.end; i++ )
  716.                     self.WriteResult ( fulltextindex[result[i]] );
  717.                     
  718.                 self.WritePagingAndCount ( page );
  719.                 window.scrollTo ( 0, 0 );
  720.             }
  721.         }
  722.     };
  723.  
  724.  
  725.     this.WriteContext = function ( item )
  726.     {
  727.         var _CONTENT = Schema.Search.Location.Content;
  728.         
  729.         var ix = item[_CONTENT].length;
  730.         
  731.         for ( var i = 0; i < self.expressionTree.length; i++ )
  732.         {
  733.             var temp;
  734.             if ( self.expressionTree[i].type == 'AND' )
  735.             {
  736.                 if ( !ContainsValue(self.expressionTree[i].where, _CONTENT) )
  737.                     continue;
  738.  
  739.                 var temp = item[_CONTENT].search ( self.expressionTree[i].regex );
  740.                 if ( temp >= 0 )
  741.                     ix = Math.min ( temp, ix );
  742.             }
  743.             else
  744.             {
  745.                 for ( var j = 0; j < self.expressionTree[i].expr.length; j++ )
  746.                 {
  747.                     if ( !ContainsValue(self.expressionTree[i].expr[j].where, _CONTENT) )
  748.                         continue;
  749.                         
  750.                     var temp = item[_CONTENT].search ( self.expressionTree[i].expr[j].regex );
  751.                     if ( temp >= 0 )
  752.                         ix = Math.min ( temp, ix );
  753.                 }
  754.             }
  755.         }
  756.         
  757.         if ( ix < 0 || ix >= item[_CONTENT].length )
  758.             ix = 0;
  759.         
  760.         if ( ix >= 0 )
  761.         {
  762.             var pos = ( ix < 100 ? 0 : ix - 100 );
  763.             var st = pos;
  764.             var ismiddle = true;
  765.             
  766.             for ( var j = ix-30; j >= pos; j-- )
  767.             {
  768.                 var c = item[_CONTENT].substr(j,1); 
  769.                 if ( c == '.' || c == '!' )
  770.                 {
  771.                     st = j+1;
  772.                     ismiddle = false;
  773.                     break;
  774.                 }
  775.                 if ( item[_CONTENT].substr(j,1) == ' ' )
  776.                     st = j;
  777.             }
  778.  
  779.             var end = st + 200;
  780.             if ( end >= item[_CONTENT].length )
  781.                 end = item[_CONTENT].length;
  782.                 
  783.             for ( var j = end; j > ix+30; j-- )
  784.             {
  785.                 if ( item[_CONTENT].substr(j,1) == " " )
  786.                 {
  787.                     end = j;
  788.                     break;
  789.                 }
  790.             }
  791.             
  792.             var text = (ismiddle && st > 0 ? "... " : "") + item[_CONTENT].substr(st, end-st) + (end < item[_CONTENT].length ? "..." : "");
  793.  
  794.             var out = document.createElement ( "div" );
  795.             out.className = "searchEntryContent";
  796.             text = self.Highlight ( text ) 
  797.             out.innerHTML = text;
  798.             return ( out );
  799.         }
  800.     };
  801.  
  802.  
  803.     this.WriteResult = function ( item )
  804.     {
  805.         var content = document.createElement ( "div" );
  806.         content.className = "searchEntry";
  807.         
  808.         var temp;
  809.         
  810.         temp = self.WriteResultTitle ( item );
  811.         if ( temp )
  812.             content.appendChild ( temp );
  813.         
  814.         temp = self.WriteContext ( item );
  815.         if ( temp )
  816.             content.appendChild ( temp );
  817.         
  818.         temp = self.WriteResultFileInfo ( item );
  819.         if ( temp )
  820.             content.appendChild ( temp );
  821.             
  822.         
  823.         element.appendChild ( content );
  824.     };
  825.  
  826.  
  827.     this.WriteResultFileInfo = function ( item )
  828.     {    
  829.         var info = document.createElement ( "div" );
  830.         info.className = "searchEntryInfo";
  831.         var html = item[Schema.Search.Location.Filename];
  832.         
  833.         var size = parseInt(item[Schema.Search.Location.Filesize]);
  834.         if ( size != NaN )
  835.             html += " - " + Math.round(size/1024) + "k";
  836.             
  837.         info.innerHTML = html;
  838.         return ( info );
  839.     };
  840.  
  841.     
  842.     
  843.     this.WriteResultTitle = function ( item )
  844.     {
  845.         var loc = Schema.Search.Location;
  846.         
  847.            var title = document.createElement ( "div" );
  848.         title.className = "searchEntryTitle";
  849.         if ( self.NavigateTo )
  850.             title.innerHTML = self.NavigateTo ( item );
  851.         else
  852.             title.innerHTML = '<a href="' + item[loc.Filename] + '">' + self.Highlight((item[loc.Title] && item[loc.Title].length > 0) ? item[loc.Title] : item[loc.Filename]) + '</a>';
  853.         return ( title );
  854.      };
  855.     
  856.     
  857.     
  858.     this.WritePagingAndCount = function ( page )
  859.     {
  860.         var content = document.createElement ( "div" );
  861.         content.className = "searchResult";
  862.         
  863.         var table = document.createElement ( "table" );
  864.         table.border = 0;
  865.         table.cellPadding = 0;
  866.         table.cellSpacing = 0;
  867.         content.appendChild ( table );
  868.         
  869.         var tbody = document.createElement ( "tbody" );
  870.         table.appendChild ( tbody );
  871.         
  872.         var row = document.createElement ( "tr" );
  873.         tbody.appendChild ( row );
  874.         
  875.         var cell1 = document.createElement ( "td" );
  876.         cell1.className = "searchResultPaging";
  877.         row.appendChild ( cell1 );
  878.         
  879.         if ( result && result.length > 0 )
  880.         {
  881.             var html = "";
  882.             var range = GetEnvironment ( page );
  883.             if ( page != range.start )
  884.                 html += self.GetPageLink ( page-1, _("Search.Result.Previous") ) + " " + _("Search.Result.Separator");
  885.             
  886.             if ( range.start != range.end )
  887.             {
  888.                 for ( var i = range.start; i <= range.end; i++ )
  889.                 {
  890.                     if ( i == page )
  891.                         html += " " + '<span class="searchResultPagingActive">' + i + '</span>';
  892.                     else
  893.                         html += " " + self.GetPageLink ( i, i );
  894.                 }
  895.             }
  896.                 
  897.             if ( page != range.end )
  898.                 html += " " + _("Search.Result.Separator") + " " + self.GetPageLink ( page+1, _("Search.Result.Next") );
  899.     
  900.             cell1.innerHTML = html;         
  901.         }
  902.         
  903.         var cell2 = document.createElement ( "td" );
  904.         cell2.className = "searchResultInfo";
  905.  
  906.         var region = GetPageRegion ( page );
  907.  
  908.         if ( !result || result.length <= 0 || !region )
  909.             cell2.innerHTML = _("Search.Result.None");
  910.         else
  911.             cell2.innerHTML = _("Search.Result.Position", (region.start+1) + " - " + (region.end+1), result.length);
  912.  
  913.         row.appendChild ( cell2 );
  914.         
  915.         element.appendChild ( content );
  916.     };
  917.     
  918.     
  919.     Initialize ( init );
  920. };