e.FLY

jsp图片放大镜

js

View Code
   1 /*
   2 ===============================================================================
   3 Chili is the jQuery code highlighter plugin
   4 ...............................................................................
   5 LICENSE: http://www.opensource.org/licenses/mit-license.php
   6 WEBSITE: http://noteslog.com/chili/
   7 
   8                                                Copyright 2008 / Andrea Ercolino
   9 ===============================================================================
  10 */
  11 
  12 
  13 ( function($) {
  14 
  15 ChiliBook = { //implied global
  16 
  17       version:            "2.2" // 2008-07-06
  18 
  19 // options --------------------------------------------------------------------
  20 
  21     , automatic:          true
  22     , automaticSelector:  "code"
  23 
  24     , lineNumbers:        !true
  25 
  26     , codeLanguage:       function( el ) {
  27         var recipeName = $( el ).attr( "class" );
  28         return recipeName ? recipeName : '';
  29     }
  30 
  31     , recipeLoading:      true
  32     , recipeFolder:       "" // used like: recipeFolder + recipeName + '.js'
  33 
  34     // IE and FF convert   to " ", Safari and Opera do not
  35     , replaceSpace:       " "
  36     , replaceTab:         "    "
  37     , replaceNewLine:     "&#160;<br/>"
  38 
  39     , selectionStyle:     [ "position:absolute; z-index:3000; overflow:scroll;"
  40                           , "width:16em;"
  41                           , "height:9em;"
  42                           , "border:1px solid gray;"
  43                           , "padding:15px;"
  44                           , "background-color:yellow;"
  45                           ].join( ' ' )
  46 
  47 // ------------------------------------------------------------- end of options
  48 
  49     , defaultReplacement: '<span class="$0">$$</span>' // TODO: make this an option again
  50     , recipes:            {} //repository
  51     , queue:              {} //registry
  52 
  53     , unique:             function() {
  54         return (new Date()).valueOf();
  55     }
  56 };
  57 
  58 
  59 
  60 $.fn.chili = function( options ) {
  61     var book = $.extend( {}, ChiliBook, options || {} );
  62 
  63     function cook( ingredients, recipe, blockName ) {
  64 
  65         function prepareBlock( recipe, blockName ) {
  66             var steps = [];
  67             for( var stepName in recipe[ blockName ] ) {
  68                 steps.push( prepareStep( recipe, blockName, stepName ) );
  69             }
  70             return steps;
  71         } // prepareBlock
  72 
  73         function prepareStep( recipe, blockName, stepName ) {
  74             var step = recipe[ blockName ][ stepName ];
  75             var exp = ( typeof step._match == "string" ) ? step._match : step._match.source;
  76             return {
  77                 recipe: recipe
  78                 , blockName: blockName
  79                 , stepName: stepName
  80                 , exp: "(" + exp + ")"
  81                 , length: 1                         // add 1 to account for the newly added parentheses
  82                     + (exp                          // count number of submatches in here
  83                         .replace( /\\./g, "%" )     // disable any escaped character
  84                         .replace( /\[.*?\]/g, "%" ) // disable any character class
  85                         .match( /\((?!\?)/g )       // match any open parenthesis, not followed by a ?
  86                     || []                           // make sure it is an empty array if there are no matches
  87                     ).length                        // get the number of matches
  88                 , replacement: step._replace ? step._replace : book.defaultReplacement
  89             };
  90         } // prepareStep
  91     
  92         function knowHow( steps ) {
  93             var prevLength = 1;
  94             var exps = [];
  95             for (var i = 0; i < steps.length; i++) {
  96                 var exp = steps[ i ].exp;
  97                 // adjust backreferences
  98                 exp = exp.replace( /\\\\|\\(\d+)/g, function( m, aNum ) {
  99                     return !aNum ? m : "\\" + ( prevLength + 1 + parseInt( aNum, 10 ) );
 100                 } );
 101                 exps.push( exp );
 102                 prevLength += steps[ i ].length;
 103             }
 104             var prolog = '((?:\\s|\\S)*?)';
 105             var epilog = '((?:\\s|\\S)+)';
 106             var source = '(?:' + exps.join( "|" ) + ')';
 107             source = prolog + source + '|' + epilog;
 108             return new RegExp( source, recipe._case ? "g" : "gi" );
 109         } // knowHow
 110 
 111         function escapeHTML( str ) {
 112             return str.replace( /&/g, "&amp;" ).replace( /</g, "&lt;" );
 113         } // escapeHTML
 114 
 115         function replaceSpaces( str ) {
 116             return str.replace( / +/g, function( spaces ) {
 117                 return spaces.replace( / /g, replaceSpace );
 118             } );
 119         } // replaceSpaces
 120 
 121         function filter( str ) {
 122             str = escapeHTML( str );
 123             if( replaceSpace ) {
 124                 str = replaceSpaces( str );
 125             }
 126             return str;
 127         } // filter
 128 
 129         function applyRecipe( subject, recipe ) {
 130             return cook( subject, recipe );
 131         } // applyRecipe
 132 
 133         function applyBlock( subject, recipe, blockName ) {
 134             return cook( subject, recipe, blockName );
 135         } // applyBlock
 136 
 137         function applyStep( subject, recipe, blockName, stepName ) {
 138             var replaceSpace       = book.replaceSpace;
 139 
 140             var step = prepareStep( recipe, blockName, stepName );
 141             var steps = [step];
 142 
 143             var perfect = subject.replace( knowHow( steps ), function() {
 144                 return chef.apply( { steps: steps }, arguments );
 145             } );
 146             return perfect;
 147         } // applyStep
 148 
 149         function applyModule( subject, module, context ) {
 150             if( ! module ) {
 151                 return filter( subject );
 152             }
 153 
 154             var sub = module.split( '/' );
 155             var recipeName = '';
 156             var blockName  = '';
 157             var stepName   = '';
 158             switch( sub.length ) {
 159                 case 1:
 160                     recipeName = sub[0];
 161                     break;
 162                 case 2:
 163                     recipeName = sub[0]; blockName = sub[1];
 164                     break;
 165                 case 3:
 166                     recipeName = sub[0]; blockName = sub[1]; stepName = sub[2];
 167                     break;
 168                 default:
 169                     return filter( subject );
 170             }
 171 
 172             function getRecipe( recipeName ) {
 173                 var path = getPath( recipeName );
 174                 var recipe = book.recipes[ path ];
 175                 if( ! recipe ) {
 176                     throw {msg:"recipe not available"};
 177                 }
 178                 return recipe;
 179             }
 180 
 181             try {
 182                 var recipe;
 183                 if ( '' == stepName ) {
 184                     if ( '' == blockName ) {
 185                         if ( '' == recipeName ) {
 186                             //nothing to do
 187                         }
 188                         else { // ( '' != recipeName )
 189                             recipe = getRecipe( recipeName );
 190                             return applyRecipe( subject, recipe );
 191                         }
 192                     }
 193                     else { // ( '' != blockName )
 194                         if( '' == recipeName ) {
 195                             recipe = context.recipe;
 196                         }
 197                         else {
 198                             recipe = getRecipe( recipeName );
 199                         }
 200                         if( ! (blockName in recipe) ) {
 201                             return filter( subject );
 202                         }
 203                         return applyBlock( subject, recipe, blockName );
 204                     }
 205                 }
 206                 else { // ( '' != stepName )
 207                     if( '' == recipeName ) {
 208                         recipe = context.recipe;
 209                     }
 210                     else {
 211                         recipe = getRecipe( recipeName );
 212                     }
 213                     if( '' == blockName ) {
 214                         blockName = context.blockName;
 215                     }
 216                     if( ! (blockName in recipe) ) {
 217                         return filter( subject );
 218                     }
 219                     if( ! (stepName in recipe[blockName]) ) {
 220                         return filter( subject );
 221                     }
 222                     return applyStep( subject, recipe, blockName, stepName );
 223                 }
 224             }
 225             catch( e ) {
 226                 if (e.msg && e.msg == "recipe not available") {
 227                     var cue = 'chili_' + book.unique();
 228                     if( book.recipeLoading ) {
 229                         var path = getPath( recipeName );
 230                         if( ! book.queue[ path ] ) {
 231                             /* this is a new recipe to download */
 232                             try {
 233                                 book.queue[ path ] = [ {cue: cue, subject: subject, module: module, context: context} ];
 234                                 $.getJSON( path, function( recipeLoaded ) {
 235                                     book.recipes[ path ] = recipeLoaded;
 236                                     var q = book.queue[ path ];
 237                                     for( var i = 0, iTop = q.length; i < iTop; i++ ) {
 238                                         var replacement = applyModule( q[ i ].subject, q[ i ].module, q[ i ].context );
 239                                         if( book.replaceTab ) {
 240                                             replacement = replacement.replace( /\t/g, book.replaceTab );
 241                                         }
 242                                         if( book.replaceNewLine ) {
 243                                             replacement = replacement.replace( /\n/g, book.replaceNewLine );
 244                                         }
 245                                         $( '#' + q[ i ].cue ).replaceWith( replacement );
 246                                     }
 247                                 } );
 248                             }
 249                             catch( recipeNotAvailable ) {
 250                                 alert( "the recipe for '" + recipeName + "' was not found in '" + path + "'" );
 251                             }
 252                         }
 253                         else {
 254                             /* not a new recipe, so just enqueue this element */
 255                             book.queue[ path ].push( {cue: cue, subject: subject, module: module, context: context} );
 256                         }
 257                         return '<span id="' + cue + '">' + filter( subject ) + '</span>';
 258                     }
 259                     return filter( subject );
 260                 }
 261                 else {
 262                     return filter( subject );
 263                 }
 264             }
 265         } // applyModule
 266 
 267         function addPrefix( prefix, replacement ) {
 268             var aux = replacement.replace( /(<span\s+class\s*=\s*(["']))((?:(?!__)\w)+\2\s*>)/ig, "$1" + prefix + "__$3" );
 269             return aux;
 270         } // addPrefix
 271 
 272         function chef() {
 273             if (! arguments[ 0 ]) {
 274                 return '';
 275             }
 276             var steps = this.steps;
 277             var i = 0;  // iterate steps
 278             var j = 2;    // iterate chef's arguments
 279             var prolog = arguments[ 1 ];
 280             var epilog = arguments[ arguments.length - 3 ];
 281             if (! epilog) {
 282                 var step;
 283                 while( step = steps[ i++ ] ) {
 284                     var aux = arguments; // this unmasks chef's arguments inside the next function
 285                     if( aux[ j ] ) {
 286                         var replacement = '';
 287                         if( $.isFunction( step.replacement ) ) {
 288                             var matches = []; //Array.slice.call( aux, j, step.length );
 289                             for (var k = 0, kTop = step.length; k < kTop; k++) {
 290                                 matches.push( aux[ j + k ] );
 291                             }
 292                             matches.push( aux[ aux.length - 2 ] );
 293                             matches.push( aux[ aux.length - 1 ] );
 294                             replacement = step.replacement
 295                                 .apply( { 
 296                                     x: function() { 
 297                                         var subject = arguments[0];
 298                                         var module  = arguments[1];
 299                                         var context = { 
 300                                               recipe:    step.recipe
 301                                             , blockName: step.blockName 
 302                                         };
 303                                         return applyModule( subject, module, context );
 304                                     } 
 305                                 }, matches );
 306                         }
 307                         else { //we expect step.replacement to be a string
 308                             replacement = step.replacement
 309                                 .replace( /(\\\$)|(?:\$\$)|(?:\$(\d+))/g, function( m, escaped, K ) {
 310                                     if( escaped ) {       /* \$ */ 
 311                                         return "$";
 312                                     }
 313                                     else if( !K ) {       /* $$ */ 
 314                                         return filter( aux[ j ] );
 315                                     }
 316                                     else if( K == "0" ) { /* $0 */ 
 317                                         return step.stepName;
 318                                     }
 319                                     else {                /* $K */
 320                                         return filter( aux[ j + parseInt( K, 10 ) ] );
 321                                     }
 322                                 } );
 323                         }
 324                         replacement = addPrefix( step.recipe._name, replacement );
 325                         return filter( prolog ) + replacement;
 326                     } 
 327                     else {
 328                         j+= step.length;
 329                     }
 330                 }
 331             }
 332             else {
 333                 return filter( epilog );
 334             }
 335         } // chef
 336 
 337         if( ! blockName ) {
 338             blockName = '_main';
 339             checkSpices( recipe );
 340         }
 341         if( ! (blockName in recipe) ) {
 342             return filter( ingredients );
 343         }
 344         var replaceSpace = book.replaceSpace;
 345         var steps = prepareBlock( recipe, blockName );
 346         var kh = knowHow( steps );
 347         var perfect = ingredients.replace( kh, function() {
 348             return chef.apply( { steps: steps }, arguments );
 349         } );
 350         return perfect;
 351 
 352     } // cook
 353 
 354     function loadStylesheetInline( sourceCode ) { 
 355         if( document.createElement ) { 
 356             var e = document.createElement( "style" ); 
 357             e.type = "text/css"; 
 358             if( e.styleSheet ) { // IE 
 359                 e.styleSheet.cssText = sourceCode; 
 360             }  
 361             else { 
 362                 var t = document.createTextNode( sourceCode ); 
 363                 e.appendChild( t ); 
 364             } 
 365             document.getElementsByTagName( "head" )[0].appendChild( e ); 
 366         } 
 367     } // loadStylesheetInline
 368             
 369     function checkSpices( recipe ) {
 370         var name = recipe._name;
 371         if( ! book.queue[ name ] ) {
 372 
 373             var content = ['/* Chili -- ' + name + ' */'];
 374             for (var blockName in recipe) {
 375                 if( blockName.search( /^_(?!main\b)/ ) < 0 ) {
 376                     for (var stepName in recipe[ blockName ]) {
 377                         var step = recipe[ blockName ][ stepName ];
 378                         if( '_style' in step ) {
 379                             if( step[ '_style' ].constructor == String ) {
 380                                 content.push( '.' + name + '__' + stepName + ' { ' + step[ '_style' ] + ' }' );
 381                             }
 382                             else {
 383                                 for (var className in step[ '_style' ]) {
 384                                     content.push( '.' + name + '__' + className + ' { ' + step[ '_style' ][ className ] + ' }' );
 385                                 }
 386                             }
 387                         }
 388                     }
 389                 }
 390             }
 391             content = content.join('\n');
 392 
 393             loadStylesheetInline( content );
 394 
 395             book.queue[ name ] = true;
 396         }
 397     } // checkSpices
 398 
 399     function askDish( el ) {
 400         var recipeName = book.codeLanguage( el );
 401         if( '' != recipeName ) {
 402             var path = getPath( recipeName );
 403             if( book.recipeLoading ) {
 404                 /* dynamic setups come here */
 405                 if( ! book.queue[ path ] ) {
 406                     /* this is a new recipe to download */
 407                     try {
 408                         book.queue[ path ] = [ el ];
 409                         $.getJSON( path, function( recipeLoaded ) {
 410                             book.recipes[ path ] = recipeLoaded;
 411                             var q = book.queue[ path ];
 412                             for( var i = 0, iTop = q.length; i < iTop; i++ ) {
 413                                 makeDish( q[ i ], path );
 414                             }
 415                         } );
 416                     }
 417                     catch( recipeNotAvailable ) {
 418                         alert( "the recipe for '" + recipeName + "' was not found in '" + path + "'" );
 419                     }
 420                 }
 421                 else {
 422                     /* not a new recipe, so just enqueue this element */
 423                     book.queue[ path ].push( el );
 424                 }
 425                 /* a recipe could have been already downloaded */
 426                 makeDish( el, path ); 
 427             }
 428             else {
 429                 /* static setups come here */
 430                 makeDish( el, path );
 431             }
 432         }
 433     } // askDish
 434 
 435     function makeDish( el, recipePath ) {
 436         var recipe = book.recipes[ recipePath ];
 437         if( ! recipe ) {
 438             return;
 439         }
 440         var $el = $( el );
 441         var ingredients = $el.text();
 442         if( ! ingredients ) {
 443             return;
 444         }
 445 
 446         //fix for msie: \r (13) is used instead of \n (10)
 447         //fix for opera: \r\n is used instead of \n
 448         ingredients = ingredients.replace(/\r\n?/g, "\n");
 449 
 450         //reverse fix for safari: msie, mozilla and opera render the initial \n
 451         if( $el.parent().is('pre') ) {
 452             if( ! $.browser.safari ) {
 453                 ingredients = ingredients.replace(/^\n/g, "");
 454             }
 455         }
 456 
 457         var dish = cook( ingredients, recipe ); // all happens here
 458     
 459         if( book.replaceTab ) {
 460             dish = dish.replace( /\t/g, book.replaceTab );
 461         }
 462         if( book.replaceNewLine ) {
 463             dish = dish.replace( /\n/g, book.replaceNewLine );
 464         }
 465 
 466         el.innerHTML = dish; //much faster than $el.html( dish );
 467         //tried also the function replaceHtml from http://blog.stevenlevithan.com/archives/faster-than-innerhtml
 468         //but it was not faster nor without sideffects (it was not possible to count spans into el)
 469 
 470         //opera and safari select PRE text correctly 
 471         if( $.browser.msie || $.browser.mozilla ) {
 472             enableSelectionHelper( el );
 473         }
 474 
 475         var $that = $el.parent();
 476         var classes = $that.attr( 'class' );
 477         var ln = /ln-(\d+)-([\w][\w\-]*)|ln-(\d+)|ln-/.exec( classes );
 478         if( ln ) {
 479             addLineNumbers( el );
 480             var start = 0;
 481             if( ln[1] ) {
 482                 start = parseInt( ln[1], 10 );
 483                 var $pieces = $( '.ln-' + ln[1] + '-' + ln[2] );
 484                 var pos = $pieces.index( $that[0] );
 485                 $pieces.slice( 0, pos ).each( function() {
 486                     start += $( this ).find( 'li' ).length;
 487                 } );
 488             }
 489             else if( ln[3] ) {
 490                 start = parseInt( ln[3], 10 );
 491             }
 492             else {
 493                 start = 1;
 494             }
 495             $el.find( 'ol' )[0].start = start;
 496             $('body').width( $('body').width() - 1 ).width( $('body').width() + 1 );
 497         }
 498         else if( book.lineNumbers ) {
 499             addLineNumbers( el );
 500         }
 501 
 502     } // makeDish
 503 
 504     function enableSelectionHelper( el ) {
 505         var element = null;
 506         $( el )
 507         .parents()
 508         .filter( "pre" )
 509         .bind( "mousedown", function() {
 510             element = this;
 511             if( $.browser.msie ) {
 512                 document.selection.empty();
 513             }
 514             else {
 515                 window.getSelection().removeAllRanges();
 516             }
 517         } )
 518         .bind( "mouseup", function( event ) {
 519             if( element && (element == this) ) {
 520                 element = null;
 521                 var selected = '';
 522                 if( $.browser.msie ) {
 523                     selected = document.selection.createRange().htmlText;
 524                     if( '' == selected ) { 
 525                         return;
 526                     }
 527                     selected = preserveNewLines( selected );
 528                     var container_tag = '<textarea style="STYLE">';
 529                 }
 530                 else {
 531                     selected = window.getSelection().toString(); //opera doesn't select new lines
 532                     if( '' == selected ) {
 533                         return;
 534                     }
 535                     selected = selected
 536                         .replace( /\r/g, '' )
 537                         .replace( /^# ?/g, '' )
 538                         .replace( /\n# ?/g, '\n' )
 539                     ;
 540                     var container_tag = '<pre style="STYLE">';
 541                 }
 542                 var $container = $( container_tag.replace( /\bSTYLE\b/, ChiliBook.selectionStyle ) )
 543                     .appendTo( 'body' )
 544                     .text( selected )
 545                     .attr( 'id', 'chili_selection' )
 546                     .click( function() { $(this).remove(); } )
 547                 ;
 548                 var top  = event.pageY - Math.round( $container.height() / 2 ) + "px";
 549                 var left = event.pageX - Math.round( $container.width() / 2 ) + "px";
 550                 $container.css( { top: top, left: left } );
 551                 if( $.browser.msie ) {
 552 //                    window.clipboardData.setData( 'Text', selected ); //I couldn't find anything similar for Mozilla
 553                     $container[0].focus();
 554                     $container[0].select();
 555                 }
 556                 else {
 557                     var s = window.getSelection();
 558                     s.removeAllRanges();
 559                     var r = document.createRange();
 560                     r.selectNodeContents( $container[0] );
 561                     s.addRange( r );
 562                 }
 563             }
 564         } )
 565         ;
 566     } // enableSelectionHelper
 567 
 568     function getPath( recipeName ) {
 569         return book.recipeFolder + recipeName + ".js";
 570     } // getPath
 571 
 572     function getSelectedText() {
 573         var text = '';
 574         if( $.browser.msie ) {
 575             text = document.selection.createRange().htmlText;
 576         }
 577         else {
 578             text = window.getSelection().toString();
 579         }
 580         return text;
 581     } // getSelectedText
 582 
 583     function preserveNewLines( html ) {
 584         do { 
 585             var newline_flag = ChiliBook.unique();
 586         }
 587         while( html.indexOf( newline_flag ) > -1 );
 588         var text = '';
 589         if (/<br/i.test(html) || /<li/i.test(html)) {
 590             if (/<br/i.test(html)) {
 591                 html = html.replace( /\<br[^>]*?\>/ig, newline_flag );
 592             }
 593             else if (/<li/i.test(html)) {
 594                 html = html.replace( /<ol[^>]*?>|<\/ol>|<li[^>]*?>/ig, '' ).replace( /<\/li>/ig, newline_flag );
 595             }
 596             var el = $( '<pre>' ).appendTo( 'body' ).hide()[0];
 597             el.innerHTML = html;
 598             text = $( el ).text().replace( new RegExp( newline_flag, "g" ), '\r\n' );
 599             $( el ).remove();
 600         }
 601         return text;
 602     } // preserveNewLines
 603 
 604     function addLineNumbers( el ) {
 605 
 606         function makeListItem1( not_last_line, not_last, last, open ) {
 607             var close = open ? '</span>' : '';
 608             var aux = '';
 609             if( not_last_line ) {
 610                 aux = '<li>' + open + not_last + close + '</li>';
 611             }
 612             else if( last ) {
 613                 aux = '<li>' + open + last + close + '</li>';
 614             }
 615             return aux;
 616         } // makeListItem1
 617 
 618         function makeListItem2( not_last_line, not_last, last, prev_li ) {
 619             var aux = '';
 620             if( prev_li ) {
 621                 aux = prev_li;
 622             }
 623             else {
 624                 aux = makeListItem1( not_last_line, not_last, last, '' )
 625             }
 626             return aux;
 627         } // makeListItem2
 628 
 629         var html = $( el ).html();
 630         var br = /<br>/.test(html) ? '<br>' : '<BR>';
 631         var empty_line = '<li>' + book.replaceSpace + '</li>';
 632         var list_items = html
 633             //extract newlines at the beginning of a span
 634             .replace( /(<span [^>]+>)((?:(?:&nbsp;|\xA0)<br>)+)(.*?)(<\/span>)/ig, '$2$1$3$4' ) // I don't know why <span .*?> does not work here
 635             //transform newlines inside of a span
 636             .replace( /(.*?)(<span .*?>)(.*?)(?:<\/span>(?:&nbsp;|\xA0)<br>|<\/span>)/ig,       // but here it does
 637                 function( all, before, open, content ) {
 638                     if (/<br>/i.test(content)) {
 639                         var pieces = before.split( br );
 640                         var lastPiece = pieces.pop();
 641                         before = pieces.join( br );
 642                         var aux = (before ? before + br : '') //+ replace1( lastPiece + content, open );
 643                             + (lastPiece + content).replace( /((.*?)(?:&nbsp;|\xA0)<br>)|(.*)/ig, 
 644                             function( tmp, not_last_line, not_last, last ) {
 645                                 var aux2 = makeListItem1( not_last_line, not_last, last, open );
 646                                 return aux2;
 647                             } 
 648                         );
 649                         return aux;
 650                     }
 651                     else {
 652                         return all;
 653                     }
 654                 } 
 655             )
 656             //transform newlines outside of a span
 657             .replace( /(<li>.*?<\/li>)|((.*?)(?:&nbsp;|\xA0)<br>)|(.+)/ig, 
 658                 function( tmp, prev_li, not_last_line, not_last, last ) {
 659                     var aux2 = makeListItem2( not_last_line, not_last, last, prev_li );
 660                     return aux2;
 661                 } 
 662             )
 663             //fix empty lines for Opera
 664             .replace( /<li><\/li>/ig, empty_line )
 665         ;
 666 
 667         el.innerHTML = '<ol>' + list_items + '</ol>';
 668     } // addLineNumbers
 669 
 670     function revealChars( tmp ) {
 671         return $
 672             .map( tmp.split(''), 
 673                 function(n, i) { 
 674                     return ' ' + n + ' ' + n.charCodeAt( 0 ) + ' ';
 675                 } )
 676             .join(' ');
 677     } // revealChars
 678 
 679     //-----------------------------------------------------------------------------
 680     // the coloring starts here
 681         this
 682         .each( function() {
 683             var $this = $( this );
 684             $this.trigger( 'chili.before_coloring' );
 685             askDish( this );
 686             $this.trigger( 'chili.after_coloring' );
 687         } );
 688     
 689         return this;
 690     //-----------------------------------------------------------------------------
 691     };
 692     
 693     
 694     
 695     //main
 696     $( function() {
 697     
 698         if( ChiliBook.automatic ) {
 699             $( ChiliBook.automaticSelector ).chili();
 700         }
 701     
 702     } );
 703 
 704 } ) ( jQuery );
 705             
 706             
 707             
 708 /*
 709 ===============================================================================
 710 Chili is the jQuery code highlighter plugin
 711 ...............................................................................
 712 LICENSE: http://www.opensource.org/licenses/mit-license.php
 713 WEBSITE: http://noteslog.com/chili/
 714 
 715                                                Copyright 2008 / Andrea Ercolino
 716 ===============================================================================
 717 */
 718 
 719 ChiliBook.recipeLoading = false;
 720 
 721 
 722 
 723 ChiliBook.recipes[ "php.js" ] =
 724 /* ----------------------------------------------------------------------------
 725  * this recipe uses a little trick for highlighting php code
 726  *   1: replace each php snippet with a placeholder
 727  *   2: highlight html without php and php snippets apart
 728  *   3: replace each placeholder with its highlighted php snippet
 729  * 
 730  * the trick is not perfect only if the html without php is broken
 731  * however, in such a case many highlighters get fooled but Chili does not
 732  * 
 733  * ---
 734  * this recipe has been adapted for working with Safari
 735  * in fact, Safari cannot match more than 101236 characters with a lazy star
 736  * --------------------------------------------------------------------------*/
 737 {
 738       _name: "php"
 739     , _case: true
 740     , _main: {
 741           all: {
 742               _match: /[\w\W]*/ 
 743             , _replace: function( all ) {
 744                 var placeholder = String.fromCharCode(0);
 745                 var blocks = [];
 746                 var that = this;
 747                 var no_php_1 = all.replace( /<\?[^?]*\?+(?:[^>][^?]*\?+)*>/g, function( block ) {
 748                     blocks.push( that.x( block, '/block/php_1' ) );
 749                     return placeholder;
 750                 } );
 751                 var no_php_2 = no_php_1.replace( /^[^?]*\?+(?:[^>][^?]*\?+)*>|<\?[\w\W]*$/g, function( block ) {
 752                     blocks.push( that.x( block, '/block/php_2' ) );
 753                     return placeholder;
 754                 } );
 755                 if( blocks.length ) {
 756                     var html = this.x( no_php_2, 'html' );
 757                     var count = 0;
 758                     return html.replace( new RegExp( placeholder, "g" ), function() {
 759                         return blocks[ count++ ];
 760                     } );
 761                 }
 762                 else {
 763                     return this.x( all, '/php' );
 764                 }
 765             }
 766         }
 767     }
 768     , block: {
 769           php_1: { // --- <? +++ ?> ---
 770               _match: /(<\?(?:php\b)?)([^?]*\?+(?:[^>][^?]*\?+)*>)/
 771             , _replace: function( all, open, content ) {
 772                 return "<span class='start'>" + this.x( open ) + "</span>"
 773                     + this.x( content.replace( /\?>$/, '' ), '/php' ) 
 774                     + "<span class='end'>" + this.x( '?>' ) + "</span>";
 775             }
 776             , _style: {
 777                       start: "color: red; font-weight: bold"
 778                     , end:   "color: red;"
 779             }
 780         }
 781         , php_2: { // +++ ?> --- <? +++
 782               _match: /([^?]*\?+(?:[^>][^?]*\?+)*>)|(<\?(?:php\b)?)([\w\W]*)/
 783             , _replace: function( all, content, open2, content2 ) {
 784                 if( open2 ) {
 785                     return "<span class='start'>" + this.x( open2 ) + "</span>"
 786                         + this.x( content2, '/php' );
 787                 }
 788                 else {
 789                     return this.x( content.replace( /\?>$/, '' ), '/php' ) 
 790                         + "<span class='end'>" + this.x( '?>' ) + "</span>";
 791                 }
 792             }
 793             , _style: {
 794                       start: "color: red; font-weight: bold"
 795                     , end:   "color: red;"
 796             }
 797         }
 798     }
 799     , php: {
 800           mlcom: {
 801               _match: /\/\*[^*]*\*+([^\/][^*]*\*+)*\// 
 802             , _style: "color: gray;"
 803         }
 804         , com: {
 805               _match: /(?:\/\/.*)|(?:[^\\]\#.*)/ 
 806             , _style: "color: green;"
 807         }
 808         , string1: {
 809               _match: /\'[^\'\\]*(?:\\.[^\'\\]*)*\'/ 
 810             , _style: "color: purple;"
 811         }
 812         , string2: {
 813               _match: /\"[^\"\\]*(?:\\.[^\"\\]*)*\"/ 
 814             , _style: "color: fuchsia;"
 815         }
 816         , value: {
 817               _match: /\b(?:[Nn][Uu][Ll][Ll]|[Tt][Rr][Uu][Ee]|[Ff][Aa][Ll][Ss][Ee])\b/ 
 818             , _style: "color: gray; font-weight: bold;"
 819         }
 820         , number: {
 821               _match: /\b[+-]?(\d*\.?\d+|\d+\.?\d*)([eE][+-]?\d+)?\b/ 
 822             , _style: "color: red;"
 823         }
 824         , const1: {
 825               _match: /\b(?:DEFAULT_INCLUDE_PATH|E_(?:ALL|CO(?:MPILE_(?:ERROR|WARNING)|RE_(?:ERROR|WARNING))|ERROR|NOTICE|PARSE|STRICT|USER_(?:ERROR|NOTICE|WARNING)|WARNING)|P(?:EAR_(?:EXTENSION_DIR|INSTALL_DIR)|HP_(?:BINDIR|CONFIG_FILE_(?:PATH|SCAN_DIR)|DATADIR|E(?:OL|XTENSION_DIR)|INT_(?:MAX|SIZE)|L(?:IBDIR|OCALSTATEDIR)|O(?:S|UTPUT_HANDLER_(?:CONT|END|START))|PREFIX|S(?:API|HLIB_SUFFIX|YSCONFDIR)|VERSION))|__COMPILER_HALT_OFFSET__)\b/ 
 826             , _style: "color: red;"
 827         }
 828         , const2: {
 829               _match: /\b(?:A(?:B(?:DAY_(?:1|2|3|4|5|6|7)|MON_(?:1(?:0|1|2|)|2|3|4|5|6|7|8|9))|LT_DIGITS|M_STR|SSERT_(?:ACTIVE|BAIL|CALLBACK|QUIET_EVAL|WARNING))|C(?:ASE_(?:LOWER|UPPER)|HAR_MAX|O(?:DESET|NNECTION_(?:ABORTED|NORMAL|TIMEOUT)|UNT_(?:NORMAL|RECURSIVE))|R(?:EDITS_(?:ALL|DOCS|FULLPAGE|G(?:ENERAL|ROUP)|MODULES|QA|SAPI)|NCYSTR|YPT_(?:BLOWFISH|EXT_DES|MD5|S(?:ALT_LENGTH|TD_DES)))|URRENCY_SYMBOL)|D(?:AY_(?:1|2|3|4|5|6|7)|ECIMAL_POINT|IRECTORY_SEPARATOR|_(?:FMT|T_FMT))|E(?:NT_(?:COMPAT|NOQUOTES|QUOTES)|RA(?:_(?:D_(?:FMT|T_FMT)|T_FMT|YEAR)|)|XTR_(?:IF_EXISTS|OVERWRITE|PREFIX_(?:ALL|I(?:F_EXISTS|NVALID)|SAME)|SKIP))|FRAC_DIGITS|GROUPING|HTML_(?:ENTITIES|SPECIALCHARS)|IN(?:FO_(?:ALL|C(?:ONFIGURATION|REDITS)|ENVIRONMENT|GENERAL|LICENSE|MODULES|VARIABLES)|I_(?:ALL|PERDIR|SYSTEM|USER)|T_(?:CURR_SYMBOL|FRAC_DIGITS))|L(?:C_(?:ALL|C(?:OLLATE|TYPE)|M(?:ESSAGES|ONETARY)|NUMERIC|TIME)|O(?:CK_(?:EX|NB|SH|UN)|G_(?:A(?:LERT|UTH(?:PRIV|))|C(?:ONS|R(?:IT|ON))|D(?:AEMON|EBUG)|E(?:MERG|RR)|INFO|KERN|L(?:OCAL(?:0|1|2|3|4|5|6|7)|PR)|MAIL|N(?:DELAY|EWS|O(?:TICE|WAIT))|ODELAY|P(?:ERROR|ID)|SYSLOG|U(?:SER|UCP)|WARNING)))|M(?:ON_(?:1(?:0|1|2|)|2|3|4|5|6|7|8|9|DECIMAL_POINT|GROUPING|THOUSANDS_SEP)|_(?:1_PI|2_(?:PI|SQRTPI)|E|L(?:N(?:10|2)|OG(?:10E|2E))|PI(?:_(?:2|4)|)|SQRT(?:1_2|2)))|N(?:EGATIVE_SIGN|O(?:EXPR|STR)|_(?:CS_PRECEDES|S(?:EP_BY_SPACE|IGN_POSN)))|P(?:ATH(?:INFO_(?:BASENAME|DIRNAME|EXTENSION)|_SEPARATOR)|M_STR|OSITIVE_SIGN|_(?:CS_PRECEDES|S(?:EP_BY_SPACE|IGN_POSN)))|RADIXCHAR|S(?:EEK_(?:CUR|END|SET)|ORT_(?:ASC|DESC|NUMERIC|REGULAR|STRING)|TR_PAD_(?:BOTH|LEFT|RIGHT))|T(?:HOUS(?:ANDS_SEP|EP)|_FMT(?:_AMPM|))|YES(?:EXPR|STR))\b/ 
 830             , _style: "color: red;"
 831         }
 832         , global: {
 833               _match: /(?:\$GLOBALS|\$_COOKIE|\$_ENV|\$_FILES|\$_GET|\$_POST|\$_REQUEST|\$_SERVER|\$_SESSION|\$php_errormsg)\b/ 
 834             , _style: "color: red;"
 835         }
 836         , keyword: {
 837               _match: /\b(?:__CLASS__|__FILE__|__FUNCTION__|__LINE__|__METHOD__|abstract|and|array|as|break|case|catch|cfunction|class|clone|const|continue|declare|default|die|do|echo|else|elseif|empty|enddeclare|endfor|endforeach|endif|endswitch|endwhile|eval|exception|exit|extends|extends|final|for|foreach|function|global|if|implements|include|include_once|interface|isset|list|new|old_function|or|php_user_filter|print|private|protected|public|require|require_once|return|static|switch|this|throw|try|unset|use|var|while|xor)\b/ 
 838             , _style: "color: navy; font-weight: bold;"
 839         }
 840         , variable: {
 841               _match: /\$(\w+)/
 842             , _replace: '<span class="keyword">$</span><span class="variable">$1</span>' 
 843             , _style: "color: #4040c2;"
 844         }
 845         , heredoc: {
 846               _match: /(\<\<\<\s*)(\w+)((?:(?!\2).*\n)+)(\2)\b/
 847             , _replace: '<span class="keyword">$1</span><span class="string1">$2</span><span class="string2">$3</span><span class="string1">$4</span>' 
 848         }
 849     }
 850 }
 851 
 852 
 853 
 854 ChiliBook.recipes[ "html.js" ] = 
 855 {
 856       _name: 'html'
 857     , _case: false
 858     , _main: {
 859           doctype: { 
 860               _match: /<!DOCTYPE\b[\w\W]*?>/ 
 861             , _style: "color: #CC6600;"
 862         }
 863         , ie_style: {
 864               _match: /(<!--\[[^\]]*\]>)([\w\W]*?)(<!\[[^\]]*\]-->)/
 865             , _replace: function( all, open, content, close ) {
 866                 return "<span class='ie_style'>" + this.x( open ) + "</span>" 
 867                       + this.x( content, '//style' ) 
 868                       + "<span class='ie_style'>" + this.x( close ) + "</span>";
 869             }
 870             , _style: "color: DarkSlateGray; font-weight: bold;"
 871         }
 872         , comment: { 
 873               _match: /<!--[\w\W]*?-->/ 
 874             , _style: "color: #4040c2;"
 875         }
 876         , script: { 
 877               _match: /(<script\s+[^>]*>)([\w\W]*?)(<\/script\s*>)/
 878             , _replace: function( all, open, content, close ) { 
 879                   return this.x( open, '//tag_start' ) 
 880                       + this.x( content, 'js' ) 
 881                       + this.x( close, '//tag_end' );
 882             } 
 883         }
 884         , style: { 
 885               _match: /(<style\s+[^>]*>)([\w\W]*?)(<\/style\s*>)/
 886             , _replace: function( all, open, content, close ) { 
 887                   return this.x( open, '//tag_start' ) 
 888                       + this.x( content, 'css' ) 
 889                       + this.x( close, '//tag_end' );
 890             } 
 891         }
 892         // matches a starting tag of an element (with attrs)
 893         // like "<div ... >" or "<img ... />"
 894         , tag_start: { 
 895               _match: /(<\w+)((?:[?%]>|[\w\W])*?)(\/>|>)/ 
 896             , _replace: function( all, open, content, close ) { 
 897                   return "<span class='tag_start'>" + this.x( open ) + "</span>" 
 898                       + this.x( content, '/tag_attrs' ) 
 899                       + "<span class='tag_start'>" + this.x( close ) + "</span>";
 900             }
 901             , _style: "color: navy; font-weight: bold;"
 902         } 
 903         // matches an ending tag
 904         // like "</div>"
 905         , tag_end: { 
 906               _match: /<\/\w+\s*>|\/>/ 
 907             , _style: "color: navy;"
 908         }
 909         , entity: { 
 910               _match: /&\w+?;/ 
 911             , _style: "color: blue;"
 912         }
 913     }
 914     , tag_attrs: {
 915         // matches a name/value pair
 916         attr: {
 917             // before in $1, name in $2, between in $3, value in $4
 918               _match: /(\W*?)([\w-]+)(\s*=\s*)((?:\'[^\']*(?:\\.[^\']*)*\')|(?:\"[^\"]*(?:\\.[^\"]*)*\"))/ 
 919             , _replace: "$1<span class='attr_name'>$2</span>$3<span class='attr_value'>$4</span>"
 920             , _style: { attr_name:  "color: green;", attr_value: "color: maroon;" }
 921         }
 922     }
 923 };
 924 
 925 
 926 
 927 ChiliBook.recipes[ "js.js" ] = 
 928 {
 929       _name: 'js'
 930     , _case: true
 931     , _main: {
 932           ml_comment: { 
 933               _match: /\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\//
 934             , _style: 'color: gray;'
 935         }
 936         , sl_comment: { 
 937               _match: /\/\/.*/
 938             , _style: 'color: green;'
 939         }
 940         , string: { 
 941               _match: /(?:\'[^\'\\\n]*(?:\\.[^\'\\\n]*)*\')|(?:\"[^\"\\\n]*(?:\\.[^\"\\\n]*)*\")/
 942             , _style: 'color: teal;'
 943         }
 944         , num: { 
 945               _match: /\b[+-]?(?:\d*\.?\d+|\d+\.?\d*)(?:[eE][+-]?\d+)?\b/
 946             , _style: 'color: red;'
 947         }
 948         , reg_not: { //this prevents "a / b / c" to be interpreted as a reg_exp
 949               _match: /(?:\w+\s*)\/[^\/\\\n]*(?:\\.[^\/\\\n]*)*\/[gim]*(?:\s*\w+)/
 950             , _replace: function( all ) {
 951                 return this.x( all, '//num' );
 952             }
 953         }
 954         , reg_exp: { 
 955               _match: /\/[^\/\\\n]*(?:\\.[^\/\\\n]*)*\/[gim]*/
 956             , _style: 'color: maroon;'
 957         }
 958         , brace: { 
 959               _match: /[\{\}]/
 960             , _style: 'color: red; font-weight: bold;'
 961         }
 962         , statement: { 
 963               _match: /\b(with|while|var|try|throw|switch|return|if|for|finally|else|do|default|continue|const|catch|case|break)\b/
 964             , _style: 'color: navy; font-weight: bold;'
 965         }
 966         , error: { 
 967               _match: /\b(URIError|TypeError|SyntaxError|ReferenceError|RangeError|EvalError|Error)\b/
 968             , _style: 'color: Coral;'
 969         }
 970         , object: { 
 971               _match: /\b(String|RegExp|Object|Number|Math|Function|Date|Boolean|Array)\b/
 972             , _style: 'color: DeepPink;'
 973         }
 974         , property: { 
 975               _match: /\b(undefined|arguments|NaN|Infinity)\b/
 976             , _style: 'color: Purple; font-weight: bold;'
 977         }
 978         , 'function': { 
 979               _match: /\b(parseInt|parseFloat|isNaN|isFinite|eval|encodeURIComponent|encodeURI|decodeURIComponent|decodeURI)\b/
 980             , _style: 'color: olive;'
 981         }
 982         , operator: {
 983               _match: /\b(void|typeof|this|new|instanceof|in|function|delete)\b/
 984             , _style: 'color: RoyalBlue; font-weight: bold;'
 985         }
 986         , liveconnect: {
 987               _match: /\b(sun|netscape|java|Packages|JavaPackage|JavaObject|JavaClass|JavaArray|JSObject|JSException)\b/
 988             , _style: 'text-decoration: overline;'
 989         }
 990     }
 991 };
 992 
 993 
 994 
 995 ChiliBook.recipes[ "css.js" ] = 
 996 {
 997       _name: 'css'
 998     , _case: true
 999     , _main: {
1000           comment: { 
1001               _match: /\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\// 
1002             , _style: "color: olive;"
1003         }
1004         , directive: {
1005               _match: /@\w+/
1006             , _style: "color: fuchsia;"
1007         }
1008         , url: {
1009               _match: /\b(url\s*\()([^)]+)(\))/
1010             , _replace: "<span class='url'>$1</span>$2<span class='url'>$3</span>"
1011             , _style: "color: fuchsia;"
1012         }
1013         , block:   {
1014               _match: /\{([\w\W]*?)\}/
1015             , _replace: function( all, pairs ) {
1016                 return '{' + this.x( pairs, '/definition' ) + '}';
1017             }
1018         }
1019         , 'class': {
1020               _match: /\.\w+/
1021             , _style: "color: #CC0066; font-weight: bold;"
1022         }
1023         , id:      {
1024               _match: /#\w+/
1025             , _style: "color: IndianRed; font-weight: bold;"
1026         }
1027         , pseudo:  {
1028               _match: /:\w+/
1029             , _style: "color: #CC9900;"
1030         }
1031         , element: {
1032               _match: /\w+/
1033             , _style: "color: Purple; font-weight: bold;"
1034         }
1035     }
1036     , definition: {
1037           comment: { 
1038               _match: /\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\//
1039         }
1040         , property: {
1041               _match: /\b(?:zoom|z-index|writing-mode|word-wrap|word-spacing|word-break|width|widows|white-space|volume|voice-family|visibility|vertical-align|unicode-bidi|top|text-underline-position|text-transform|text-shadow|text-overflow|text-kashida-space|text-justify|text-indent|text-decoration|text-autospace|text-align-last|text-align|table-layout|stress|speech-rate|speak-punctuation|speak-numeral|speak-header|speak|size|scrollbar-track-color|scrollbar-shadow-color|scrollbar-highlight-color|scrollbar-face-color|scrollbar-dark-shadow-color|scrollbar-base-color|scrollbar-arrow-color|scrollbar-3d-light-color|ruby-position|ruby-overhang|ruby-align|right|richness|quotes|position|play-during|pitch-range|pitch|pause-before|pause-after|pause|page-break-inside|page-break-before|page-break-after|page|padding-top|padding-right|padding-left|padding-bottom|padding|overflow-Y|overflow-X|overflow|outline-width|outline-style|outline-color|outline|orphans|min-width|min-height|max-width|max-height|marks|marker-offset|margin-top|margin-right|margin-left|margin-bottom|margin|list-style-type|list-style-position|list-style-image|list-style|line-height|line-break|letter-spacing|left|layout-grid-type|layout-grid-mode|layout-grid-line|layout-grid-char-spacing|layout-grid-char|layout-grid|layout-flow|layer-background-image|layer-background-color|include-source|ime-mode|height|font-weight|font-variant|font-style|font-stretch|font-size-adjust|font-size|font-family|font|float|filter|empty-cells|elevation|display|direction|cursor|cue-before|cue-after|cue|counter-reset|counter-increment|content|color|clip|clear|caption-side|bottom|border-width|border-top-width|border-top-style|border-top-color|border-top|border-style|border-spacing|border-right-width|border-right-style|border-right-color|border-right|border-left-width|border-left-style|border-left-color|border-left|border-color|border-collapse|border-bottom-width|border-bottom-style|border-bottom-color|border-bottom|border|behavior|background-repeat|background-position-y|background-position-x|background-position|background-image|background-color|background-attachment|background|azimuth|accelerator)\s*:/
1042             , _style: "color: #330066;"
1043         }
1044         , special: {
1045               _match: /\b(?:-use-link-source|-set-link-source|-replace|-moz-user-select|-moz-user-modify|-moz-user-input|-moz-user-focus|-moz-outline-width|-moz-outline-style|-moz-outline-color|-moz-outline|-moz-opacity|-moz-border-top-colors|-moz-border-right-colors|-moz-border-radius-topright|-moz-border-radius-topleft|-moz-border-radius-bottomright|-moz-border-radius-bottomleft|-moz-border-radius|-moz-border-left-colors|-moz-border-bottom-colors|-moz-binding)\s*:/
1046             , _style: "color: #330066; text-decoration: underline;"
1047         }
1048         , url: {
1049               _match: /\b(url\s*\()([^)]+)(\))/
1050             , _replace: "<span class='url'>$1</span>$2<span class='url'>$3</span>"
1051         }
1052         , value: {
1053               _match: /\b(?:xx-small|xx-large|x-soft|x-small|x-slow|x-low|x-loud|x-large|x-high|x-fast|wider|wait|w-resize|visible|url|uppercase|upper-roman|upper-latin|upper-alpha|underline|ultra-expanded|ultra-condensed|tv|tty|transparent|top|thin|thick|text-top|text-bottom|table-row-group|table-row|table-header-group|table-footer-group|table-column-group|table-column|table-cell|table-caption|sw-resize|super|sub|status-bar|static|square|spell-out|speech|solid|soft|smaller|small-caption|small-caps|small|slower|slow|silent|show|separate|semi-expanded|semi-condensed|se-resize|scroll|screen|s-resize|run-in|rtl|rightwards|right-side|right|ridge|rgb|repeat-y|repeat-x|repeat|relative|projection|print|pre|portrait|pointer|overline|outside|outset|open-quote|once|oblique|nw-resize|nowrap|normal|none|no-repeat|no-open-quote|no-close-quote|ne-resize|narrower|n-resize|move|mix|middle|message-box|medium|marker|ltr|lowercase|lower-roman|lower-latin|lower-greek|lower-alpha|lower|low|loud|local|list-item|line-through|lighter|level|leftwards|left-side|left|larger|large|landscape|justify|italic|invert|inside|inset|inline-table|inline|icon|higher|high|hide|hidden|help|hebrew|handheld|groove|format|fixed|faster|fast|far-right|far-left|fantasy|extra-expanded|extra-condensed|expanded|embossed|embed|e-resize|double|dotted|disc|digits|default|decimal-leading-zero|decimal|dashed|cursive|crosshair|cross|crop|counters|counter|continuous|condensed|compact|collapse|code|close-quote|circle|center-right|center-left|center|caption|capitalize|braille|bottom|both|bolder|bold|block|blink|bidi-override|below|behind|baseline|avoid|auto|aural|attr|armenian|always|all|absolute|above)\b/
1054             , _style: "color: #3366FF;"
1055         }
1056         , string: { 
1057               _match: /(?:\'[^\'\\\n]*(?:\\.[^\'\\\n]*)*\')|(?:\"[^\"\\\n]*(?:\\.[^\"\\\n]*)*\")/ 
1058             , _style: "color: teal;"
1059         }
1060         , number: { 
1061               _match: /(?:\b[+-]?(?:\d*\.?\d+|\d+\.?\d*))(?:%|(?:(?:px|pt|em|)\b))/ 
1062             , _style: "color: red;"
1063         }
1064         , color : { 
1065               _match: /(?:\#[a-fA-F0-9]{3,6})|\b(?:yellow|white|teal|silver|red|purple|olive|navy|maroon|lime|green|gray|fuchsia|blue|black|aqua|YellowGreen|Yellow|WhiteSmoke|White|Wheat|Violet|Turquoise|Tomato|Thistle|Teal|Tan|SteelBlue|SpringGreen|Snow|SlateGrey|SlateGray|SlateBlue|SkyBlue|Silver|Sienna|SeaShell|SeaGreen|SandyBrown|Salmon|SaddleBrown|RoyalBlue|RosyBrown|Red|Purple|PowderBlue|Plum|Pink|Peru|PeachPuff|PapayaWhip|PaleVioletRed|PaleTurquoise|PaleGreen|PaleGoldenRod|Orchid|OrangeRed|Orange|OliveDrab|Olive|OldLace|Navy|NavajoWhite|Moccasin|MistyRose|MintCream|MidnightBlue|MediumVioletRed|MediumTurquoise|MediumSpringGreen|MediumSlateBlue|MediumSeaGreen|MediumPurple|MediumOrchid|MediumBlue|MediumAquaMarine|Maroon|Magenta|Linen|LimeGreen|Lime|LightYellow|LightSteelBlue|LightSlateGrey|LightSlateGray|LightSkyBlue|LightSeaGreen|LightSalmon|LightPink|LightGrey|LightGreen|LightGray|LightGoldenRodYellow|LightCyan|LightCoral|LightBlue|LemonChiffon|LawnGreen|LavenderBlush|Lavender|Khaki|Ivory|Indigo|IndianRed|HotPink|HoneyDew|Grey|GreenYellow|Green|Gray|GoldenRod|Gold|GhostWhite|Gainsboro|Fuchsia|ForestGreen|FloralWhite|FireBrick|DodgerBlue|DimGrey|DimGray|DeepSkyBlue|DeepPink|Darkorange|DarkViolet|DarkTurquoise|DarkSlateGrey|DarkSlateGray|DarkSlateBlue|DarkSeaGreen|DarkSalmon|DarkRed|DarkOrchid|DarkOliveGreen|DarkMagenta|DarkKhaki|DarkGrey|DarkGreen|DarkGray|DarkGoldenRod|DarkCyan|DarkBlue|Cyan|Crimson|Cornsilk|CornflowerBlue|Coral|Chocolate|Chartreuse|CadetBlue|BurlyWood|Brown|BlueViolet|Blue|BlanchedAlmond|Black|Bisque|Beige|Azure|Aquamarine|Aqua|AntiqueWhite|AliceBlue)\b/ 
1066             , _style: "color: green;"
1067         }
1068     }
1069 };
1070 
1071 
1072 /*
1073 ===============================================================================
1074 Chili is the jQuery code highlighter plugin
1075 ...............................................................................
1076 LICENSE: http://www.opensource.org/licenses/mit-license.php
1077 WEBSITE: http://noteslog.com/chili/
1078 页面代码
1079 * 1、只要包含图片的div有imgMagnifier有类样式
1080 * 2、包含 jquery.chili.2.2.css 样式文件
1081 * 3、包含:{
1082   <div class="imgMagnifierWrap"> 
1083       <div class="overlay"></div><!--覆盖层,鼠标的感应区域,位于小图上最方--> 
1084       <div class="tipboxHover"></div><!--小图上方的悬停提示方框--> 
1085       <div class="imgOriginal"></div> 
1086   </div>
1087 * }
1088                                                Copyright 2008 / Andrea Ercolino
1089 ===============================================================================
1090 */
1091 
1092 
1093 (function($){
1094         $.imgPreloader=function(url,eventLists){
1095             var img=new Image();
1096             var $img=$(img);
1097             img.src=url;
1098             $.each(eventLists,function(type,fn){
1099                 $img.bind(type,fn);
1100             });
1101             $img.trigger(img.complete?'load':'begin');
1102             return $img;
1103         };
1104     
1105         $.fn.imgPreloader=function(url,eventLists){        
1106             return this.each(function(){
1107                 $(this).append(
1108                     $.imgPreloader(url,eventLists)
1109                 );
1110             });
1111         };
1112         $.fn.imgMagnifier=function(options){            
1113                 return this.each(function(){
1114                     var cfg=$.extend({
1115                         width:500,
1116                         height:500,
1117                         left:12
1118                         },
1119                         options || {});
1120                 
1121                     var $anchor=$(this);
1122                     var $thumb=$('img',this);
1123                     var $wrap=$('<div>').addClass('imgMagnifierWrap').appendTo('body');
1124                     var $tipbox=$('<div>').addClass('tipboxHover').appendTo($wrap);
1125                     //小图大小及坐标存储
1126                     var thumbInfo={
1127                         height:$thumb.outerHeight(),
1128                         width:$thumb.outerWidth(),
1129                         left:$thumb.offset().left,
1130                         top:$thumb.offset().top
1131                     };
1132                     //与小图等大的遮罩层,IE兼容、透明,省去判断烦恼
1133                     var $overlay=$('<div>').addClass('overlay').css(thumbInfo).appendTo($wrap);
1134                     //悬停的指示方框大小
1135                     var tipboxInfo={
1136                         width:$tipbox.width(),
1137                         height:$tipbox.height()
1138                     };
1139                                     
1140                     //加载大图,默认右置
1141                     var $o=$('<div>').addClass('imgOriginal').appendTo($wrap)
1142                         .css({
1143                               top:thumbInfo.top,
1144                               left:thumbInfo.left+thumbInfo.width+cfg.left,
1145                               width:cfg.width,
1146                               height:cfg.height,
1147                               lineHeight:cfg.height+'px'
1148                               });
1149                     //感应区域计算(小图所处感应区域四边各减去指示方框各四边的1/2大小)
1150                     var borderLeft =thumbInfo.left+tipboxInfo.width/2;
1151                     var borderTop=thumbInfo.top+tipboxInfo.height/2;
1152                     
1153                     //鼠标位置存储,用以解决大图预载的load事件和小图上的mousemove事件不同步的问题
1154                     var mouseInfo={x:0,y:0};
1155                     //指示框定位
1156                     var setTipboxPosition=function(e){
1157                         mouseInfo.x=e.pageX;
1158                         mouseInfo.y=e.pageY;
1159                         $tipbox.css({
1160                             top:mouseInfo.y<thumbInfo.width/2+thumbInfo.top
1161                                 ?Math.max(mouseInfo.y-tipboxInfo.height/2,thumbInfo.top)
1162                                 :Math.min(mouseInfo.y-tipboxInfo.height/2,thumbInfo.top+thumbInfo.height-tipboxInfo.height),
1163                             left:mouseInfo.x<thumbInfo.width/2+thumbInfo.left
1164                                 ?Math.max(mouseInfo.x-tipboxInfo.width/2,thumbInfo.left)
1165                                 :Math.min(mouseInfo.x-tipboxInfo.width/2,thumbInfo.left+thumbInfo.width-tipboxInfo.width)
1166                             });    
1167                         setImgPosition();
1168                     };
1169                     //图片过小时自动适应
1170                     var autoFitPicture=function(){
1171                         var $i=$o.children('img');
1172                         if( $i.length && $i.width()>0 ){
1173                                 if($i.width()<cfg.width){
1174                                     cfg.width=$i.width();
1175                                     $o.width(cfg.width);
1176                                 }
1177                                 if($i.height()<cfg.height){
1178                                     cfg.height=$i.height();
1179                                     $o.height(cfg.height);
1180                                 }
1181                                 setImgPosition();
1182                         }
1183                     };
1184                     //大图定位
1185                     var setImgPosition=function(){
1186                         //比例坐标计算
1187                         var ratioX=(mouseInfo.x-borderLeft)/(thumbInfo.width-tipboxInfo.width);
1188                         var ratioY=(mouseInfo.y-borderTop)/(thumbInfo.height-tipboxInfo.height);
1189                         //按有效感应范围(0~100%)快捷筛选
1190                         ratioX=ratioX<0?0:ratioX>1?1:ratioX;
1191                         ratioY=ratioY<0?0:ratioY>1?1:ratioY;
1192                         var $i=$o.children('img');
1193                             $i.css({
1194                                 left:-($i.width()-cfg.width)*ratioX,
1195                                 top:-($i.height()-cfg.height)*ratioY
1196                             });
1197                     };
1198                     var isImageReady=false;
1199                     $overlay.data('ready',false).bind('mouseenter mouseleave',function(e){
1200                         if( ! isImageReady && e.type=='mouseenter' ){
1201                             $.imgPreloader($anchor.children('img').attr('src'),{
1202                                 load:function(){
1203                                     isImageReady=true;
1204                                     $o.empty().append(this);
1205                                     setTimeout(autoFitPicture,0);
1206                                     },
1207                                 begin:function(){
1208                                     $o.text('loading...');
1209                                 },
1210                                 error:function(){
1211                                     isImageReady=true;
1212                                     $o.text('invalid picture!');
1213                                 }
1214                             });
1215                          }                                                                                
1216                          $tipbox.add($o).toggle();
1217                     })
1218                     .mousemove(setTipboxPosition);
1219                 });
1220         };
1221     })(jQuery);
1222 
1223 $(function(){
1224     $("div[id='localImag']").addClass("imgMagnifier");
1225     setTimeout(function(){
1226         ChiliBook.recipeFolder = "chili/";
1227         $('pre>code').chili();
1228         $('div.imgMagnifier:eq(0)').imgMagnifier({width:400});
1229     },100);
1230 });
1231             

css

 1 *{margin:0; padding:0; border:none;}
 2 body{width:60em; padding-left:5em;}
 3 ul{padding:1em 0 5em 1em; list-style:georgian inside;}
 4 pre{background-color:rgb(248,248,232);}
 5 a.imgMagnifier{}
 6 a.imgMagnifier img{/* width:300px; height:200px;*/}
 7 .imgMagnifierWrap *{position:absolute;background:#fff;}
 8 .imgMagnifierWrap .tipboxHover{width:80px; height:60px; filter:alpha(opacity=30);opacity:.3;display:none;}
 9 .imgMagnifierWrap .imgOriginal{display:none;z-index:9999;overflow:hidden; width:400px; height:400px;background-color:#cdf; background-repeat:no-repeat; text-align:center;border:1px solid #555; }
10 .imgMagnifierWrap .overlay{cursor:crosshair;filter:alpha(opacity=0);opacity:0;}

需要include进来的jsp

1 <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
2 <script type="text/javascript" src="${path}/js/jquery.chili.2.2/jquery.chili.2.2.js"></script>
3 <link type="text/css" rel="stylesheet" href="${path }/js/jquery.chili.2.2/jquery.chili.2.2.css"/> 
4 <div class="imgMagnifierWrap"> 
5     <div class="overlay"></div><!--覆盖层,鼠标的感应区域,位于小图上最方--> 
6     <div class="tipboxHover"></div><!--小图上方的悬停提示方框--> 
7     <div class="imgOriginal"></div> 
8 </div> 

显示的jsp格式:

1 <jsp:include page="/js/jquery.chili.2.2/jquery.chili.2.2.jsp"></jsp:include>
2                   <div class="gift-middle-left" id="localImag">
3                       
4                       <img id="preview" width="320px" height="322px" src="${path}${giftBean.giftImageId}"/>
5                   </div>

注意点:
包含<img/>标签的div必须要一个id:localImag;也可以自己配置,但是又在jquery.chili.2.2.js文件中改。

 

 

posted on 2012-04-11 12:57  e.FLY  阅读(790)  评论(0)    收藏  举报