3440 lines
110 KiB
JavaScript
3440 lines
110 KiB
JavaScript
/*!
|
||
* ZUI: Lite edition - v1.8.1 - 2018-01-18
|
||
* http://zui.sexy
|
||
* GitHub: https://github.com/easysoft/zui.git
|
||
* Copyright (c) 2018 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-2016 cnezsoft.com; Licensed MIT
|
||
* ======================================================================== */
|
||
|
||
|
||
(function($, window, undefined) {
|
||
'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 MOUSE_BUTTON_CODES = {
|
||
all: -1,
|
||
left: 0,
|
||
middle: 1,
|
||
right: 2
|
||
};
|
||
|
||
var lastUuidAmend = 0;
|
||
$.zui({
|
||
uuid: function() {
|
||
return(new Date()).getTime() * 1000 + (lastUuidAmend++) % 1000;
|
||
},
|
||
|
||
callEvent: function(func, event, proxy) {
|
||
if($.isFunction(func)) {
|
||
if(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;
|
||
}
|
||
if(!lang) {
|
||
var hl = $('html').attr('lang');
|
||
lang = hl ? hl : (navigator.userLanguage || navigator.userLanguage || 'zh_cn');
|
||
}
|
||
return lang.replace('-', '_').toLowerCase();
|
||
},
|
||
|
||
strCode: function(str) {
|
||
var code = 0;
|
||
if(str && str.length) {
|
||
for(var i = 0; i < str.length; ++i) {
|
||
code += i * str.charCodeAt(i);
|
||
}
|
||
}
|
||
return code;
|
||
},
|
||
|
||
getMouseButtonCode: function(mouseButton) {
|
||
if(typeof mouseButton !== 'number') {
|
||
mouseButton = MOUSE_BUTTON_CODES[mouseButton];
|
||
}
|
||
if(mouseButton === undefined || mouseButton === null) mouseButton = -1;
|
||
return mouseButton;
|
||
}
|
||
});
|
||
|
||
$.fn.callEvent = function(name, event, model) {
|
||
var $this = $(this);
|
||
var dotIndex = name.indexOf('.zui.');
|
||
var shortName = dotIndex < 0 ? name : name.substring(0, dotIndex);
|
||
var e = $.Event(shortName, event);
|
||
|
||
if((model === undefined) && dotIndex > 0) {
|
||
model = $this.data(name.substring(dotIndex + 1));
|
||
}
|
||
|
||
if(model && model.options) {
|
||
var func = model.options[shortName];
|
||
if($.isFunction(func)) {
|
||
e.result = $.zui.callEvent(func, e, model);
|
||
}
|
||
}
|
||
$this.trigger(e);
|
||
return e;
|
||
};
|
||
|
||
$.fn.callComEvent = function(component, eventName, params) {
|
||
if (params !== undefined && !$.isArray(params)) {
|
||
params = [params];
|
||
}
|
||
var $this = this;
|
||
var result = $this.triggerHandler(eventName, params);
|
||
|
||
var eventCallback = component.options[eventName];
|
||
if (eventCallback) {
|
||
result = eventCallback.apply(component, params);
|
||
}
|
||
return result;
|
||
};
|
||
}(jQuery, window, undefined));
|
||
|
||
|
||
/* ========================================================================
|
||
* ZUI: typography.js
|
||
* http://zui.sexy
|
||
* ========================================================================
|
||
* Copyright (c) 2014-2016 cnezsoft.com; Licensed MIT
|
||
* ======================================================================== */
|
||
|
||
|
||
(function($) {
|
||
'use strict';
|
||
|
||
$.fn.fixOlPd = function(pd) {
|
||
pd = pd || 10;
|
||
return this.each(function() {
|
||
var $ol = $(this);
|
||
$ol.css('paddingLeft', Math.ceil(Math.log10($ol.children().length)) * pd + 10);
|
||
});
|
||
};
|
||
|
||
$(function() {
|
||
$('.ol-pd-fix,.article ol').fixOlPd();
|
||
});
|
||
}(jQuery));
|
||
|
||
|
||
/* ========================================================================
|
||
* 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.
|
||
*
|
||
* ZUI: The file has been changed in ZUI. It will not keep update with the
|
||
* Bootsrap version in the future.
|
||
* http://zui.sexy
|
||
* ======================================================================== */
|
||
|
||
|
||
+ 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: transition.js v3.2.0
|
||
* http://getbootstrap.com/javascript/#transitions
|
||
*
|
||
* ZUI: The file has been changed in ZUI. It will not keep update with the
|
||
* Bootsrap version in the future.
|
||
* http://zui.sexy
|
||
* ========================================================================
|
||
* 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
|
||
*
|
||
* ZUI: The file has been changed in ZUI. It will not keep update with the
|
||
* Bootsrap version in the future.
|
||
* http://zui.sexy
|
||
* ========================================================================
|
||
* 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('.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-2016 cnezsoft.com; Licensed MIT
|
||
* ======================================================================== */
|
||
|
||
|
||
(function(window, $) {
|
||
'use strict';
|
||
var desktopLg = 1200,
|
||
desktop = 992,
|
||
tablet = 768;
|
||
|
||
var $window = $(window);
|
||
|
||
var resetCssClass = function() {
|
||
var width = $window.width();
|
||
$('html').toggleClass('screen-desktop', width >= desktop && width < desktopLg)
|
||
.toggleClass('screen-desktop-wide', width >= desktopLg)
|
||
.toggleClass('screen-tablet', width >= tablet && width < desktop)
|
||
.toggleClass('screen-phone', width < tablet)
|
||
.toggleClass('device-mobile', width < desktop)
|
||
.toggleClass('device-desktop', width >= desktop);
|
||
};
|
||
|
||
var classNames = '';
|
||
var userAgent = navigator.userAgent;
|
||
if (userAgent.match(/(iPad|iPhone|iPod)/i)) {
|
||
classNames += ' os-ios';
|
||
} else if (userAgent.match(/android/i)) {
|
||
classNames += ' os-android';
|
||
} else if (userAgent.match(/Win/i)) {
|
||
classNames += ' os-windows';
|
||
} else if (userAgent.match(/Mac/i)) {
|
||
classNames += ' os-mac';
|
||
} else if (userAgent.match(/Linux/i)) {
|
||
classNames += ' os-linux';
|
||
} else if (userAgent.match(/X11/i)) {
|
||
classNames += ' os-unix';
|
||
}
|
||
if ('ontouchstart' in document.documentElement) {
|
||
classNames += ' is-touchable';
|
||
}
|
||
$('html').addClass(classNames);
|
||
|
||
$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': '您的浏览器版本过低,无法体验所有功能,建议升级或者更换浏览器。 <a href="http://browsehappy.com/" target="_blank" class="alert-link">了解更多...</a>',
|
||
'zh_tw': '您的瀏覽器版本過低,無法體驗所有功能,建議升級或者更换瀏覽器。<a href="http://browsehappy.com/" target="_blank" class="alert-link">了解更多...</a>',
|
||
'en': 'Your browser is too old, it has been unable to experience the colorful internet. We strongly recommend that you upgrade a better one. <a href="http://browsehappy.com/" target="_blank" class="alert-link">Learn more...</a>'
|
||
};
|
||
|
||
// The browser modal class
|
||
var Browser = function() {
|
||
var ie = this.isIE() || this.isIE10() || false;
|
||
if(ie) {
|
||
for(var i = 10; i > 5; i--) {
|
||
if(this.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(showCoontent) {
|
||
var $browseHappy = $('#browseHappyTip');
|
||
if(!$browseHappy.length) {
|
||
$browseHappy = $('<div id="browseHappyTip" class="alert alert-dismissable alert-danger-inverse alert-block" style="position: relative; z-index: 99999"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button><div class="container"><div class="content text-center"></div></div></div>');
|
||
$browseHappy.prependTo('body');
|
||
}
|
||
|
||
$browseHappy.find('.content').html(showCoontent || this.browseHappyTip || browseHappyTip[$.zui.clientLang() || 'zh_cn']);
|
||
};
|
||
|
||
// Detect it is IE, can given a version
|
||
Browser.prototype.isIE = function(version) {
|
||
if(version === 10) return this.isIE10();
|
||
var b = document.createElement('b');
|
||
b.innerHTML = '<!--[if IE ' + (version || '') + ']><i></i><![endif]-->';
|
||
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')) {
|
||
if($.zui.browser.ie && $.zui.browser.ie < 8) {
|
||
$.zui.browser.tip();
|
||
}
|
||
}
|
||
});
|
||
}(jQuery));
|
||
|
||
|
||
/* ========================================================================
|
||
* ZUI: date.js
|
||
* Date polyfills
|
||
* 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();
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Create an date instance with string, timestamp or date instance
|
||
* @param {Date|String|Number} date
|
||
* @return {Date}
|
||
*/
|
||
if (!Date.create) {
|
||
Date.create = function(date) {
|
||
if (!(date instanceof Date)) {
|
||
if (typeof date === 'number' && date < 10000000000) {
|
||
date *= 1000;
|
||
}
|
||
date = new Date(date);
|
||
}
|
||
return date;
|
||
};
|
||
}
|
||
|
||
if (!Date.timestamp) {
|
||
Date.timestamp = function(date) {
|
||
if (typeof date === 'number') {
|
||
if (date < 10000000000) {
|
||
date *= 1000;
|
||
}
|
||
} else {
|
||
date = Date.create(date).getTime();
|
||
}
|
||
return date;
|
||
};
|
||
}
|
||
}());
|
||
|
||
|
||
/* ========================================================================
|
||
* ZUI: string.js
|
||
* String Polyfill.
|
||
* http://zui.sexy
|
||
* ========================================================================
|
||
* Copyright (c) 2014-2016 cnezsoft.com; Licensed MIT
|
||
* ======================================================================== */
|
||
|
||
|
||
(function() {
|
||
'use strict';
|
||
|
||
/**
|
||
* Format string with argument list or object
|
||
* @param {object | arguments} args
|
||
* @return {String}
|
||
*/
|
||
if(!String.prototype.format) {
|
||
String.prototype.format = function(args) {
|
||
var result = this;
|
||
if(arguments.length > 0) {
|
||
var reg;
|
||
if(arguments.length <= 2 && typeof(args) == 'object') {
|
||
for(var key in args) {
|
||
if(args[key] !== undefined) {
|
||
reg = new RegExp('(' + (arguments[1] ? arguments[1].replace('0', key) : '{' + 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;
|
||
};
|
||
}
|
||
|
||
if(!String.prototype.endsWith) {
|
||
String.prototype.endsWith = function(searchString, position) {
|
||
var subjectString = this.toString();
|
||
if(position === undefined || position > subjectString.length) {
|
||
position = subjectString.length;
|
||
}
|
||
position -= searchString.length;
|
||
var lastIndex = subjectString.indexOf(searchString, position);
|
||
return lastIndex !== -1 && lastIndex === position;
|
||
};
|
||
}
|
||
|
||
if(!String.prototype.startsWith) {
|
||
String.prototype.startsWith = function(searchString, position) {
|
||
position = position || 0;
|
||
return this.lastIndexOf(searchString, position) === position;
|
||
};
|
||
}
|
||
|
||
if(!String.prototype.includes) {
|
||
String.prototype.includes = function() {
|
||
return String.prototype.indexOf.apply(this, arguments) !== -1;
|
||
};
|
||
}
|
||
|
||
})();
|
||
|
||
|
||
/* ========================================================================
|
||
* Resize: resize.js [Version: 1.1]
|
||
* http://benalman.com/projects/jquery-resize-plugin/
|
||
*
|
||
* ZUI: The file has been changed in ZUI. It will not keep update with the
|
||
* official version in the future.
|
||
* http://zui.sexy
|
||
* ========================================================================
|
||
* opyright (c) 2010 "Cowboy" Ben Alman
|
||
* Dual licensed under the MIT and GPL licenses.
|
||
* http://benalman.com/about/license/
|
||
* ======================================================================== */
|
||
|
||
|
||
/*!
|
||
* jQuery resize event - v1.1
|
||
* http://benalman.com/projects/jquery-resize-plugin/
|
||
* Copyright (c) 2010 "Cowboy" Ben Alman
|
||
* MIT & GPL 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 <jQuery.resize.delay> 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 <jQuery.resize.delay> 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);
|
||
|
||
|
||
/* ========================================================================
|
||
* ZUI: storeb.js
|
||
* http://zui.sexy
|
||
* ========================================================================
|
||
* Copyright (c) 2014-2016 cnezsoft.com; Licensed MIT
|
||
* ======================================================================== */
|
||
|
||
|
||
(function(window, $) {
|
||
'use strict';
|
||
|
||
var lsName = 'localStorage';
|
||
var storage,
|
||
dataset,
|
||
pageName = 'page_' + window.location.pathname + window.location.search;
|
||
|
||
/* The Store object */
|
||
var Store = function() {
|
||
this.slience = true;
|
||
try {
|
||
if((lsName in window) && window[lsName] && window[lsName].setItem) {
|
||
this.enable = true;
|
||
storage = window[lsName];
|
||
}
|
||
} catch(e){}
|
||
if(!this.enable) {
|
||
dataset = {};
|
||
storage = {
|
||
getLength: function() {
|
||
var length = 0;
|
||
$.each(dataset, function() {
|
||
length++;
|
||
});
|
||
return length;
|
||
},
|
||
key: function(index) {
|
||
var key, i = 0;
|
||
$.each(dataset, function(k) {
|
||
if(i === index) {
|
||
key = k;
|
||
return false;
|
||
}
|
||
i++;
|
||
});
|
||
return key;
|
||
},
|
||
removeItem: function(key) {
|
||
delete dataset[key];
|
||
},
|
||
getItem: function(key) {
|
||
return dataset[key];
|
||
},
|
||
setItem: function(key, val) {
|
||
dataset[key] = val;
|
||
},
|
||
clear: function() {
|
||
dataset = {};
|
||
}
|
||
};
|
||
}
|
||
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) {
|
||
var length = this.length();
|
||
for(var i = 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));
|
||
|
||
|
||
/* ========================================================================
|
||
* Bootstrap: tab.js v3.0.0
|
||
* http://twbs.github.com/bootstrap/javascript.html#tabs
|
||
*
|
||
* ZUI: The file has been changed in ZUI. It will not keep update with the
|
||
* Bootsrap version in the future.
|
||
* http://zui.sexy
|
||
* ========================================================================
|
||
* 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') || $this.attr('data-tab')
|
||
|
||
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-tab]', function(e) {
|
||
e.preventDefault()
|
||
$(this).tab('show')
|
||
})
|
||
|
||
}(window.jQuery);
|
||
|
||
|
||
/* ========================================================================
|
||
* Bootstrap: modal.js v3.2.0
|
||
* http://getbootstrap.com/javascript/#modals
|
||
*
|
||
* ZUI: The file has been changed in ZUI. It will not keep update with the
|
||
* Bootsrap version in the future.
|
||
* http://zui.sexy
|
||
* ========================================================================
|
||
* 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) {
|
||
var that = this;
|
||
that.options = options
|
||
that.$body = $(document.body)
|
||
that.$element = $(element)
|
||
that.$backdrop =
|
||
that.isShown = null
|
||
that.scrollbarWidth = 0
|
||
|
||
if(options.moveable === undefined) {
|
||
that.options.moveable = that.$element.hasClass('modal-moveable');
|
||
}
|
||
|
||
if(options.remote) {
|
||
that.$element
|
||
.find('.modal-content')
|
||
.load(options.remote, function() {
|
||
that.$element.trigger('loaded.' + zuiname)
|
||
})
|
||
}
|
||
}
|
||
|
||
Modal.VERSION = '3.2.0'
|
||
|
||
Modal.TRANSITION_DURATION = 300
|
||
Modal.BACKDROP_TRANSITION_DURATION = 150
|
||
|
||
Modal.DEFAULTS = {
|
||
backdrop: true,
|
||
keyboard: true,
|
||
show: true,
|
||
// rememberPos: false,
|
||
// moveable: false,
|
||
position: 'fit' // 'center' or '40px' or '10%'
|
||
};
|
||
|
||
var setDialogPos = function($dialog, pos) {
|
||
var $window = $(window);
|
||
pos.left = Math.max(0, Math.min(pos.left, $window.width() - $dialog.outerWidth()));
|
||
pos.top = Math.max(0, Math.min(pos.top, $window.height() - $dialog.outerHeight()));
|
||
$dialog.css(pos);
|
||
};
|
||
|
||
Modal.prototype.toggle = function(_relatedTarget, position) {
|
||
return this.isShown ? this.hide() : this.show(_relatedTarget, position)
|
||
}
|
||
|
||
Modal.prototype.ajustPosition = function(position) {
|
||
var that = this;
|
||
var options = that.options;
|
||
if(typeof position === 'undefined') position = options.position;
|
||
if(typeof position === 'undefined') return;
|
||
var $dialog = that.$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 = null;
|
||
var rememberPos = options.rememberPos;
|
||
if(rememberPos) {
|
||
if(rememberPos === true) {
|
||
pos = that.$element.data('modal-pos');
|
||
} else if($.zui.store) {
|
||
pos = $.zui.store.pageGet(zuiname + '.rememberPos.' + rememberPos);
|
||
}
|
||
}
|
||
if(!pos) {
|
||
pos = {
|
||
left: Math.max(0, ($(window).width() - $dialog.outerWidth()) / 2),
|
||
top: topPos
|
||
};
|
||
}
|
||
if (options.moveable === 'inside') {
|
||
setDialogPos($dialog, pos);
|
||
} else {
|
||
$dialog.css(pos);
|
||
}
|
||
} else {
|
||
$dialog.css('margin-top', topPos);
|
||
}
|
||
}
|
||
|
||
Modal.prototype.setMoveale = function() {
|
||
if(!$.fn.draggable) console.error('Moveable modal requires draggable.js.');
|
||
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) {
|
||
var rememberPos = options.rememberPos;
|
||
if(rememberPos) {
|
||
that.$element.data('modal-pos', e.pos);
|
||
if($.zui.store && rememberPos !== true) {
|
||
$.zui.store.pageSet(zuiname + '.rememberPos.' + rememberPos, e.pos);
|
||
}
|
||
}
|
||
},
|
||
move: options.moveable === 'inside' ? function (dragPos) {
|
||
setDialogPos($dialog, dragPos);
|
||
} : true
|
||
});
|
||
}
|
||
}
|
||
|
||
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.moveable) 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 = $('<div class="modal-backdrop ' + animate + '" />')
|
||
.appendTo(this.$body)
|
||
|
||
this.$element.on('mousedown.dismiss.' + zuiname, $.proxy(function(e) {
|
||
if(e.target !== e.currentTarget) return
|
||
this.options.backdrop == 'static' ? this.$element[0].focus.call(this.$element[0]) : this.hide.call(this)
|
||
}, this))
|
||
|
||
if(doAnimate) this.$backdrop[0].offsetWidth // force reflow
|
||
|
||
this.$backdrop.addClass('in')
|
||
|
||
if(!callback) return
|
||
|
||
doAnimate ?
|
||
this.$backdrop
|
||
.one('bsTransitionEnd', callback)
|
||
.emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
|
||
callback()
|
||
|
||
} else if(!this.isShown && this.$backdrop) {
|
||
this.$backdrop.removeClass('in')
|
||
|
||
var callbackRemove = function() {
|
||
that.removeBackdrop()
|
||
callback && callback()
|
||
}
|
||
$.support.transition && this.$element.hasClass('fade') ?
|
||
this.$backdrop
|
||
.one('bsTransitionEnd', callbackRemove)
|
||
.emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
|
||
callbackRemove()
|
||
|
||
} else if(callback) {
|
||
callback()
|
||
}
|
||
}
|
||
|
||
Modal.prototype.checkScrollbar = function() {
|
||
if(document.body.clientWidth >= window.innerWidth) return
|
||
this.scrollbarWidth = this.scrollbarWidth || this.measureScrollbar()
|
||
}
|
||
|
||
Modal.prototype.setScrollbar = function() {
|
||
var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
|
||
if(this.scrollbarWidth) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
|
||
}
|
||
|
||
Modal.prototype.resetScrollbar = function() {
|
||
this.$body.css('padding-right', '')
|
||
}
|
||
|
||
Modal.prototype.measureScrollbar = function() { // thx walsh
|
||
var scrollDiv = document.createElement('div')
|
||
scrollDiv.className = 'modal-scrollbar-measure'
|
||
this.$body.append(scrollDiv)
|
||
var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
|
||
this.$body[0].removeChild(scrollDiv)
|
||
return scrollbarWidth
|
||
}
|
||
|
||
|
||
// MODAL PLUGIN DEFINITION
|
||
// =======================
|
||
|
||
function Plugin(option, _relatedTarget, position) {
|
||
return this.each(function() {
|
||
var $this = $(this)
|
||
var data = $this.data(zuiname)
|
||
var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
|
||
|
||
if(!data) $this.data(zuiname, (data = new Modal(this, options)))
|
||
if(typeof option == 'string') data[option](_relatedTarget, position)
|
||
else if(options.show) data.show(_relatedTarget, position)
|
||
})
|
||
}
|
||
|
||
var old = $.fn.modal
|
||
|
||
$.fn.modal = Plugin
|
||
$.fn.modal.Constructor = Modal
|
||
|
||
|
||
// MODAL NO CONFLICT
|
||
// =================
|
||
|
||
$.fn.modal.noConflict = function() {
|
||
$.fn.modal = old
|
||
return this
|
||
}
|
||
|
||
|
||
// MODAL DATA-API
|
||
// ==============
|
||
|
||
$(document).on('click.' + zuiname + '.data-api', '[data-toggle="modal"]', function(e) {
|
||
var $this = $(this)
|
||
var href = $this.attr('href')
|
||
var $target = null
|
||
try {
|
||
// strip for ie7
|
||
$target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, '')));
|
||
} catch(ex) {
|
||
return
|
||
}
|
||
if(!$target.length) return;
|
||
var option = $target.data(zuiname) ? 'toggle' : $.extend({
|
||
remote: !/#/.test(href) && href
|
||
}, $target.data(), $this.data())
|
||
|
||
if($this.is('a')) e.preventDefault()
|
||
|
||
$target.one('show.' + zuiname, function(showEvent) {
|
||
// only register focus restorer if modal will actually get shown
|
||
if(showEvent.isDefaultPrevented()) return
|
||
$target.one('hidden.' + zuiname, function() {
|
||
$this.is(':visible') && $this.trigger('focus')
|
||
})
|
||
})
|
||
Plugin.call($target, option, this, $this.data('position'))
|
||
})
|
||
|
||
}(jQuery);
|
||
|
||
|
||
/* ========================================================================
|
||
* ZUI: modal.trigger.js [1.2.0+]
|
||
* http://zui.sexy
|
||
* ========================================================================
|
||
* Copyright (c) 2014-2016 cnezsoft.com; Licensed MIT
|
||
* ======================================================================== */
|
||
|
||
|
||
(function($, window) {
|
||
'use strict';
|
||
|
||
if(!$.fn.modal) throw new Error('Modal trigger requires modal.js');
|
||
|
||
var NAME = 'zui.modaltrigger',
|
||
STR_AJAX = 'ajax',
|
||
ZUI_MODAL = '.zui.modal',
|
||
STR_STRING = 'string';
|
||
|
||
// MODAL TRIGGER CLASS DEFINITION
|
||
// ======================
|
||
var ModalTrigger = function(options, $trigger) {
|
||
options = $.extend({}, ModalTrigger.DEFAULTS, $.ModalTriggerDefaults, $trigger ? $trigger.data() : null, options);
|
||
this.isShown;
|
||
this.$trigger = $trigger;
|
||
this.options = options;
|
||
this.id = $.zui.uuid();
|
||
};
|
||
|
||
ModalTrigger.DEFAULTS = {
|
||
type: 'custom',
|
||
// width: null, // number, css definition
|
||
// size: null, // 'md', 'sm', 'lg', 'fullscreen'
|
||
height: 'auto',
|
||
// icon: null,
|
||
name: 'triggerModal',
|
||
// className: '',
|
||
fade: true,
|
||
position: 'fit',
|
||
showHeader: true,
|
||
delay: 0,
|
||
// iframeBodyClass: '',
|
||
// onlyIncreaseHeight: false,
|
||
// moveable: false,
|
||
// rememberPos: false,
|
||
backdrop: true,
|
||
keyboard: true,
|
||
waittime: 0,
|
||
loadingIcon: 'icon-spinner-indicator'
|
||
};
|
||
|
||
ModalTrigger.prototype.init = function(options) {
|
||
var that = this;
|
||
if(options.url) {
|
||
if(!options.type || (options.type != STR_AJAX && options.type != 'iframe')) {
|
||
options.type = STR_AJAX;
|
||
}
|
||
}
|
||
if(options.remote) {
|
||
options.type = STR_AJAX;
|
||
if(typeof options.remote === STR_STRING) options.url = options.remote;
|
||
} else if(options.iframe) {
|
||
options.type = 'iframe';
|
||
if(typeof options.iframe === STR_STRING) options.url = options.iframe;
|
||
} else if(options.custom) {
|
||
options.type = 'custom';
|
||
if(typeof options.custom === STR_STRING) {
|
||
var $doms;
|
||
try {
|
||
$doms = $(options.custom);
|
||
} catch(e) {}
|
||
|
||
if($doms && $doms.length) {
|
||
options.custom = $doms;
|
||
} else if($.isFunction(window[options.custom])) {
|
||
options.custom = window[options.custom];
|
||
}
|
||
}
|
||
}
|
||
|
||
var $modal = $('#' + options.name);
|
||
if($modal.length) {
|
||
if(!that.isShown) $modal.off(ZUI_MODAL);
|
||
$modal.remove();
|
||
}
|
||
$modal = $('<div id="' + options.name + '" class="modal modal-trigger ' + (options.className || '') + '">' + (typeof options.loadingIcon === 'string' && options.loadingIcon.indexOf('icon-') === 0 ? ('<div class="icon icon-spin loader ' + options.loadingIcon + '"></div>') : options.loadingIcon) + '<div class="modal-dialog"><div class="modal-content"><div class="modal-header"><button class="close" data-dismiss="modal">×</button><h4 class="modal-title"><i class="modal-icon"></i> <span class="modal-title-name"></span></h4></div><div class="modal-body"></div></div></div></div>').appendTo('body').data(NAME, that);
|
||
|
||
var bindEvent = function(optonName, eventName) {
|
||
var handleFunc = options[optonName];
|
||
if($.isFunction(handleFunc)) $modal.on(eventName + ZUI_MODAL, handleFunc);
|
||
};
|
||
bindEvent('onShow', 'show');
|
||
bindEvent('shown', 'shown');
|
||
bindEvent('onHide', 'hide');
|
||
bindEvent('hidden', 'hidden');
|
||
bindEvent('loaded', 'loaded');
|
||
|
||
$modal.on('shown' + ZUI_MODAL, function() {
|
||
that.isShown = true;
|
||
}).on('hidden' + ZUI_MODAL, function() {
|
||
that.isShown = false;
|
||
});
|
||
|
||
this.$modal = $modal;
|
||
this.$dialog = $modal.find('.modal-dialog');
|
||
|
||
if(options.mergeOptions) this.options = options;
|
||
};
|
||
|
||
ModalTrigger.prototype.show = function(option) {
|
||
var options = $.extend({}, this.options, {url: this.$trigger ? (this.$trigger.attr('href') || this.$trigger.attr('data-url') || this.$trigger.data('url')) : this.options.url}, option);
|
||
this.init(options);
|
||
var that = this,
|
||
$modal = this.$modal,
|
||
$dialog = this.$dialog,
|
||
custom = options.custom;
|
||
var $body = $dialog.find('.modal-body').css('padding', ''),
|
||
$header = $dialog.find('.modal-header'),
|
||
$content = $dialog.find('.modal-content');
|
||
|
||
$modal.toggleClass('fade', options.fade)
|
||
.addClass(options.className)
|
||
.toggleClass('modal-loading', !this.isShown);
|
||
|
||
$dialog.toggleClass('modal-md', options.size === 'md')
|
||
.toggleClass('modal-sm', options.size === 'sm')
|
||
.toggleClass('modal-lg', options.size === 'lg')
|
||
.toggleClass('modal-fullscreen', options.size === 'fullscreen');
|
||
|
||
$header.toggle(options.showHeader);
|
||
$header.find('.modal-icon').attr('class', 'modal-icon icon-' + options.icon);
|
||
$header.find('.modal-title-name').text(options.title || '');
|
||
if(options.size && options.size === 'fullscreen') {
|
||
options.width = '';
|
||
options.height = '';
|
||
}
|
||
|
||
var resizeDialog = function() {
|
||
clearTimeout(this.resizeTask);
|
||
this.resizeTask = setTimeout(function() {
|
||
that.ajustPosition();
|
||
}, 100);
|
||
};
|
||
|
||
var readyToShow = function(delay, callback) {
|
||
if(typeof delay === 'undefined') delay = options.delay;
|
||
return setTimeout(function() {
|
||
$dialog = $modal.find('.modal-dialog');
|
||
if(options.width && options.width != 'auto') {
|
||
$dialog.css('width', options.width);
|
||
}
|
||
if(options.height && options.height != 'auto') {
|
||
$dialog.css('height', options.height);
|
||
if(options.type === 'iframe') $body.css('height', $dialog.height() - $header.outerHeight());
|
||
}
|
||
that.ajustPosition(options.position);
|
||
$modal.removeClass('modal-loading');
|
||
|
||
if(options.type != 'iframe') {
|
||
$dialog.off('resize.' + NAME).on('resize.' + NAME, resizeDialog);
|
||
}
|
||
|
||
callback && callback();
|
||
}, delay);
|
||
};
|
||
|
||
if(options.type === 'custom' && custom) {
|
||
if($.isFunction(custom)) {
|
||
var customContent = custom({
|
||
modal: $modal,
|
||
options: options,
|
||
modalTrigger: that,
|
||
ready: readyToShow
|
||
});
|
||
if(typeof customContent === STR_STRING) {
|
||
$body.html(customContent);
|
||
readyToShow();
|
||
}
|
||
} else if(custom instanceof $) {
|
||
$body.html($('<div>').append(custom.clone()).html());
|
||
readyToShow();
|
||
} else {
|
||
$body.html(custom);
|
||
readyToShow();
|
||
}
|
||
} else if(options.url) {
|
||
var onLoadBroken = function() {
|
||
var brokenContent = $modal.callComEvent(that, 'broken');
|
||
if(brokenContent) {
|
||
$body.html(brokenContent);
|
||
readyToShow();
|
||
}
|
||
};
|
||
|
||
$modal.attr('ref', options.url);
|
||
if(options.type === 'iframe') {
|
||
$modal.addClass('modal-iframe');
|
||
this.firstLoad = true;
|
||
var iframeName = 'iframe-' + options.name;
|
||
$header.detach();
|
||
$body.detach();
|
||
$content.empty().append($header).append($body);
|
||
$body.css('padding', 0)
|
||
.html('<iframe id="' + iframeName + '" name="' + iframeName + '" src="' + options.url + '" frameborder="no" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true" allowtransparency="true" scrolling="auto" style="width: 100%; height: 100%; left: 0px;"></iframe>');
|
||
|
||
if(options.waittime > 0) {
|
||
that.waitTimeout = readyToShow(options.waittime, onLoadBroken);
|
||
}
|
||
|
||
var frame = document.getElementById(iframeName);
|
||
frame.onload = frame.onreadystatechange = function() {
|
||
if(that.firstLoad) $modal.addClass('modal-loading');
|
||
if(this.readyState && this.readyState != 'complete') return;
|
||
that.firstLoad = false;
|
||
|
||
if(options.waittime > 0) {
|
||
clearTimeout(that.waitTimeout);
|
||
}
|
||
|
||
try {
|
||
$modal.attr('ref', frame.contentWindow.location.href);
|
||
var frame$ = window.frames[iframeName].$;
|
||
if(frame$ && options.height === 'auto' && options.size != 'fullscreen') {
|
||
// todo: update iframe url to ref attribute
|
||
var $framebody = frame$('body').addClass('body-modal');
|
||
if(options.iframeBodyClass) $framebody.addClass(options.iframeBodyClass);
|
||
var ajustFrameSize = function(check) {
|
||
$modal.removeClass('fade');
|
||
var height = $framebody.outerHeight();
|
||
if(check === true && options.onlyIncreaseHeight) {
|
||
height = Math.max(height, $body.data('minModalHeight') || 0);
|
||
$body.data('minModalHeight', height);
|
||
}
|
||
$body.css('height', height);
|
||
if(options.fade) $modal.addClass('fade');
|
||
readyToShow();
|
||
};
|
||
|
||
$modal.callComEvent(that, 'loaded', {
|
||
modalType: 'iframe',
|
||
jQuery: frame$
|
||
});
|
||
|
||
setTimeout(ajustFrameSize, 100);
|
||
|
||
$framebody.off('resize.' + NAME).on('resize.' + NAME, resizeDialog);
|
||
} else {
|
||
readyToShow();
|
||
}
|
||
|
||
frame$.extend({
|
||
closeModal: window.closeModal
|
||
});
|
||
} catch(e) {
|
||
readyToShow();
|
||
}
|
||
};
|
||
} else {
|
||
$.ajax($.extend({
|
||
url: options.url,
|
||
success: function(data) {
|
||
try {
|
||
var $data = $(data);
|
||
if($data.hasClass('modal-dialog')) {
|
||
$dialog.replaceWith($data);
|
||
} else if($data.hasClass('modal-content')) {
|
||
$dialog.find('.modal-content').replaceWith($data);
|
||
} else {
|
||
$body.wrapInner($data);
|
||
}
|
||
} catch(e) {
|
||
$modal.html(data);
|
||
}
|
||
$modal.callComEvent(that, 'loaded', {
|
||
modalType: STR_AJAX
|
||
});
|
||
readyToShow();
|
||
},
|
||
error: onLoadBroken
|
||
}, options.ajaxOptions));
|
||
}
|
||
}
|
||
|
||
$modal.modal({
|
||
show : 'show',
|
||
backdrop : options.backdrop,
|
||
moveable : options.moveable,
|
||
rememberPos: options.rememberPos,
|
||
keyboard : options.keyboard
|
||
});
|
||
};
|
||
|
||
ModalTrigger.prototype.close = function(callback, redirect) {
|
||
if(callback || redirect) {
|
||
this.$modal.on('hidden' + ZUI_MODAL, function() {
|
||
if($.isFunction(callback)) callback();
|
||
|
||
if(typeof redirect === STR_STRING) {
|
||
if(redirect === 'this') window.location.reload();
|
||
else window.location = redirect;
|
||
}
|
||
});
|
||
}
|
||
this.$modal.modal('hide');
|
||
};
|
||
|
||
ModalTrigger.prototype.toggle = function(options) {
|
||
if(this.isShown) this.close();
|
||
else this.show(options);
|
||
};
|
||
|
||
ModalTrigger.prototype.ajustPosition = function(position) {
|
||
this.$modal.modal('ajustPosition', position || this.options.position);
|
||
};
|
||
|
||
$.zui({
|
||
ModalTrigger: ModalTrigger,
|
||
modalTrigger: new ModalTrigger()
|
||
});
|
||
|
||
$.fn.modalTrigger = function(option, settings) {
|
||
return $(this).each(function() {
|
||
var $this = $(this);
|
||
var data = $this.data(NAME),
|
||
options = $.extend({
|
||
title: $this.attr('title') || $this.text(),
|
||
url: $this.attr('href'),
|
||
type: $this.hasClass('iframe') ? 'iframe' : ''
|
||
}, $this.data(), $.isPlainObject(option) && option);
|
||
if(!data) $this.data(NAME, (data = new ModalTrigger(options, $this)));
|
||
if(typeof option == STR_STRING) data[option](settings);
|
||
else if(options.show) data.show(settings);
|
||
|
||
$this.on((options.trigger || 'click') + '.toggle.' + NAME, function(e) {
|
||
data.toggle(options);
|
||
if($this.is('a')) e.preventDefault();
|
||
});
|
||
});
|
||
};
|
||
|
||
var old = $.fn.modal;
|
||
$.fn.modal = function(option, settings) {
|
||
return $(this).each(function() {
|
||
var $this = $(this);
|
||
if($this.hasClass('modal')) old.call($this, option, settings);
|
||
else $this.modalTrigger(option, settings);
|
||
});
|
||
};
|
||
|
||
var getModal = function(modal) {
|
||
var modalType = typeof(modal);
|
||
if(modalType === 'undefined') {
|
||
modal = $('.modal.modal-trigger');
|
||
} else if(modalType === STR_STRING) {
|
||
modal = $(modal);
|
||
}
|
||
if(modal && (modal instanceof $)) return modal;
|
||
return null;
|
||
};
|
||
|
||
// callback, redirect, modal
|
||
var closeModal = function(modal, callback, redirect) {
|
||
if($.isFunction(modal)) {
|
||
var oldModal = redirect;
|
||
redirect = callback;
|
||
callback = modal;
|
||
modal = oldModal;
|
||
}
|
||
modal = getModal(modal);
|
||
if(modal && modal.length) {
|
||
modal.each(function() {
|
||
$(this).data(NAME).close(callback, redirect);
|
||
});
|
||
}
|
||
};
|
||
|
||
var ajustModalPosition = function(position, modal) {
|
||
modal = getModal(modal);
|
||
if(modal && modal.length) {
|
||
modal.modal('ajustPosition', position);
|
||
}
|
||
};
|
||
|
||
$.zui({
|
||
closeModal: closeModal,
|
||
ajustModalPosition: ajustModalPosition
|
||
});
|
||
|
||
$(document).on('click.' + NAME + '.data-api', '[data-toggle="modal"]', function(e) {
|
||
var $this = $(this);
|
||
var href = $this.attr('href');
|
||
var $target = null;
|
||
try {
|
||
$target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, '')));
|
||
} catch(ex) {}
|
||
if(!$target || !$target.length) {
|
||
if(!$this.data(NAME)) {
|
||
$this.modalTrigger({
|
||
show: true,
|
||
});
|
||
} else {
|
||
$this.trigger('.toggle.' + NAME);
|
||
}
|
||
}
|
||
if($this.is('a')) {
|
||
e.preventDefault();
|
||
}
|
||
});
|
||
}(window.jQuery, window));
|
||
|
||
|
||
/* ========================================================================
|
||
* Bootstrap: tooltip.js v3.0.0
|
||
* http://twzui.github.com/bootstrap/javascript.html#tooltip
|
||
* Inspired by the original jQuery.tipsy by Jason Frame
|
||
*
|
||
* ZUI: The file has been changed in ZUI. It will not keep update with the
|
||
* Bootsrap version in the future.
|
||
* http://zui.sexy
|
||
* ========================================================================
|
||
* 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';
|
||
|
||
// TOOLTIP PUBLIC CLASS DEFINITION
|
||
// ===============================
|
||
|
||
var Tooltip = function(element, options) {
|
||
this.type = null
|
||
this.options = null
|
||
this.enabled = null
|
||
this.timeout = null
|
||
this.hoverState = null
|
||
this.$element = null
|
||
|
||
this.init('tooltip', element, options)
|
||
}
|
||
|
||
Tooltip.DEFAULTS = {
|
||
animation: true,
|
||
placement: 'top',
|
||
selector: false,
|
||
template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
|
||
trigger: 'hover focus',
|
||
title: '',
|
||
delay: 0,
|
||
html: false,
|
||
container: false
|
||
}
|
||
|
||
Tooltip.prototype.init = function(type, element, options) {
|
||
this.enabled = true
|
||
this.type = type
|
||
this.$element = $(element)
|
||
this.options = this.getOptions(options)
|
||
|
||
var triggers = this.options.trigger.split(' ')
|
||
|
||
for(var i = triggers.length; i--;) {
|
||
var trigger = triggers[i]
|
||
|
||
if(trigger == 'click') {
|
||
this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
|
||
} else if(trigger != 'manual') {
|
||
var eventIn = trigger == 'hover' ? 'mouseenter' : 'focus'
|
||
var eventOut = trigger == 'hover' ? 'mouseleave' : 'blur'
|
||
|
||
this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
|
||
this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
|
||
}
|
||
}
|
||
|
||
this.options.selector ?
|
||
(this._options = $.extend({}, this.options, {
|
||
trigger: 'manual',
|
||
selector: ''
|
||
})) :
|
||
this.fixTitle()
|
||
}
|
||
|
||
Tooltip.prototype.getDefaults = function() {
|
||
return Tooltip.DEFAULTS
|
||
}
|
||
|
||
Tooltip.prototype.getOptions = function(options) {
|
||
options = $.extend({}, this.getDefaults(), this.$element.data(), options)
|
||
|
||
if(options.delay && typeof options.delay == 'number') {
|
||
options.delay = {
|
||
show: options.delay,
|
||
hide: options.delay
|
||
}
|
||
}
|
||
|
||
return options
|
||
}
|
||
|
||
Tooltip.prototype.getDelegateOptions = function() {
|
||
var options = {}
|
||
var defaults = this.getDefaults()
|
||
|
||
this._options && $.each(this._options, function(key, value) {
|
||
if(defaults[key] != value) options[key] = value
|
||
})
|
||
|
||
return options
|
||
}
|
||
|
||
Tooltip.prototype.enter = function(obj) {
|
||
var self = obj instanceof this.constructor ?
|
||
obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('zui.' + this.type)
|
||
|
||
clearTimeout(self.timeout)
|
||
|
||
self.hoverState = 'in'
|
||
|
||
if(!self.options.delay || !self.options.delay.show) return self.show()
|
||
|
||
self.timeout = setTimeout(function() {
|
||
if(self.hoverState == 'in') self.show()
|
||
}, self.options.delay.show)
|
||
}
|
||
|
||
Tooltip.prototype.leave = function(obj) {
|
||
var self = obj instanceof this.constructor ?
|
||
obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('zui.' + this.type)
|
||
|
||
clearTimeout(self.timeout)
|
||
|
||
self.hoverState = 'out'
|
||
|
||
if(!self.options.delay || !self.options.delay.hide) return self.hide()
|
||
|
||
self.timeout = setTimeout(function() {
|
||
if(self.hoverState == 'out') self.hide()
|
||
}, self.options.delay.hide)
|
||
}
|
||
|
||
Tooltip.prototype.show = function(content) {
|
||
var e = $.Event('show.zui.' + this.type)
|
||
|
||
if((content || this.hasContent()) && this.enabled) {
|
||
var that = this
|
||
that.$element.trigger(e)
|
||
|
||
if(e.isDefaultPrevented()) return
|
||
|
||
var $tip = that.tip()
|
||
|
||
that.setContent(content)
|
||
|
||
if(that.options.animation) $tip.addClass('fade')
|
||
|
||
var placement = typeof that.options.placement == 'function' ?
|
||
that.options.placement.call(that, $tip[0], that.$element[0]) :
|
||
that.options.placement
|
||
|
||
var autoToken = /\s?auto?\s?/i
|
||
var autoPlace = autoToken.test(placement)
|
||
if(autoPlace) placement = placement.replace(autoToken, '') || 'top'
|
||
|
||
$tip
|
||
.detach()
|
||
.css({
|
||
top: 0,
|
||
left: 0,
|
||
display: 'block'
|
||
})
|
||
.addClass(placement)
|
||
|
||
that.options.container ? $tip.appendTo(that.options.container) : $tip.insertAfter(that.$element)
|
||
|
||
var pos = that.getPosition()
|
||
var actualWidth = $tip[0].offsetWidth
|
||
var actualHeight = $tip[0].offsetHeight
|
||
|
||
if(autoPlace) {
|
||
var $parent = that.$element.parent()
|
||
|
||
var orgPlacement = placement
|
||
var docScroll = document.documentElement.scrollTop || document.body.scrollTop
|
||
var parentWidth = that.options.container == 'body' ? window.innerWidth : $parent.outerWidth()
|
||
var parentHeight = that.options.container == 'body' ? window.innerHeight : $parent.outerHeight()
|
||
var parentLeft = that.options.container == 'body' ? 0 : $parent.offset().left
|
||
|
||
placement = placement == 'bottom' && pos.top + pos.height + actualHeight - docScroll > parentHeight ? 'top' :
|
||
placement == 'top' && pos.top - docScroll - actualHeight < 0 ? 'bottom' :
|
||
placement == 'right' && pos.right + actualWidth > parentWidth ? 'left' :
|
||
placement == 'left' && pos.left - actualWidth < parentLeft ? 'right' :
|
||
placement
|
||
|
||
$tip
|
||
.removeClass(orgPlacement)
|
||
.addClass(placement)
|
||
}
|
||
|
||
var calculatedOffset = that.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
|
||
|
||
that.applyPlacement(calculatedOffset, placement)
|
||
var complete = function () {
|
||
var prevHoverState = that.hoverState
|
||
that.$element.trigger('shown.zui.' + that.type)
|
||
that.hoverState = null
|
||
|
||
if (prevHoverState == 'out') that.leave(that)
|
||
}
|
||
|
||
$.support.transition && that.$tip.hasClass('fade') ?
|
||
$tip
|
||
.one('bsTransitionEnd', complete)
|
||
.emulateTransitionEnd(150) :
|
||
complete()
|
||
}
|
||
}
|
||
|
||
Tooltip.prototype.applyPlacement = function(offset, placement) {
|
||
var replace
|
||
var $tip = this.tip()
|
||
var width = $tip[0].offsetWidth
|
||
var height = $tip[0].offsetHeight
|
||
|
||
// manually read margins because getBoundingClientRect includes difference
|
||
var marginTop = parseInt($tip.css('margin-top'), 10)
|
||
var marginLeft = parseInt($tip.css('margin-left'), 10)
|
||
|
||
// we must check for NaN for ie 8/9
|
||
if(isNaN(marginTop)) marginTop = 0
|
||
if(isNaN(marginLeft)) marginLeft = 0
|
||
|
||
offset.top = offset.top + marginTop
|
||
offset.left = offset.left + marginLeft
|
||
|
||
$tip
|
||
.offset(offset)
|
||
.addClass('in')
|
||
|
||
// check to see if placing tip in new offset caused the tip to resize itself
|
||
var actualWidth = $tip[0].offsetWidth
|
||
var actualHeight = $tip[0].offsetHeight
|
||
|
||
if(placement == 'top' && actualHeight != height) {
|
||
replace = true
|
||
offset.top = offset.top + height - actualHeight
|
||
}
|
||
|
||
if(/bottom|top/.test(placement)) {
|
||
var delta = 0
|
||
|
||
if(offset.left < 0) {
|
||
delta = offset.left * -2
|
||
offset.left = 0
|
||
|
||
$tip.offset(offset)
|
||
|
||
actualWidth = $tip[0].offsetWidth
|
||
actualHeight = $tip[0].offsetHeight
|
||
}
|
||
|
||
this.replaceArrow(delta - width + actualWidth, actualWidth, 'left')
|
||
} else {
|
||
this.replaceArrow(actualHeight - height, actualHeight, 'top')
|
||
}
|
||
|
||
if(replace) $tip.offset(offset)
|
||
}
|
||
|
||
Tooltip.prototype.replaceArrow = function(delta, dimension, position) {
|
||
this.arrow().css(position, delta ? (50 * (1 - delta / dimension) + "%") : '')
|
||
}
|
||
|
||
Tooltip.prototype.setContent = function(content) {
|
||
var $tip = this.tip()
|
||
var title = content || this.getTitle()
|
||
|
||
if(this.options.tipId) $tip.attr('id', this.options.tipId)
|
||
if(this.options.tipClass) $tip.addClass(this.options.tipClass)
|
||
|
||
$tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
|
||
$tip.removeClass('fade in top bottom left right')
|
||
}
|
||
|
||
Tooltip.prototype.hide = function() {
|
||
var that = this
|
||
var $tip = this.tip()
|
||
var e = $.Event('hide.zui.' + this.type)
|
||
|
||
function complete() {
|
||
if(that.hoverState != 'in') $tip.detach()
|
||
}
|
||
|
||
this.$element.trigger(e)
|
||
|
||
if(e.isDefaultPrevented()) return
|
||
|
||
$tip.removeClass('in')
|
||
|
||
$.support.transition && this.$tip.hasClass('fade') ?
|
||
$tip
|
||
.one($.support.transition.end, complete)
|
||
.emulateTransitionEnd(150) :
|
||
complete()
|
||
|
||
this.$element.trigger('hidden.zui.' + this.type)
|
||
|
||
return this
|
||
}
|
||
|
||
Tooltip.prototype.fixTitle = function() {
|
||
var $e = this.$element
|
||
if($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
|
||
$e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
|
||
}
|
||
}
|
||
|
||
Tooltip.prototype.hasContent = function() {
|
||
return this.getTitle()
|
||
}
|
||
|
||
Tooltip.prototype.getPosition = function() {
|
||
var el = this.$element[0]
|
||
return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : {
|
||
width: el.offsetWidth,
|
||
height: el.offsetHeight
|
||
}, this.$element.offset())
|
||
}
|
||
|
||
Tooltip.prototype.getCalculatedOffset = function(placement, pos, actualWidth, actualHeight) {
|
||
return placement == 'bottom' ? {
|
||
top: pos.top + pos.height,
|
||
left: pos.left + pos.width / 2 - actualWidth / 2
|
||
} :
|
||
placement == 'top' ? {
|
||
top: pos.top - actualHeight,
|
||
left: pos.left + pos.width / 2 - actualWidth / 2
|
||
} :
|
||
placement == 'left' ? {
|
||
top: pos.top + pos.height / 2 - actualHeight / 2,
|
||
left: pos.left - actualWidth
|
||
} :
|
||
/* placement == 'right' */
|
||
{
|
||
top: pos.top + pos.height / 2 - actualHeight / 2,
|
||
left: pos.left + pos.width
|
||
}
|
||
}
|
||
|
||
Tooltip.prototype.getTitle = function() {
|
||
var title
|
||
var $e = this.$element
|
||
var o = this.options
|
||
|
||
title = $e.attr('data-original-title') || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
|
||
|
||
return title
|
||
}
|
||
|
||
Tooltip.prototype.tip = function() {
|
||
return this.$tip = this.$tip || $(this.options.template)
|
||
}
|
||
|
||
Tooltip.prototype.arrow = function() {
|
||
return this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')
|
||
}
|
||
|
||
Tooltip.prototype.validate = function() {
|
||
if(!this.$element[0].parentNode) {
|
||
this.hide()
|
||
this.$element = null
|
||
this.options = null
|
||
}
|
||
}
|
||
|
||
Tooltip.prototype.enable = function() {
|
||
this.enabled = true
|
||
}
|
||
|
||
Tooltip.prototype.disable = function() {
|
||
this.enabled = false
|
||
}
|
||
|
||
Tooltip.prototype.toggleEnabled = function() {
|
||
this.enabled = !this.enabled
|
||
}
|
||
|
||
Tooltip.prototype.toggle = function(e) {
|
||
var self = e ? $(e.currentTarget)[this.type](this.getDelegateOptions()).data('zui.' + this.type) : this
|
||
self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
|
||
}
|
||
|
||
Tooltip.prototype.destroy = function() {
|
||
this.hide().$element.off('.' + this.type).removeData('zui.' + this.type)
|
||
}
|
||
|
||
|
||
// TOOLTIP PLUGIN DEFINITION
|
||
// =========================
|
||
|
||
var old = $.fn.tooltip
|
||
|
||
$.fn.tooltip = function(option, params) {
|
||
return this.each(function() {
|
||
var $this = $(this)
|
||
var data = $this.data('zui.tooltip')
|
||
var options = typeof option == 'object' && option
|
||
|
||
if(!data) $this.data('zui.tooltip', (data = new Tooltip(this, options)))
|
||
if(typeof option == 'string') data[option](params)
|
||
})
|
||
}
|
||
|
||
$.fn.tooltip.Constructor = Tooltip
|
||
|
||
|
||
// TOOLTIP NO CONFLICT
|
||
// ===================
|
||
|
||
$.fn.tooltip.noConflict = function() {
|
||
$.fn.tooltip = old
|
||
return this
|
||
}
|
||
|
||
}(window.jQuery);
|
||
|
||
|
||
/* ========================================================================
|
||
* Bootstrap: popover.js v3.0.0
|
||
* http://twbs.github.com/bootstrap/javascript.html#popovers
|
||
*
|
||
* ZUI: The file has been changed in ZUI. It will not keep update with the
|
||
* Bootsrap version in the future.
|
||
* http://zui.sexy
|
||
* ========================================================================
|
||
* 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';
|
||
|
||
// POPOVER PUBLIC CLASS DEFINITION
|
||
// ===============================
|
||
|
||
var Popover = function(element, options) {
|
||
this.init('popover', element, options)
|
||
}
|
||
|
||
if(!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
|
||
|
||
Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
|
||
placement: 'right',
|
||
trigger: 'click',
|
||
content: '',
|
||
template: '<div class="popover"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
|
||
})
|
||
|
||
|
||
// NOTE: POPOVER EXTENDS tooltip.js
|
||
// ================================
|
||
|
||
Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
|
||
|
||
Popover.prototype.constructor = Popover
|
||
|
||
Popover.prototype.getDefaults = function() {
|
||
return Popover.DEFAULTS
|
||
}
|
||
|
||
Popover.prototype.setContent = function() {
|
||
var $tip = this.tip()
|
||
var target = this.getTarget()
|
||
|
||
if(target) {
|
||
if(target.find('.arrow').length < 1)
|
||
$tip.addClass('no-arrow')
|
||
$tip.html(target.html())
|
||
return
|
||
}
|
||
|
||
var title = this.getTitle()
|
||
var content = this.getContent()
|
||
|
||
$tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
|
||
$tip.find('.popover-content')[this.options.html ? 'html' : 'text'](content)
|
||
|
||
$tip.removeClass('fade top bottom left right in')
|
||
|
||
if(this.options.tipId) $tip.attr('id', this.options.tipId)
|
||
if(this.options.tipClass) $tip.addClass(this.options.tipClass)
|
||
|
||
// IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
|
||
// this manually by checking the contents.
|
||
if(!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
|
||
}
|
||
|
||
Popover.prototype.hasContent = function() {
|
||
return this.getTarget() || this.getTitle() || this.getContent()
|
||
}
|
||
|
||
Popover.prototype.getContent = function() {
|
||
var $e = this.$element
|
||
var o = this.options
|
||
|
||
return $e.attr('data-content') || (typeof o.content == 'function' ?
|
||
o.content.call($e[0]) :
|
||
o.content)
|
||
}
|
||
|
||
Popover.prototype.getTarget = function() {
|
||
var $e = this.$element
|
||
var o = this.options
|
||
|
||
var target = $e.attr('data-target') || (typeof o.target == 'function' ?
|
||
o.target.call($e[0]) :
|
||
o.target)
|
||
return(target && true) ? (target == '$next' ? $e.next('.popover') : $(target)) : false
|
||
}
|
||
|
||
Popover.prototype.arrow = function() {
|
||
return this.$arrow = this.$arrow || this.tip().find('.arrow')
|
||
}
|
||
|
||
Popover.prototype.tip = function() {
|
||
if(!this.$tip) this.$tip = $(this.options.template)
|
||
return this.$tip
|
||
}
|
||
|
||
|
||
// POPOVER PLUGIN DEFINITION
|
||
// =========================
|
||
|
||
var old = $.fn.popover
|
||
|
||
$.fn.popover = function(option) {
|
||
return this.each(function() {
|
||
var $this = $(this)
|
||
var data = $this.data('zui.popover')
|
||
var options = typeof option == 'object' && option
|
||
|
||
if(!data) $this.data('zui.popover', (data = new Popover(this, options)))
|
||
if(typeof option == 'string') data[option]()
|
||
})
|
||
}
|
||
|
||
$.fn.popover.Constructor = Popover
|
||
|
||
|
||
// POPOVER NO CONFLICT
|
||
// ===================
|
||
|
||
$.fn.popover.noConflict = function() {
|
||
$.fn.popover = old
|
||
return this
|
||
}
|
||
|
||
}(window.jQuery);
|
||
|
||
|
||
/* ========================================================================
|
||
* Bootstrap: dropdown.js v3.0.0
|
||
* http://twbs.github.com/bootstrap/javascript.html#dropdowns
|
||
*
|
||
* ZUI: The file has been changed in ZUI. It will not keep update with the
|
||
* Bootsrap version in the future.
|
||
* http://zui.sexy
|
||
* ========================================================================
|
||
* 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';
|
||
|
||
// DROPDOWN CLASS DEFINITION
|
||
// =========================
|
||
|
||
var zuiname = 'zui.dropdown';
|
||
var backdrop = '.dropdown-backdrop'
|
||
var toggle = '[data-toggle=dropdown]'
|
||
var Dropdown = function(element) {
|
||
var $el = $(element).on('click.' + zuiname, this.toggle)
|
||
}
|
||
|
||
Dropdown.prototype.toggle = function(e) {
|
||
var $this = $(this)
|
||
|
||
if($this.is('.disabled, :disabled')) return
|
||
|
||
var $parent = getParent($this)
|
||
var isActive = $parent.hasClass('open')
|
||
|
||
clearMenus()
|
||
|
||
if(!isActive) {
|
||
if('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
|
||
// if mobile we we use a backdrop because click events don't delegate
|
||
$('<div class="dropdown-backdrop"/>').insertAfter($(this)).on('click', clearMenus)
|
||
}
|
||
|
||
$parent.trigger(e = $.Event('show.' + zuiname))
|
||
|
||
if(e.isDefaultPrevented()) return
|
||
|
||
$parent
|
||
.toggleClass('open')
|
||
.trigger('shown.' + zuiname)
|
||
|
||
$this.focus()
|
||
}
|
||
|
||
return false
|
||
}
|
||
|
||
Dropdown.prototype.keydown = function(e) {
|
||
if(!/(38|40|27)/.test(e.keyCode)) return
|
||
|
||
var $this = $(this)
|
||
|
||
e.preventDefault()
|
||
e.stopPropagation()
|
||
|
||
if($this.is('.disabled, :disabled')) return
|
||
|
||
var $parent = getParent($this)
|
||
var isActive = $parent.hasClass('open')
|
||
|
||
if(!isActive || (isActive && e.keyCode == 27)) {
|
||
if(e.which == 27) $parent.find(toggle).focus()
|
||
return $this.click()
|
||
}
|
||
|
||
var $items = $('[role=menu] li:not(.divider):visible a', $parent)
|
||
|
||
if(!$items.length) return
|
||
|
||
var index = $items.index($items.filter(':focus'))
|
||
|
||
if(e.keyCode == 38 && index > 0) index-- // up
|
||
if(e.keyCode == 40 && index < $items.length - 1) index++ // down
|
||
if(!~index) index = 0
|
||
|
||
$items.eq(index).focus()
|
||
}
|
||
|
||
function clearMenus() {
|
||
$(backdrop).remove()
|
||
$(toggle).each(function(e) {
|
||
var $parent = getParent($(this))
|
||
if(!$parent.hasClass('open')) return
|
||
$parent.trigger(e = $.Event('hide.' + zuiname))
|
||
if(e.isDefaultPrevented()) return
|
||
$parent.removeClass('open').trigger('hidden.' + zuiname)
|
||
})
|
||
}
|
||
|
||
function getParent($this) {
|
||
var selector = $this.attr('data-target')
|
||
|
||
if(!selector) {
|
||
selector = $this.attr('href')
|
||
selector = selector && /#/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
|
||
}
|
||
var $parent;
|
||
try {
|
||
$parent = selector && $(selector);
|
||
} catch(e) {}
|
||
return $parent && $parent.length ? $parent : $this.parent()
|
||
}
|
||
|
||
|
||
// DROPDOWN PLUGIN DEFINITION
|
||
// ==========================
|
||
|
||
var old = $.fn.dropdown
|
||
|
||
$.fn.dropdown = function(option) {
|
||
return this.each(function() {
|
||
var $this = $(this)
|
||
var data = $this.data('dropdown')
|
||
|
||
if(!data) $this.data('dropdown', (data = new Dropdown(this)))
|
||
if(typeof option == 'string') data[option].call($this)
|
||
})
|
||
}
|
||
|
||
$.fn.dropdown.Constructor = Dropdown
|
||
|
||
|
||
// DROPDOWN NO CONFLICT
|
||
// ====================
|
||
|
||
$.fn.dropdown.noConflict = function() {
|
||
$.fn.dropdown = old
|
||
return this
|
||
}
|
||
|
||
|
||
// APPLY TO STANDARD DROPDOWN ELEMENTS
|
||
// ===================================
|
||
|
||
var apiName = zuiname + '.data-api'
|
||
$(document)
|
||
.on('click.' + apiName, clearMenus)
|
||
.on('click.' + apiName, '.dropdown form', function(e) {
|
||
e.stopPropagation()
|
||
})
|
||
.on('click.' + apiName, toggle, Dropdown.prototype.toggle)
|
||
.on('keydown.' + apiName, toggle + ', [role=menu]', Dropdown.prototype.keydown)
|
||
|
||
}(window.jQuery);
|
||
|
||
|
||
/* ========================================================================
|
||
* Bootstrap: carousel.js v3.0.0
|
||
* http://twzui.github.com/bootstrap/javascript.html#carousel
|
||
*
|
||
* ZUI: The file has been changed in ZUI. It will not keep update with the
|
||
* Bootsrap version in the future.
|
||
* http://zui.sexy
|
||
* ========================================================================
|
||
* 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.
|
||
* ========================================================================
|
||
* Updates in ZUI:
|
||
* 1. support touch event for touchable devices
|
||
* ======================================================================== */
|
||
|
||
|
||
+ function($) {
|
||
'use strict';
|
||
|
||
// CAROUSEL CLASS DEFINITION
|
||
// =========================
|
||
|
||
var Carousel = function(element, options) {
|
||
this.$element = $(element)
|
||
this.$indicators = this.$element.find('.carousel-indicators')
|
||
this.options = options
|
||
this.paused =
|
||
this.sliding =
|
||
this.interval =
|
||
this.$active =
|
||
this.$items = null
|
||
|
||
this.options.pause == 'hover' && this.$element
|
||
.on('mouseenter', $.proxy(this.pause, this))
|
||
.on('mouseleave', $.proxy(this.cycle, this))
|
||
}
|
||
|
||
Carousel.DEFAULTS = {
|
||
interval: 5000,
|
||
pause: 'hover',
|
||
wrap: true,
|
||
touchable: true
|
||
}
|
||
|
||
Carousel.prototype.touchable = function() {
|
||
if(!this.options.touchable) return;
|
||
|
||
this.$element.on('touchstart touchmove touchend', touch);
|
||
var touchStartX, touchStartY;
|
||
var that = this;
|
||
|
||
/* listen the touch event */
|
||
function touch(event) {
|
||
var event = event || window.event;
|
||
if(event.originalEvent) event = event.originalEvent;
|
||
var carousel = $(this);
|
||
|
||
switch(event.type) {
|
||
case "touchstart":
|
||
touchStartX = event.touches[0].pageX;
|
||
touchStartY = event.touches[0].pageY;
|
||
break;
|
||
case "touchend":
|
||
var distanceX = event.changedTouches[0].pageX - touchStartX;
|
||
var distanceY = event.changedTouches[0].pageY - touchStartY;
|
||
if(Math.abs(distanceX) > Math.abs(distanceY)) {
|
||
handleCarousel(carousel, distanceX);
|
||
if(Math.abs(distanceX) > 10) {
|
||
event.preventDefault();
|
||
}
|
||
} else {
|
||
var $w = $(window);
|
||
$('body,html').animate({
|
||
scrollTop: $w.scrollTop() - distanceY
|
||
}, 400)
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
function handleCarousel(carousel, distance) {
|
||
if(distance > 10) that.prev();
|
||
else if(distance < -10) that.next();
|
||
}
|
||
}
|
||
|
||
Carousel.prototype.cycle = function(e) {
|
||
e || (this.paused = false)
|
||
|
||
this.interval && clearInterval(this.interval)
|
||
|
||
this.options.interval && !this.paused && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
|
||
|
||
return this
|
||
}
|
||
|
||
Carousel.prototype.getActiveIndex = function() {
|
||
this.$active = this.$element.find('.item.active')
|
||
this.$items = this.$active.parent().children()
|
||
|
||
return this.$items.index(this.$active)
|
||
}
|
||
|
||
Carousel.prototype.to = function(pos) {
|
||
var that = this
|
||
var activeIndex = this.getActiveIndex()
|
||
|
||
if(pos > (this.$items.length - 1) || pos < 0) return
|
||
|
||
if(this.sliding) return this.$element.one('slid', function() {
|
||
that.to(pos)
|
||
})
|
||
if(activeIndex == pos) return this.pause().cycle()
|
||
|
||
return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos]))
|
||
}
|
||
|
||
Carousel.prototype.pause = function(e) {
|
||
e || (this.paused = true)
|
||
|
||
if(this.$element.find('.next, .prev').length && $.support.transition.end) {
|
||
this.$element.trigger($.support.transition.end)
|
||
this.cycle(true)
|
||
}
|
||
|
||
this.interval = clearInterval(this.interval)
|
||
|
||
return this
|
||
}
|
||
|
||
Carousel.prototype.next = function() {
|
||
if(this.sliding) return
|
||
return this.slide('next')
|
||
}
|
||
|
||
Carousel.prototype.prev = function() {
|
||
if(this.sliding) return
|
||
return this.slide('prev')
|
||
}
|
||
|
||
Carousel.prototype.slide = function(type, next) {
|
||
var $active = this.$element.find('.item.active')
|
||
var $next = next || $active[type]()
|
||
var isCycling = this.interval
|
||
var direction = type == 'next' ? 'left' : 'right'
|
||
var fallback = type == 'next' ? 'first' : 'last'
|
||
var that = this
|
||
|
||
if(!$next.length) {
|
||
if(!this.options.wrap) return
|
||
$next = this.$element.find('.item')[fallback]()
|
||
}
|
||
|
||
this.sliding = true
|
||
|
||
isCycling && this.pause()
|
||
|
||
var e = $.Event('slide.zui.carousel', {
|
||
relatedTarget: $next[0],
|
||
direction: direction
|
||
})
|
||
|
||
if($next.hasClass('active')) return
|
||
|
||
if(this.$indicators.length) {
|
||
this.$indicators.find('.active').removeClass('active')
|
||
this.$element.one('slid', function() {
|
||
var $nextIndicator = $(that.$indicators.children()[that.getActiveIndex()])
|
||
$nextIndicator && $nextIndicator.addClass('active')
|
||
})
|
||
}
|
||
|
||
if($.support.transition && this.$element.hasClass('slide')) {
|
||
this.$element.trigger(e)
|
||
if(e.isDefaultPrevented()) return
|
||
$next.addClass(type)
|
||
$next[0].offsetWidth // force reflow
|
||
$active.addClass(direction)
|
||
$next.addClass(direction)
|
||
$active
|
||
.one($.support.transition.end, function() {
|
||
$next.removeClass([type, direction].join(' ')).addClass('active')
|
||
$active.removeClass(['active', direction].join(' '))
|
||
that.sliding = false
|
||
setTimeout(function() {
|
||
that.$element.trigger('slid')
|
||
}, 0)
|
||
})
|
||
.emulateTransitionEnd(600)
|
||
} else {
|
||
this.$element.trigger(e)
|
||
if(e.isDefaultPrevented()) return
|
||
$active.removeClass('active')
|
||
$next.addClass('active')
|
||
this.sliding = false
|
||
this.$element.trigger('slid')
|
||
}
|
||
|
||
isCycling && this.cycle()
|
||
|
||
return this
|
||
}
|
||
|
||
|
||
// CAROUSEL PLUGIN DEFINITION
|
||
// ==========================
|
||
|
||
var old = $.fn.carousel
|
||
|
||
$.fn.carousel = function(option) {
|
||
return this.each(function() {
|
||
var $this = $(this)
|
||
var data = $this.data('zui.carousel')
|
||
var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
|
||
var action = typeof option == 'string' ? option : options.slide
|
||
|
||
if(!data) $this.data('zui.carousel', (data = new Carousel(this, options)))
|
||
if(typeof option == 'number') data.to(option)
|
||
else if(action) data[action]()
|
||
else if(options.interval) data.pause().cycle()
|
||
|
||
if(options.touchable) data.touchable()
|
||
})
|
||
}
|
||
|
||
$.fn.carousel.Constructor = Carousel
|
||
|
||
|
||
// CAROUSEL NO CONFLICT
|
||
// ====================
|
||
|
||
$.fn.carousel.noConflict = function() {
|
||
$.fn.carousel = old
|
||
return this
|
||
}
|
||
|
||
|
||
// CAROUSEL DATA-API
|
||
// =================
|
||
|
||
$(document).on('click.zui.carousel.data-api', '[data-slide], [data-slide-to]', function(e) {
|
||
var $this = $(this),
|
||
href
|
||
var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
|
||
var options = $.extend({}, $target.data(), $this.data())
|
||
var slideIndex = $this.attr('data-slide-to')
|
||
if(slideIndex) options.interval = false
|
||
|
||
$target.carousel(options)
|
||
|
||
if(slideIndex = $this.attr('data-slide-to')) {
|
||
$target.data('zui.carousel').to(slideIndex)
|
||
}
|
||
|
||
e.preventDefault()
|
||
})
|
||
|
||
$(window).on('load', function() {
|
||
$('[data-ride="carousel"]').each(function() {
|
||
var $carousel = $(this)
|
||
$carousel.carousel($carousel.data())
|
||
})
|
||
})
|
||
|
||
}(window.jQuery);
|
||
|