hjg
2023-11-18 bb48edb3d9faaaeab0088151c86fc24137acdb08
提交 | 用户 | 时间
58d006 1 /**
A 2  <b>Onpage Help</b>. You can use this to provide help dialogs on your application pages. See docs for more info.
3 */
4
5 window.Onpage_Help = function(options) {
6     var $ = window.jQuery || null;
7     if($ == null) return;
8
9     options = options || {}
10     var defaults = {
11         include_all: true,
12         icon_1: 'fa fa-question',
13         icon_2: 'fa fa-lightbulb-o',
14         base: '',
15         code_highlight: (!!window.Rainbow ? 'rainbow' : (!!window.Prism ? 'prism' : null)),
16
17         add_panels: true,
18         panel_content_selector: '.info-section',
19         panel_content_title: '.info-title'
20     }
21     this.settings = $.extend({}, defaults, options);
22     
23
24     var $base = this.settings['base'];
25     var ie_fix = document.all && !window.atob;//ie9 and below need a little fix
26
27     var section_start = {};
28     var section_end = {};
29     var section_rect = {};
30     var section_count = 0;
31     
32     var created = false;
33     var active = false;
34     
35     var self = this, _ = this;
36     var ovfx = '';
37     var help_container = null;
38     
39     var body_h, body_w;
40     
41     var captureFocus = function() {
42         if(!help_container) return;
43         var scroll = -1;
44         //like bootstrap modal
45         $(document)
46         .off('focusin.ace.help') //remove any previously attached handler
47         .on('focusin.ace.help', function (e) {
48             if (!( help_container[0] == e.target || $.contains(help_container[0], e.target) )) {
49               help_container.focus();
50             }
51
52             if(e.target == document && scroll > -1) {
53                 //when window regains focus and container is focused, it scrolls to bottom
54                 //so we put it back to its place
55                 $('body,html').scrollTop(scroll);
56                 scroll = -1;
57             }
58         })
59
60         $(window).on('blur.ace.help', function(){
61             scroll = $(window).scrollTop();
62         });
63     }
64     var releaseFocus = function() {
65         $(document).off('focusin.ace.help');
66         $(window).off('blur.ace.help');
67     }
68
69
70     this.toggle = function() {
71         if(active) {
72             self.disable();
73         }
74         else {
75             self.enable();
76         }
77     }
78
79     this.enable = function() {
80         if(active) return;
81         if(typeof _.settings.before_enable === 'function' && _.settings.before_enable.call(self) === false) return;
82         ////
83
84         //if( !created ) this.init();
85         active = true;
86         
87         $('.onpage-help-backdrop, .onpage-help-section').removeClass('hidden');
88         
89         ovfx = document.body.style.overflowX;
90         document.body.style.overflowX = 'hidden';//hide body:overflow-x
91         
92         display_help_sections();
93         captureFocus();
94
95         ////
96         if(typeof _.settings.after_enable === 'function') _.settings.after_enable.call(self);
97     }
98     
99     this.disable = function() {
100         if(!active) return;
101         if(typeof _.settings.before_disable === 'function' && _.settings.before_disable.call(self)) return;
102         ////
103                 
104         active = false;
105         $('.onpage-help-backdrop, .onpage-help-section').addClass('hidden');
106
107         document.body.style.overflowX = ovfx;//restore body:overflow-x
108         releaseFocus();
109         
110         ////
111         if(typeof _.settings.after_disable === 'function') _.settings.after_disable.call(self);
112     }
113     
114     this.is_active = function() {
115         return active;
116     }
117     this.show_section_help = function(section) {
118         launch_help_modal(section, true);
119     }
120     
121     
122     this.init = function() {
123         if( created ) return;
124     
125         help_container = 
126         $('<div class="onpage-help-container" id="onpage-help-container" tabindex="-1" />')
127         .appendTo('body');
128
129         help_container.append('<div class="onpage-help-backdrop hidden" />')
130
131         //update to correct position and size
132         $(window).on('resize.onpage_help', function() {
133             if(!active) return;
134             display_help_sections();
135             
136             if( help_modal != null && help_modal.hasClass('in') ) {
137                 setBodyHeight();                
138                 disableBodyScroll();
139             }
140         })
141
142         created = true;
143     }
144     this.init();//create once at first
145     
146
147     ///////////////////////////
148     this.update_sections = function() {
149         save_sections(true);//reset sections, maybe because of new elements and comments inserted into DOM
150     }
151
152
153     function display_help_sections() {
154         if(!active) return;
155
156         save_sections();//finds comments and relevant help sections
157
158         body_h = document.body.scrollHeight - 2;
159         body_w = document.body.scrollWidth - 2;
160
161         //we first calculate all positions
162         //because if we calculate one position and then make changes to DOM,
163         //next position calculation will become slow on Webkit, because it tries to re-calculate layout changes and things
164         //i.e. we batch call all and save offsets and scrollWidth, etc and then use them later in highlight_section
165         //Firefox doesn't have such issue
166         for(var name in section_start) {
167             if(section_start.hasOwnProperty(name)) {
168                 save_section_offset(name);
169             }
170         }
171         for(var name in section_start) {
172             if(section_start.hasOwnProperty(name)) {
173                 highlight_section(name);
174             }
175         }
176     }
177
178     
179     //finds comments and relevant help sections
180     function save_sections(reset) {
181         if( !(reset === true || section_count == 0) ) return;//no need to re-calculate sections, then return
182         if(reset === true) help_container.find('.onpage-help-section').remove();
183
184         section_start = {};
185         section_end = {};
186         section_count = 0;
187         
188         var count1 = 0, count2 = 0;
189         
190         //find all relevant comments
191         var comments = $('*').contents().filter(function(){ return this.nodeType == 8/**Node.COMMENT_NODE;*/ })
192         $(comments).each(function() {
193             var match
194             if( (match = $.trim(this.data).match(/#section\s*:\s*([\w\d\-\.\/]+)/i)) ) {
195                 var section_name = match[1];
196                 if( !(section_name in section_start) )     section_start[ section_name ] = this;
197             }
198             if( (match = $.trim(this.data).match(/\/section\s*:\s*([\w\d\-\.\/]+)/i)) ) {
199                 var section_name = match[1];
200                 if( !(section_name in section_end) && (section_name in section_start) ) {
201                     section_end[ section_name ] = this;
202                     section_count++;
203                 }
204             }
205         })
206     }
207
208
209     
210     function save_section_offset(name) {
211         if( !(name in section_start) || !(name in section_end) ) return;
212         
213         var x1 = 1000000, y1 = 1000000, x2 = -1000000, y2 = -1000000;
214         var visible = false;
215
216         
217         var elements = [];
218         
219         var start = section_start[name];
220         var end = section_end[name];
221         while(start != end) {
222             start = start.nextSibling;
223             if(start == null) break;
224             else if(start.nodeType == 1 /**Node.ELEMENT_NODE*/) elements.push(start);
225         }
226
227         var elen = elements.length;
228         if(elen > 0 && !_.settings['include_all']) {
229             //calculate dimension of only first and last element
230             elements = elen == 1 ? [elements[0]] : [elements[0], elements[elen - 1]]
231         }
232
233         $(elements).each(function() {
234             var $this = $(this);
235             if( $this.is(':hidden') ) return;
236             
237             var off = $this.offset();
238             var w = $this.outerWidth();
239             var h = $this.outerHeight();
240             
241             if( !off || !w || !h ) return;
242             
243             visible = true;
244             if(off.left < x1) x1 = off.left;
245             if(off.left + w > x2) x2 = off.left + w;
246             
247             if(off.top < y1) y1 = off.top;
248             if(off.top + h > y2) y2 = off.top + h;
249         });
250         
251                     
252         if( !visible ) {
253             section_rect[name] = {is_hidden: true}
254             return;
255         }
256         
257         x1 -= 1;
258         y1 -= 1;
259         x2 += 1;
260         y2 += 1;
261         
262         
263         var width = x2 - x1, height = y2 - y1;
264         //section_rect is out of window ???
265         if(x1 + width < 2 || x1 > body_w || y1 + height < 2 || y1 > body_h ) {
266             section_rect[name] = {is_hidden: true}
267             return;
268         }
269
270         section_rect[name] = {
271             'left': parseInt(x1),
272             'top': parseInt(y1),
273             'width': parseInt(width),
274             'height': parseInt(height)
275         }
276     }
277
278
279     function highlight_section(name) {
280         if( !(name in section_rect) || !help_container ) return;
281
282         //div is the highlighted box above each section
283         var div = help_container.find('.onpage-help-section[data-section="'+name+'"]').eq(0);
284         if(div.length == 0)    {
285             div = $('<a class="onpage-help-section" href="#" />').appendTo(help_container);
286             if(ie_fix) div.append('<span class="ie-hover-fix" />');
287             
288             if(_.settings.icon_1) div.append('<i class="help-icon-1 '+_.settings.icon_1+'"></i>');
289             if(_.settings.icon_2) div.append('<i class="help-icon-2 '+_.settings.icon_2+'"></i>');
290             
291             div.attr('data-section', name);
292
293             div.on('click', function(e) {
294                 e.preventDefault();
295                 launch_help_modal(name);
296             });
297         }
298
299         var rect = section_rect[name];
300         if(rect['is_hidden'] === true) {
301             div.addClass('hidden');
302             return;
303         }
304         
305         div.css({
306             left: rect.left,
307             top: rect.top,
308             width: rect.width,
309             height: rect.height
310         });
311         
312
313         div.removeClass('hidden');
314         div.removeClass('help-section-small help-section-smaller');
315         if(rect.height < 55 || rect.width < 55) {
316             div.addClass('help-section-smaller');
317         }
318         else if(rect.height < 75 || rect.width < 75) {
319             div.addClass('help-section-small');
320         }
321     }
322     
323
324     var nav_list = [];
325     var nav_pos = -1;
326     var mbody = null;
327     var maxh = 0;
328     var help_modal = null;
329
330     //disable body scroll, when modal content has no scrollbars or reached end of scrolling
331     function disableBodyScroll() {
332         if (!mbody) return;
333         
334         var body = mbody[0];
335         var disableScroll = body.scrollHeight <= body.clientHeight;
336         
337         //mousewheel library available?
338         var mousewheel_event = !!$.event.special.mousewheel ? 'mousewheel.ace.help' : 'mousewheel.ace.help DOMMouseScroll.ace.help';
339
340         mbody.parent()
341         .off(mousewheel_event)
342         .on(mousewheel_event, function(event) {
343             if(disableScroll) event.preventDefault();
344             else {
345                 event.deltaY = event.deltaY || 0;
346                 var delta = (event.deltaY > 0 || event.originalEvent.detail < 0 || event.originalEvent.wheelDelta > 0) ? 1 : -1
347
348                 if(delta == -1 && body.scrollTop + body.clientHeight >= body.scrollHeight) event.preventDefault();
349                 else if(delta == 1 && body.scrollTop <= 0) event.preventDefault();
350             }
351         });
352     }
353     
354     function setBodyHeight() {
355         if (!mbody) return;
356         
357         var diff = parseInt(help_modal.find('.modal-dialog').css('margin-top'));
358         diff = diff + 110 + parseInt(diff / 2);
359         maxh = parseInt( $(window).innerHeight() - diff + 40 );
360         mbody.css({'max-height': maxh});
361     }
362
363
364     function launch_help_modal(section_name, save_to_list) {
365         if(help_modal == null) {
366             help_modal = $('<div id="onpage-help-modal" class="modal onpage-help-modal" tabindex="-1" role="dialog" aria-labelledby="HelpModalDialog" aria-hidden="true">\
367               <div class="modal-dialog modal-lg">\
368                 <div class="modal-content">\
369                     <div class="modal-header">\
370                       <div class="pull-right onpage-help-modal-buttons">\
371                         <button aria-hidden="true" data-navdir="up" type="button" class="disabled btn btn-white btn-success btn-sm"><i class="ace-icon fa fa-level-up fa-flip-horizontal bigger-125 icon-only"></i></button>\
372                         &nbsp;\
373                         <button aria-hidden="true" data-navdir="back" type="button" class="disabled btn btn-white btn-info btn-sm"><i class="ace-icon fa fa-arrow-left icon-only"></i></button>\
374                         <button aria-hidden="true" data-navdir="forward" type="button" class="disabled btn btn-white btn-info  btn-sm"><i class="ace-icon fa fa-arrow-right icon-only"></i></button>\
375                         &nbsp;\
376                         <button aria-hidden="true" data-dismiss="modal" class="btn btn-white btn-danger btn-sm" type="button"><i class="ace-icon fa fa-times icon-only"></i></button>\
377                       </div>\
378                       <h4 class="modal-title">Help Dialog</h4>\
379                     </div>\
380                     <div class="modal-body"><div class="onpage-help-content"></div></div>\
381                 </div>\
382               </div>\
383             </div>').appendTo('body');
384         
385             mbody = help_modal.find('.modal-body');
386             mbody.css({'overflow-y': 'auto', 'overflow-x': 'hidden'});
387             
388             help_modal.css({'overflow' : 'hidden'})
389             .on('show.bs.modal', function() {
390                 releaseFocus();
391             })
392             .on('hidden.bs.modal', function() {
393                 captureFocus();
394             })
395             
396             help_modal.find('.onpage-help-modal-buttons').on('click', 'button[data-navdir]', function() {
397                 var dir = $(this).attr('data-navdir');
398                 if(dir == 'back') {
399                     if(nav_pos > 0) {
400                         nav_pos--;
401                         launch_help_modal(nav_list[nav_pos], false);
402                     }
403                 }
404                 else if(dir == 'forward') {
405                     if(nav_pos < nav_list.length - 1) {
406                         nav_pos++;
407                         launch_help_modal(nav_list[nav_pos], false);//don't save to history list, already in the list
408                     }
409                 }
410                 else if(dir == 'up') {
411                     var $this = $(this), url;
412                     if( $this.hasClass('disabled') || !(url = $this.attr('data-url')) ) return;
413                     
414                     launch_help_modal(url , true);//add to history list
415                 }
416             });
417         }
418
419
420         if( !help_modal.hasClass('in') ) {
421             if( document.body.lastChild != help_modal[0] ) $(document.body).append(help_modal);//move it to become the last child of body
422             help_modal.modal('show');
423             
424             setBodyHeight();
425         }
426
427         help_modal.find('.modal-title').wrapInner("<span class='hidden' />").append('<i class="fa fa-spinner fa-spin blue bigger-125"></i>');
428         var content = $('.onpage-help-content');
429         content.addClass('hidden')
430         
431         $(document.body).removeClass('modal-open');//modal by default hides body scrollbars, but we don't want to do so, because on modal hide, a winow resize is triggered
432         
433         var parts = section_name.match(/file\:(.*?)\:(.+)/i);
434         if(parts && parts.length == 3) {
435             display_codeview(parts[2], parts[1], false);
436             return;
437         }
438
439         section_name = section_name.replace(/^#/g, '');
440         if(typeof _.settings.section_url === 'function') url = _.settings.section_url.call(self, section_name);
441
442         $.ajax({url: url, dataType: 'text'})
443         .done(function(result) {
444             //find the title for this dialog by looking for a tag that has data-id attribute
445             var title = '', excerpt = '';
446             
447             if(typeof _.settings.section_title === 'function') title = _.settings.section_title.call(self, result, section_name, url);
448             else {
449                 var escapeSpecialChars = function(name) {
450                     return name.replace(/[\-\.\(\)\=\"\'\\\/]/g, function(a,b){return "\\"+a;})
451                 }
452                 var tname = section_name;
453                 while(title.length == 0) {    
454                     var reg_str = '\\<([a-z][a-z0-9]*)(?:\\s+)(?:[^\\<\\>]+?)data\\-id\\=\\"\\#'+escapeSpecialChars(tname)+'\\"(?:[^\\>]*)\\>([\\s\\S]*?)</\\1>';
455                     
456                     var regexp = new RegExp(reg_str , "im");
457                     var arr = result.match(reg_str);
458                     if(arr && arr[2]) {
459                         title = arr[2];
460                         break;
461                     }
462
463                     //if no "#something.part" was not found try looking for "#something" instead
464                     var tpos
465                     if((tpos = tname.lastIndexOf('.')) > -1) {
466                         tname = tname.substr(0, tpos);
467                     } else break;
468                 }
469             }
470
471             help_modal.find('.modal-title').html( $.trim(title) || '&nbsp;' );
472
473             if(typeof _.settings.section_content === 'function') excerpt = _.settings.section_content.call(self, result, section_name, url);
474             else {
475                 var find1 = '<!-- #section:'+section_name+' -->';
476                 var pos1 = result.indexOf(find1);
477                 var pos2 = result.indexOf('<!-- /section:'+section_name+' -->', pos1);
478
479                 if(pos1 == -1 || pos2 == -1) {
480                     help_modal.find('.modal-title').html( '&nbsp;' );
481                     return;
482                 }
483
484                 excerpt = result.substring(pos1 + find1.length + 1, pos2);
485             }
486
487             
488             //convert `<` and `>` to `&lt;` and `&gt;` inside code snippets
489             if(typeof _.settings.code_highlight === 'function') {
490                 excerpt = _.settings.code_highlight.call(self, excerpt);
491             }
492             else {
493                 //find prism & rainbow style pre tags and replace < > characters with &lt; &gt;
494                 excerpt =
495                 excerpt.replace(/\<pre((?:(?:.*?)(?:data\-language=["'](?:[\w\d]+)["'])(?:.*?))|(?:(?:.*?)(?:class=["'](?:.*?)language\-(?:[\w\d]+)(?:.*?)["'])(?:.*?)))\>([\s\S]+?)\<\/pre\>/ig, function(a, b, c){
496                     return '<pre'+(b)+'>'+c.replace(/\</g , '&lt;').replace(/\>/g , '&gt;')+'</pre>';
497                 });
498             }
499
500
501             //modify image paths if needed!
502             if(typeof _.settings.img_url === 'function') {
503                 excerpt = excerpt.replace(/\<img(?:(?:.*?)src=["']([^"']+)["'])/ig, function(img, src) {
504                     var new_src = _.settings.img_url.call(self, src);
505                     return img.replace(src, new_src)
506                 });
507             }
508
509
510             //now update content area
511             content.empty().append(excerpt);
512             if(typeof _.settings.code_highlight === 'function') {
513                 _.settings.code_highlight.call(self, content);
514             }
515             else if(_.settings.code_highlight === 'rainbow') {
516                 try {
517                     Rainbow.color(content[0]);
518                 } catch(e) {}
519             }
520             else if(_.settings.code_highlight === 'prism') {
521                 try {
522                     content.find('pre[class*="language-"],code[class*="language-"]').each(function() {
523                         Prism.highlightElement(this);
524                     })
525                 } catch(e) {}
526             }
527
528
529             //wrap titles and contents inside panels
530             if(_.settings.add_panels) {
531                 content
532                 .find(_.settings.panel_content_selector).each(function() {
533                     var header = $(this).prevAll(_.settings.panel_content_title);
534                     if(header.length == 0) return false;
535                     
536                     header =
537                     header.attr('class', 'panel-title')
538                     .wrapInner('<a class="help-panel-toggle" href="#" data-parent="#" data-toggle="collapse" />')
539                     .wrap('<div class="panel-heading" />')
540                     .closest('.panel-heading');
541
542                     $(this).wrap('<div class="panel panel-default panel-help"><div class="panel-collapse collapse"><div class="panel-body"></div></div></div>');
543                     $(this).closest('.panel').prepend(header);
544                 })
545                             
546                 var group_count = $('.panel-group').length;
547                 content.find('.panel').each(function() {
548                     if( $(this).parent().hasClass('panel-group') ) return;
549
550                     var group_id = 'panel-group-help-'+ (++group_count);
551                     var group = $('<div class="panel-group" />').insertBefore(this);
552                     group.attr('id', group_id);
553                     
554                     var panel_id = 0;
555                     group.siblings('.panel').appendTo(group);
556                     group.find('.help-panel-toggle')
557                     .append('<i class="pull-right ace-icon fa fa-plus" data-icon-show="ace-icon fa fa-plus" data-icon-hide="ace-icon fa fa-minus"></i>')
558                     .attr('data-parent', '#'+group_id)
559                     .each(function() {
560                         panel_id++;
561                         $(this).attr('data-target', '#'+group_id+'-'+panel_id);
562                         $(this).closest('.panel-heading').siblings('.panel-collapse').attr('id', group_id+'-'+panel_id);
563                     });
564                 });
565                 $(document).off('click.help-panel-toggle', '.help-panel-toggle').on('click.help-panel-toggle', '.help-panel-toggle', function(e) {
566                     e.preventDefault();
567                 });
568             }
569
570
571             ///////////////////////////////////////////
572
573             content.removeClass('hidden')
574
575             var images = content.find('img:visible');
576             if(images.length > 0) {
577                 //handle scrollbars when all images are loaded
578                 var ev_count = 0;
579                 images.off('.help_body_scroll').on('load.help_body_scroll error.help_body_scroll', function() {
580                     $(this).off('.help_body_scroll');
581                     ev_count++;
582                     if(ev_count >= images.length) disableBodyScroll();
583                 });
584             }
585
586             disableBodyScroll();
587             content.find('.panel > .panel-collapse').on('shown.bs.collapse hidden.bs.collapse', function() {
588                 disableBodyScroll();
589             });
590
591
592             //save history list
593             add_to_nav_list(section_name, save_to_list);
594         
595             var pos = -1;
596             if((pos = section_name.lastIndexOf('.')) > -1) {
597                 section_name = section_name.substr(0, pos);
598                 help_modal.find('button[data-navdir=up]').removeClass('disabled').attr('data-url', section_name);
599             }
600             else {
601                 help_modal.find('button[data-navdir=up]').addClass('disabled').removeAttr('data-url').blur();
602             }
603         })
604         .fail(function() {
605             help_modal.find('.modal-title').find('.fa-spin').remove().end().find('.hidden').children().unwrap();
606         });
607     }//launch_help_modal
608
609
610     $(document).on('click', '.onpage-help-modal a[href^="http"]', function() {
611         $(this).attr('target', '_blank');
612     });
613     
614     $(document).on('click', '.help-more', function(e) {
615         e.preventDefault();
616         var href = $(this).attr('href');
617         launch_help_modal(href);
618     });
619     
620
621     
622     function add_to_nav_list(section_name, save_to_list) {
623         if(save_to_list !== false) {
624             if(nav_list.length > 0) {
625                 nav_list = nav_list.slice(0, nav_pos + 1);
626             }
627             if(nav_list[nav_list.length - 1] != section_name) {
628                 nav_list.push(section_name);
629                 nav_pos = nav_list.length - 1;
630             }
631         }
632         
633         if(nav_pos == 0){
634             help_modal.find('button[data-navdir=back]').addClass('disabled').blur();
635         }
636         else {
637             help_modal.find('button[data-navdir=back]').removeClass('disabled');
638         }
639         
640         if(nav_pos == nav_list.length - 1){
641             help_modal.find('button[data-navdir=forward]').addClass('disabled').blur();
642         }
643         else {
644             help_modal.find('button[data-navdir=forward]').removeClass('disabled');
645         }
646     }
647
648     
649     $(document).on('click', '.open-file[data-open-file]', function() {
650         help_modal.find('.modal-title').wrapInner("<span class='hidden' />").append('<i class="fa fa-spinner fa-spin blue bigger-125"></i>');
651         $('.onpage-help-content').addClass('hidden')
652
653         var url = $(this).attr('data-path') || $(this).text();
654         var language = $(this).attr('data-open-file');
655         display_codeview(url, language, true);
656     });
657     
658     
659     function display_codeview(url, language, save_to_list) {
660         var $url = url;
661     
662         if(typeof _.settings.file_url === 'function') url = _.settings.file_url.call(self, url, language);
663         $.ajax({url: url, dataType:'text'})
664         .done(function(result) {
665
666             add_to_nav_list('file:'+language+':'+$url, save_to_list);
667             
668             help_modal.find('button[data-navdir=up]').addClass('disabled').blur();
669             help_modal.find('.modal-title').html($url).wrapInner('<code />');
670
671             if(language != 'json') {
672                 if(language != 'css') {
673                     //replace each tab character with two spaces (only those that start at a new line)
674                     result = result.replace(/\n[\t]{1,}/g, function(p, q) {
675                         return p.replace(/\t/g, "  ");
676                     });
677                 } else {
678                     result = result.replace(/\t/g , "  ")
679                 }
680             }
681             else {
682                 language = 'javascript';
683                 result = JSON.stringify(JSON.parse(result), null, 2);//add spacing and somehow beautification
684             }
685             
686             result = result.replace(/\>/g, '&gt;').replace(/\</g, '&lt;');
687
688             var content = $('.onpage-help-content');
689             content.removeClass('hidden').empty();
690
691             if(typeof _.settings.code_highlight === 'function') {
692                 result = _.settings.code_highlight.call(self, result, language);
693                 content.html(result);
694             }
695             else if(_.settings.code_highlight === 'rainbow') {
696                 try {
697                     Rainbow.color(result, language, function(highlighted_code) {
698                         content.html(highlighted_code).wrapInner('<pre data-language="'+language+'" />');
699                     });
700                 } catch(e){}
701             }
702             else if(_.settings.code_highlight === 'prism') {
703                 try {
704                     result = Prism.highlight(result, Prism.languages[language] , language);
705                     content.html(result).wrapInner('<pre class="language-'+language+'" />');
706                 } catch(e){}
707             }
708
709         });
710     }
711
712 };