zui
Version:
一个基于 Bootstrap 深度定制开源前端实践方案,帮助你快速构建现代跨屏应用。
1,551 lines (1,281 loc) • 220 kB
JavaScript
/*!
* ZUI: Standard edition - v1.9.0 - 2019-03-04
* http://zui.sexy
* GitHub: https://github.com/easysoft/zui.git
* Copyright (c) 2019 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(asNumber) {
var uuidNumber = (new Date()).getTime() * 1000 + (lastUuidAmend++) % 1000;
return asNumber ? uuidNumber : uuidNumber.toString(36);
},
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: button.js v3.0.3
* http://getbootstrap.com/javascript/#buttons
*
* 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';
// BUTTON PUBLIC CLASS DEFINITION
// ==============================
var Button = function(element, options) {
this.$element = $(element)
this.options = $.extend({}, Button.DEFAULTS, options)
this.isLoading = false
}
Button.DEFAULTS = {
loadingText: 'loading...'
}
Button.prototype.setState = function(state) {
var d = 'disabled'
var $el = this.$element
var val = $el.is('input') ? 'val' : 'html'
var data = $el.data()
state = state + 'Text'
if(!data.resetText) $el.data('resetText', $el[val]())
$el[val](data[state] || this.options[state])
// push to event loop to allow forms to submit
setTimeout($.proxy(function() {
if(state == 'loadingText') {
this.isLoading = true
$el.addClass(d).attr(d, d)
} else if(this.isLoading) {
this.isLoading = false
$el.removeClass(d).removeAttr(d)
}
}, this), 0)
}
Button.prototype.toggle = function() {
var changed = true
var $parent = this.$element.closest('[data-toggle="buttons"]')
if($parent.length) {
var $input = this.$element.find('input')
if($input.prop('type') == 'radio') {
if($input.prop('checked') && this.$element.hasClass('active')) changed = false
else $parent.find('.active').removeClass('active')
}
if(changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change')
}
if(changed) this.$element.toggleClass('active')
}
// BUTTON PLUGIN DEFINITION
// ========================
var old = $.fn.button
$.fn.button = function(option) {
return this.each(function() {
var $this = $(this)
var data = $this.data('zui.button')
var options = typeof option == 'object' && option
if(!data) $this.data('zui.button', (data = new Button(this, options)))
if(option == 'toggle') data.toggle()
else if(option) data.setState(option)
})
}
$.fn.button.Constructor = Button
// BUTTON NO CONFLICT
// ==================
$.fn.button.noConflict = function() {
$.fn.button = old
return this
}
// BUTTON DATA-API
// ===============
$(document).on('click.zui.button.data-api', '[data-toggle^=button]', function(e) {
var $btn = $(e.target)
if(!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
$btn.button('toggle')
e.preventDefault()
})
}(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);
/* ========================================================================
* ZUI: pager.js
* http://zui.sexy
* ========================================================================
* Copyright (c) 2017-2018 cnezsoft.com; Licensed MIT
* ======================================================================== */
(function($, undefined) {
'use strict';
var NAME = 'zui.pager'; // model name
var DEFAULT_PAGER = {
page: 1, // current page index
recTotal: 0, // records total count
recPerPage: 10, // records count per page
};
var LANG = {
zh_cn: {
pageOfText: '第 {0} 页',
prev: '上一页',
next: '下一页',
first: '第一页',
last: '最后一页',
goto: '跳转',
pageOf: '第 <strong>{page}</strong> 页',
totalPage: '共 <strong>{totalPage}</strong> 页',
totalCount: '共 <strong>{recTotal}</strong> 项',
pageSize: '每页 <strong>{recPerPage}</strong> 项',
itemsRange: '第 <strong>{start}</strong> ~ <strong>{end}</strong> 项',
pageOfTotal: '第 <strong>{page}</strong>/<strong>{totalPage}</strong> 页'
},
zh_tw: {
pageOfText: '第 {0} 頁',
prev: '上一頁',
next: '下一頁',
first: '第一頁',
last: '最後一頁',
goto: '跳轉',
pageOf: '第 <strong>{page}</strong> 頁',
totalPage: '共 <strong>{totalPage}</strong> 頁',
totalCount: '共 <strong>{recTotal}</strong> 項',
pageSize: '每頁 <strong>{recPerPage}</strong> 項',
itemsRange: '第 <strong>{start}</strong> ~ <strong>{end}</strong> 項',
pageOfTotal: '第 <strong>{page}</strong>/<strong>{totalPage}</strong> 頁'
},
en: {
pageOfText: 'Page {0}',
prev: 'Prev',
next: 'Next',
first: 'First',
last: 'Last',
goto: 'Goto',
pageOf: 'Page <strong>{page}</strong>',
totalPage: '<strong>{totalPage}</strong> pages',
totalCount: '<strong>{recTotal}</strong> in total',
pageSize: '<strong>{recPerPage}</strong> per page',
itemsRange: 'From <strong>{start}</strong> to <strong>{end}</strong>',
pageOfTotal: 'Page <strong>{page}</strong> of <strong>{totalPage}</strong>'
}
};
// The pager model class
var Pager = function(element, options) {
var that = this;
that.name = NAME;
that.$ = $(element);
options = that.options = $.extend({}, Pager.DEFAULTS, this.$.data(), options);
var lang = options.lang || $.zui.clientLang();
that.lang = $.isPlainObject(lang) ? ($.extend(true, {}, LANG[lang.lang || $.zui.clientLang()], lang)) : LANG[lang];
that.state = {};
that.set(options.page, options.recTotal, options.recPerPage, true);
that.$.on('click', '.pager-goto-btn', function() {
var $goto = $(this).closest('.pager-goto');
var page = parseInt($goto.find('.pager-goto-input').val());
if (page !== NaN) {
that.set(page);
}
}).on('click', '.pager-item', function() {
var page = $(this).data('page');
if (typeof page === 'number' && page > 0) {
that.set(page);
}
}).on('click', '.pager-size-menu [data-size]', function() {
var size = $(this).data('size');
if (typeof size === 'number' && size > 0) {
that.set(-1, -1, size);
}
});
};
Pager.prototype.set = function(page, recTotal, recPerPage, notTiggerChange) {
var that = this;
if (typeof page === 'object' && page !== null) {
recPerPage = page.recPerPage;
recTotal = page.recTotal;
page = page.page;
}
var state = that.state;
if (!state) {
state = $.extend({}, DEFAULT_PAGER);
}
var oldState = $.extend({}, state);
if (typeof recPerPage === 'number' && recPerPage > 0) {
state.recPerPage = recPerPage;
}
if (typeof recTotal === 'number' && recTotal >= 0) {
state.recTotal = recTotal;
}
if (typeof page === 'number' && page >= 0) {
state.page = page;
}
state.totalPage = (state.recTotal && state.recPerPage) ? (Math.ceil(state.recTotal / state.recPerPage)) : 1;
state.page = Math.max(0, Math.min(state.page, state.totalPage));
// stateRecCount is items count in current page
state.pageRecCount = state.recTotal;
if (state.page && state.recTotal) {
if (state.page < state.totalPage) {
state.pageRecCount = state.recPerPage;
} else if (state.page > 1) {
state.pageRecCount = state.recTotal - (state.recPerPage * (state.page - 1));
}
}
state.skip = state.page > 1 ? ((state.page - 1) * state.recPerPage) : 0;
state.start = state.skip + 1;
state.end = state.skip + state.pageRecCount;
state.prev = state.page > 1 ? (state.page - 1) : 0;
state.next = state.page < state.totalPage ? (state.page + 1) : 0;
that.state = state;
if (!notTiggerChange && (oldState.page !== state.page || oldState.recTotal !== state.recTotal || oldState.recPerPage !== state.recPerPage)) {
that.$.callComEvent(that, 'onPageChange', [state, oldState]);
}
return that.render();
};
Pager.prototype.createLinkItem = function(page, text, asAElement) {
var that = this;
if (text === undefined) {
text = page;
}
var $ele = $('<a title="' + that.lang.pageOfText.format(page) + '" class="pager-item" data-page="' + page + '"/>').attr('href', page ? that.createLink(page, that.state) : '###').html(text);
if (!asAElement) {
$ele = $('<li />').append($ele).toggleClass('active', page === that.state.page).toggleClass('disabled', !page || page === that.state.page);
}
return $ele;
};
Pager.prototype.createNavItems = function(maxCount) {
var that = this;
var $nav = that.$;
var pager = that.state;
var totalPage = pager.totalPage;
var page = pager.page;
var appendItem = function(p, to) {
if(p === false) {
$nav.append(that.createLinkItem(0, to || that.options.navEllipsisItem));
return;
}
if(to === undefined) to = p;
for(var i = p; i <= to; ++i) {
$nav.append(that.createLinkItem(i));
}
};
if (maxCount === undefined) {
maxCount = that.options.maxNavCount || 10;
}
appendItem(1);
if(totalPage > 1) {
if(totalPage <= maxCount) {
appendItem(2, totalPage);
}
else if(page < (maxCount - 2)) {
appendItem(2, maxCount - 2);
appendItem(false);
appendItem(totalPage);
}
else if(page > (totalPage - maxCount + 2)) {
appendItem(false);
appendItem((totalPage - maxCount + 2), totalPage);
}
else {
appendItem(false);
appendItem(page - Math.ceil((maxCount-4)/2), page + Math.floor((maxCount-4)/2));
appendItem(false);
appendItem(totalPage);
}
}
};
Pager.prototype.createGoto = function() {
var that = this;
var pager = this.state;
var $goto = $('<div class="input-group pager-goto" style="width: ' + (35 + (pager.page + '').length * 9 + 25 + that.lang.goto.length*12) + 'px"><input value="' + pager.page + '" type="number" min="1" max="' + pager.totalPage + '" placeholder="' + pager.page + '" class="form-control pager-goto-input"><span class="input-group-btn"><button class="btn pager-goto-btn" type="button">' + that.lang.goto + '</button></span></div>');
return $goto;
};
Pager.prototype.createSizeMenu = function() {
var that = this;
var pager = this.state;
var $menu = $('<ul class="dropdown-menu"></ul>');
var options = that.options.pageSizeOptions;
if (typeof options === 'string') {
options = options.split(',');
}
for (var i = 0; i < options.length; ++i) {
var size = options[i];
if (typeof size === 'string') {
size = parseInt(size);
}
var $li = $('<li><a href="###" data-size="' + size + '">' + size + '</a></li>').toggleClass('active', size === pager.recPerPage);
$menu.append($li);
}
return $('<div class="btn-group pager-size-menu"><button type="button" class="btn dropdown-toggle" data-toggle="dropdown">' + that.lang.pageSize.format(pager) + ' <span class="caret"></span></button></div>').addClass(that.options.menuDirection).append($menu);
};
Pager.prototype.createElement = function(element, $pager, pager) {
var that = this;
var createLinkItem= $.proxy(that.createLinkItem, that);
var lang = that.lang;
switch (element) {
case 'prev':
return createLinkItem(pager.prev, lang.prev);
case 'prev_icon':
return createLinkItem(pager.prev, '<i class="icon ' + that.options.prevIcon + '"></i>');
case 'next':
return createLinkItem(pager.next, lang.next);
case 'next_icon':
return createLinkItem(pager.next, '<i class="icon ' + that.options.nextIcon + '"></i>');
case 'first':
return createLinkItem(1, lang.first);
case 'first_icon':
return createLinkItem(1, '<i class="icon ' + that.options.firstIcon + '"></i>');
case 'last':
return createLinkItem(pager.totalPage, lang.last);
case 'last_icon':
return createLinkItem(pager.totalPage, '<i class="icon ' + that.options.lastIcon + '"></i>');
case 'space':
case '|':
return $('<li class="space" />');
case 'nav':
case 'pages':
that.createNavItems();
return;
case 'total_text':
return $(('<div class="pager-label">' + lang.totalCount + '</div>').format(pager));
case 'page_text':
return $(('<div class="pager-label">' + lang.pageOf + '</div>').format(pager));
case 'total_page_text':
return $(('<div class="pager-label">' + lang.totalPage + '</div>').format(pager));
case 'page_of_total_text':
return $(('<div class="pager-label">' + lang.pageOfTotal + '</div>').format(pager));
case 'page_size_text':
return $(('<div class="pager-label">' + lang.pageSize + '</div>').format(pager));
case 'items_range_text':
return $(('<div class="pager-label">' + lang.itemsRange + '</div>').format(pager));
case 'goto':
return that.createGoto();
case 'size_menu':
return that.createSizeMenu();
default:
return $('<li/>').html(element.format(pager));
}
};
Pager.prototype.createLink = function(page, pager) {
if (page === undefined) {
page = this.state.page;
}
if (pager === undefined) {
pager = this.state;
}
var linkCreator = this.options.linkCreator;
if (typeof linkCreator === 'string') {
return linkCreator.format($.extend({}, pager, {page: page}));
} else if ($.isFunction(linkCreator)) {
return linkCreator(page, pager);
}
return '#page=' + page;
};
Pager.prototype.render = function(elements) {
var that = this;
var state = that.state;
var createElement = that.options.elementCreator || that.createElement;
var isMapperCreator = $.isPlainObject(createElement);
elements = elements || that.elements || that.options.elements;
if (typeof elements == 'string') {
elements = elements.split(',');
}
that.elements = elements;
that.$.empty();
for(var i = 0; i < elements.length; ++i) {
var element = $.trim(elements[i]);
var creator = isMapperCreator ? (createElement[element] || createElement) : createElement;
var $element = creator.call(that, element, that.$, state);
if ($element === false) {
$element = that.createElement(element, that.$, state);
}
if ($element instanceof $) {
if ($element[0].tagName !== 'LI') {
$element = $('<li/>').append($element);
}
that.$.append($element);
}
}
// Fix page item border
var $lastItem = null;
that.$.children('li').each(function() {
var $li = $(this);
var isItem = !!$li.children('.pager-item').length;
if ($lastItem) {
$lastItem.toggleClass('pager-item-right', !isItem);
} else {
if (isItem) {
$li.addClass('pager-item-left');
}
}
$lastItem = isItem ? $li : null;
});
if ($lastItem) {
$lastItem.addClass('pager-item-right');
}
that.$.callComEvent(that, 'onRender', [state]);
return that;
};
// default options
Pager.DEFAULTS = $.extend({
elements: ['first_icon', 'prev_icon', 'pages', 'next_icon', 'last_icon', 'page_of_total_text', 'items_range_text', 'total_text'],
prevIcon: 'icon-double-angle-left',
nextIcon: 'icon-double-angle-right',
firstIcon: 'icon-step-backward',
lastIcon: 'icon-step-forward',
navEllipsisItem: '<i class="icon icon-ellipsis-h"></i>',
maxNavCount: 10,
menuDirection: 'dropdown', // or dropup
pageSizeOptions: [10, 20, 30, 50, 100],
// onPageChange: null
}, DEFAULT_PAGER);
// Extense jquery element
$.fn.pager = function(option) {
return this.each(function() {
var $this = $(this);
var data = $this.data(NAME);
var options = typeof option == 'object' && option;
if(!data) $this.data(NAME, (data = new Pager(this, options)));
if(typeof option == 'string') data[option]();
});
};
Pager.NAME = NAME;
$.fn.pager.Constructor = Pager;
// Auto call pager after document load complete
$(function() {
$('[data-ride="pager"]').pager();
});
}(jQuery, undefined));
/* ========================================================================
* 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: 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] ?