/*! * ZUI: Standard edition - v1.9.1 - 2019-06-03 * 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: '第 {page} 页', totalPage: '共 {totalPage} 页', totalCount: '共 {recTotal} 项', pageSize: '每页 {recPerPage} 项', itemsRange: '第 {start} ~ {end} 项', pageOfTotal: '第 {page}/{totalPage} 页' }, zh_tw: { pageOfText: '第 {0} 頁', prev: '上一頁', next: '下一頁', first: '第一頁', last: '最後一頁', goto: '跳轉', pageOf: '第 {page} 頁', totalPage: '共 {totalPage} 頁', totalCount: '共 {recTotal} 項', pageSize: '每頁 {recPerPage} 項', itemsRange: '第 {start} ~ {end} 項', pageOfTotal: '第 {page}/{totalPage} 頁' }, en: { pageOfText: 'Page {0}', prev: 'Prev', next: 'Next', first: 'First', last: 'Last', goto: 'Goto', pageOf: 'Page {page}', totalPage: '{totalPage} pages', totalCount: '{recTotal} in total', pageSize: '{recPerPage} per page', itemsRange: 'From {start} to {end}', pageOfTotal: 'Page {page} of {totalPage}' } }; // 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 = $('').attr('href', page ? that.createLink(page, that.state) : '###').html(text); if (!asAElement) { $ele = $('
  • ').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 = $('
    '); return $goto; }; Pager.prototype.createSizeMenu = function() { var that = this; var pager = this.state; var $menu = $(''); 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 = $('
  • ' + size + '
  • ').toggleClass('active', size === pager.recPerPage); $menu.append($li); } return $('
    ').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, ''); case 'next': return createLinkItem(pager.next, lang.next); case 'next_icon': return createLinkItem(pager.next, ''); case 'first': return createLinkItem(1, lang.first); case 'first_icon': return createLinkItem(1, ''); case 'last': return createLinkItem(pager.totalPage, lang.last); case 'last_icon': return createLinkItem(pager.totalPage, ''); case 'space': case '|': return $('
  • '); case 'nav': case 'pages': that.createNavItems(); return; case 'total_text': return $(('
    ' + lang.totalCount + '
    ').format(pager)); case 'page_text': return $(('
    ' + lang.pageOf + '
    ').format(pager)); case 'total_page_text': return $(('
    ' + lang.totalPage + '
    ').format(pager)); case 'page_of_total_text': return $(('
    ' + lang.pageOfTotal + '
    ').format(pager)); case 'page_size_text': return $(('
    ' + lang.pageSize + '
    ').format(pager)); case 'items_range_text': return $(('
    ' + lang.itemsRange + '
    ').format(pager)); case 'goto': return that.createGoto(); case 'size_menu': return that.createSizeMenu(); default: return $('
  • ').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 = $('
  • ').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: '', 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': '您的浏览器版本过低,无法体验所有功能,建议升级或者更换浏览器。 了解更多...', 'zh_tw': '您的瀏覽器版本過低,無法體驗所有功能,建議升級或者更换瀏覽器。了解更多...', 'en': 'Your browser is too old, it has been unable to experience the colorful internet. We strongly recommend that you upgrade a better one. Learn more...' }; // The browser modal class var Browser = function () { var 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 = $('
    '); $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 = ''; 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 milliseconds. Defaults to true. // // Because the window object has its own resize event, it doesn't need to be // provided by this plugin, and its execution can be left entirely up to the // browser. However, since certain browsers fire the resize event continuously // while others do not, enabling this will throttle the window resize event, // making event behavior consistent across all elements in all browsers. // // While setting this property to false will disable window object resize // event throttling, please note that this property must be changed before any // window object resize event callbacks are bound. jq_resize[str_throttle] = true; // Event: resize event // // Fired when an element's width or height changes. Because browsers only // provide this event for the window element, for other elements a polling // loop is initialized, running every milliseconds // to see if elements' dimensions have changed. You may bind with either // .resize( fn ) or .bind( "resize", fn ), and unbind with .unbind( "resize" ). // // Usage: // // > jQuery('selector').bind( 'resize', function(e) { // > // element's width or height has changed! // > ... // > }); // // Additional Notes: // // * The polling loop is not created until at least one callback is actually // bound to the 'resize' event, and this single polling loop is shared // across all elements. // // Double firing issue in jQuery 1.3.2: // // While this plugin works in jQuery 1.3.2, if an element's event callbacks // are manually triggered via .trigger( 'resize' ) or .resize() those // callbacks may double-fire, due to limitations in the jQuery 1.3.2 special // events system. This is not an issue when using jQuery 1.4+. // // > // While this works in jQuery 1.4+ // > $(elem).css({ width: new_w, height: new_h }).resize(); // > // > // In jQuery 1.3.2, you need to do this: // > var elem = $(elem); // > elem.css({ width: new_w, height: new_h }); // > elem.data( 'resize-special-event', { width: elem.width(), height: elem.height() } ); // > elem.resize(); $.event.special[str_resize] = { // Called only when the first 'resize' event callback is bound per element. setup: function() { // Since window has its own native 'resize' event, return false so that // jQuery will bind the event using DOM methods. Since only 'window' // objects have a .setTimeout method, this should be a sufficient test. // Unless, of course, we're throttling the 'resize' event for window. if(!jq_resize[str_throttle] && this[str_setTimeout]) { return false; } var elem = $(this); // Add this element to the list of internal elements to monitor. elems = elems.add(elem); // Initialize data store on the element. $.data(this, str_data, { w: elem.width(), h: elem.height() }); // If this is the first element added, start the polling loop. if(elems.length === 1) { loopy(); } }, // Called only when the last 'resize' event callback is unbound per element. teardown: function() { // Since window has its own native 'resize' event, return false so that // jQuery will unbind the event using DOM methods. Since only 'window' // objects have a .setTimeout method, this should be a sufficient test. // Unless, of course, we're throttling the 'resize' event for window. if(!jq_resize[str_throttle] && this[str_setTimeout]) { return false; } var elem = $(this); // Remove this element from the list of internal elements to monitor. elems = elems.not(elem); // Remove any data stored on the element. elem.removeData(str_data); // If this is the last element removed, stop the polling loop. if(!elems.length) { clearTimeout(timeout_id); } }, // Called every time a 'resize' event callback is bound per element (new in // jQuery 1.4). add: function(handleObj) { // Since window has its own native 'resize' event, return false so that // jQuery doesn't modify the event object. Unless, of course, we're // throttling the 'resize' event for window. if(!jq_resize[str_throttle] && this[str_setTimeout]) { return false; } var old_handler; // The new_handler function is executed every time the event is triggered. // This is used to update the internal element data store with the width // and height when the event is triggered manually, to avoid double-firing // of the event callback. See the "Double firing issue in jQuery 1.3.2" // comments above for more information. function new_handler(e, w, h) { var elem = $(this), data = $.data(this, str_data) || {}; // If called from the polling loop, w and h will be passed in as // arguments. If called manually, via .trigger( 'resize' ) or .resize(), // those values will need to be computed. data.w = w !== undefined ? w : elem.width(); data.h = h !== undefined ? h : elem.height(); old_handler.apply(this, arguments); }; // This may seem a little complicated, but it normalizes the special event // .add method between jQuery 1.4/1.4.1 and 1.4.2+ if($.isFunction(handleObj)) { // 1.4, 1.4.1 old_handler = handleObj; return new_handler; } else { // 1.4.2+ old_handler = handleObj.handler; handleObj.handler = new_handler; } } }; function loopy() { // Start the polling loop, asynchronously. timeout_id = window[str_setTimeout](function() { // Iterate over all elements to which the 'resize' event is bound. elems.each(function() { var elem = $(this), width = elem.width(), height = elem.height(), data = $.data(this, str_data); // If element size has changed since the last time, update the element // data store and trigger the 'resize' event. if(width !== data.w || height !== data.h) { elem.trigger(str_resize, [data.w = width, data.h = height]); } }); // Loop. loopy(); }, jq_resize[str_delay]); }; })(jQuery, this); /* ======================================================================== * Bootstrap: scrollspy.js v3.0.3 * http://getbootstrap.com/javascript/#scrollspy * * 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'; // SCROLLSPY CLASS DEFINITION // ========================== var zuiname = 'zui.scrollspy' function ScrollSpy(element, options) { var href var process = $.proxy(this.process, this) this.$element = $(element).is('body') ? $(window) : $(element) this.$body = $('body') this.$scrollElement = this.$element.on('scroll.' + zuiname + '.data-api', process) this.options = $.extend({}, ScrollSpy.DEFAULTS, options) if(!this.selector) this.selector = (this.options.target || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7 || '') + ' .nav li > a' this.offsets = $([]) this.targets = $([]) this.activeTarget = null this.refresh() this.process() } ScrollSpy.DEFAULTS = { offset: 10 } ScrollSpy.prototype.refresh = function() { var offsetMethod = this.$element[0] == window ? 'offset' : 'position' this.offsets = $([]) this.targets = $([]) var self = this var $targets = this.$body .find(this.selector) .map(function() { var $el = $(this) var href = $el.data('target') || $el.attr('href') var $href = /^#./.test(href) && $(href) return($href && $href.length && $href.is(':visible') && [ [$href[offsetMethod]().top + (!$.isWindow(self.$scrollElement.get(0)) && self.$scrollElement.scrollTop()), href] ]) || null }) .sort(function(a, b) { return a[0] - b[0] }) .each(function() { self.offsets.push(this[0]) self.targets.push(this[1]) }) } ScrollSpy.prototype.process = function() { var scrollTop = this.$scrollElement.scrollTop() + this.options.offset var scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight var maxScroll = scrollHeight - this.$scrollElement.height() var offsets = this.offsets var targets = this.targets var activeTarget = this.activeTarget var i if(scrollTop >= maxScroll) { return activeTarget != (i = targets.last()[0]) && this.activate(i) } if(activeTarget && scrollTop <= offsets[0]) { return activeTarget != (i = targets[0]) && this.activate(i) } for(i = offsets.length; i--;) { activeTarget != targets[i] && scrollTop >= offsets[i] && (!offsets[i + 1] || scrollTop <= offsets[i + 1]) && this.activate(targets[i]) } } ScrollSpy.prototype.activate = function(target) { this.activeTarget = target $(this.selector) .parentsUntil(this.options.target, '.active') .removeClass('active') var selector = this.selector + '[data-target="' + target + '"],' + this.selector + '[href="' + target + '"]' var active = $(selector) .parents('li') .addClass('active') if(active.parent('.dropdown-menu').length) { active = active .closest('li.dropdown') .addClass('active') } active.trigger('activate.' + zuiname) } // SCROLLSPY PLUGIN DEFINITION // =========================== var old = $.fn.scrollspy $.fn.scrollspy = function(option) { return this.each(function() { var $this = $(this) var data = $this.data(zuiname) var options = typeof option == 'object' && option if(!data) $this.data(zuiname, (data = new ScrollSpy(this, options))) if(typeof option == 'string') data[option]() }) } $.fn.scrollspy.Constructor = ScrollSpy // SCROLLSPY NO CONFLICT // ===================== $.fn.scrollspy.noConflict = function() { $.fn.scrollspy = old return this } // SCROLLSPY DATA-API // ================== $(window).on('load', function() { $('[data-spy="scroll"]').each(function() { var $spy = $(this) $spy.scrollspy($spy.data()) }) }) }(jQuery); /* ======================================================================== * ZUI: storeb.js * http://zui.sexy * ======================================================================== * Copyright (c) 2014-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)); /* ======================================================================== * ZUI: searchbox.js * http://zui.sexy * ======================================================================== * Copyright (c) 2014-2016 cnezsoft.com; Licensed MIT * ======================================================================== */ (function($) { 'use strict'; var NAME = 'zui.searchBox'; // modal name // The searchbox modal class var SearchBox = function(element, options) { var that = this; that.name = name; that.$ = $(element); that.options = options = $.extend({}, SearchBox.DEFAULTS, that.$.data(), options); // Initialize here var $input = that.$.is(options.inputSelector) ? that.$ : that.$.find(options.inputSelector); if ($input.length) { var clearChangeTimer = function() { if (that.changeTimer) { clearTimeout(that.changeTimer); that.changeTimer = null; } }; var handleChange = function() { clearChangeTimer(); var value = that.getSearch(); if (value !== that.lastValue) { var isEmpty = value === ''; $input.toggleClass('empty', isEmpty); that.$.callComEvent(that, 'onSearchChange', [value, isEmpty]); that.lastValue = value; } }; that.$input = $input = $input.first(); $input.on(options.listenEvent, function(params) { that.changeTimer = setTimeout(function() { handleChange(); }, options.changeDelay); }).on('focus', function(e) { $input.addClass('focus'); that.$.callComEvent(that, 'onFocus', [e]); }).on('blur', function(e) { $input.removeClass('focus'); that.$.callComEvent(that, 'onBlur', [e]); }).on('keydown', function(e) { var handled = 0; var keyCode = e.which; if (keyCode === 27 && options.escToClear) { // esc this.setSearch('', true); handleChange(); handled = 1; } else if (keyCode === 13 && options.onPressEnter) { handleChange(); that.$.callComEvent(that, 'onPressEnter', [e]); } var onKeyDownResult = that.$.callComEvent(that, 'onKeyDown', [e]); if (onKeyDownResult === false) { handled = 1; } if (handled) { e.preventDefault(); } }); that.$.on('click', '.search-clear-btn', function(e) { that.setSearch('', true); handleChange(); that.focus(); e.preventDefault(); }); handleChange(); } else { console.error('ZUI: search box init error, cannot find search box input element.'); } }; // default options SearchBox.DEFAULTS = { inputSelector: 'input[type="search"],input[type="text"]', listenEvent: 'change input paste', changeDelay: 500, // onKeyDown: null, // onFocus: null, // onBlur: null, // onSearchChange: null, // onPressEnter: null, // escToClear: true }; // Get current search string SearchBox.prototype.getSearch = function() { return this.$input && $.trim(this.$input.val()); }; // Set current search string SearchBox.prototype.setSearch = function(value, notTriggerChange) { var $input = this.$input; if ($input) { $input.val(value); if (!notTriggerChange) { $input.trigger('change'); } } }; // Focus input element SearchBox.prototype.focus = function() { this.$input && this.$input.focus(); }; // Extense jquery element $.fn.searchBox = 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 SearchBox(this, options))); if(typeof option == 'string') data[option](); }); }; SearchBox.NAME = NAME; $.fn.searchBox.Constructor = SearchBox; }(jQuery)); /* ======================================================================== * ZUI: draggable.js * http://zui.sexy * ======================================================================== * Copyright (c) 2014-2016 cnezsoft.com; Licensed MIT * ======================================================================== */ (function($, document) { 'use strict'; var NAME = 'zui.draggable', DEFAULTS = { // selector: '', container: 'body', move: true // mouseButton: -1 // 0, 1, 2, -1, all, left, right, middle }; var idIncrementer = 0; var Draggable = function(element, options) { var that = this; that.$ = $(element); that.id = idIncrementer++; that.options = $.extend({}, DEFAULTS, that.$.data(), options); that.init(); }; Draggable.DEFAULTS = DEFAULTS; Draggable.NAME = NAME; Draggable.prototype.init = function() { var that = this, $root = that.$, BEFORE = 'before', DRAG = 'drag', FINISH = 'finish', eventSuffix = '.' + NAME + '.' + that.id, mouseDownEvent = 'mousedown' + eventSuffix, mouseUpEvent = 'mouseup' + eventSuffix, mouseMoveEvent = 'mousemove' + eventSuffix, setting = that.options, selector = setting.selector, handle = setting.handle, $ele = $root, isMoveFunc = $.isFunction(setting.move), startPos, cPos, startOffset, mousePos, moved; var mouseMove = function(event) { var mX = event.pageX, mY = event.pageY; moved = true; var dragPos = { left: mX - startOffset.x, top: mY - startOffset.y }; $ele.removeClass('drag-ready').addClass('dragging'); if(setting.move) { if (isMoveFunc) { setting.move(dragPos, $ele); } else { $ele.css(dragPos); } } setting[DRAG] && setting[DRAG]({ event: event, element: $ele, startOffset: startOffset, pos: dragPos, offset: { x: mX - startPos.x, y: mY - startPos.y }, smallOffset: { x: mX - mousePos.x, y: mY - mousePos.y } }); mousePos.x = mX; mousePos.y = mY; if(setting.stopPropagation) { event.stopPropagation(); } }; var mouseUp = function(event) { $(document).off(eventSuffix); if(!moved) { $ele.removeClass('drag-ready'); return; } var endPos = { left: event.pageX - startOffset.x, top: event.pageY - startOffset.y }; $ele.removeClass('drag-ready dragging'); if(setting.move) { if (isMoveFunc) { setting.move(endPos, $ele); } else { $ele.css(endPos); } } setting[FINISH] && setting[FINISH]({ event: event, element: $ele, startOffset: startOffset, pos: endPos, offset: { x: event.pageX - startPos.x, y: event.pageY - startPos.y }, smallOffset: { x: event.pageX - mousePos.x, y: event.pageY - mousePos.y } }); event.preventDefault(); if(setting.stopPropagation) { event.stopPropagation(); } }; var mouseDown = function(event) { var mouseButton = $.zui.getMouseButtonCode(setting.mouseButton); if(mouseButton > -1 && event.button !== mouseButton) { return; } var $mouseDownEle = $(this); if(selector) { $ele = handle ? $mouseDownEle.closest(selector) : $mouseDownEle; } if(setting[BEFORE]) { var isSure = setting[BEFORE]({ event: event, element: $ele }); if(isSure === false) return; } var $container = $(setting.container), pos = $ele.offset(); cPos = $container.offset(); startPos = { x: event.pageX, y: event.pageY }; startOffset = { x: event.pageX - pos.left + cPos.left, y: event.pageY - pos.top + cPos.top }; mousePos = $.extend({}, startPos); moved = false; $ele.addClass('drag-ready'); event.preventDefault(); if(setting.stopPropagation) { event.stopPropagation(); } $(document).on(mouseMoveEvent, mouseMove).on(mouseUpEvent, mouseUp); }; if(handle) { $root.on(mouseDownEvent, handle, mouseDown); } else if(selector) { $root.on(mouseDownEvent, selector, mouseDown); } else { $root.on(mouseDownEvent, mouseDown); } }; Draggable.prototype.destroy = function() { var eventSuffix = '.' + NAME + '.' + this.id; this.$.off(eventSuffix); $(document).off(eventSuffix); this.$.data(NAME, null); }; $.fn.draggable = 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 Draggable(this, options))); if(typeof option == 'string') data[option](); }); }; $.fn.draggable.Constructor = Draggable; }(jQuery, document)); /* ======================================================================== * ZUI: droppable.js * http://zui.sexy * ======================================================================== * Copyright (c) 2014-2016 cnezsoft.com; Licensed MIT * ======================================================================== */ (function($, document, Math) { 'use strict'; var NAME = 'zui.droppable', DEFAULTS = { // container: '', // selector: '', // handle: '', // flex: false, // nested: false, target: '.droppable-target', deviation: 5, sensorOffsetX: 0, sensorOffsetY: 0, dropToClass: 'drop-to', // mouseButton: -1 // 0, 1, 2, -1, all, left, right, middle }; var idIncrementer = 0; var Droppable = function(element, options) { var that = this; that.id = idIncrementer++; that.$ = $(element); that.options = $.extend({}, DEFAULTS, that.$.data(), options); that.init(); }; Droppable.DEFAULTS = DEFAULTS; Droppable.NAME = NAME; Droppable.prototype.trigger = function(name, params) { return $.zui.callEvent(this.options[name], params, this); }; Droppable.prototype.init = function() { var that = this, $root = that.$, setting = that.options, deviation = setting.deviation, eventSuffix = '.' + NAME + '.' + that.id, mouseDownEvent = 'mousedown' + eventSuffix, mouseUpEvent = 'mouseup' + eventSuffix, mouseMoveEvent = 'mousemove' + eventSuffix, selector = setting.selector, handle = setting.handle, flex = setting.flex, container = setting.container, canMoveHere = setting.canMoveHere, dropToClass = setting.dropToClass, $ele = $root, isMouseDown = false, $container = container ? $(setting.container).first() : (selector ? $root : $('body')), $targets, $target, $shadow, isIn, isSelf, oldCssPosition, startOffset, startMouseOffset, containerOffset, clickOffset, mouseOffset, lastMouseOffset, mouseDownBackEventCall; var mouseMove = function(event) { if(!isMouseDown) return; mouseOffset = {left: event.pageX, top: event.pageY}; // ignore small move if(Math.abs(mouseOffset.left - startMouseOffset.left) < deviation && Math.abs(mouseOffset.top - startMouseOffset.top) < deviation) return; if($shadow === null) // create shadow { var cssPosition = $container.css('position'); if(cssPosition != 'absolute' && cssPosition != 'relative' && cssPosition != 'fixed') { oldCssPosition = cssPosition; $container.css('position', 'relative'); } $shadow = $ele.clone().removeClass('drag-from').addClass('drag-shadow').css({ position: 'absolute', width: $ele.outerWidth(), transition: 'none' }).appendTo($container); $ele.addClass('dragging'); that.trigger('start', { event: event, element: $ele, targets: $targets }); } var offset = { left: mouseOffset.left - clickOffset.left, top: mouseOffset.top - clickOffset.top }; var position = { left: offset.left - containerOffset.left, top: offset.top - containerOffset.top }; $shadow.css(position); $.extend(lastMouseOffset, mouseOffset); var isNew = false; isIn = false; if(!flex) { $targets.removeClass(dropToClass); } var $newTarget = null; $targets.each(function() { var t = $(this), tPos = t.offset(), tW = t.outerWidth(), tH = t.outerHeight(), tX = tPos.left + setting.sensorOffsetX, tY = tPos.top + setting.sensorOffsetY; if(mouseOffset.left > tX && mouseOffset.top > tY && mouseOffset.left < (tX + tW) && mouseOffset.top < (tY + tH)) { if($newTarget) $newTarget.removeClass(dropToClass); $newTarget = t; if(!setting.nested) return false; } }); if($newTarget) { isIn = true; var id = $newTarget.data('id'); if($ele.data('id') != id) isSelf = false; if($target === null || ($target.data('id') !== id && (!isSelf))) isNew = true; $target = $newTarget; if(flex) { $targets.removeClass(dropToClass); } $target.addClass(dropToClass); } if(!flex) { $ele.toggleClass('drop-in', isIn); $shadow.toggleClass('drop-in', isIn); } else if($target !== null && $target.length) { isIn = true; } if(!canMoveHere || canMoveHere($ele, $target) !== false) { that.trigger('drag', { event: event, isIn: isIn, target: $target, element: $ele, isNew: isNew, selfTarget: isSelf, clickOffset: clickOffset, offset: offset, position: { left: offset.left - containerOffset.left, top: offset.top - containerOffset.top }, mouseOffset: mouseOffset }); } event.preventDefault(); }; var mouseUp = function(event) { $(document).off(eventSuffix); clearTimeout(mouseDownBackEventCall); if(!isMouseDown) return; isMouseDown = false; if(oldCssPosition) { $container.css('position', oldCssPosition); } if($shadow === null) { $ele.removeClass('drag-from'); that.trigger('always', { event: event, cancel: true }); return; } if(!isIn) $target = null; var isSure = true; mouseOffset = event ? { left: event.pageX, top: event.pageY } : lastMouseOffset; var offset = { left: mouseOffset.left - clickOffset.left, top: mouseOffset.top - clickOffset.top }; var moveOffset = { left: mouseOffset.left - lastMouseOffset.left, top: mouseOffset.top - lastMouseOffset.top }; lastMouseOffset.left = mouseOffset.left; lastMouseOffset.top = mouseOffset.top; var eventOptions = { event: event, isIn: isIn, target: $target, element: $ele, isNew: (!isSelf) && $target !== null, selfTarget: isSelf, offset: offset, mouseOffset: mouseOffset, position: { left: offset.left - containerOffset.left, top: offset.top - containerOffset.top }, lastMouseOffset: lastMouseOffset, moveOffset: moveOffset }; isSure = that.trigger('beforeDrop', eventOptions); if(isSure && isIn) { that.trigger('drop', eventOptions); } $targets.removeClass(dropToClass); $ele.removeClass('dragging').removeClass('drag-from'); $shadow.remove(); $shadow = null; that.trigger('finish', eventOptions); that.trigger('always', eventOptions); if(event) event.preventDefault(); }; var mouseDown = function(event) { var mouseButton = $.zui.getMouseButtonCode(setting.mouseButton); if(mouseButton > -1 && event.button !== mouseButton) { return; } var $mouseDownEle = $(this); if(selector) { $ele = handle ? $mouseDownEle.closest(selector) : $mouseDownEle; } if($ele.hasClass('drag-shadow')) { return; } if(setting['before']) { if(setting['before']({ event: event, element: $ele }) === false) return; } isMouseDown = true; $targets = $.isFunction(setting.target) ? setting.target($ele, $root) : $container.find(setting.target), $target = null, $shadow = null, isIn = false, isSelf = true, oldCssPosition = null, startOffset = $ele.offset(), containerOffset = $container.offset(); containerOffset.top = containerOffset.top - $container.scrollTop(); containerOffset.left = containerOffset.left - $container.scrollLeft(); startMouseOffset = {left: event.pageX, top: event.pageY}; lastMouseOffset = $.extend({}, startMouseOffset); clickOffset = { left: startMouseOffset.left - startOffset.left, top: startMouseOffset.top - startOffset.top }; $ele.addClass('drag-from'); $(document).on(mouseMoveEvent, mouseMove).on(mouseUpEvent, mouseUp); mouseDownBackEventCall = setTimeout(function() { $(document).on(mouseDownEvent, mouseUp); }, 10); event.preventDefault(); if(setting.stopPropagation) { event.stopPropagation(); } }; if(handle) { $root.on(mouseDownEvent, handle, mouseDown); } else if(selector) { $root.on(mouseDownEvent, selector, mouseDown); } else { $root.on(mouseDownEvent, mouseDown); } }; Droppable.prototype.destroy = function() { var eventSuffix = '.' + NAME + '.' + this.id; this.$.off(eventSuffix); $(document).off(eventSuffix); this.$.data(NAME, null); }; Droppable.prototype.reset = function() { this.destroy(); this.init(); }; $.fn.droppable = 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 Droppable(this, options))); if(typeof option == 'string') data[option](); }); }; $.fn.droppable.Constructor = Droppable; }(jQuery, document, Math)); /* ======================================================================== * 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($, undefined) { '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%', // scrollInside: false, // headerHeight: 'auto', }; 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(position === undefined) position = options.position; if(position === undefined || position === null) return; if ($.isFunction(position)) { position = position(that); } var $dialog = that.$element.find('.modal-dialog'); var winHeight = $(window).height(); var bodyCss = {maxHeight: 'initial', overflow: 'visible'}; var $body = $dialog.find('.modal-body').css(bodyCss); if (options.scrollInside) { var headerHeight = options.headerHeight; if (typeof headerHeight !== 'number') { headerHeight = $dialog.find('.modal-header').height(); } else if ($.isFunction(headerHeight)) { headerHeight = headerHeight($header); } bodyCss.maxHeight = winHeight - headerHeight; if ($body.outerHeight() > bodyCss.maxHeight) { bodyCss.overflow = 'auto'; } } $body.css(bodyCss); var half = Math.max(0, (winHeight - $dialog.outerHeight()) / 2); if (position === 'fit') { position = {top: half > 50 ? Math.floor(half * 2 / 3) : half}; } else if (position === 'center') { position = {top: half}; } else if (!$.isPlainObject(position)) { position = {top: 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); } } position = $.extend(position, {left: Math.max(0, ($(window).width() - $dialog.outerWidth()) / 2)}, pos); if (options.moveable === 'inside') { setDialogPos($dialog, position); } else { $dialog.css(position); } } else { $dialog.css(position); } } 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() { var marginTop = $dialog.css('margin-top'); if (marginTop && marginTop !== '0px') { $dialog.css('top', marginTop).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) that.$element.toggleClass('modal-scroll-inside', !!that.options.scrollInside); if(that.isShown || e.isDefaultPrevented()) return that.isShown = true if(that.options.moveable) that.setMoveale(); that.checkScrollbar() if (that.options.backdrop !== false) { that.$body.addClass('modal-open') that.setScrollbar() } that.escape() that.$element.on('click.dismiss.' + zuiname, '[data-dismiss="modal"]',function(e) { that.hide(); e.stopPropagation(); }) 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.preventDefault() var that = this; e = $.Event('hide.' + zuiname) that.$element.trigger(e) if(!that.isShown || e.isDefaultPrevented()) return that.isShown = false if (that.options.backdrop !== false) { that.$body.removeClass('modal-open') that.resetScrollbar() } that.escape() $(document).off('focusin.' + zuiname) that.$element .removeClass('in') .attr('aria-hidden', true) .off('click.dismiss.' + zuiname) $.support.transition && that.$element.hasClass('fade') ? that.$element .one('bsTransitionEnd', $.proxy(that.hideModal, that)) .emulateTransitionEnd(Modal.TRANSITION_DURATION) : that.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 = $('
  • '); } var $a = $('').attr({ href: item.url || '###', 'class': item.className, style: item.style }).data('item', item); if (item.html) { $a.html(item.html === true ? (item.label || item.text) : item.html); } else { $a.text(item.label || item.text); } if (item.onClick) { $a.on('click', item.onClick); } return $('
  • ').toggleClass('disabled', item.disabled === true).append($a); }; var animationTimer = null; var hideContextMenu = function(id, callback) { if (typeof id === 'function') { callback = id; id = null; } if (animationTimer) { clearTimeout(animationTimer); animationTimer = null; } var $target = $('#' + targetId); if ($target.length) { var options = $target.data('options'); if (!id || options.id === id) { var afterHide = function() { $target.hide(); options.onHidden && options.onHidden(); callback && callback(); }; options.onHide && options.onHide(); var animation = options.animation; $target.removeClass('in'); if (animation) { animationTimer = setTimeout(afterHide, options.duration); } else { afterHide(); } } } return ContextMenu; }; var showContextMenu = function(items, options, callback) { if ($.isPlainObject(items)) { callback = options; options = items; items = options.items; } isShowingMenu = true; // hideContextMenu(); options = $.extend({}, DEFAULTS, options); var x = options.x; var y = options.y; if (x === undefined) x = (options.event || options).clientX; if (x === undefined) x = mouseX; if (y === undefined) y = (options.event || options).clientY; if (y === undefined) y = mouseY; var $target = $('#' + targetId); if (!$target.length) { $target = $('').appendTo('body'); } var $menu = $target.find('.contextmenu-menu').off('click.' + NAME).on('click.' + NAME, 'a', function(e) { var $item = $(this); var clickResult = options.onClickItem && options.onClickItem($item.data('item'), $item, e); if (clickResult !== false) { hideContextMenu(); } }).empty();; $target.hide().attr('class', 'contextmenu'); var itemCreator = options.itemCreator || createMenuItem; var itemsType = typeof items; if (itemsType === 'string') { items = items.split(','); } else if (itemsType === 'function') { items = items(options); } $.each(items, function(index, item) { $menu.append(itemCreator(item, index, options)); }); // Show menu var animation = options.animation; var duration = options.duration; if (animation === true) options.animation = animation = 'fade'; if (animationTimer) { clearTimeout(animationTimer); animationTimer = null; } var afterShow = function() { $target.addClass('in'); options.onShown && options.onShown(); callback && callback(); }; options.onShow && options.onShow(); $target.data('options', { animation: animation, onHide: options.onHide, onHidden: options.onHidden, id: options.id, duration: duration }); var $w = $(window); x = Math.max(0, Math.min(x, $w.width() - $menu.outerWidth())); y = Math.max(0, Math.min(y, $w.height() - $menu.outerHeight())); $target.css({ left: x, top: y }); if (animation) { $target.addClass('open').addClass(animation).show(); animationTimer = setTimeout(function() { afterShow(); isShowingMenu = false; }, options.duration); } else { $target.addClass('open').show(); afterShow(); animationTimer = setTimeout(function() { isShowingMenu = false; }, 200); } return ContextMenu; }; $(document).on('click', function(e) { if (!isShowingMenu && !$(e.target).closest('.contextmenu').length) { hideContextMenu(); } }); $.extend(ContextMenu, { NAME: NAME, DEFAULTS: DEFAULTS, show: showContextMenu, hide: hideContextMenu, listenMouse: listenMouseMove }); $.zui({ContextMenu: ContextMenu}); // The contextmenu model class var ContextListener = function(element, options) { var that = this; that.name = NAME; that.$ = $(element); options = that.options = $.extend({trigger: 'contextmenu'}, ContextMenu.DEFAULTS, this.$.data(), options); var trigger = options.trigger; that.id = $.zui.uuid(); var eventHandler = function(e) { if (e.type === 'mousedown' && e.button !== 2) { return; } var config = { x: e.clientX, y: e.clientY, event: e }; if (options.itemsCreator) { config.items = options.itemsCreator.call(this, e); } that.show(config); e.preventDefault(); e.returnValue = false; // 解决IE8右键弹出 return false; }; var eventName = trigger + '.' + NAME; if (options.selector) { that.$.on(eventName, options.selector, eventHandler); } else { that.$.on(eventName, eventHandler); } }; ContextListener.prototype.destory = function () { that.$.off('.' + NAME); }; ContextListener.prototype.hide = function (callback) { ContextMenu.hide(this.id, callback); }; ContextListener.prototype.show = function (options, callback) { options = $.extend({}, this.options, options); ContextMenu.show(options, callback); }; // Extense jquery element $.fn.contextmenu = 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 ContextListener(this, options))); if(typeof option == 'string') data[option](); }); }; $.fn.contextmenu.Constructor = ContextListener; }(jQuery, undefined)); /* ======================================================================== * 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); /* ======================================================================== * TangBin: image.ready.js * http://www.planeart.cn/?p=1121 * * ZUI: The file has been changed in ZUI. It will not keep update with the * original version in the future. * http://zui.sexy * ======================================================================== * @version 2011.05.27 * @author TangBin * ======================================================================== */ /*! TangBin: image.ready.js http://www.planeart.cn/?p=1121 */ (function($) { 'use strict'; /** * Image ready * @param {String} image url * @param {Function} callback on image ready * @param {Function} callback on image load * @param {Function} callback on error * @example imgReady('image.png', function () { alert('size ready: width=' + this.width + '; height=' + this.height); }); */ $.zui.imgReady = (function() { var list = [], intervalId = null, // 用来执行队列 tick = function() { var i = 0; for(; i < list.length; i++) { list[i].end ? list.splice(i--, 1) : list[i](); }!list.length && stop(); }, // 停止所有定时器队列 stop = function() { clearInterval(intervalId); intervalId = null; }; return function(url, ready, load, error) { var onready, width, height, newWidth, newHeight, img = new Image(); img.src = url; // 如果图片被缓存,则直接返回缓存数据 if(img.complete) { ready.call(img); load && load.call(img); return; } width = img.width; height = img.height; // 加载错误后的事件 img.onerror = function() { error && error.call(img); onready.end = true; img = img.onload = img.onerror = null; }; // 图片尺寸就绪 onready = function() { newWidth = img.width; newHeight = img.height; if(newWidth !== width || newHeight !== height || // 如果图片已经在其他地方加载可使用面积检测 newWidth * newHeight > 1024 ) { ready.call(img); onready.end = true; } }; onready(); // 完全加载完毕的事件 img.onload = function() { // onload在定时器时间差范围内可能比onready快 // 这里进行检查并保证onready优先执行 !onready.end && onready(); load && load.call(img); // IE gif动画会循环执行onload,置空onload即可 img = img.onload = img.onerror = null; }; // 加入队列中定期执行 if(!onready.end) { list.push(onready); // 无论何时只允许出现一个定时器,减少浏览器性能损耗 if(intervalId === null) intervalId = setInterval(tick, 40); } }; })(); }(jQuery)); /* ======================================================================== * ZUI: lightbox.js * http://zui.sexy * ======================================================================== * Copyright (c) 2014-2016 cnezsoft.com; Licensed MIT * ======================================================================== */ (function($, window, Math) { 'use strict'; if(!$.fn.modalTrigger) throw new Error('modal & modalTrigger requires for lightbox'); if(!$.zui.imgReady) throw new Error('imgReady requires for lightbox'); var Lightbox = function(element, options) { this.$ = $(element); this.options = this.getOptions(options); this.init(); }; Lightbox.DEFAULTS = { modalTeamplate: '