/*! * ZUI - v1.3.0 - 2015-05-06 * http://zui.sexy * GitHub: https://github.com/easysoft/zui.git * Copyright (c) 2015 cnezsoft.com; Licensed MIT */ /* Some code copy from Bootstrap v3.0.0 by @fat and @mdo. (Copyright 2013 Twitter, Inc. Licensed under http://www.apache.org/licenses/)*/ /* ======================================================================== * ZUI: jquery.extensions.js * http://zui.sexy * ======================================================================== * Copyright (c) 2014 cnezsoft.com; Licensed MIT * ======================================================================== */ (function($, window){ 'use strict'; /* Check jquery */ if (typeof($) === 'undefined') throw new Error('ZUI requires jQuery'); // ZUI shared object if (!$.zui) $.zui = function(obj) { if ($.isPlainObject(obj)) { $.extend($.zui, obj); } }; var lastUuidAmend = 0; $.zui( { uuid: function() { return (new Date()).getTime() * 1000 + (lastUuidAmend++) % 1000; }, callEvent: function(func, event, proxy) { if ($.isFunction(func)) { if (typeof proxy != 'undefined') { func = $.proxy(func, proxy); } var result = func(event); if (event) event.result = result; return !(result !== undefined && (!result)); } return 1; }, clientLang: function() { var lang; var config = window.config; if (typeof(config) != 'undefined' && config.clientLang) { lang = config.clientLang; } else { var hl = $('html').attr('lang'); lang = hl ? hl : (navigator.userLanguage || navigator.userLanguage || 'zh_cn'); } return lang.replace('-', '_').toLowerCase(); } }); $.fn.callEvent = function(name, event, model) { var $this = $(this); var dotIndex = name.indexOf('.zui.'); var shortName = name; if (dotIndex < 0 && model && model.name) { name += '.' + model.name; } else { shortName = name.substring(0, dotIndex); } var e = $.Event(name, event); if ((typeof model === 'undefined') && dotIndex > 0) { model = $this.data(name.substring(dotIndex + 1)); } if (model && model.options) { var func = model.options[shortName]; if ($.isFunction(func)) { $.zui.callEvent(model.options[shortName], e, model); } } return e; }; }(jQuery, window)); /* ======================================================================== * Bootstrap: alert.js v3.0.0 * http://twbs.github.com/bootstrap/javascript.html#alerts * ======================================================================== * Copyright 2013 Twitter, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ======================================================================== */ + function($){ 'use strict'; // ALERT CLASS DEFINITION // ====================== var dismiss = '[data-dismiss="alert"]' var zuiname = 'zui.alert'; var Alert = function(el) { $(el).on('click', dismiss, this.close) } Alert.prototype.close = function(e) { var $this = $(this) var selector = $this.attr('data-target') if (!selector) { selector = $this.attr('href') selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 } var $parent = $(selector) if (e) e.preventDefault() if (!$parent.length) { $parent = $this.hasClass('alert') ? $this : $this.parent() } $parent.trigger(e = $.Event('close.' + zuiname)) if (e.isDefaultPrevented()) return $parent.removeClass('in') function removeElement() { $parent.trigger('closed.' + zuiname).remove() } $.support.transition && $parent.hasClass('fade') ? $parent .one($.support.transition.end, removeElement) .emulateTransitionEnd(150) : removeElement() } // ALERT PLUGIN DEFINITION // ======================= var old = $.fn.alert $.fn.alert = function(option) { return this.each(function() { var $this = $(this) var data = $this.data(zuiname) if (!data) $this.data(zuiname, (data = new Alert(this))) if (typeof option == 'string') data[option].call($this) }) } $.fn.alert.Constructor = Alert // ALERT NO CONFLICT // ================= $.fn.alert.noConflict = function() { $.fn.alert = old return this } // ALERT DATA-API // ============== $(document).on('click.' + zuiname + '.data-api', dismiss, Alert.prototype.close) }(window.jQuery); /* ======================================================================== * Bootstrap: tab.js v3.0.0 * http://twbs.github.com/bootstrap/javascript.html#tabs * ======================================================================== * Copyright 2012 Twitter, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ======================================================================== */ +function ($) { 'use strict'; // TAB CLASS DEFINITION // ==================== var zuiname = 'zui.tab' var Tab = function (element) { this.element = $(element) } Tab.prototype.show = function () { var $this = this.element var $ul = $this.closest('ul:not(.dropdown-menu)') var selector = $this.attr('data-target') if (!selector) { selector = $this.attr('href') selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 } if ($this.parent('li').hasClass('active')) return var previous = $ul.find('.active:last a')[0] var e = $.Event('show.' + zuiname, { relatedTarget: previous }) $this.trigger(e) if (e.isDefaultPrevented()) return var $target = $(selector) this.activate($this.parent('li'), $ul) this.activate($target, $target.parent(), function () { $this.trigger({ type: 'shown.' + zuiname , relatedTarget: previous }) }) } Tab.prototype.activate = function (element, container, callback) { var $active = container.find('> .active') var transition = callback && $.support.transition && $active.hasClass('fade') function next() { $active .removeClass('active') .find('> .dropdown-menu > .active') .removeClass('active') element.addClass('active') if (transition) { element[0].offsetWidth // reflow for transition element.addClass('in') } else { element.removeClass('fade') } if (element.parent('.dropdown-menu')) { element.closest('li.dropdown').addClass('active') } callback && callback() } transition ? $active .one($.support.transition.end, next) .emulateTransitionEnd(150) : next() $active.removeClass('in') } // TAB PLUGIN DEFINITION // ===================== var old = $.fn.tab $.fn.tab = function ( option ) { return this.each(function () { var $this = $(this) var data = $this.data(zuiname) if (!data) $this.data(zuiname, (data = new Tab(this))) if (typeof option == 'string') data[option]() }) } $.fn.tab.Constructor = Tab // TAB NO CONFLICT // =============== $.fn.tab.noConflict = function () { $.fn.tab = old return this } // TAB DATA-API // ============ $(document).on('click.zui.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) { e.preventDefault() $(this).tab('show') }) }(window.jQuery); /* ======================================================================== * Bootstrap: transition.js v3.2.0 * http://getbootstrap.com/javascript/#transitions * ======================================================================== * Copyright 2011-2014 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ + function($){ 'use strict'; // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) // ============================================================ function transitionEnd() { var el = document.createElement('bootstrap') var transEndEventNames = { WebkitTransition: 'webkitTransitionEnd', MozTransition: 'transitionend', OTransition: 'oTransitionEnd otransitionend', transition: 'transitionend' } for (var name in transEndEventNames) { if (el.style[name] !== undefined) { return { end: transEndEventNames[name] } } } return false // explicit for ie8 ( ._.) } // http://blog.alexmaccaw.com/css-transitions $.fn.emulateTransitionEnd = function(duration) { var called = false var $el = this $(this).one('bsTransitionEnd', function() { called = true }) var callback = function() { if (!called) $($el).trigger($.support.transition.end) } setTimeout(callback, duration) return this } $(function() { $.support.transition = transitionEnd() if (!$.support.transition) return $.event.special.bsTransitionEnd = { bindType: $.support.transition.end, delegateType: $.support.transition.end, handle: function(e) { if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments) } } }) }(jQuery); /* ======================================================================== * Bootstrap: collapse.js v3.0.0 * http://twbs.github.com/bootstrap/javascript.html#collapse * ======================================================================== * Copyright 2012 Twitter, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ======================================================================== */ + function($){ 'use strict'; var zuiname = 'zui.collapse' // COLLAPSE PUBLIC CLASS DEFINITION // ================================ var Collapse = function(element, options) { this.$element = $(element) this.options = $.extend( {}, Collapse.DEFAULTS, options) this.transitioning = null if (this.options.parent) this.$parent = $(this.options.parent) if (this.options.toggle) this.toggle() } Collapse.DEFAULTS = { toggle: true } Collapse.prototype.dimension = function() { var hasWidth = this.$element.hasClass('width') return hasWidth ? 'width' : 'height' } Collapse.prototype.show = function() { if (this.transitioning || this.$element.hasClass('in')) return var startEvent = $.Event('show.' + zuiname) this.$element.trigger(startEvent) if (startEvent.isDefaultPrevented()) return var actives = this.$parent && this.$parent.find('> .panel > .in') if (actives && actives.length) { var hasData = actives.data(zuiname) if (hasData && hasData.transitioning) return actives.collapse('hide') hasData || actives.data(zuiname, null) } var dimension = this.dimension() this.$element .removeClass('collapse') .addClass('collapsing')[dimension](0) this.transitioning = 1 var complete = function() { this.$element .removeClass('collapsing') .addClass('in')[dimension]('auto') this.transitioning = 0 this.$element.trigger('shown.' + zuiname) } if (!$.support.transition) return complete.call(this) var scrollSize = $.camelCase(['scroll', dimension].join('-')) this.$element .one($.support.transition.end, $.proxy(complete, this)) .emulateTransitionEnd(350)[dimension](this.$element[0][scrollSize]) } Collapse.prototype.hide = function() { if (this.transitioning || !this.$element.hasClass('in')) return var startEvent = $.Event('hide.' + zuiname) this.$element.trigger(startEvent) if (startEvent.isDefaultPrevented()) return var dimension = this.dimension() this.$element[dimension](this.$element[dimension]())[0].offsetHeight this.$element .addClass('collapsing') .removeClass('collapse') .removeClass('in') this.transitioning = 1 var complete = function() { this.transitioning = 0 this.$element .trigger('hidden.' + zuiname) .removeClass('collapsing') .addClass('collapse') } if (!$.support.transition) return complete.call(this) this.$element[dimension](0) .one($.support.transition.end, $.proxy(complete, this)) .emulateTransitionEnd(350) } Collapse.prototype.toggle = function() { this[this.$element.hasClass('in') ? 'hide' : 'show']() } // COLLAPSE PLUGIN DEFINITION // ========================== var old = $.fn.collapse $.fn.collapse = function(option) { return this.each(function() { var $this = $(this) var data = $this.data(zuiname) var options = $.extend( {}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) if (!data) $this.data(zuiname, (data = new Collapse(this, options))) if (typeof option == 'string') data[option]() }) } $.fn.collapse.Constructor = Collapse // COLLAPSE NO CONFLICT // ==================== $.fn.collapse.noConflict = function() { $.fn.collapse = old return this } // COLLAPSE DATA-API // ================= $(document).on('click.' + zuiname + '.data-api', '[data-toggle=collapse]', function(e) { var $this = $(this), href var target = $this.attr('data-target') || e.preventDefault() || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7 var $target = $(target) var data = $target.data(zuiname) var option = data ? 'toggle' : $this.data() var parent = $this.attr('data-parent') var $parent = parent && $(parent) if (!data || !data.transitioning) { if ($parent) $parent.find('[data-toggle=collapse][data-parent="' + parent + '"]').not($this).addClass('collapsed') $this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed') } $target.collapse(option) }) }(window.jQuery); /* ======================================================================== * ZUI: device.js * http://zui.sexy * ======================================================================== * Copyright (c) 2014 cnezsoft.com; Licensed MIT * ======================================================================== */ (function(window, $) { 'use strict'; var desktopLg = 1200, desktop = 992, tablet = 768, cssNames = { desktop: 'screen-desktop', desktopLg: 'screen-desktop-wide', tablet: 'screen-tablet', phone: 'screen-phone', isMobile: 'device-mobile', isDesktop: 'device-desktop' }; var $window = $(window); var resetCssClass = function() { var width = $window.width(); $('html').toggleClass(cssNames.desktop, width >= desktop && width < desktopLg) .toggleClass(cssNames.desktopLg, width >= desktopLg) .toggleClass(cssNames.tablet, width >= tablet && width < desktop) .toggleClass(cssNames.phone, width < tablet) .toggleClass(cssNames.isMobile, width < desktop) .toggleClass(cssNames.isDesktop, width >= desktop); }; $window.resize(resetCssClass); resetCssClass(); }(window, jQuery)); /* ======================================================================== * ZUI: browser.js * http://zui.sexy * ======================================================================== * Copyright (c) 2014 cnezsoft.com; Licensed MIT * ======================================================================== */ (function($) { 'use strict'; var browseHappyTip = { 'zh_cn': '您的浏览器版本过低,无法体验所有功能,建议升级或者更换浏览器。 了解更多...', 'zh_tw': '您的瀏覽器版本過低,無法體驗所有功能,建議升級或者更换瀏覽器。了解更多...', 'en': 'Your browser is too old, it has been unable to experience the colorful internet. We strongly recommend that you upgrade a better one. Learn more...' }; // The browser modal class var Browser = function() { var isIE = this.isIE; var ie = isIE(); if (ie) { for (var i = 10; i > 5; i--) { if (isIE(i)) { ie = i; break; } } } this.ie = ie; this.cssHelper(); }; // Append CSS class to html tag Browser.prototype.cssHelper = function() { var ie = this.ie, $html = $('html'); $html.toggleClass('ie', ie) .removeClass('ie-6 ie-7 ie-8 ie-9 ie-10'); if (ie) { $html.addClass('ie-' + ie) .toggleClass('gt-ie-7 gte-ie-8 support-ie', ie >= 8) .toggleClass('lte-ie-7 lt-ie-8 outdated-ie', ie < 8) .toggleClass('gt-ie-8 gte-ie-9', ie >= 9) .toggleClass('lte-ie-8 lt-ie-9', ie < 9) .toggleClass('gt-ie-9 gte-ie-10', ie >= 10) .toggleClass('lte-ie-9 lt-ie-10', ie < 10); } }; // Show browse happy tip Browser.prototype.tip = function() { if (this.ie && this.ie < 8) { var $browseHappy = $('#browseHappyTip'); if (!$browseHappy.length) { $browseHappy = $('
'); $browseHappy.prependTo('body'); } $browseHappy.find('.content').html(this.browseHappyTip || browseHappyTip[$.zui.clientLang() || 'zh_cn']); } }; // Detect it is IE, can given a version Browser.prototype.isIE = function(version) { // var ie = /*@cc_on !@*/false; var b = document.createElement('b'); b.innerHTML = ''; return b.getElementsByTagName('i').length === 1; }; // Detect ie 10 with hack Browser.prototype.isIE10 = function() { return ( /*@cc_on!@*/ false); }; $.zui({browser: new Browser()}); $(function() { if (!$('body').hasClass('disabled-browser-tip')) { $.zui.browser.tip(); } }); }(jQuery)); /* ======================================================================== * ZUI: date.js * http://zui.sexy * ======================================================================== * Copyright (c) 2014 cnezsoft.com; Licensed MIT * ======================================================================== */ (function() { 'use strict'; /** * Ticks of a whole day * @type {number} */ Date.ONEDAY_TICKS = 24 * 3600 * 1000; /** * Format date to a string * * @param string format * @return string */ if(!Date.prototype.format) { Date.prototype.format = function(format) { var date = { 'M+': this.getMonth() + 1, 'd+': this.getDate(), 'h+': this.getHours(), 'm+': this.getMinutes(), 's+': this.getSeconds(), 'q+': Math.floor((this.getMonth() + 3) / 3), 'S+': this.getMilliseconds() }; if (/(y+)/i.test(format)) { format = format.replace(RegExp.$1, (this.getFullYear() + '').substr(4 - RegExp.$1.length)); } for (var k in date) { if (new RegExp('(' + k + ')').test(format)) { format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? date[k] : ('00' + date[k]).substr(('' + date[k]).length)); } } return format; }; } /** * Add milliseconds to the date * @param {number} value */ if(!Date.prototype.addMilliseconds) { Date.prototype.addMilliseconds = function(value) { this.setTime(this.getTime() + value); return this; }; } /** * Add days to the date * @param {number} days */ if(!Date.prototype.addDays) { Date.prototype.addDays = function(days) { this.addMilliseconds(days * Date.ONEDAY_TICKS); return this; }; } /** * Clone a new date instane from the date * @return {Date} */ if(!Date.prototype.clone) { Date.prototype.clone = function() { var date = new Date(); date.setTime(this.getTime()); return date; }; } /** * Judge the year is in a leap year * @param {integer} year * @return {Boolean} */ if(!Date.isLeapYear) { Date.isLeapYear = function(year) { return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0)); }; } if(!Date.getDaysInMonth) { /** * Get days number of the date * @param {integer} year * @param {integer} month * @return {integer} */ Date.getDaysInMonth = function(year, month) { return [31, (Date.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]; }; } /** * Judge the date is in a leap year * @return {Boolean} */ if(!Date.prototype.isLeapYear) { Date.prototype.isLeapYear = function() { return Date.isLeapYear(this.getFullYear()); }; } /** * Clear time part of the date * @return {date} */ if(!Date.prototype.clearTime) { Date.prototype.clearTime = function() { this.setHours(0); this.setMinutes(0); this.setSeconds(0); this.setMilliseconds(0); return this; }; } /** * Get days of this month of the date * @return {integer} */ if(!Date.prototype.getDaysInMonth) { Date.prototype.getDaysInMonth = function() { return Date.getDaysInMonth(this.getFullYear(), this.getMonth()); }; } /** * Add months to the date * @param {date} value */ if(!Date.prototype.addMonths) { Date.prototype.addMonths = function(value) { var n = this.getDate(); this.setDate(1); this.setMonth(this.getMonth() + value); this.setDate(Math.min(n, this.getDaysInMonth())); return this; }; } /** * Get last week day of the date * @param {integer} day * @return {date} */ if(!Date.prototype.getLastWeekday) { Date.prototype.getLastWeekday = function(day) { day = day || 1; var d = this.clone(); while (d.getDay() != day) { d.addDays(-1); } d.clearTime(); return d; }; } /** * Judge the date is same day as another date * @param {date} date * @return {Boolean} */ if(!Date.prototype.isSameDay) { Date.prototype.isSameDay = function(date) { return date.toDateString() === this.toDateString(); }; } /** * Judge the date is in same week as another date * @param {date} date * @return {Boolean} */ if(!Date.prototype.isSameWeek) { Date.prototype.isSameWeek = function(date) { var weekStart = this.getLastWeekday(); var weekEnd = weekStart.clone().addDays(7); return date >= weekStart && date < weekEnd; }; } /** * Judge the date is in same year as another date * @param {date} date * @return {Boolean} */ if(!Date.prototype.isSameYear) { Date.prototype.isSameYear = function(date) { return this.getFullYear() === date.getFullYear(); }; } }()); /* ======================================================================== * ZUI: string.js * http://zui.sexy * ======================================================================== * Copyright (c) 2014 cnezsoft.com; Licensed MIT * ======================================================================== */ (function() { 'use strict'; if (!String.prototype.format) { String.prototype.format = function(args) { var result = this; if (arguments.length > 0) { var reg; if (arguments.length == 1 && typeof(args) == "object") { for (var key in args) { if (args[key] !== undefined) { reg = new RegExp("({" + key + "})", "g"); result = result.replace(reg, args[key]); } } } else { for (var i = 0; i < arguments.length; i++) { if (arguments[i] !== undefined) { reg = new RegExp("({[" + i + "]})", "g"); result = result.replace(reg, arguments[i]); } } } } return result; }; } /** * Judge the string is a integer number * * @access public * @return bool */ if (!String.prototype.isNum) { String.prototype.isNum = function(s) { if (s !== null) { var r, re; re = /\d*/i; r = s.match(re); return (r == s) ? true : false; } return false; }; } })(); /*! * jQuery resize event - v1.1 - 3/14/2010 * http://benalman.com/projects/jquery-resize-plugin/ * * Copyright (c) 2010 "Cowboy" Ben Alman * Dual licensed under the MIT and GPL licenses. * http://benalman.com/about/license/ */ // Script: jQuery resize event // // *Version: 1.1, Last updated: 3/14/2010* // // Project Home - http://benalman.com/projects/jquery-resize-plugin/ // GitHub - http://github.com/cowboy/jquery-resize/ // Source - http://github.com/cowboy/jquery-resize/raw/master/jquery.ba-resize.js // (Minified) - http://github.com/cowboy/jquery-resize/raw/master/jquery.ba-resize.min.js (1.0kb) // // About: License // // Copyright (c) 2010 "Cowboy" Ben Alman, // Dual licensed under the MIT and GPL licenses. // http://benalman.com/about/license/ // // About: Examples // // This working example, complete with fully commented code, illustrates a few // ways in which this plugin can be used. // // resize event - http://benalman.com/code/projects/jquery-resize/examples/resize/ // // About: Support and Testing // // Information about what version or versions of jQuery this plugin has been // tested with, what browsers it has been tested in, and where the unit tests // reside (so you can test it yourself). // // jQuery Versions - 1.3.2, 1.4.1, 1.4.2 // Browsers Tested - Internet Explorer 6-8, Firefox 2-3.6, Safari 3-4, Chrome, Opera 9.6-10.1. // Unit Tests - http://benalman.com/code/projects/jquery-resize/unit/ // // About: Release History // // 1.1 - (3/14/2010) Fixed a minor bug that was causing the event to trigger // immediately after bind in some circumstances. Also changed $.fn.data // to $.data to improve performance. // 1.0 - (2/10/2010) Initial release (function($,window,undefined){ '$:nomunge'; // Used by YUI compressor. // A jQuery object containing all non-window elements to which the resize // event is bound. var elems = $([]), // Extend $.resize if it already exists, otherwise create it. jq_resize = $.resize = $.extend( $.resize, {} ), timeout_id, // Reused strings. str_setTimeout = 'setTimeout', str_resize = 'resize', str_data = str_resize + '-special-event', str_delay = 'delay', str_throttle = 'throttleWindow'; // Property: jQuery.resize.delay // // The numeric interval (in milliseconds) at which the resize event polling // loop executes. Defaults to 250. jq_resize[ str_delay ] = 250; // Property: jQuery.resize.throttleWindow // // Throttle the native window object resize event to fire no more than once // every milliseconds. Defaults to true. // // Because the window object has its own resize event, it doesn't need to be // provided by this plugin, and its execution can be left entirely up to the // browser. However, since certain browsers fire the resize event continuously // while others do not, enabling this will throttle the window resize event, // making event behavior consistent across all elements in all browsers. // // While setting this property to false will disable window object resize // event throttling, please note that this property must be changed before any // window object resize event callbacks are bound. jq_resize[ str_throttle ] = true; // Event: resize event // // Fired when an element's width or height changes. Because browsers only // provide this event for the window element, for other elements a polling // loop is initialized, running every milliseconds // to see if elements' dimensions have changed. You may bind with either // .resize( fn ) or .bind( "resize", fn ), and unbind with .unbind( "resize" ). // // Usage: // // > jQuery('selector').bind( 'resize', function(e) { // > // element's width or height has changed! // > ... // > }); // // Additional Notes: // // * The polling loop is not created until at least one callback is actually // bound to the 'resize' event, and this single polling loop is shared // across all elements. // // Double firing issue in jQuery 1.3.2: // // While this plugin works in jQuery 1.3.2, if an element's event callbacks // are manually triggered via .trigger( 'resize' ) or .resize() those // callbacks may double-fire, due to limitations in the jQuery 1.3.2 special // events system. This is not an issue when using jQuery 1.4+. // // > // While this works in jQuery 1.4+ // > $(elem).css({ width: new_w, height: new_h }).resize(); // > // > // In jQuery 1.3.2, you need to do this: // > var elem = $(elem); // > elem.css({ width: new_w, height: new_h }); // > elem.data( 'resize-special-event', { width: elem.width(), height: elem.height() } ); // > elem.resize(); $.event.special[ str_resize ] = { // Called only when the first 'resize' event callback is bound per element. setup: function() { // Since window has its own native 'resize' event, return false so that // jQuery will bind the event using DOM methods. Since only 'window' // objects have a .setTimeout method, this should be a sufficient test. // Unless, of course, we're throttling the 'resize' event for window. if ( !jq_resize[ str_throttle ] && this[ str_setTimeout ] ) { return false; } var elem = $(this); // Add this element to the list of internal elements to monitor. elems = elems.add( elem ); // Initialize data store on the element. $.data( this, str_data, { w: elem.width(), h: elem.height() } ); // If this is the first element added, start the polling loop. if ( elems.length === 1 ) { loopy(); } }, // Called only when the last 'resize' event callback is unbound per element. teardown: function() { // Since window has its own native 'resize' event, return false so that // jQuery will unbind the event using DOM methods. Since only 'window' // objects have a .setTimeout method, this should be a sufficient test. // Unless, of course, we're throttling the 'resize' event for window. if ( !jq_resize[ str_throttle ] && this[ str_setTimeout ] ) { return false; } var elem = $(this); // Remove this element from the list of internal elements to monitor. elems = elems.not( elem ); // Remove any data stored on the element. elem.removeData( str_data ); // If this is the last element removed, stop the polling loop. if ( !elems.length ) { clearTimeout( timeout_id ); } }, // Called every time a 'resize' event callback is bound per element (new in // jQuery 1.4). add: function( handleObj ) { // Since window has its own native 'resize' event, return false so that // jQuery doesn't modify the event object. Unless, of course, we're // throttling the 'resize' event for window. if ( !jq_resize[ str_throttle ] && this[ str_setTimeout ] ) { return false; } var old_handler; // The new_handler function is executed every time the event is triggered. // This is used to update the internal element data store with the width // and height when the event is triggered manually, to avoid double-firing // of the event callback. See the "Double firing issue in jQuery 1.3.2" // comments above for more information. function new_handler( e, w, h ) { var elem = $(this), data = $.data( this, str_data ) || {}; // If called from the polling loop, w and h will be passed in as // arguments. If called manually, via .trigger( 'resize' ) or .resize(), // those values will need to be computed. data.w = w !== undefined ? w : elem.width(); data.h = h !== undefined ? h : elem.height(); old_handler.apply( this, arguments ); }; // This may seem a little complicated, but it normalizes the special event // .add method between jQuery 1.4/1.4.1 and 1.4.2+ if ( $.isFunction( handleObj ) ) { // 1.4, 1.4.1 old_handler = handleObj; return new_handler; } else { // 1.4.2+ old_handler = handleObj.handler; handleObj.handler = new_handler; } } }; function loopy() { // Start the polling loop, asynchronously. timeout_id = window[ str_setTimeout ](function(){ // Iterate over all elements to which the 'resize' event is bound. elems.each(function(){ var elem = $(this), width = elem.width(), height = elem.height(), data = $.data( this, str_data ); // If element size has changed since the last time, update the element // data store and trigger the 'resize' event. if ( width !== data.w || height !== data.h ) { elem.trigger( str_resize, [ data.w = width, data.h = height ] ); } }); // Loop. loopy(); }, jq_resize[ str_delay ] ); }; })(jQuery,this); /* ======================================================================== * Bootstrap: scrollspy.js v3.0.3 * http://getbootstrap.com/javascript/#scrollspy * ======================================================================== * Copyright 2011-2014 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // SCROLLSPY CLASS DEFINITION // ========================== var zuiname = 'zui.scrollspy' function ScrollSpy(element, options) { var href var process = $.proxy(this.process, this) this.$element = $(element).is('body') ? $(window) : $(element) this.$body = $('body') this.$scrollElement = this.$element.on('scroll. ' + zuiname + ' .data-api', process) this.options = $.extend({}, ScrollSpy.DEFAULTS, options) if(!this.selector) this.selector = (this.options.target || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7 || '') + ' .nav li > a' this.offsets = $([]) this.targets = $([]) this.activeTarget = null this.refresh() this.process() } ScrollSpy.DEFAULTS = { offset: 10 } ScrollSpy.prototype.refresh = function () { var offsetMethod = this.$element[0] == window ? 'offset' : 'position' this.offsets = $([]) this.targets = $([]) var self = this var $targets = this.$body .find(this.selector) .map(function () { var $el = $(this) var href = $el.data('target') || $el.attr('href') var $href = /^#./.test(href) && $(href) return ($href && $href.length && $href.is(':visible') && [[ $href[offsetMethod]().top + (!$.isWindow(self.$scrollElement.get(0)) && self.$scrollElement.scrollTop()), href ]]) || null }) .sort(function (a, b) { return a[0] - b[0] }) .each(function () { self.offsets.push(this[0]) self.targets.push(this[1]) }) } ScrollSpy.prototype.process = function () { var scrollTop = this.$scrollElement.scrollTop() + this.options.offset var scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight var maxScroll = scrollHeight - this.$scrollElement.height() var offsets = this.offsets var targets = this.targets var activeTarget = this.activeTarget var i if (scrollTop >= maxScroll) { return activeTarget != (i = targets.last()[0]) && this.activate(i) } if (activeTarget && scrollTop <= offsets[0]) { return activeTarget != (i = targets[0]) && this.activate(i) } for (i = offsets.length; i--;) { activeTarget != targets[i] && scrollTop >= offsets[i] && (!offsets[i + 1] || scrollTop <= offsets[i + 1]) && this.activate( targets[i] ) } } ScrollSpy.prototype.activate = function (target) { this.activeTarget = target $(this.selector) .parentsUntil(this.options.target, '.active') .removeClass('active') var selector = this.selector + '[data-target="' + target + '"],' + this.selector + '[href="' + target + '"]' var active = $(selector) .parents('li') .addClass('active') if (active.parent('.dropdown-menu').length) { active = active .closest('li.dropdown') .addClass('active') } active.trigger('activate.' + zuiname) } // SCROLLSPY PLUGIN DEFINITION // =========================== var old = $.fn.scrollspy $.fn.scrollspy = function (option) { return this.each(function () { var $this = $(this) var data = $this.data(zuiname) var options = typeof option == 'object' && option if (!data) $this.data(zuiname, (data = new ScrollSpy(this, options))) if (typeof option == 'string') data[option]() }) } $.fn.scrollspy.Constructor = ScrollSpy // SCROLLSPY NO CONFLICT // ===================== $.fn.scrollspy.noConflict = function () { $.fn.scrollspy = old return this } // SCROLLSPY DATA-API // ================== $(window).on('load', function () { $('[data-spy="scroll"]').each(function () { var $spy = $(this) $spy.scrollspy($spy.data()) }) }) }(jQuery); /* ======================================================================== * ZUI: storeb.js * http://zui.sexy * ======================================================================== * Copyright (c) 2014 cnezsoft.com; Licensed MIT * ======================================================================== */ (function(window, $) { 'use strict'; var lsName = 'localStorage'; var storage = window[lsName], old = window.store, pageName = 'page_' + window.location.pathname + window.location.search; /* The Store object */ var Store = function() { this.slience = true; this.enable = (lsName in window) && window[lsName] && window[lsName].setItem; this.storage = storage; this.page = this.get(pageName, {}); }; /* Save page data */ Store.prototype.pageSave = function() { if ($.isEmptyObject(this.page)) { this.remove(pageName); } else { var forDeletes = [], i; for (i in this.page) { var val = this.page[i]; if (val === null) forDeletes.push(i); } for (i = forDeletes.length - 1; i >= 0; i--) { delete this.page[forDeletes[i]]; } this.set(pageName, this.page); } }; /* Remove page data item */ Store.prototype.pageRemove = function(key) { if (typeof this.page[key] != 'undefined') { this.page[key] = null; this.pageSave(); } }; /* Clear page data */ Store.prototype.pageClear = function() { this.page = {}; this.pageSave(); }; /* Get page data */ Store.prototype.pageGet = function(key, defaultValue) { var val = this.page[key]; return (defaultValue !== undefined && (val === null || val === undefined)) ? defaultValue : val; }; /* Set page data */ Store.prototype.pageSet = function(objOrKey, val) { if ($.isPlainObject(objOrKey)) { $.extend(true, this.page, objOrKey); } else { this.page[this.serialize(objOrKey)] = val; } this.pageSave(); }; /* Check enable status */ Store.prototype.check = function() { if (!this.enable) { if (!this.slience) throw new Error('Browser not support localStorage or enable status been set true.'); } return this.enable; }; /* Get length */ Store.prototype.length = function() { if (this.check()) { return storage.getLength ? storage.getLength() : storage.length; } return 0; }; /* Remove item with browser localstorage native method */ Store.prototype.removeItem = function(key) { storage.removeItem(key); return this; }; /* Remove item with browser localstorage native method, same as removeItem */ Store.prototype.remove = function(key) { return this.removeItem(key); }; /* Get item value with browser localstorage native method, and without deserialize */ Store.prototype.getItem = function(key) { return storage.getItem(key); }; /* Get item value and deserialize it, if value is null and defaultValue been given then return defaultValue */ Store.prototype.get = function(key, defaultValue) { var val = this.deserialize(this.getItem(key)); if (typeof val === 'undefined' || val === null) { if (typeof defaultValue !== 'undefined') { return defaultValue; } } return val; }; /* Get item key by index and deserialize it */ Store.prototype.key = function(index) { return storage.key(index); }; /* Set item value with browser localstorage native method, and without serialize filter */ Store.prototype.setItem = function(key, val) { storage.setItem(key, val); return this; }; /* Set item value, serialize it if the given value is not an string */ Store.prototype.set = function(key, val) { if (val === undefined) return this.remove(key); this.setItem(key, this.serialize(val)); return this; }; /* Clear all items with browser localstorage native method */ Store.prototype.clear = function() { storage.clear(); return this; }; /* Iterate all items with callback */ Store.prototype.forEach = function(callback) { for (var i = storage.length - 1; i >= 0; i--) { var key = storage.key(i); callback(key, this.get(key)); } return this; }; /* Get all items and set value in an object. */ Store.prototype.getAll = function() { var all = {}; this.forEach(function(key, val) { all[key] = val; }); return all; }; /* Serialize value with JSON.stringify */ Store.prototype.serialize = function(value) { if (typeof value === 'string') return value; return JSON.stringify(value); }; /* Deserialize value, with JSON.parse if the given value is not a string */ Store.prototype.deserialize = function(value) { if (typeof value !== 'string') return undefined; try { return JSON.parse(value); } catch (e) { return value || undefined; } }; $.zui( { store: new Store() }); }(window, jQuery)); /* ======================================================================== * ZUI: draggable.js * http://zui.sexy * ======================================================================== * Copyright (c) 2014 cnezsoft.com; Licensed MIT * ======================================================================== */ (function($) { 'use strict'; var Draggable = function(element, options) { this.$ = $(element); this.options = this.getOptions(options); this.init(); }; Draggable.DEFAULTS = { container: 'body', move: true }; Draggable.prototype.getOptions = function(options) { options = $.extend( {}, Draggable.DEFAULTS, this.$.data(), options); return options; }; Draggable.prototype.init = function() { this.handleMouseEvents(); }; Draggable.prototype.handleMouseEvents = function() { var $e = this.$, BEFORE = 'before', DRAG = 'drag', FINISH = 'finish', setting = this.options, startPos, cPos, startOffset, mousePos, moved; var mouseDown = function(event) { if (setting.hasOwnProperty(BEFORE) && $.isFunction(setting[BEFORE])) { var isSure = setting[BEFORE]( { event: event, element: $e }); if (isSure !== undefined && (!isSure)) return; } var $container = $(setting.container), pos = $e.offset(); cPos = $container.offset(); startPos = { x: event.pageX, y: event.pageY }; startOffset = { x: event.pageX - pos.left + cPos.left, y: event.pageY - pos.top + cPos.top }; mousePos = $.extend( {}, startPos); moved = false; $e.addClass('drag-ready'); $(document).bind('mousemove', mouseMove).bind('mouseup', mouseUp); event.preventDefault(); if (setting.stopPropagation) { event.stopPropagation(); } }; var mouseMove = function(event) { moved = true; var mX = event.pageX, mY = event.pageY; var dragPos = { left: mX - startOffset.x, top: mY - startOffset.y }; $e.removeClass('drag-ready').addClass('dragging'); if (setting.move) { $e.css(dragPos); } if (setting.hasOwnProperty(DRAG) && $.isFunction(setting[DRAG])) { setting[DRAG]( { event: event, element: $e, startOffset: startOffset, pos: dragPos, offset: { x: mX - startPos.x, y: mY - startPos.y }, smallOffset: { x: mX - mousePos.x, y: mY - mousePos.y } }); } mousePos.x = mX; mousePos.y = mY; if (setting.stopPropagation) { event.stopPropagation(); } }; var mouseUp = function(event) { $(document).unbind('mousemove', mouseMove).unbind('mouseup', mouseUp); if (!moved) { $e.removeClass('drag-ready'); return; } var endPos = { left: event.pageX - startOffset.x, top: event.pageY - startOffset.y }; $e.removeClass('drag-ready').removeClass('dragging'); if (setting.move) { $e.css(endPos); } if (setting.hasOwnProperty(FINISH) && $.isFunction(setting[FINISH])) { setting[FINISH]( { event: event, element: $e, pos: endPos, offset: { x: event.pageX - startPos.x, y: event.pageY - startPos.y }, smallOffset: { x: event.pageX - mousePos.x, y: event.pageY - mousePos.y } }); } event.preventDefault(); if (setting.stopPropagation) { event.stopPropagation(); } }; if (setting.handle) { $e.on('mousedown', setting.handle, mouseDown); } else { $e.on('mousedown', mouseDown); } }; $.fn.draggable = function(option) { return this.each(function() { var $this = $(this); var data = $this.data('zui.draggable'); var options = typeof option == 'object' && option; if (!data) $this.data('zui.draggable', (data = new Draggable(this, options))); if (typeof option == 'string') data[option](); }); }; $.fn.draggable.Constructor = Draggable; }(jQuery)); /* ======================================================================== * ZUI: droppable.js * http://zui.sexy * ======================================================================== * Copyright (c) 2014 cnezsoft.com; Licensed MIT * ======================================================================== */ (function($, document, Math) { 'use strict'; var Droppable = function(element, options) { this.$ = $(element); this.options = this.getOptions(options); this.init(); }; Droppable.DEFAULTS = { container: 'body', // flex: false, // nested: false, deviation: 5, sensorOffsetX: 0, sensorOffsetY: 0 }; Droppable.prototype.getOptions = function(options) { options = $.extend( {}, Droppable.DEFAULTS, this.$.data(), options); return options; }; Droppable.prototype.callEvent = function(name, params) { return $.zui.callEvent(this.options[name], params, this); }; Droppable.prototype.init = function() { this.handleMouseEvents(); }; Droppable.prototype.handleMouseEvents = function() { var $e = this.$, self = this, setting = this.options, BEFORE = 'before'; this.$triggerTarget = (setting.trigger ? ($.isFunction(setting.trigger) ? setting.trigger($e) : $e.find(setting.trigger)).first() : $e); this.$triggerTarget.on('mousedown', function(event) { if (setting.hasOwnProperty(BEFORE) && $.isFunction(setting[BEFORE])) { var isSure = setting[BEFORE]( { event: event, element: $e }); if (isSure !== undefined && (!isSure)) return; } var $targets = $.isFunction(setting.target) ? setting.target($e) : $(setting.target), target = null, shadow = null, $container = $(setting.container).first(), isIn = false, isSelf = true, oldCssPosition, startOffset = $e.offset(), startMouseOffset = { left: event.pageX, top: event.pageY }; var containerOffset = $container.offset(); var clickOffset = { left: startMouseOffset.left - startOffset.left, top: startMouseOffset.top - startOffset.top }; var lastMouseOffset = { left: startMouseOffset.left, top: startMouseOffset.top }; $e.addClass('drag-from'); $(document).bind('mousemove', mouseMove).bind('mouseup', mouseUp); event.preventDefault(); function mouseMove(event) { var mouseOffset = { left: event.pageX, top: event.pageY }; // ignore small move if (Math.abs(mouseOffset.left - startMouseOffset.left) < setting.deviation && Math.abs(mouseOffset.top - startMouseOffset.top) < setting.deviation) return; if (shadow === null) // create shadow { var cssPosition = $container.css('position'); if (cssPosition != 'absolute' && cssPosition != 'relative' && cssPosition != 'fixed') { oldCssPosition = cssPosition; $container.css('position', 'relative'); } shadow = $e.clone().removeClass('drag-from').addClass('drag-shadow').css( { position: 'absolute', width: $e.outerWidth(), transition: 'none' }).appendTo($container); $e.addClass('dragging'); self.callEvent('start', { event: event, element: $e }); } var offset = { left: mouseOffset.left - clickOffset.left, top: mouseOffset.top - clickOffset.top }; var position = { left: offset.left - containerOffset.left, top: offset.top - containerOffset.top }; shadow.css(position); lastMouseOffset.left = mouseOffset.left; lastMouseOffset.top = mouseOffset.top; var isNew = false; isIn = false; if (!setting.flex) { $targets.removeClass('drop-to'); } var newTarget = null; $targets.each(function() { var t = $(this); var tPos = t.offset(); var tW = t.outerWidth(), tH = t.outerHeight(), tX = tPos.left + setting.sensorOffsetX, tY = tPos.top + setting.sensorOffsetY; if (mouseOffset.left > tX && mouseOffset.top > tY && mouseOffset.left < (tX + tW) && mouseOffset.top < (tY + tH)) { if (newTarget) newTarget.removeClass('drop-to'); newTarget = t; if (!setting.nested) return false; } }); if (newTarget) { isIn = true; var id = newTarget.data('id'); if ($e.data('id') != id) isSelf = false; if (target === null || (target.data('id') !== id && (!isSelf))) isNew = true; target = newTarget; if (setting.flex) { $targets.removeClass('drop-to'); } target.addClass('drop-to'); } if (!setting.flex) { $e.toggleClass('drop-in', isIn); shadow.toggleClass('drop-in', isIn); } else if (target !== null && target.length) { isIn = true; } self.callEvent('drag', { event: event, isIn: isIn, target: target, element: $e, isNew: isNew, selfTarget: isSelf, clickOffset: clickOffset, offset: offset, position: { left: offset.left - containerOffset.left, top: offset.top - containerOffset.top }, mouseOffset: mouseOffset }); event.preventDefault(); } function mouseUp(event) { if (oldCssPosition) { $container.css('position', oldCssPosition); } if (shadow === null) { $e.removeClass('drag-from'); $(document).unbind('mousemove', mouseMove).unbind('mouseup', mouseUp); self.callEvent('always', {event: event, cancel: true}); return; } if (!isIn) target = null; var isSure = true, mouseOffset = { left: event.pageX, top: event.pageY }; var offset = { left: mouseOffset.left - clickOffset.left, top: mouseOffset.top - clickOffset.top }; var moveOffset = { left: mouseOffset.left - lastMouseOffset.left, top: mouseOffset.top - lastMouseOffset.top }; lastMouseOffset.left = mouseOffset.left; lastMouseOffset.top = mouseOffset.top; var eventOptions = { event: event, isIn: isIn, target: target, element: $e, isNew: (!isSelf) && target !== null, selfTarget: isSelf, offset: offset, mouseOffset: mouseOffset, position: { left: offset.left - containerOffset.left, top: offset.top - containerOffset.top }, lastMouseOffset: lastMouseOffset, moveOffset: moveOffset }; isSure = self.callEvent('beforeDrop', eventOptions); if (isSure && isIn) { self.callEvent('drop', eventOptions); } $(document).unbind('mousemove', mouseMove).unbind('mouseup', mouseUp); $targets.removeClass('drop-to'); $e.removeClass('dragging').removeClass('drag-from'); shadow.remove(); self.callEvent('finish', eventOptions); self.callEvent('always', eventOptions); event.preventDefault(); } }); }; Droppable.prototype.reset = function() { this.$triggerTarget.off('mousedown'); this.handleMouseEvents(); }; $.fn.droppable = function(option) { return this.each(function() { var $this = $(this); var data = $this.data('zui.droppable'); var options = typeof option == 'object' && option; if (!data) $this.data('zui.droppable', (data = new Droppable(this, options))); if (typeof option == 'string') data[option](); }); }; $.fn.droppable.Constructor = Droppable; }(jQuery, document, Math)); /* ======================================================================== * ZUI: sortable.js * http://zui.sexy * ======================================================================== * Copyright (c) 2014 cnezsoft.com; Licensed MIT * ======================================================================== */ +function($, window, document, Math) { 'use strict'; var Sortable = function(element, options) { this.$ = $(element); this.options = this.getOptions(options); this.init(); }; Sortable.DEFAULTS = {list: 'li, div', dragCssClass: 'invisible'}; // default options Sortable.prototype.getOptions = function (options) { options = $.extend({}, Sortable.DEFAULTS, this.$.data(), options); return options; }; Sortable.prototype.init = function() { this.bindEventToList(this.$.children(this.options.selector)); }; Sortable.prototype.reset = function() { var that = this, order = 0; var list = this.$.children(this.options.selector); list.each(function() { var $this = $(this); if($this.data('zui.droppable')) { $this.data('zui.droppable').options.target = list; $this.droppable('reset'); } else { that.bindEventToList($this); } $(this).attr('data-order', ++order); }); }; Sortable.prototype.bindEventToList = function($list) { var self = this.$, options = this.options; markOrders($list); $list.droppable( { trigger: options.trigger, target: self.children(options.selector), container: self, always: options.always, flex: true, start: function(e) { if(options.dragCssClass) e.element.addClass(options.dragCssClass); $.zui.callEvent(options['start']); }, drag: function(e) { if(e.isIn) { var $ele = e.element, $target = e.target; var eleOrder = $ele.attr('data-order'), targetOrder = $target.attr('data-order'); if(eleOrder == targetOrder) return; else if(eleOrder > targetOrder) { $target.before($ele); } else { $target.after($ele); } var list = self.children(options.selector); markOrders(list); $.zui.callEvent(options['order'], {list: list, element: $ele}); } }, finish: function(e) { if(options.dragCssClass && e.element) e.element.removeClass(options.dragCssClass); $.zui.callEvent(options['finish'], {list: self.children(options.selector), element: e.element}); } }); function markOrders(list) { var order = 0; list.each(function() { $(this).attr('data-order', ++order); }); } }; $.fn.sortable = function(option) { return this.each(function() { var $this = $(this); var data = $this.data('zui.sortable'); var options = typeof option == 'object' && option; if (!data) $this.data('zui.sortable', (data = new Sortable(this, options))); else if(typeof option == 'object') data.reset(); if (typeof option == 'string') data[option](); }) }; $.fn.sortable.Constructor = Sortable; }(jQuery,window,document,Math); /* ======================================================================== * Bootstrap: modal.js v3.2.0 * http://getbootstrap.com/javascript/#modals * ======================================================================== * Copyright 2011-2014 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== * Updates in ZUI: * 1. changed event namespace to *.zui.modal * 2. added position option to ajust poisition of modal * 3. added event 'escaping.zui.modal' with an param 'esc' to judge the esc * key down * 4. get moveable options value from '.modal-moveable' on '.modal-dialog' * 5. add setMoveable method to make modal dialog moveable * ======================================================================== */ + function($){ 'use strict'; // MODAL CLASS DEFINITION // ====================== var zuiname = 'zui.modal' var Modal = function(element, options) { this.options = options this.$body = $(document.body) this.$element = $(element) this.$backdrop = this.isShown = null this.scrollbarWidth = 0 if (typeof this.options.moveable === 'undefined') { this.options.moveable = this.$element.hasClass('modal-moveable'); } if (this.options.remote) { this.$element .find('.modal-content') .load(this.options.remote, $.proxy(function() { this.$element.trigger('loaded.' + zuiname) }, this)) } } Modal.VERSION = '3.2.0' Modal.TRANSITION_DURATION = 300 Modal.BACKDROP_TRANSITION_DURATION = 150 Modal.DEFAULTS = { backdrop: true, keyboard: true, show: true, rememberPos: true, position: 'fit' // 'center' or '40px' or '10%' } Modal.prototype.toggle = function(_relatedTarget, position) { return this.isShown ? this.hide() : this.show(_relatedTarget, position) } Modal.prototype.ajustPosition = function(position) { if (typeof position === 'undefined') position = this.options.position; if (typeof position === 'undefined') return; var $dialog = this.$element.find('.modal-dialog'); // if($dialog.hasClass('modal-dragged')) return; var half = Math.max(0, ($(window).height() - $dialog.outerHeight()) / 2); var topPos = position == 'fit' ? (half * 2 / 3) : (position == 'center' ? half : position); if ($dialog.hasClass('modal-moveable')) { var pos = this.options.rememberPos ? this.$element.data('modal-pos') : null; if (!pos) { pos = { left: Math.max(0, ($(window).width() - $dialog.outerWidth()) / 2), top: topPos }; } $dialog.css(pos); } else { $dialog.css('margin-top', topPos); } } Modal.prototype.setMoveale = function() { var that = this; var options = that.options; var $dialog = that.$element.find('.modal-dialog').removeClass('modal-dragged'); $dialog.toggleClass('modal-moveable', options.moveable); if (!that.$element.data('modal-moveable-setup')) { $dialog.draggable( { container: that.$element, handle: '.modal-header', before: function() { $dialog.css('margin-top', '').addClass('modal-dragged'); }, finish: function(e) { that.$element.data('modal-pos', e.pos); } }); } } Modal.prototype.show = function(_relatedTarget, position) { var that = this var e = $.Event('show.' + zuiname, { relatedTarget: _relatedTarget }) that.$element.trigger(e) if (that.isShown || e.isDefaultPrevented()) return that.isShown = true if (that.options.draggable) that.setMoveale(); that.checkScrollbar() that.$body.addClass('modal-open') that.setScrollbar() that.escape() that.$element.on('click.dismiss.' + zuiname, '[data-dismiss="modal"]', $.proxy(that.hide, that)) that.backdrop(function() { var transition = $.support.transition && that.$element.hasClass('fade') if (!that.$element.parent().length) { that.$element.appendTo(that.$body) // don't move modals dom position } that.$element .show() .scrollTop(0) if (transition) { that.$element[0].offsetWidth // force reflow } that.$element .addClass('in') .attr('aria-hidden', false) that.ajustPosition(position); that.enforceFocus() var e = $.Event('shown.' + zuiname, { relatedTarget: _relatedTarget }) transition ? that.$element.find('.modal-dialog') // wait for modal to slide in .one('bsTransitionEnd', function() { that.$element.trigger('focus').trigger(e) }) .emulateTransitionEnd(Modal.TRANSITION_DURATION) : that.$element.trigger('focus').trigger(e) }) } Modal.prototype.hide = function(e) { if (e) e.preventDefault() e = $.Event('hide.' + zuiname) this.$element.trigger(e) if (!this.isShown || e.isDefaultPrevented()) return this.isShown = false this.$body.removeClass('modal-open') this.resetScrollbar() this.escape() $(document).off('focusin.' + zuiname) this.$element .removeClass('in') .attr('aria-hidden', true) .off('click.dismiss.' + zuiname) $.support.transition && this.$element.hasClass('fade') ? this.$element .one('bsTransitionEnd', $.proxy(this.hideModal, this)) .emulateTransitionEnd(Modal.TRANSITION_DURATION) : this.hideModal() } Modal.prototype.enforceFocus = function() { $(document) .off('focusin.' + zuiname) // guard against infinite focus loop .on('focusin.' + zuiname, $.proxy(function(e) { if (this.$element[0] !== e.target && !this.$element.has(e.target).length) { this.$element.trigger('focus') } }, this)) } Modal.prototype.escape = function() { if (this.isShown && this.options.keyboard) { $(document).on('keydown.dismiss.' + zuiname, $.proxy(function(e) { if (e.which == 27) { var et = $.Event('escaping.' + zuiname) var result = this.$element.triggerHandler(et, 'esc') if (result != undefined && (!result)) return this.hide() } }, this)) } else if (!this.isShown) { $(document).off('keydown.dismiss.' + zuiname) } } Modal.prototype.hideModal = function() { var that = this this.$element.hide() this.backdrop(function() { that.$element.trigger('hidden.' + zuiname) }) } Modal.prototype.removeBackdrop = function() { this.$backdrop && this.$backdrop.remove() this.$backdrop = null } Modal.prototype.backdrop = function(callback) { var that = this var animate = this.$element.hasClass('fade') ? 'fade' : '' if (this.isShown && this.options.backdrop) { var doAnimate = $.support.transition && animate this.$backdrop = $('