lxy-kit/root/res/zui/js/zui.lite.js
2019-03-13 16:03:59 +08:00

3440 lines
110 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*!
* 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);