jquery.chili-2.2.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708
  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. Copyright 2008 / Andrea Ercolino
  8. ===============================================================================
  9. */
  10. ( function($) {
  11. ChiliBook = { //implied global
  12. version: "2.2" // 2008-07-06
  13. // options --------------------------------------------------------------------
  14. , automatic: true
  15. , automaticSelector: "code"
  16. , lineNumbers: !true
  17. , codeLanguage: function( el ) {
  18. var recipeName = $( el ).attr( "class" );
  19. return recipeName ? recipeName : '';
  20. }
  21. , recipeLoading: true
  22. , recipeFolder: "" // used like: recipeFolder + recipeName + '.js'
  23. // IE and FF convert   to " ", Safari and Opera do not
  24. , replaceSpace: " "
  25. , replaceTab: "    "
  26. , replaceNewLine: "&#160;<br/>"
  27. , selectionStyle: [ "position:absolute; z-index:3000; overflow:scroll;"
  28. , "width:16em;"
  29. , "height:9em;"
  30. , "border:1px solid gray;"
  31. , "padding:15px;"
  32. , "background-color:yellow;"
  33. ].join( ' ' )
  34. // ------------------------------------------------------------- end of options
  35. , defaultReplacement: '<span class="$0">$$</span>' // TODO: make this an option again
  36. , recipes: {} //repository
  37. , queue: {} //registry
  38. , unique: function() {
  39. return (new Date()).valueOf();
  40. }
  41. };
  42. $.fn.chili = function( options ) {
  43. var book = $.extend( {}, ChiliBook, options || {} );
  44. function cook( ingredients, recipe, blockName ) {
  45. function prepareBlock( recipe, blockName ) {
  46. var steps = [];
  47. for( var stepName in recipe[ blockName ] ) {
  48. steps.push( prepareStep( recipe, blockName, stepName ) );
  49. }
  50. return steps;
  51. } // prepareBlock
  52. function prepareStep( recipe, blockName, stepName ) {
  53. var step = recipe[ blockName ][ stepName ];
  54. var exp = ( typeof step._match == "string" ) ? step._match : step._match.source;
  55. return {
  56. recipe: recipe
  57. , blockName: blockName
  58. , stepName: stepName
  59. , exp: "(" + exp + ")"
  60. , length: 1 // add 1 to account for the newly added parentheses
  61. + (exp // count number of submatches in here
  62. .replace( /\\./g, "%" ) // disable any escaped character
  63. .replace( /\[.*?\]/g, "%" ) // disable any character class
  64. .match( /\((?!\?)/g ) // match any open parenthesis, not followed by a ?
  65. || [] // make sure it is an empty array if there are no matches
  66. ).length // get the number of matches
  67. , replacement: step._replace ? step._replace : book.defaultReplacement
  68. };
  69. } // prepareStep
  70. function knowHow( steps ) {
  71. var prevLength = 1;
  72. var exps = [];
  73. for (var i = 0; i < steps.length; i++) {
  74. var exp = steps[ i ].exp;
  75. // adjust backreferences
  76. exp = exp.replace( /\\\\|\\(\d+)/g, function( m, aNum ) {
  77. return !aNum ? m : "\\" + ( prevLength + 1 + parseInt( aNum, 10 ) );
  78. } );
  79. exps.push( exp );
  80. prevLength += steps[ i ].length;
  81. }
  82. var prolog = '((?:\\s|\\S)*?)';
  83. var epilog = '((?:\\s|\\S)+)';
  84. var source = '(?:' + exps.join( "|" ) + ')';
  85. source = prolog + source + '|' + epilog;
  86. return new RegExp( source, recipe._case ? "g" : "gi" );
  87. } // knowHow
  88. function escapeHTML( str ) {
  89. return str.replace( /&/g, "&amp;" ).replace( /</g, "&lt;" );
  90. } // escapeHTML
  91. function replaceSpaces( str ) {
  92. return str.replace( / +/g, function( spaces ) {
  93. return spaces.replace( / /g, replaceSpace );
  94. } );
  95. } // replaceSpaces
  96. function filter( str ) {
  97. str = escapeHTML( str );
  98. if( replaceSpace ) {
  99. str = replaceSpaces( str );
  100. }
  101. return str;
  102. } // filter
  103. function applyRecipe( subject, recipe ) {
  104. return cook( subject, recipe );
  105. } // applyRecipe
  106. function applyBlock( subject, recipe, blockName ) {
  107. return cook( subject, recipe, blockName );
  108. } // applyBlock
  109. function applyStep( subject, recipe, blockName, stepName ) {
  110. var replaceSpace = book.replaceSpace;
  111. var step = prepareStep( recipe, blockName, stepName );
  112. var steps = [step];
  113. var perfect = subject.replace( knowHow( steps ), function() {
  114. return chef.apply( { steps: steps }, arguments );
  115. } );
  116. return perfect;
  117. } // applyStep
  118. function applyModule( subject, module, context ) {
  119. if( ! module ) {
  120. return filter( subject );
  121. }
  122. var sub = module.split( '/' );
  123. var recipeName = '';
  124. var blockName = '';
  125. var stepName = '';
  126. switch( sub.length ) {
  127. case 1:
  128. recipeName = sub[0];
  129. break;
  130. case 2:
  131. recipeName = sub[0]; blockName = sub[1];
  132. break;
  133. case 3:
  134. recipeName = sub[0]; blockName = sub[1]; stepName = sub[2];
  135. break;
  136. default:
  137. return filter( subject );
  138. }
  139. function getRecipe( recipeName ) {
  140. var path = getPath( recipeName );
  141. var recipe = book.recipes[ path ];
  142. if( ! recipe ) {
  143. throw {msg:"recipe not available"};
  144. }
  145. return recipe;
  146. }
  147. try {
  148. var recipe;
  149. if ( '' == stepName ) {
  150. if ( '' == blockName ) {
  151. if ( '' == recipeName ) {
  152. //nothing to do
  153. }
  154. else { // ( '' != recipeName )
  155. recipe = getRecipe( recipeName );
  156. return applyRecipe( subject, recipe );
  157. }
  158. }
  159. else { // ( '' != blockName )
  160. if( '' == recipeName ) {
  161. recipe = context.recipe;
  162. }
  163. else {
  164. recipe = getRecipe( recipeName );
  165. }
  166. if( ! (blockName in recipe) ) {
  167. return filter( subject );
  168. }
  169. return applyBlock( subject, recipe, blockName );
  170. }
  171. }
  172. else { // ( '' != stepName )
  173. if( '' == recipeName ) {
  174. recipe = context.recipe;
  175. }
  176. else {
  177. recipe = getRecipe( recipeName );
  178. }
  179. if( '' == blockName ) {
  180. blockName = context.blockName;
  181. }
  182. if( ! (blockName in recipe) ) {
  183. return filter( subject );
  184. }
  185. if( ! (stepName in recipe[blockName]) ) {
  186. return filter( subject );
  187. }
  188. return applyStep( subject, recipe, blockName, stepName );
  189. }
  190. }
  191. catch( e ) {
  192. if (e.msg && e.msg == "recipe not available") {
  193. var cue = 'chili_' + book.unique();
  194. if( book.recipeLoading ) {
  195. var path = getPath( recipeName );
  196. if( ! book.queue[ path ] ) {
  197. /* this is a new recipe to download */
  198. try {
  199. book.queue[ path ] = [ {cue: cue, subject: subject, module: module, context: context} ];
  200. $.getJSON( path, function( recipeLoaded ) {
  201. book.recipes[ path ] = recipeLoaded;
  202. var q = book.queue[ path ];
  203. for( var i = 0, iTop = q.length; i < iTop; i++ ) {
  204. var replacement = applyModule( q[ i ].subject, q[ i ].module, q[ i ].context );
  205. if( book.replaceTab ) {
  206. replacement = replacement.replace( /\t/g, book.replaceTab );
  207. }
  208. if( book.replaceNewLine ) {
  209. replacement = replacement.replace( /\n/g, book.replaceNewLine );
  210. }
  211. $( '#' + q[ i ].cue ).replaceWith( replacement );
  212. }
  213. } );
  214. }
  215. catch( recipeNotAvailable ) {
  216. alert( "the recipe for '" + recipeName + "' was not found in '" + path + "'" );
  217. }
  218. }
  219. else {
  220. /* not a new recipe, so just enqueue this element */
  221. book.queue[ path ].push( {cue: cue, subject: subject, module: module, context: context} );
  222. }
  223. return '<span id="' + cue + '">' + filter( subject ) + '</span>';
  224. }
  225. return filter( subject );
  226. }
  227. else {
  228. return filter( subject );
  229. }
  230. }
  231. } // applyModule
  232. function addPrefix( prefix, replacement ) {
  233. var aux = replacement.replace( /(<span\s+class\s*=\s*(["']))((?:(?!__)\w)+\2\s*>)/ig, "$1" + prefix + "__$3" );
  234. return aux;
  235. } // addPrefix
  236. function chef() {
  237. if (! arguments[ 0 ]) {
  238. return '';
  239. }
  240. var steps = this.steps;
  241. var i = 0; // iterate steps
  242. var j = 2; // iterate chef's arguments
  243. var prolog = arguments[ 1 ];
  244. var epilog = arguments[ arguments.length - 3 ];
  245. if (! epilog) {
  246. var step;
  247. while( step = steps[ i++ ] ) {
  248. var aux = arguments; // this unmasks chef's arguments inside the next function
  249. if( aux[ j ] ) {
  250. var replacement = '';
  251. if( $.isFunction( step.replacement ) ) {
  252. var matches = []; //Array.slice.call( aux, j, step.length );
  253. for (var k = 0, kTop = step.length; k < kTop; k++) {
  254. matches.push( aux[ j + k ] );
  255. }
  256. matches.push( aux[ aux.length - 2 ] );
  257. matches.push( aux[ aux.length - 1 ] );
  258. replacement = step.replacement
  259. .apply( {
  260. x: function() {
  261. var subject = arguments[0];
  262. var module = arguments[1];
  263. var context = {
  264. recipe: step.recipe
  265. , blockName: step.blockName
  266. };
  267. return applyModule( subject, module, context );
  268. }
  269. }, matches );
  270. }
  271. else { //we expect step.replacement to be a string
  272. replacement = step.replacement
  273. .replace( /(\\\$)|(?:\$\$)|(?:\$(\d+))/g, function( m, escaped, K ) {
  274. if( escaped ) { /* \$ */
  275. return "$";
  276. }
  277. else if( !K ) { /* $$ */
  278. return filter( aux[ j ] );
  279. }
  280. else if( K == "0" ) { /* $0 */
  281. return step.stepName;
  282. }
  283. else { /* $K */
  284. return filter( aux[ j + parseInt( K, 10 ) ] );
  285. }
  286. } );
  287. }
  288. replacement = addPrefix( step.recipe._name, replacement );
  289. return filter( prolog ) + replacement;
  290. }
  291. else {
  292. j+= step.length;
  293. }
  294. }
  295. }
  296. else {
  297. return filter( epilog );
  298. }
  299. } // chef
  300. if( ! blockName ) {
  301. blockName = '_main';
  302. checkSpices( recipe );
  303. }
  304. if( ! (blockName in recipe) ) {
  305. return filter( ingredients );
  306. }
  307. var replaceSpace = book.replaceSpace;
  308. var steps = prepareBlock( recipe, blockName );
  309. var kh = knowHow( steps );
  310. var perfect = ingredients.replace( kh, function() {
  311. return chef.apply( { steps: steps }, arguments );
  312. } );
  313. return perfect;
  314. } // cook
  315. function loadStylesheetInline( sourceCode ) {
  316. if( document.createElement ) {
  317. var e = document.createElement( "style" );
  318. e.type = "text/css";
  319. if( e.styleSheet ) { // IE
  320. e.styleSheet.cssText = sourceCode;
  321. }
  322. else {
  323. var t = document.createTextNode( sourceCode );
  324. e.appendChild( t );
  325. }
  326. document.getElementsByTagName( "head" )[0].appendChild( e );
  327. }
  328. } // loadStylesheetInline
  329. function checkSpices( recipe ) {
  330. var name = recipe._name;
  331. if( ! book.queue[ name ] ) {
  332. var content = ['/* Chili -- ' + name + ' */'];
  333. for (var blockName in recipe) {
  334. if( blockName.search( /^_(?!main\b)/ ) < 0 ) {
  335. for (var stepName in recipe[ blockName ]) {
  336. var step = recipe[ blockName ][ stepName ];
  337. if( '_style' in step ) {
  338. if( step[ '_style' ].constructor == String ) {
  339. content.push( '.' + name + '__' + stepName + ' { ' + step[ '_style' ] + ' }' );
  340. }
  341. else {
  342. for (var className in step[ '_style' ]) {
  343. content.push( '.' + name + '__' + className + ' { ' + step[ '_style' ][ className ] + ' }' );
  344. }
  345. }
  346. }
  347. }
  348. }
  349. }
  350. content = content.join('\n');
  351. loadStylesheetInline( content );
  352. book.queue[ name ] = true;
  353. }
  354. } // checkSpices
  355. function askDish( el ) {
  356. var recipeName = book.codeLanguage( el );
  357. if( '' != recipeName ) {
  358. var path = getPath( recipeName );
  359. if( book.recipeLoading ) {
  360. /* dynamic setups come here */
  361. if( ! book.queue[ path ] ) {
  362. /* this is a new recipe to download */
  363. try {
  364. book.queue[ path ] = [ el ];
  365. $.getJSON( path, function( recipeLoaded ) {
  366. book.recipes[ path ] = recipeLoaded;
  367. var q = book.queue[ path ];
  368. for( var i = 0, iTop = q.length; i < iTop; i++ ) {
  369. makeDish( q[ i ], path );
  370. }
  371. } );
  372. }
  373. catch( recipeNotAvailable ) {
  374. alert( "the recipe for '" + recipeName + "' was not found in '" + path + "'" );
  375. }
  376. }
  377. else {
  378. /* not a new recipe, so just enqueue this element */
  379. book.queue[ path ].push( el );
  380. }
  381. /* a recipe could have been already downloaded */
  382. makeDish( el, path );
  383. }
  384. else {
  385. /* static setups come here */
  386. makeDish( el, path );
  387. }
  388. }
  389. } // askDish
  390. function makeDish( el, recipePath ) {
  391. var recipe = book.recipes[ recipePath ];
  392. if( ! recipe ) {
  393. return;
  394. }
  395. var $el = $( el );
  396. var ingredients = $el.text();
  397. if( ! ingredients ) {
  398. return;
  399. }
  400. //fix for msie: \r (13) is used instead of \n (10)
  401. //fix for opera: \r\n is used instead of \n
  402. ingredients = ingredients.replace(/\r\n?/g, "\n");
  403. //reverse fix for safari: msie, mozilla and opera render the initial \n
  404. if( $el.parent().is('pre') ) {
  405. if( ! $.browser.safari ) {
  406. ingredients = ingredients.replace(/^\n/g, "");
  407. }
  408. }
  409. var dish = cook( ingredients, recipe ); // all happens here
  410. if( book.replaceTab ) {
  411. dish = dish.replace( /\t/g, book.replaceTab );
  412. }
  413. if( book.replaceNewLine ) {
  414. dish = dish.replace( /\n/g, book.replaceNewLine );
  415. }
  416. el.innerHTML = dish; //much faster than $el.html( dish );
  417. //tried also the function replaceHtml from http://blog.stevenlevithan.com/archives/faster-than-innerhtml
  418. //but it was not faster nor without sideffects (it was not possible to count spans into el)
  419. //opera and safari select PRE text correctly
  420. if( $.browser.msie || $.browser.mozilla ) {
  421. enableSelectionHelper( el );
  422. }
  423. var $that = $el.parent();
  424. var classes = $that.attr( 'class' );
  425. var ln = /ln-(\d+)-([\w][\w\-]*)|ln-(\d+)|ln-/.exec( classes );
  426. if( ln ) {
  427. addLineNumbers( el );
  428. var start = 0;
  429. if( ln[1] ) {
  430. start = parseInt( ln[1], 10 );
  431. var $pieces = $( '.ln-' + ln[1] + '-' + ln[2] );
  432. var pos = $pieces.index( $that[0] );
  433. $pieces.slice( 0, pos ).each( function() {
  434. start += $( this ).find( 'li' ).length;
  435. } );
  436. }
  437. else if( ln[3] ) {
  438. start = parseInt( ln[3], 10 );
  439. }
  440. else {
  441. start = 1;
  442. }
  443. $el.find( 'ol' )[0].start = start;
  444. $('body').width( $('body').width() - 1 ).width( $('body').width() + 1 );
  445. }
  446. else if( book.lineNumbers ) {
  447. addLineNumbers( el );
  448. }
  449. } // makeDish
  450. function enableSelectionHelper( el ) {
  451. var element = null;
  452. $( el )
  453. .parents()
  454. .filter( "pre" )
  455. .bind( "mousedown", function() {
  456. element = this;
  457. if( $.browser.msie ) {
  458. document.selection.empty();
  459. }
  460. else {
  461. window.getSelection().removeAllRanges();
  462. }
  463. } )
  464. .bind( "mouseup", function( event ) {
  465. if( element && (element == this) ) {
  466. element = null;
  467. var selected = '';
  468. if( $.browser.msie ) {
  469. selected = document.selection.createRange().htmlText;
  470. if( '' == selected ) {
  471. return;
  472. }
  473. selected = preserveNewLines( selected );
  474. var container_tag = '<textarea style="STYLE">';
  475. }
  476. else {
  477. selected = window.getSelection().toString(); //opera doesn't select new lines
  478. if( '' == selected ) {
  479. return;
  480. }
  481. selected = selected
  482. .replace( /\r/g, '' )
  483. .replace( /^# ?/g, '' )
  484. .replace( /\n# ?/g, '\n' )
  485. ;
  486. var container_tag = '<pre style="STYLE">';
  487. }
  488. var $container = $( container_tag.replace( /\bSTYLE\b/, ChiliBook.selectionStyle ) )
  489. .appendTo( 'body' )
  490. .text( selected )
  491. .attr( 'id', 'chili_selection' )
  492. .click( function() { $(this).remove(); } )
  493. ;
  494. var top = event.pageY - Math.round( $container.height() / 2 ) + "px";
  495. var left = event.pageX - Math.round( $container.width() / 2 ) + "px";
  496. $container.css( { top: top, left: left } );
  497. if( $.browser.msie ) {
  498. // window.clipboardData.setData( 'Text', selected ); //I couldn't find anything similar for Mozilla
  499. $container[0].focus();
  500. $container[0].select();
  501. }
  502. else {
  503. var s = window.getSelection();
  504. s.removeAllRanges();
  505. var r = document.createRange();
  506. r.selectNodeContents( $container[0] );
  507. s.addRange( r );
  508. }
  509. }
  510. } )
  511. ;
  512. } // enableSelectionHelper
  513. function getPath( recipeName ) {
  514. return book.recipeFolder + recipeName + ".js";
  515. } // getPath
  516. function getSelectedText() {
  517. var text = '';
  518. if( $.browser.msie ) {
  519. text = document.selection.createRange().htmlText;
  520. }
  521. else {
  522. text = window.getSelection().toString();
  523. }
  524. return text;
  525. } // getSelectedText
  526. function preserveNewLines( html ) {
  527. do {
  528. var newline_flag = ChiliBook.unique();
  529. }
  530. while( html.indexOf( newline_flag ) > -1 );
  531. var text = '';
  532. if (/<br/i.test(html) || /<li/i.test(html)) {
  533. if (/<br/i.test(html)) {
  534. html = html.replace( /\<br[^>]*?\>/ig, newline_flag );
  535. }
  536. else if (/<li/i.test(html)) {
  537. html = html.replace( /<ol[^>]*?>|<\/ol>|<li[^>]*?>/ig, '' ).replace( /<\/li>/ig, newline_flag );
  538. }
  539. var el = $( '<pre>' ).appendTo( 'body' ).hide()[0];
  540. el.innerHTML = html;
  541. text = $( el ).text().replace( new RegExp( newline_flag, "g" ), '\r\n' );
  542. $( el ).remove();
  543. }
  544. return text;
  545. } // preserveNewLines
  546. function addLineNumbers( el ) {
  547. function makeListItem1( not_last_line, not_last, last, open ) {
  548. var close = open ? '</span>' : '';
  549. var aux = '';
  550. if( not_last_line ) {
  551. aux = '<li>' + open + not_last + close + '</li>';
  552. }
  553. else if( last ) {
  554. aux = '<li>' + open + last + close + '</li>';
  555. }
  556. return aux;
  557. } // makeListItem1
  558. function makeListItem2( not_last_line, not_last, last, prev_li ) {
  559. var aux = '';
  560. if( prev_li ) {
  561. aux = prev_li;
  562. }
  563. else {
  564. aux = makeListItem1( not_last_line, not_last, last, '' )
  565. }
  566. return aux;
  567. } // makeListItem2
  568. var html = $( el ).html();
  569. var br = /<br>/.test(html) ? '<br>' : '<BR>';
  570. var empty_line = '<li>' + book.replaceSpace + '</li>';
  571. var list_items = html
  572. //extract newlines at the beginning of a span
  573. .replace( /(<span [^>]+>)((?:(?:&nbsp;|\xA0)<br>)+)(.*?)(<\/span>)/ig, '$2$1$3$4' ) // I don't know why <span .*?> does not work here
  574. //transform newlines inside of a span
  575. .replace( /(.*?)(<span .*?>)(.*?)(?:<\/span>(?:&nbsp;|\xA0)<br>|<\/span>)/ig, // but here it does
  576. function( all, before, open, content ) {
  577. if (/<br>/i.test(content)) {
  578. var pieces = before.split( br );
  579. var lastPiece = pieces.pop();
  580. before = pieces.join( br );
  581. var aux = (before ? before + br : '') //+ replace1( lastPiece + content, open );
  582. + (lastPiece + content).replace( /((.*?)(?:&nbsp;|\xA0)<br>)|(.*)/ig,
  583. function( tmp, not_last_line, not_last, last ) {
  584. var aux2 = makeListItem1( not_last_line, not_last, last, open );
  585. return aux2;
  586. }
  587. );
  588. return aux;
  589. }
  590. else {
  591. return all;
  592. }
  593. }
  594. )
  595. //transform newlines outside of a span
  596. .replace( /(<li>.*?<\/li>)|((.*?)(?:&nbsp;|\xA0)<br>)|(.+)/ig,
  597. function( tmp, prev_li, not_last_line, not_last, last ) {
  598. var aux2 = makeListItem2( not_last_line, not_last, last, prev_li );
  599. return aux2;
  600. }
  601. )
  602. //fix empty lines for Opera
  603. .replace( /<li><\/li>/ig, empty_line )
  604. ;
  605. el.innerHTML = '<ol>' + list_items + '</ol>';
  606. } // addLineNumbers
  607. function revealChars( tmp ) {
  608. return $
  609. .map( tmp.split(''),
  610. function(n, i) {
  611. return ' ' + n + ' ' + n.charCodeAt( 0 ) + ' ';
  612. } )
  613. .join(' ');
  614. } // revealChars
  615. //-----------------------------------------------------------------------------
  616. // the coloring starts here
  617. this
  618. .each( function() {
  619. var $this = $( this );
  620. $this.trigger( 'chili.before_coloring' );
  621. askDish( this );
  622. $this.trigger( 'chili.after_coloring' );
  623. } );
  624. return this;
  625. //-----------------------------------------------------------------------------
  626. };
  627. //main
  628. $( function() {
  629. if( ChiliBook.automatic ) {
  630. $( ChiliBook.automaticSelector ).chili();
  631. }
  632. } );
  633. } ) ( jQuery );
  634. //YCODASLIDER DEMO BASIC SETTING
  635. ChiliBook.recipeFolder = "../../lib/chili/";
  636. ChiliBook