hjg
2024-10-30 8cf23534166c07e711aac2a25911ada317ba01f0
提交 | 用户 | 时间
58d006 1 /**
A 2  Required. Ace's Basic File to Initiliaze Different Parts and Some Variables.
3 */
4
5 //document ready function
6 jQuery(function($) {
7   try {
8     ace.demo.init();
9   } catch(e) {}
10 });
11
12
13 //some basic variables
14 (function(undefined) {
15     if( !('ace' in window) ) window['ace'] = {}
16     if( !('helper' in window['ace']) ) window['ace'].helper = {}
17     if( !('vars' in window['ace']) ) window['ace'].vars = {}
18     window['ace'].vars['icon'] = ' ace-icon ';
19     window['ace'].vars['.icon'] = '.ace-icon';
20
21     ace.vars['touch']    = ('ontouchstart' in window);//(('ontouchstart' in document.documentElement) || (window.DocumentTouch && document instanceof DocumentTouch));
22     
23     //sometimes the only good way to work around browser's pecularities is to detect them using user-agents
24     //though it's not accurate
25     var agent = navigator.userAgent
26     ace.vars['webkit'] = !!agent.match(/AppleWebKit/i)
27     ace.vars['safari'] = !!agent.match(/Safari/i) && !agent.match(/Chrome/i);
28     ace.vars['android'] = ace.vars['safari'] && !!agent.match(/Android/i)
29     ace.vars['ios_safari'] = !!agent.match(/OS ([4-9])(_\d)+ like Mac OS X/i) && !agent.match(/CriOS/i)
30     
31     ace.vars['ie'] = window.navigator.msPointerEnabled || (document.all && document.querySelector);//8-11
32     ace.vars['old_ie'] = document.all && !document.addEventListener;//8 and below
33     ace.vars['very_old_ie']    = document.all && !document.querySelector;//7 and below
34     ace.vars['firefox'] = 'MozAppearance' in document.documentElement.style;
35     
36     ace.vars['non_auto_fixed'] = ace.vars['android'] || ace.vars['ios_safari'];
37     
38     
39     //sometimes we try to use 'tap' event instead of 'click' if jquery mobile plugin is available
40     ace['click_event'] = ace.vars['touch'] && jQuery.fn.tap ? 'tap' : 'click';
41 })();
42
43
44
45 (function($ , undefined) {
46
47     ace.demo = {
48         functions: {},
49         
50         init: function(initAnyway) {
51             //initAnyway used to make sure the call is from our RequireJS app and not a document ready event!
52             var initAnyway = !!initAnyway && true;
53             if(typeof requirejs !== "undefined" && !initAnyway) return;
54             
55             for(var func in ace.demo.functions) if(ace.demo.functions.hasOwnProperty(func)) {
56                 ace.demo.functions[func]();
57             }
58         }
59     }
60
61
62     ace.demo.functions.basics = function() {
63         // for android and ios we don't use "top:auto" when breadcrumbs is fixed
64         if(ace.vars['non_auto_fixed']) {
65             $('body').addClass('mob-safari');
66         }
67
68         ace.vars['transition'] = ace.vars['animation'] || !!$.support.transition;
69     }
70     
71     ace.demo.functions.enableSidebar = function() {
72         //initiate sidebar function
73         var $sidebar = $('.sidebar');
74         if($.fn.ace_sidebar) $sidebar.ace_sidebar();
75         if($.fn.ace_sidebar_scroll) $sidebar.ace_sidebar_scroll({
76             //for other options please see documentation
77             'include_toggle': false || ace.vars['safari'] || ace.vars['ios_safari'] //true = include toggle button in the scrollbars
78         });
79         if($.fn.ace_sidebar_hover)    $sidebar.ace_sidebar_hover({
80             'sub_hover_delay': 750,
81             'sub_scroll_style': 'no-track scroll-thin scroll-margin scroll-visible'
82         });
83     }
84
85     
86     //Load content via ajax
87     ace.demo.functions.enableDemoAjax = function() {
88         if(!$.fn.ace_ajax) return;
89  
90         if(window.Pace) {
91             window.paceOptions = {
92                 ajax: true,
93                 document: true,
94                 eventLag: false // disabled
95                 //elements: {selectors: ['.page-content-area']}
96             }
97         }
98
99         var demo_ajax_options = {
100              'close_active': true,
101              
102              close_mobile_menu: '#sidebar',
103              close_dropdowns: true,
104              
105              'default_url': 'page/index',//default hash
106              'content_url': function(hash) {
107                 //***NOTE***
108                 //this is for Ace demo only, you should change it to return a valid URL
109                 //please refer to documentation for more info
110
111                 if( !hash.match(/^page\//) ) return false;
112                 var path = document.location.pathname;
113
114                 //for example in Ace HTML demo version we convert /ajax/index.html#page/gallery to > /ajax/content/gallery.html and load it
115                 if(path.match(/(\/ajax\/)(index\.html)?/))
116                     return path.replace(/(\/ajax\/)(index\.html)?/, '/ajax/content/'+hash.replace(/^page\//, '')+'.html') ;
117
118                 //for example in Ace PHP demo version we convert "ajax.php#page/dashboard" to "ajax.php?page=dashboard" and load it
119                 return path + "?" + hash.replace(/\//, "=");
120               }              
121         }
122            
123         //for IE9 and below we exclude PACE loader (using conditional IE comments)
124         //for other browsers we use the following extra ajax loader options
125         if(window.Pace) {
126             demo_ajax_options['loading_overlay'] = 'body';//the opaque overlay is applied to 'body'
127         }
128
129         //initiate ajax loading on this element( which is .page-content-area[data-ajax-content=true] in Ace's demo)
130         $('[data-ajax-content=true]').ace_ajax(demo_ajax_options)
131
132         //if general error happens and ajax is working, let's stop loading icon & PACE
133         $(window).on('error.ace_ajax', function() {
134             $('[data-ajax-content=true]').each(function() {
135                 var $this = $(this);
136                 if( $this.ace_ajax('working') ) {
137                     if(window.Pace && Pace.running) Pace.stop();
138                     $this.ace_ajax('stopLoading', true);
139                 }
140             })
141         })
142     }
143
144     /////////////////////////////
145
146     ace.demo.functions.handleScrollbars = function() {
147         //add scrollbars for navbar dropdowns
148         var has_scroll = !!$.fn.ace_scroll;
149         if(has_scroll) $('.dropdown-content').ace_scroll({reset: false, mouseWheelLock: true})
150
151         //reset scrolls bars on window resize
152         if(has_scroll && !ace.vars['old_ie']) {//IE has an issue with widget fullscreen on ajax?!!!
153             $(window).on('resize.reset_scroll', function() {
154                 $('.ace-scroll:not(.scroll-disabled)').not(':hidden').ace_scroll('reset');
155             });
156             if(has_scroll) $(document).on('settings.ace.reset_scroll', function(e, name) {
157                 if(name == 'sidebar_collapsed') $('.ace-scroll:not(.scroll-disabled)').not(':hidden').ace_scroll('reset');
158             });
159         }
160     }
161
162
163     ace.demo.functions.dropdownAutoPos = function() {
164         //change a dropdown to "dropup" depending on its position
165         $(document).on('click.dropdown.pos', '.dropdown-toggle[data-position="auto"]', function() {
166             var offset = $(this).offset();
167             var parent = $(this.parentNode);
168
169             if ( parseInt(offset.top + $(this).height()) + 50 
170                     >
171                 (ace.helper.scrollTop() + ace.helper.winHeight() - parent.find('.dropdown-menu').eq(0).height()) 
172                 ) parent.addClass('dropup');
173             else parent.removeClass('dropup');
174         });
175     }
176
177     
178     ace.demo.functions.navbarHelpers = function() {
179         //prevent dropdowns from hiding when a from is clicked
180         /**$(document).on('click', '.dropdown-navbar form', function(e){
181             e.stopPropagation();
182         });*/
183
184
185         //disable navbar icon animation upon click
186         $('.ace-nav [class*="icon-animated-"]').closest('a').one('click', function(){
187             var icon = $(this).find('[class*="icon-animated-"]').eq(0);
188             var $match = icon.attr('class').match(/icon\-animated\-([\d\w]+)/);
189             icon.removeClass($match[0]);
190         });
191
192
193         //prevent dropdowns from hiding when a tab is selected
194         $(document).on('click', '.dropdown-navbar .nav-tabs', function(e){
195             e.stopPropagation();
196             var $this , href
197             var that = e.target
198             if( ($this = $(e.target).closest('[data-toggle=tab]')) && $this.length > 0) {
199                 $this.tab('show');
200                 e.preventDefault();
201                 $(window).triggerHandler('resize.navbar.dropdown')
202             }
203         });
204     }
205
206     
207     ace.demo.functions.sidebarTooltips = function() {
208         //tooltip in sidebar items
209         $('.sidebar .nav-list .badge[title],.sidebar .nav-list .badge[title]').each(function() {
210             var tooltip_class = $(this).attr('class').match(/tooltip\-(?:\w+)/);
211             tooltip_class = tooltip_class ? tooltip_class[0] : 'tooltip-error';
212             $(this).tooltip({
213                 'placement': function (context, source) {
214                     var offset = $(source).offset();
215
216                     if( parseInt(offset.left) < parseInt(document.body.scrollWidth / 2) ) return 'right';
217                     return 'left';
218                 },
219                 container: 'body',
220                 template: '<div class="tooltip '+tooltip_class+'"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
221             });
222         });
223         
224         //or something like this if items are dynamically inserted
225         /**
226         $('.sidebar').tooltip({
227             'placement': function (context, source) {
228                 var offset = $(source).offset();
229
230                 if( parseInt(offset.left) < parseInt(document.body.scrollWidth / 2) ) return 'right';
231                 return 'left';
232             },
233             selector: '.nav-list .badge[title],.nav-list .label[title]',
234             container: 'body',
235             template: '<div class="tooltip tooltip-error"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
236         });
237         */
238     }
239     
240     
241
242     ace.demo.functions.scrollTopBtn = function() {
243         //the scroll to top button
244         var scroll_btn = $('.btn-scroll-up');
245         if(scroll_btn.length > 0) {
246             var is_visible = false;
247             $(window).on('scroll.scroll_btn', function() {
248                 var scroll = ace.helper.scrollTop();
249                 var h = ace.helper.winHeight();
250                 var body_sH = document.body.scrollHeight;
251                 if(scroll > parseInt(h / 4) || (scroll > 0 && body_sH >= h && h + scroll >= body_sH - 1)) {//|| for smaller pages, when reached end of page
252                     if(!is_visible) {
253                         scroll_btn.addClass('display');
254                         is_visible = true;
255                     }
256                 } else {
257                     if(is_visible) {
258                         scroll_btn.removeClass('display');
259                         is_visible = false;
260                     }
261                 }
262             }).triggerHandler('scroll.scroll_btn');
263
264             scroll_btn.on(ace.click_event, function(){
265                 var duration = Math.min(500, Math.max(100, parseInt(ace.helper.scrollTop() / 3)));
266                 $('html,body').animate({scrollTop: 0}, duration);
267                 return false;
268             });
269         }
270     }
271
272
273     
274     ace.demo.functions.someBrowserFix = function() {
275         //chrome and webkit have a problem here when resizing from 479px to more
276         //we should force them redraw the navbar!
277         if( ace.vars['webkit'] ) {
278             var ace_nav = $('.ace-nav').get(0);
279             if( ace_nav ) $(window).on('resize.webkit_fix' , function(){
280                 ace.helper.redraw(ace_nav);
281             });
282         }
283         
284         
285         //fix an issue with ios safari, when an element is fixed and an input receives focus
286         if(ace.vars['ios_safari']) {
287           $(document).on('ace.settings.ios_fix', function(e, event_name, event_val) {
288             if(event_name != 'navbar_fixed') return;
289
290             $(document).off('focus.ios_fix blur.ios_fix', 'input,textarea,.wysiwyg-editor');
291             if(event_val == true) {
292               $(document).on('focus.ios_fix', 'input,textarea,.wysiwyg-editor', function() {
293                 $(window).on('scroll.ios_fix', function() {
294                     var navbar = $('#navbar').get(0);
295                     if(navbar) ace.helper.redraw(navbar);
296                 });
297               }).on('blur.ios_fix', 'input,textarea,.wysiwyg-editor', function() {
298                 $(window).off('scroll.ios_fix');
299               })
300             }
301           }).triggerHandler('ace.settings.ios_fix', ['navbar_fixed', $('#navbar').css('position') == 'fixed']);
302         }
303     }
304
305     
306     
307     ace.demo.functions.bsCollapseToggle = function() {
308         //bootstrap collapse component icon toggle
309         $(document).on('hide.bs.collapse show.bs.collapse', function (ev) {
310             var panel_id = ev.target.getAttribute('id')
311             var panel = $('a[href*="#'+ panel_id+'"]');
312             if(panel.length == 0) panel = $('a[data-target*="#'+ panel_id+'"]');
313             if(panel.length == 0) return;
314
315             panel.find(ace.vars['.icon']).each(function(){
316                 var $icon = $(this)
317
318                 var $match
319                 var $icon_down = null
320                 var $icon_up = null
321                 if( ($icon_down = $icon.attr('data-icon-show')) ) {
322                     $icon_up = $icon.attr('data-icon-hide')
323                 }
324                 else if( $match = $icon.attr('class').match(/fa\-(.*)\-(up|down)/) ) {
325                     $icon_down = 'fa-'+$match[1]+'-down'
326                     $icon_up = 'fa-'+$match[1]+'-up'
327                 }
328
329                 if($icon_down) {
330                     if(ev.type == 'show') $icon.removeClass($icon_down).addClass($icon_up)
331                         else $icon.removeClass($icon_up).addClass($icon_down)
332                         
333                     return false;//ignore other icons that match, one is enough
334                 }
335
336             });
337         })
338     }
339     
340
341     
342     //in small devices display navbar dropdowns like modal boxes
343     ace.demo.functions.smallDeviceDropdowns = function() {
344       if(ace.vars['old_ie']) return;
345       
346       $(document)
347       .on('shown.bs.dropdown.navbar', '.ace-nav > li.dropdown-modal', function(e) {
348         adjustNavbarDropdown.call(this);
349         var self = this;
350         $(window).on('resize.navbar.dropdown', function() {
351             adjustNavbarDropdown.call(self);
352         })
353       })
354       .on('hidden.bs.dropdown.navbar', '.ace-nav > li.dropdown-modal', function(e) {
355         $(window).off('resize.navbar.dropdown');
356         resetNavbarDropdown.call(this);
357       })
358      
359       function adjustNavbarDropdown() {
360         var $sub = $(this).find('> .dropdown-menu');
361
362         if( $sub.css('position') == 'fixed' ) {
363             var win_width = parseInt($(window).width());
364             var offset_w = win_width > 320 ? 60 : (win_width > 240 ? 40 : 30);
365             var avail_width = parseInt(win_width) - offset_w;
366             var avail_height = parseInt($(window).height()) - 30;
367             
368             var width = parseInt(Math.min(avail_width , 320));
369             //we set 'width' here for text wrappings and spacings to take effect before calculating scrollHeight
370             $sub.css('width', width);
371
372             var tabbed = false;
373             var extra_parts = 0;
374             var dropdown_content = $sub.find('.tab-pane.active .dropdown-content.ace-scroll');
375             if(dropdown_content.length == 0) dropdown_content = $sub.find('.dropdown-content.ace-scroll');
376             else tabbed = true;
377
378             var parent_menu = dropdown_content.closest('.dropdown-menu');
379             var scrollHeight = $sub[0].scrollHeight;
380             if(dropdown_content.length == 1) {
381                 //sometimes there's no scroll-content, for example in detached scrollbars
382                 var content =  dropdown_content.find('.scroll-content')[0];
383                 if(content) {
384                     scrollHeight = content.scrollHeight;
385                 }
386             
387                 extra_parts += parent_menu.find('.dropdown-header').outerHeight();
388                 extra_parts += parent_menu.find('.dropdown-footer').outerHeight();
389                 
390                 var tab_content = parent_menu.closest('.tab-content');
391                 if( tab_content.length != 0 ) {
392                     extra_parts += tab_content.siblings('.nav-tabs').eq(0).height();
393                 }
394             }
395             
396
397             
398             var height = parseInt(Math.min(avail_height , 480, scrollHeight + extra_parts));
399             var left = parseInt(Math.abs((avail_width + offset_w - width)/2));
400             var top = parseInt(Math.abs((avail_height + 30 - height)/2));
401
402             
403             var zindex = parseInt($sub.css('z-index')) || 0;
404
405             $sub.css({'height': height, 'left': left, 'right': 'auto', 'top': top - (!tabbed ? 1 : 3)});
406             if(dropdown_content.length == 1) {
407                 if(!ace.vars['touch']) {
408                     dropdown_content.ace_scroll('update', {size: height - extra_parts}).ace_scroll('enable').ace_scroll('reset');
409                 }
410                 else {
411                     dropdown_content
412                     .ace_scroll('disable').css('max-height', height - extra_parts).addClass('overflow-scroll');
413                 }
414             }
415             $sub.css('height', height + (!tabbed ? 2 : 7));//for bottom border adjustment and tab content paddings
416             
417             
418             if($sub.hasClass('user-menu')) {
419                 $sub.css('height', '');//because of user-info hiding/showing at different widths, which changes above 'scrollHeight', so we remove it!
420                 
421                 //user menu is re-positioned in small widths
422                 //but we need to re-position again in small heights as well (modal mode)
423                 var user_info = $(this).find('.user-info');
424                 if(user_info.length == 1 && user_info.css('position') == 'fixed') {
425                     user_info.css({'left': left, 'right': 'auto', 'top': top, 'width': width - 2, 'max-width': width - 2, 'z-index': zindex + 1});
426                 }
427                 else user_info.css({'left': '', 'right': '', 'top': '', 'width': '', 'max-width': '', 'z-index': ''});
428             }
429             
430             //dropdown's z-index is limited by parent .navbar's z-index (which doesn't make sense because dropdowns are fixed!)
431             //so for example when in 'content-slider' page, fixed modal toggle buttons go above are dropdowns
432             //so we increase navbar's z-index to fix this!
433             $(this).closest('.navbar.navbar-fixed-top').css('z-index', zindex);
434         }
435         else {
436             if($sub.length != 0) resetNavbarDropdown.call(this, $sub);
437         }
438       }
439
440       //reset scrollbars and user menu
441       function resetNavbarDropdown($sub) {
442         $sub = $sub || $(this).find('> .dropdown-menu');
443       
444         if($sub.length > 0) {
445             $sub
446             .css({'width': '', 'height': '', 'left': '', 'right': '', 'top': ''})
447             .find('.dropdown-content').each(function() {
448                 if(ace.vars['touch']) {
449                     $(this).css('max-height', '').removeClass('overflow-scroll');
450                 }
451
452                 var size = parseInt($(this).attr('data-size') || 0) || $.fn.ace_scroll.defaults.size;
453                 $(this).ace_scroll('update', {size: size}).ace_scroll('enable').ace_scroll('reset');
454             })
455             
456             if( $sub.hasClass('user-menu') ) {
457                 var user_info = 
458                 $(this).find('.user-info')
459                 .css({'left': '', 'right': '', 'top': '', 'width': '', 'max-width': '', 'z-index': ''});
460             }
461         }
462         
463         $(this).closest('.navbar').css('z-index', '');
464       }
465     }
466
467 })(jQuery);
468
469
470 //some ace helper functions
471 (function($$ , undefined) {//$$ is ace.helper
472  $$.unCamelCase = function(str) {
473     return str.replace(/([a-z])([A-Z])/g, function(match, c1, c2){ return c1+'-'+c2.toLowerCase() })
474  }
475  $$.strToVal = function(str) {
476     var res = str.match(/^(?:(true)|(false)|(null)|(\-?[\d]+(?:\.[\d]+)?)|(\[.*\]|\{.*\}))$/i);
477
478     var val = str;
479     if(res) {
480         if(res[1]) val = true;
481         else if(res[2]) val = false;
482         else if(res[3]) val = null;    
483         else if(res[4]) val = parseFloat(str);
484         else if(res[5]) {
485             try { val = JSON.parse(str) }
486             catch (err) {}
487         }
488     }
489
490     return val;
491  }
492  $$.getAttrSettings = function(elem, attr_list, prefix) {
493     if(!elem) return;
494     var list_type = attr_list instanceof Array ? 1 : 2;
495     //attr_list can be Array or Object(key/value)
496     var prefix = prefix ? prefix.replace(/([^\-])$/ , '$1-') : '';
497     prefix = 'data-' + prefix;
498
499     var settings = {}
500     for(var li in attr_list) if(attr_list.hasOwnProperty(li)) {
501         var name = list_type == 1 ? attr_list[li] : li;
502         var attr_val, attr_name = $$.unCamelCase(name.replace(/[^A-Za-z0-9]{1,}/g , '-')).toLowerCase()
503
504         if( ! ((attr_val = elem.getAttribute(prefix + attr_name))  ) ) continue;
505         settings[name] = $$.strToVal(attr_val);
506     }
507
508     return settings;
509  }
510
511  $$.scrollTop = function() {
512     return document.scrollTop || document.documentElement.scrollTop || document.body.scrollTop
513  }
514  $$.winHeight = function() {
515     return window.innerHeight || document.documentElement.clientHeight;
516  }
517  $$.redraw = function(elem, force) {
518     if(!elem) return;
519     var saved_val = elem.style['display'];
520     elem.style.display = 'none';
521     elem.offsetHeight;
522     if(force !== true) {
523         elem.style.display = saved_val;
524     }
525     else {
526         //force redraw for example in old IE
527         setTimeout(function() {
528             elem.style.display = saved_val;
529         }, 10);
530     }
531  }
532 })(ace.helper);