提交 | 用户 | 时间
|
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 |
\ |
|
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 |
\ |
|
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) || ' ' ); |
|
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( ' ' ); |
|
481 |
return; |
|
482 |
} |
|
483 |
|
|
484 |
excerpt = result.substring(pos1 + find1.length + 1, pos2); |
|
485 |
} |
|
486 |
|
|
487 |
|
|
488 |
//convert `<` and `>` to `<` and `>` 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 < > |
|
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 , '<').replace(/\>/g , '>')+'</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, '>').replace(/\</g, '<'); |
|
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 |
}; |