lib/assets/javascripts/scrivito_sdk.js in scrivito_sdk-0.30.0 vs lib/assets/javascripts/scrivito_sdk.js in scrivito_sdk-0.40.0.rc1

- old
+ new

@@ -1,19558 +1,41 @@ -/*! - * jQuery UI Core 1.10.2 - * http://jqueryui.com - * - * Copyright 2013 jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/category/ui-core/ - */ - -(function( $, undefined ) { - -var uuid = 0, - runiqueId = /^ui-id-\d+$/; - -// $.ui might exist from components with no dependencies, e.g., $.ui.position -$.ui = $.ui || {}; - -$.extend( $.ui, { - version: "1.10.2", - - keyCode: { - BACKSPACE: 8, - COMMA: 188, - DELETE: 46, - DOWN: 40, - END: 35, - ENTER: 13, - ESCAPE: 27, - HOME: 36, - LEFT: 37, - NUMPAD_ADD: 107, - NUMPAD_DECIMAL: 110, - NUMPAD_DIVIDE: 111, - NUMPAD_ENTER: 108, - NUMPAD_MULTIPLY: 106, - NUMPAD_SUBTRACT: 109, - PAGE_DOWN: 34, - PAGE_UP: 33, - PERIOD: 190, - RIGHT: 39, - SPACE: 32, - TAB: 9, - UP: 38 - } -}); - -// plugins -$.fn.extend({ - focus: (function( orig ) { - return function( delay, fn ) { - return typeof delay === "number" ? - this.each(function() { - var elem = this; - setTimeout(function() { - $( elem ).focus(); - if ( fn ) { - fn.call( elem ); - } - }, delay ); - }) : - orig.apply( this, arguments ); - }; - })( $.fn.focus ), - - scrollParent: function() { - var scrollParent; - if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) { - scrollParent = this.parents().filter(function() { - return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); - }).eq(0); - } else { - scrollParent = this.parents().filter(function() { - return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); - }).eq(0); - } - - return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent; - }, - - zIndex: function( zIndex ) { - if ( zIndex !== undefined ) { - return this.css( "zIndex", zIndex ); - } - - if ( this.length ) { - var elem = $( this[ 0 ] ), position, value; - while ( elem.length && elem[ 0 ] !== document ) { - // Ignore z-index if position is set to a value where z-index is ignored by the browser - // This makes behavior of this function consistent across browsers - // WebKit always returns auto if the element is positioned - position = elem.css( "position" ); - if ( position === "absolute" || position === "relative" || position === "fixed" ) { - // IE returns 0 when zIndex is not specified - // other browsers return a string - // we ignore the case of nested elements with an explicit value of 0 - // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> - value = parseInt( elem.css( "zIndex" ), 10 ); - if ( !isNaN( value ) && value !== 0 ) { - return value; - } - } - elem = elem.parent(); - } - } - - return 0; - }, - - uniqueId: function() { - return this.each(function() { - if ( !this.id ) { - this.id = "ui-id-" + (++uuid); - } - }); - }, - - removeUniqueId: function() { - return this.each(function() { - if ( runiqueId.test( this.id ) ) { - $( this ).removeAttr( "id" ); - } - }); - } -}); - -// selectors -function focusable( element, isTabIndexNotNaN ) { - var map, mapName, img, - nodeName = element.nodeName.toLowerCase(); - if ( "area" === nodeName ) { - map = element.parentNode; - mapName = map.name; - if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { - return false; - } - img = $( "img[usemap=#" + mapName + "]" )[0]; - return !!img && visible( img ); - } - return ( /input|select|textarea|button|object/.test( nodeName ) ? - !element.disabled : - "a" === nodeName ? - element.href || isTabIndexNotNaN : - isTabIndexNotNaN) && - // the element and all of its ancestors must be visible - visible( element ); -} - -function visible( element ) { - return $.expr.filters.visible( element ) && - !$( element ).parents().addBack().filter(function() { - return $.css( this, "visibility" ) === "hidden"; - }).length; -} - -$.extend( $.expr[ ":" ], { - data: $.expr.createPseudo ? - $.expr.createPseudo(function( dataName ) { - return function( elem ) { - return !!$.data( elem, dataName ); - }; - }) : - // support: jQuery <1.8 - function( elem, i, match ) { - return !!$.data( elem, match[ 3 ] ); - }, - - focusable: function( element ) { - return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) ); - }, - - tabbable: function( element ) { - var tabIndex = $.attr( element, "tabindex" ), - isTabIndexNaN = isNaN( tabIndex ); - return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN ); - } -}); - -// support: jQuery <1.8 -if ( !$( "<a>" ).outerWidth( 1 ).jquery ) { - $.each( [ "Width", "Height" ], function( i, name ) { - var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ], - type = name.toLowerCase(), - orig = { - innerWidth: $.fn.innerWidth, - innerHeight: $.fn.innerHeight, - outerWidth: $.fn.outerWidth, - outerHeight: $.fn.outerHeight - }; - - function reduce( elem, size, border, margin ) { - $.each( side, function() { - size -= parseFloat( $.css( elem, "padding" + this ) ) || 0; - if ( border ) { - size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0; - } - if ( margin ) { - size -= parseFloat( $.css( elem, "margin" + this ) ) || 0; - } - }); - return size; - } - - $.fn[ "inner" + name ] = function( size ) { - if ( size === undefined ) { - return orig[ "inner" + name ].call( this ); - } - - return this.each(function() { - $( this ).css( type, reduce( this, size ) + "px" ); - }); - }; - - $.fn[ "outer" + name] = function( size, margin ) { - if ( typeof size !== "number" ) { - return orig[ "outer" + name ].call( this, size ); - } - - return this.each(function() { - $( this).css( type, reduce( this, size, true, margin ) + "px" ); - }); - }; - }); -} - -// support: jQuery <1.8 -if ( !$.fn.addBack ) { - $.fn.addBack = function( selector ) { - return this.add( selector == null ? - this.prevObject : this.prevObject.filter( selector ) - ); - }; -} - -// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413) -if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) { - $.fn.removeData = (function( removeData ) { - return function( key ) { - if ( arguments.length ) { - return removeData.call( this, $.camelCase( key ) ); - } else { - return removeData.call( this ); - } - }; - })( $.fn.removeData ); -} - - - - - -// deprecated -$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ); - -$.support.selectstart = "onselectstart" in document.createElement( "div" ); -$.fn.extend({ - disableSelection: function() { - return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) + - ".ui-disableSelection", function( event ) { - event.preventDefault(); - }); - }, - - enableSelection: function() { - return this.unbind( ".ui-disableSelection" ); - } -}); - -$.extend( $.ui, { - // $.ui.plugin is deprecated. Use the proxy pattern instead. - plugin: { - add: function( module, option, set ) { - var i, - proto = $.ui[ module ].prototype; - for ( i in set ) { - proto.plugins[ i ] = proto.plugins[ i ] || []; - proto.plugins[ i ].push( [ option, set[ i ] ] ); - } - }, - call: function( instance, name, args ) { - var i, - set = instance.plugins[ name ]; - if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) { - return; - } - - for ( i = 0; i < set.length; i++ ) { - if ( instance.options[ set[ i ][ 0 ] ] ) { - set[ i ][ 1 ].apply( instance.element, args ); - } - } - } - }, - - // only used by resizable - hasScroll: function( el, a ) { - - //If overflow is hidden, the element might have extra content, but the user wants to hide it - if ( $( el ).css( "overflow" ) === "hidden") { - return false; - } - - var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", - has = false; - - if ( el[ scroll ] > 0 ) { - return true; - } - - // TODO: determine which cases actually cause this to happen - // if the element doesn't have the scroll set, see if it's possible to - // set the scroll - el[ scroll ] = 1; - has = ( el[ scroll ] > 0 ); - el[ scroll ] = 0; - return has; - } -}); - -})( jQuery ); -/*! - * jQuery UI Widget 1.10.2 - * http://jqueryui.com - * - * Copyright 2013 jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/jQuery.widget/ - */ - -(function( $, undefined ) { - -var uuid = 0, - slice = Array.prototype.slice, - _cleanData = $.cleanData; -$.cleanData = function( elems ) { - for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { - try { - $( elem ).triggerHandler( "remove" ); - // http://bugs.jquery.com/ticket/8235 - } catch( e ) {} - } - _cleanData( elems ); -}; - -$.widget = function( name, base, prototype ) { - var fullName, existingConstructor, constructor, basePrototype, - // proxiedPrototype allows the provided prototype to remain unmodified - // so that it can be used as a mixin for multiple widgets (#8876) - proxiedPrototype = {}, - namespace = name.split( "." )[ 0 ]; - - name = name.split( "." )[ 1 ]; - fullName = namespace + "-" + name; - - if ( !prototype ) { - prototype = base; - base = $.Widget; - } - - // create selector for plugin - $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { - return !!$.data( elem, fullName ); - }; - - $[ namespace ] = $[ namespace ] || {}; - existingConstructor = $[ namespace ][ name ]; - constructor = $[ namespace ][ name ] = function( options, element ) { - // allow instantiation without "new" keyword - if ( !this._createWidget ) { - return new constructor( options, element ); - } - - // allow instantiation without initializing for simple inheritance - // must use "new" keyword (the code above always passes args) - if ( arguments.length ) { - this._createWidget( options, element ); - } - }; - // extend with the existing constructor to carry over any static properties - $.extend( constructor, existingConstructor, { - version: prototype.version, - // copy the object used to create the prototype in case we need to - // redefine the widget later - _proto: $.extend( {}, prototype ), - // track widgets that inherit from this widget in case this widget is - // redefined after a widget inherits from it - _childConstructors: [] - }); - - basePrototype = new base(); - // we need to make the options hash a property directly on the new instance - // otherwise we'll modify the options hash on the prototype that we're - // inheriting from - basePrototype.options = $.widget.extend( {}, basePrototype.options ); - $.each( prototype, function( prop, value ) { - if ( !$.isFunction( value ) ) { - proxiedPrototype[ prop ] = value; - return; - } - proxiedPrototype[ prop ] = (function() { - var _super = function() { - return base.prototype[ prop ].apply( this, arguments ); - }, - _superApply = function( args ) { - return base.prototype[ prop ].apply( this, args ); - }; - return function() { - var __super = this._super, - __superApply = this._superApply, - returnValue; - - this._super = _super; - this._superApply = _superApply; - - returnValue = value.apply( this, arguments ); - - this._super = __super; - this._superApply = __superApply; - - return returnValue; - }; - })(); - }); - constructor.prototype = $.widget.extend( basePrototype, { - // TODO: remove support for widgetEventPrefix - // always use the name + a colon as the prefix, e.g., draggable:start - // don't prefix for widgets that aren't DOM-based - widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name - }, proxiedPrototype, { - constructor: constructor, - namespace: namespace, - widgetName: name, - widgetFullName: fullName - }); - - // If this widget is being redefined then we need to find all widgets that - // are inheriting from it and redefine all of them so that they inherit from - // the new version of this widget. We're essentially trying to replace one - // level in the prototype chain. - if ( existingConstructor ) { - $.each( existingConstructor._childConstructors, function( i, child ) { - var childPrototype = child.prototype; - - // redefine the child widget using the same prototype that was - // originally used, but inherit from the new version of the base - $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); - }); - // remove the list of existing child constructors from the old constructor - // so the old child constructors can be garbage collected - delete existingConstructor._childConstructors; - } else { - base._childConstructors.push( constructor ); - } - - $.widget.bridge( name, constructor ); -}; - -$.widget.extend = function( target ) { - var input = slice.call( arguments, 1 ), - inputIndex = 0, - inputLength = input.length, - key, - value; - for ( ; inputIndex < inputLength; inputIndex++ ) { - for ( key in input[ inputIndex ] ) { - value = input[ inputIndex ][ key ]; - if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { - // Clone objects - if ( $.isPlainObject( value ) ) { - target[ key ] = $.isPlainObject( target[ key ] ) ? - $.widget.extend( {}, target[ key ], value ) : - // Don't extend strings, arrays, etc. with objects - $.widget.extend( {}, value ); - // Copy everything else by reference - } else { - target[ key ] = value; - } - } - } - } - return target; -}; - -$.widget.bridge = function( name, object ) { - var fullName = object.prototype.widgetFullName || name; - $.fn[ name ] = function( options ) { - var isMethodCall = typeof options === "string", - args = slice.call( arguments, 1 ), - returnValue = this; - - // allow multiple hashes to be passed on init - options = !isMethodCall && args.length ? - $.widget.extend.apply( null, [ options ].concat(args) ) : - options; - - if ( isMethodCall ) { - this.each(function() { - var methodValue, - instance = $.data( this, fullName ); - if ( !instance ) { - return $.error( "cannot call methods on " + name + " prior to initialization; " + - "attempted to call method '" + options + "'" ); - } - if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { - return $.error( "no such method '" + options + "' for " + name + " widget instance" ); - } - methodValue = instance[ options ].apply( instance, args ); - if ( methodValue !== instance && methodValue !== undefined ) { - returnValue = methodValue && methodValue.jquery ? - returnValue.pushStack( methodValue.get() ) : - methodValue; - return false; - } - }); - } else { - this.each(function() { - var instance = $.data( this, fullName ); - if ( instance ) { - instance.option( options || {} )._init(); - } else { - $.data( this, fullName, new object( options, this ) ); - } - }); - } - - return returnValue; - }; -}; - -$.Widget = function( /* options, element */ ) {}; -$.Widget._childConstructors = []; - -$.Widget.prototype = { - widgetName: "widget", - widgetEventPrefix: "", - defaultElement: "<div>", - options: { - disabled: false, - - // callbacks - create: null - }, - _createWidget: function( options, element ) { - element = $( element || this.defaultElement || this )[ 0 ]; - this.element = $( element ); - this.uuid = uuid++; - this.eventNamespace = "." + this.widgetName + this.uuid; - this.options = $.widget.extend( {}, - this.options, - this._getCreateOptions(), - options ); - - this.bindings = $(); - this.hoverable = $(); - this.focusable = $(); - - if ( element !== this ) { - $.data( element, this.widgetFullName, this ); - this._on( true, this.element, { - remove: function( event ) { - if ( event.target === element ) { - this.destroy(); - } - } - }); - this.document = $( element.style ? - // element within the document - element.ownerDocument : - // element is window or document - element.document || element ); - this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); - } - - this._create(); - this._trigger( "create", null, this._getCreateEventData() ); - this._init(); - }, - _getCreateOptions: $.noop, - _getCreateEventData: $.noop, - _create: $.noop, - _init: $.noop, - - destroy: function() { - this._destroy(); - // we can probably remove the unbind calls in 2.0 - // all event bindings should go through this._on() - this.element - .unbind( this.eventNamespace ) - // 1.9 BC for #7810 - // TODO remove dual storage - .removeData( this.widgetName ) - .removeData( this.widgetFullName ) - // support: jquery <1.6.3 - // http://bugs.jquery.com/ticket/9413 - .removeData( $.camelCase( this.widgetFullName ) ); - this.widget() - .unbind( this.eventNamespace ) - .removeAttr( "aria-disabled" ) - .removeClass( - this.widgetFullName + "-disabled " + - "ui-state-disabled" ); - - // clean up events and states - this.bindings.unbind( this.eventNamespace ); - this.hoverable.removeClass( "ui-state-hover" ); - this.focusable.removeClass( "ui-state-focus" ); - }, - _destroy: $.noop, - - widget: function() { - return this.element; - }, - - option: function( key, value ) { - var options = key, - parts, - curOption, - i; - - if ( arguments.length === 0 ) { - // don't return a reference to the internal hash - return $.widget.extend( {}, this.options ); - } - - if ( typeof key === "string" ) { - // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } - options = {}; - parts = key.split( "." ); - key = parts.shift(); - if ( parts.length ) { - curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); - for ( i = 0; i < parts.length - 1; i++ ) { - curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; - curOption = curOption[ parts[ i ] ]; - } - key = parts.pop(); - if ( value === undefined ) { - return curOption[ key ] === undefined ? null : curOption[ key ]; - } - curOption[ key ] = value; - } else { - if ( value === undefined ) { - return this.options[ key ] === undefined ? null : this.options[ key ]; - } - options[ key ] = value; - } - } - - this._setOptions( options ); - - return this; - }, - _setOptions: function( options ) { - var key; - - for ( key in options ) { - this._setOption( key, options[ key ] ); - } - - return this; - }, - _setOption: function( key, value ) { - this.options[ key ] = value; - - if ( key === "disabled" ) { - this.widget() - .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value ) - .attr( "aria-disabled", value ); - this.hoverable.removeClass( "ui-state-hover" ); - this.focusable.removeClass( "ui-state-focus" ); - } - - return this; - }, - - enable: function() { - return this._setOption( "disabled", false ); - }, - disable: function() { - return this._setOption( "disabled", true ); - }, - - _on: function( suppressDisabledCheck, element, handlers ) { - var delegateElement, - instance = this; - - // no suppressDisabledCheck flag, shuffle arguments - if ( typeof suppressDisabledCheck !== "boolean" ) { - handlers = element; - element = suppressDisabledCheck; - suppressDisabledCheck = false; - } - - // no element argument, shuffle and use this.element - if ( !handlers ) { - handlers = element; - element = this.element; - delegateElement = this.widget(); - } else { - // accept selectors, DOM elements - element = delegateElement = $( element ); - this.bindings = this.bindings.add( element ); - } - - $.each( handlers, function( event, handler ) { - function handlerProxy() { - // allow widgets to customize the disabled handling - // - disabled as an array instead of boolean - // - disabled class as method for disabling individual parts - if ( !suppressDisabledCheck && - ( instance.options.disabled === true || - $( this ).hasClass( "ui-state-disabled" ) ) ) { - return; - } - return ( typeof handler === "string" ? instance[ handler ] : handler ) - .apply( instance, arguments ); - } - - // copy the guid so direct unbinding works - if ( typeof handler !== "string" ) { - handlerProxy.guid = handler.guid = - handler.guid || handlerProxy.guid || $.guid++; - } - - var match = event.match( /^(\w+)\s*(.*)$/ ), - eventName = match[1] + instance.eventNamespace, - selector = match[2]; - if ( selector ) { - delegateElement.delegate( selector, eventName, handlerProxy ); - } else { - element.bind( eventName, handlerProxy ); - } - }); - }, - - _off: function( element, eventName ) { - eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; - element.unbind( eventName ).undelegate( eventName ); - }, - - _delay: function( handler, delay ) { - function handlerProxy() { - return ( typeof handler === "string" ? instance[ handler ] : handler ) - .apply( instance, arguments ); - } - var instance = this; - return setTimeout( handlerProxy, delay || 0 ); - }, - - _hoverable: function( element ) { - this.hoverable = this.hoverable.add( element ); - this._on( element, { - mouseenter: function( event ) { - $( event.currentTarget ).addClass( "ui-state-hover" ); - }, - mouseleave: function( event ) { - $( event.currentTarget ).removeClass( "ui-state-hover" ); - } - }); - }, - - _focusable: function( element ) { - this.focusable = this.focusable.add( element ); - this._on( element, { - focusin: function( event ) { - $( event.currentTarget ).addClass( "ui-state-focus" ); - }, - focusout: function( event ) { - $( event.currentTarget ).removeClass( "ui-state-focus" ); - } - }); - }, - - _trigger: function( type, event, data ) { - var prop, orig, - callback = this.options[ type ]; - - data = data || {}; - event = $.Event( event ); - event.type = ( type === this.widgetEventPrefix ? - type : - this.widgetEventPrefix + type ).toLowerCase(); - // the original event may come from any element - // so we need to reset the target on the new event - event.target = this.element[ 0 ]; - - // copy original event properties over to the new event - orig = event.originalEvent; - if ( orig ) { - for ( prop in orig ) { - if ( !( prop in event ) ) { - event[ prop ] = orig[ prop ]; - } - } - } - - this.element.trigger( event, data ); - return !( $.isFunction( callback ) && - callback.apply( this.element[0], [ event ].concat( data ) ) === false || - event.isDefaultPrevented() ); - } -}; - -$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { - $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { - if ( typeof options === "string" ) { - options = { effect: options }; - } - var hasOptions, - effectName = !options ? - method : - options === true || typeof options === "number" ? - defaultEffect : - options.effect || defaultEffect; - options = options || {}; - if ( typeof options === "number" ) { - options = { duration: options }; - } - hasOptions = !$.isEmptyObject( options ); - options.complete = callback; - if ( options.delay ) { - element.delay( options.delay ); - } - if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { - element[ method ]( options ); - } else if ( effectName !== method && element[ effectName ] ) { - element[ effectName ]( options.duration, options.easing, callback ); - } else { - element.queue(function( next ) { - $( this )[ method ](); - if ( callback ) { - callback.call( element[ 0 ] ); - } - next(); - }); - } - }; -}); - -})( jQuery ); -/*! - * jQuery UI Mouse 1.10.2 - * http://jqueryui.com - * - * Copyright 2013 jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/mouse/ - * - * Depends: - * jquery.ui.widget.js - */ - -(function( $, undefined ) { - -var mouseHandled = false; -$( document ).mouseup( function() { - mouseHandled = false; -}); - -$.widget("ui.mouse", { - version: "1.10.2", - options: { - cancel: "input,textarea,button,select,option", - distance: 1, - delay: 0 - }, - _mouseInit: function() { - var that = this; - - this.element - .bind("mousedown."+this.widgetName, function(event) { - return that._mouseDown(event); - }) - .bind("click."+this.widgetName, function(event) { - if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) { - $.removeData(event.target, that.widgetName + ".preventClickEvent"); - event.stopImmediatePropagation(); - return false; - } - }); - - this.started = false; - }, - - // TODO: make sure destroying one instance of mouse doesn't mess with - // other instances of mouse - _mouseDestroy: function() { - this.element.unbind("."+this.widgetName); - if ( this._mouseMoveDelegate ) { - $(document) - .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate) - .unbind("mouseup."+this.widgetName, this._mouseUpDelegate); - } - }, - - _mouseDown: function(event) { - // don't let more than one widget handle mouseStart - if( mouseHandled ) { return; } - - // we may have missed mouseup (out of window) - (this._mouseStarted && this._mouseUp(event)); - - this._mouseDownEvent = event; - - var that = this, - btnIsLeft = (event.which === 1), - // event.target.nodeName works around a bug in IE 8 with - // disabled inputs (#7620) - elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false); - if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) { - return true; - } - - this.mouseDelayMet = !this.options.delay; - if (!this.mouseDelayMet) { - this._mouseDelayTimer = setTimeout(function() { - that.mouseDelayMet = true; - }, this.options.delay); - } - - if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { - this._mouseStarted = (this._mouseStart(event) !== false); - if (!this._mouseStarted) { - event.preventDefault(); - return true; - } - } - - // Click event may never have fired (Gecko & Opera) - if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) { - $.removeData(event.target, this.widgetName + ".preventClickEvent"); - } - - // these delegates are required to keep context - this._mouseMoveDelegate = function(event) { - return that._mouseMove(event); - }; - this._mouseUpDelegate = function(event) { - return that._mouseUp(event); - }; - $(document) - .bind("mousemove."+this.widgetName, this._mouseMoveDelegate) - .bind("mouseup."+this.widgetName, this._mouseUpDelegate); - - event.preventDefault(); - - mouseHandled = true; - return true; - }, - - _mouseMove: function(event) { - // IE mouseup check - mouseup happened when mouse was out of window - if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) { - return this._mouseUp(event); - } - - if (this._mouseStarted) { - this._mouseDrag(event); - return event.preventDefault(); - } - - if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { - this._mouseStarted = - (this._mouseStart(this._mouseDownEvent, event) !== false); - (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event)); - } - - return !this._mouseStarted; - }, - - _mouseUp: function(event) { - $(document) - .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate) - .unbind("mouseup."+this.widgetName, this._mouseUpDelegate); - - if (this._mouseStarted) { - this._mouseStarted = false; - - if (event.target === this._mouseDownEvent.target) { - $.data(event.target, this.widgetName + ".preventClickEvent", true); - } - - this._mouseStop(event); - } - - return false; - }, - - _mouseDistanceMet: function(event) { - return (Math.max( - Math.abs(this._mouseDownEvent.pageX - event.pageX), - Math.abs(this._mouseDownEvent.pageY - event.pageY) - ) >= this.options.distance - ); - }, - - _mouseDelayMet: function(/* event */) { - return this.mouseDelayMet; - }, - - // These are placeholder methods, to be overriden by extending plugin - _mouseStart: function(/* event */) {}, - _mouseDrag: function(/* event */) {}, - _mouseStop: function(/* event */) {}, - _mouseCapture: function(/* event */) { return true; } -}); - -})(jQuery); -/*! - * jQuery UI Sortable 1.10.2 - * http://jqueryui.com - * - * Copyright 2013 jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/sortable/ - * - * Depends: - * jquery.ui.core.js - * jquery.ui.mouse.js - * jquery.ui.widget.js - */ - -(function( $, undefined ) { - -/*jshint loopfunc: true */ - -function isOverAxis( x, reference, size ) { - return ( x > reference ) && ( x < ( reference + size ) ); -} - -function isFloating(item) { - return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display")); -} - -$.widget("ui.sortable", $.ui.mouse, { - version: "1.10.2", - widgetEventPrefix: "sort", - ready: false, - options: { - appendTo: "parent", - axis: false, - connectWith: false, - containment: false, - cursor: "auto", - cursorAt: false, - dropOnEmpty: true, - forcePlaceholderSize: false, - forceHelperSize: false, - grid: false, - handle: false, - helper: "original", - items: "> *", - opacity: false, - placeholder: false, - revert: false, - scroll: true, - scrollSensitivity: 20, - scrollSpeed: 20, - scope: "default", - tolerance: "intersect", - zIndex: 1000, - - // callbacks - activate: null, - beforeStop: null, - change: null, - deactivate: null, - out: null, - over: null, - receive: null, - remove: null, - sort: null, - start: null, - stop: null, - update: null - }, - _create: function() { - - var o = this.options; - this.containerCache = {}; - this.element.addClass("ui-sortable"); - - //Get the items - this.refresh(); - - //Let's determine if the items are being displayed horizontally - this.floating = this.items.length ? o.axis === "x" || isFloating(this.items[0].item) : false; - - //Let's determine the parent's offset - this.offset = this.element.offset(); - - //Initialize mouse events for interaction - this._mouseInit(); - - //We're ready to go - this.ready = true; - - }, - - _destroy: function() { - this.element - .removeClass("ui-sortable ui-sortable-disabled"); - this._mouseDestroy(); - - for ( var i = this.items.length - 1; i >= 0; i-- ) { - this.items[i].item.removeData(this.widgetName + "-item"); - } - - return this; - }, - - _setOption: function(key, value){ - if ( key === "disabled" ) { - this.options[ key ] = value; - - this.widget().toggleClass( "ui-sortable-disabled", !!value ); - } else { - // Don't call widget base _setOption for disable as it adds ui-state-disabled class - $.Widget.prototype._setOption.apply(this, arguments); - } - }, - - _mouseCapture: function(event, overrideHandle) { - var currentItem = null, - validHandle = false, - that = this; - - if (this.reverting) { - return false; - } - - if(this.options.disabled || this.options.type === "static") { - return false; - } - - //We have to refresh the items data once first - this._refreshItems(event); - - //Find out if the clicked node (or one of its parents) is a actual item in this.items - $(event.target).parents().each(function() { - if($.data(this, that.widgetName + "-item") === that) { - currentItem = $(this); - return false; - } - }); - if($.data(event.target, that.widgetName + "-item") === that) { - currentItem = $(event.target); - } - - if(!currentItem) { - return false; - } - if(this.options.handle && !overrideHandle) { - $(this.options.handle, currentItem).find("*").addBack().each(function() { - if(this === event.target) { - validHandle = true; - } - }); - if(!validHandle) { - return false; - } - } - - this.currentItem = currentItem; - this._removeCurrentsFromItems(); - return true; - - }, - - _mouseStart: function(event, overrideHandle, noActivation) { - - var i, body, - o = this.options; - - this.currentContainer = this; - - //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture - this.refreshPositions(); - - //Create and append the visible helper - this.helper = this._createHelper(event); - - //Cache the helper size - this._cacheHelperProportions(); - - /* - * - Position generation - - * This block generates everything position related - it's the core of draggables. - */ - - //Cache the margins of the original element - this._cacheMargins(); - - //Get the next scrolling parent - this.scrollParent = this.helper.scrollParent(); - - //The element's absolute position on the page minus margins - this.offset = this.currentItem.offset(); - this.offset = { - top: this.offset.top - this.margins.top, - left: this.offset.left - this.margins.left - }; - - $.extend(this.offset, { - click: { //Where the click happened, relative to the element - left: event.pageX - this.offset.left, - top: event.pageY - this.offset.top - }, - parent: this._getParentOffset(), - relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper - }); - - // Only after we got the offset, we can change the helper's position to absolute - // TODO: Still need to figure out a way to make relative sorting possible - this.helper.css("position", "absolute"); - this.cssPosition = this.helper.css("position"); - - //Generate the original position - this.originalPosition = this._generatePosition(event); - this.originalPageX = event.pageX; - this.originalPageY = event.pageY; - - //Adjust the mouse offset relative to the helper if "cursorAt" is supplied - (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); - - //Cache the former DOM position - this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] }; - - //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way - if(this.helper[0] !== this.currentItem[0]) { - this.currentItem.hide(); - } - - //Create the placeholder - this._createPlaceholder(); - - //Set a containment if given in the options - if(o.containment) { - this._setContainment(); - } - - if( o.cursor && o.cursor !== "auto" ) { // cursor option - body = this.document.find( "body" ); - - // support: IE - this.storedCursor = body.css( "cursor" ); - body.css( "cursor", o.cursor ); - - this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body ); - } - - if(o.opacity) { // opacity option - if (this.helper.css("opacity")) { - this._storedOpacity = this.helper.css("opacity"); - } - this.helper.css("opacity", o.opacity); - } - - if(o.zIndex) { // zIndex option - if (this.helper.css("zIndex")) { - this._storedZIndex = this.helper.css("zIndex"); - } - this.helper.css("zIndex", o.zIndex); - } - - //Prepare scrolling - if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { - this.overflowOffset = this.scrollParent.offset(); - } - - //Call callbacks - this._trigger("start", event, this._uiHash()); - - //Recache the helper size - if(!this._preserveHelperProportions) { - this._cacheHelperProportions(); - } - - - //Post "activate" events to possible containers - if( !noActivation ) { - for ( i = this.containers.length - 1; i >= 0; i-- ) { - this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) ); - } - } - - //Prepare possible droppables - if($.ui.ddmanager) { - $.ui.ddmanager.current = this; - } - - if ($.ui.ddmanager && !o.dropBehaviour) { - $.ui.ddmanager.prepareOffsets(this, event); - } - - this.dragging = true; - - this.helper.addClass("ui-sortable-helper"); - this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position - return true; - - }, - - _mouseDrag: function(event) { - var i, item, itemElement, intersection, - o = this.options, - scrolled = false; - - //Compute the helpers position - this.position = this._generatePosition(event); - this.positionAbs = this._convertPositionTo("absolute"); - - if (!this.lastPositionAbs) { - this.lastPositionAbs = this.positionAbs; - } - - //Do scrolling - if(this.options.scroll) { - if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { - - if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { - this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed; - } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) { - this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed; - } - - if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { - this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed; - } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) { - this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed; - } - - } else { - - if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) { - scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); - } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { - scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); - } - - if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { - scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); - } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { - scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); - } - - } - - if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { - $.ui.ddmanager.prepareOffsets(this, event); - } - } - - //Regenerate the absolute position used for position checks - this.positionAbs = this._convertPositionTo("absolute"); - - //Set the helper position - if(!this.options.axis || this.options.axis !== "y") { - this.helper[0].style.left = this.position.left+"px"; - } - if(!this.options.axis || this.options.axis !== "x") { - this.helper[0].style.top = this.position.top+"px"; - } - - //Rearrange - for (i = this.items.length - 1; i >= 0; i--) { - - //Cache variables and intersection, continue if no intersection - item = this.items[i]; - itemElement = item.item[0]; - intersection = this._intersectsWithPointer(item); - if (!intersection) { - continue; - } - - // Only put the placeholder inside the current Container, skip all - // items form other containers. This works because when moving - // an item from one container to another the - // currentContainer is switched before the placeholder is moved. - // - // Without this moving items in "sub-sortables" can cause the placeholder to jitter - // beetween the outer and inner container. - if (item.instance !== this.currentContainer) { - continue; - } - - // cannot intersect with itself - // no useless actions that have been done before - // no action if the item moved is the parent of the item checked - if (itemElement !== this.currentItem[0] && - this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement && - !$.contains(this.placeholder[0], itemElement) && - (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true) - ) { - - this.direction = intersection === 1 ? "down" : "up"; - - if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) { - this._rearrange(event, item); - } else { - break; - } - - this._trigger("change", event, this._uiHash()); - break; - } - } - - //Post events to containers - this._contactContainers(event); - - //Interconnect with droppables - if($.ui.ddmanager) { - $.ui.ddmanager.drag(this, event); - } - - //Call callbacks - this._trigger("sort", event, this._uiHash()); - - this.lastPositionAbs = this.positionAbs; - return false; - - }, - - _mouseStop: function(event, noPropagation) { - - if(!event) { - return; - } - - //If we are using droppables, inform the manager about the drop - if ($.ui.ddmanager && !this.options.dropBehaviour) { - $.ui.ddmanager.drop(this, event); - } - - if(this.options.revert) { - var that = this, - cur = this.placeholder.offset(), - axis = this.options.axis, - animation = {}; - - if ( !axis || axis === "x" ) { - animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft); - } - if ( !axis || axis === "y" ) { - animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop); - } - this.reverting = true; - $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() { - that._clear(event); - }); - } else { - this._clear(event, noPropagation); - } - - return false; - - }, - - cancel: function() { - - if(this.dragging) { - - this._mouseUp({ target: null }); - - if(this.options.helper === "original") { - this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); - } else { - this.currentItem.show(); - } - - //Post deactivating events to containers - for (var i = this.containers.length - 1; i >= 0; i--){ - this.containers[i]._trigger("deactivate", null, this._uiHash(this)); - if(this.containers[i].containerCache.over) { - this.containers[i]._trigger("out", null, this._uiHash(this)); - this.containers[i].containerCache.over = 0; - } - } - - } - - if (this.placeholder) { - //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! - if(this.placeholder[0].parentNode) { - this.placeholder[0].parentNode.removeChild(this.placeholder[0]); - } - if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) { - this.helper.remove(); - } - - $.extend(this, { - helper: null, - dragging: false, - reverting: false, - _noFinalSort: null - }); - - if(this.domPosition.prev) { - $(this.domPosition.prev).after(this.currentItem); - } else { - $(this.domPosition.parent).prepend(this.currentItem); - } - } - - return this; - - }, - - serialize: function(o) { - - var items = this._getItemsAsjQuery(o && o.connected), - str = []; - o = o || {}; - - $(items).each(function() { - var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/)); - if (res) { - str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2])); - } - }); - - if(!str.length && o.key) { - str.push(o.key + "="); - } - - return str.join("&"); - - }, - - toArray: function(o) { - - var items = this._getItemsAsjQuery(o && o.connected), - ret = []; - - o = o || {}; - - items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); }); - return ret; - - }, - - /* Be careful with the following core functions */ - _intersectsWith: function(item) { - - var x1 = this.positionAbs.left, - x2 = x1 + this.helperProportions.width, - y1 = this.positionAbs.top, - y2 = y1 + this.helperProportions.height, - l = item.left, - r = l + item.width, - t = item.top, - b = t + item.height, - dyClick = this.offset.click.top, - dxClick = this.offset.click.left, - isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r; - - if ( this.options.tolerance === "pointer" || - this.options.forcePointerForContainers || - (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"]) - ) { - return isOverElement; - } else { - - return (l < x1 + (this.helperProportions.width / 2) && // Right Half - x2 - (this.helperProportions.width / 2) < r && // Left Half - t < y1 + (this.helperProportions.height / 2) && // Bottom Half - y2 - (this.helperProportions.height / 2) < b ); // Top Half - - } - }, - - _intersectsWithPointer: function(item) { - - var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), - isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), - isOverElement = isOverElementHeight && isOverElementWidth, - verticalDirection = this._getDragVerticalDirection(), - horizontalDirection = this._getDragHorizontalDirection(); - - if (!isOverElement) { - return false; - } - - return this.floating ? - ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 ) - : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) ); - - }, - - _intersectsWithSides: function(item) { - - var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height), - isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), - verticalDirection = this._getDragVerticalDirection(), - horizontalDirection = this._getDragHorizontalDirection(); - - if (this.floating && horizontalDirection) { - return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf)); - } else { - return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf)); - } - - }, - - _getDragVerticalDirection: function() { - var delta = this.positionAbs.top - this.lastPositionAbs.top; - return delta !== 0 && (delta > 0 ? "down" : "up"); - }, - - _getDragHorizontalDirection: function() { - var delta = this.positionAbs.left - this.lastPositionAbs.left; - return delta !== 0 && (delta > 0 ? "right" : "left"); - }, - - refresh: function(event) { - this._refreshItems(event); - this.refreshPositions(); - return this; - }, - - _connectWith: function() { - var options = this.options; - return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith; - }, - - _getItemsAsjQuery: function(connected) { - - var i, j, cur, inst, - items = [], - queries = [], - connectWith = this._connectWith(); - - if(connectWith && connected) { - for (i = connectWith.length - 1; i >= 0; i--){ - cur = $(connectWith[i]); - for ( j = cur.length - 1; j >= 0; j--){ - inst = $.data(cur[j], this.widgetFullName); - if(inst && inst !== this && !inst.options.disabled) { - queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), inst]); - } - } - } - } - - queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), this]); - - for (i = queries.length - 1; i >= 0; i--){ - queries[i][0].each(function() { - items.push(this); - }); - } - - return $(items); - - }, - - _removeCurrentsFromItems: function() { - - var list = this.currentItem.find(":data(" + this.widgetName + "-item)"); - - this.items = $.grep(this.items, function (item) { - for (var j=0; j < list.length; j++) { - if(list[j] === item.item[0]) { - return false; - } - } - return true; - }); - - }, - - _refreshItems: function(event) { - - this.items = []; - this.containers = [this]; - - var i, j, cur, inst, targetData, _queries, item, queriesLength, - items = this.items, - queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]], - connectWith = this._connectWith(); - - if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down - for (i = connectWith.length - 1; i >= 0; i--){ - cur = $(connectWith[i]); - for (j = cur.length - 1; j >= 0; j--){ - inst = $.data(cur[j], this.widgetFullName); - if(inst && inst !== this && !inst.options.disabled) { - queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]); - this.containers.push(inst); - } - } - } - } - - for (i = queries.length - 1; i >= 0; i--) { - targetData = queries[i][1]; - _queries = queries[i][0]; - - for (j=0, queriesLength = _queries.length; j < queriesLength; j++) { - item = $(_queries[j]); - - item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager) - - items.push({ - item: item, - instance: targetData, - width: 0, height: 0, - left: 0, top: 0 - }); - } - } - - }, - - refreshPositions: function(fast) { - - //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change - if(this.offsetParent && this.helper) { - this.offset.parent = this._getParentOffset(); - } - - var i, item, t, p; - - for (i = this.items.length - 1; i >= 0; i--){ - item = this.items[i]; - - //We ignore calculating positions of all connected containers when we're not over them - if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) { - continue; - } - - t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item; - - if (!fast) { - item.width = t.outerWidth(); - item.height = t.outerHeight(); - } - - p = t.offset(); - item.left = p.left; - item.top = p.top; - } - - if(this.options.custom && this.options.custom.refreshContainers) { - this.options.custom.refreshContainers.call(this); - } else { - for (i = this.containers.length - 1; i >= 0; i--){ - p = this.containers[i].element.offset(); - this.containers[i].containerCache.left = p.left; - this.containers[i].containerCache.top = p.top; - this.containers[i].containerCache.width = this.containers[i].element.outerWidth(); - this.containers[i].containerCache.height = this.containers[i].element.outerHeight(); - } - } - - return this; - }, - - _createPlaceholder: function(that) { - that = that || this; - var className, - o = that.options; - - if(!o.placeholder || o.placeholder.constructor === String) { - className = o.placeholder; - o.placeholder = { - element: function() { - - var nodeName = that.currentItem[0].nodeName.toLowerCase(), - element = $( that.document[0].createElement( nodeName ) ) - .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder") - .removeClass("ui-sortable-helper"); - - if ( nodeName === "tr" ) { - // Use a high colspan to force the td to expand the full - // width of the table (browsers are smart enough to - // handle this properly) - element.append( "<td colspan='99'>&#160;</td>" ); - } else if ( nodeName === "img" ) { - element.attr( "src", that.currentItem.attr( "src" ) ); - } - - if ( !className ) { - element.css( "visibility", "hidden" ); - } - - return element; - }, - update: function(container, p) { - - // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that - // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified - if(className && !o.forcePlaceholderSize) { - return; - } - - //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item - if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); } - if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); } - } - }; - } - - //Create the placeholder - that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem)); - - //Append it after the actual current item - that.currentItem.after(that.placeholder); - - //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) - o.placeholder.update(that, that.placeholder); - - }, - - _contactContainers: function(event) { - var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom, floating, - innermostContainer = null, - innermostIndex = null; - - // get innermost container that intersects with item - for (i = this.containers.length - 1; i >= 0; i--) { - - // never consider a container that's located within the item itself - if($.contains(this.currentItem[0], this.containers[i].element[0])) { - continue; - } - - if(this._intersectsWith(this.containers[i].containerCache)) { - - // if we've already found a container and it's more "inner" than this, then continue - if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) { - continue; - } - - innermostContainer = this.containers[i]; - innermostIndex = i; - - } else { - // container doesn't intersect. trigger "out" event if necessary - if(this.containers[i].containerCache.over) { - this.containers[i]._trigger("out", event, this._uiHash(this)); - this.containers[i].containerCache.over = 0; - } - } - - } - - // if no intersecting containers found, return - if(!innermostContainer) { - return; - } - - // move the item into the container if it's not there already - if(this.containers.length === 1) { - if (!this.containers[innermostIndex].containerCache.over) { - this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); - this.containers[innermostIndex].containerCache.over = 1; - } - } else { - - //When entering a new container, we will find the item with the least distance and append our item near it - dist = 10000; - itemWithLeastDistance = null; - floating = innermostContainer.floating || isFloating(this.currentItem); - posProperty = floating ? "left" : "top"; - sizeProperty = floating ? "width" : "height"; - base = this.positionAbs[posProperty] + this.offset.click[posProperty]; - for (j = this.items.length - 1; j >= 0; j--) { - if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) { - continue; - } - if(this.items[j].item[0] === this.currentItem[0]) { - continue; - } - if (floating && !isOverAxis(this.positionAbs.top + this.offset.click.top, this.items[j].top, this.items[j].height)) { - continue; - } - cur = this.items[j].item.offset()[posProperty]; - nearBottom = false; - if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){ - nearBottom = true; - cur += this.items[j][sizeProperty]; - } - - if(Math.abs(cur - base) < dist) { - dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j]; - this.direction = nearBottom ? "up": "down"; - } - } - - //Check if dropOnEmpty is enabled - if(!itemWithLeastDistance && !this.options.dropOnEmpty) { - return; - } - - if(this.currentContainer === this.containers[innermostIndex]) { - return; - } - - itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); - this._trigger("change", event, this._uiHash()); - this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); - this.currentContainer = this.containers[innermostIndex]; - - //Update the placeholder - this.options.placeholder.update(this.currentContainer, this.placeholder); - - this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); - this.containers[innermostIndex].containerCache.over = 1; - } - - - }, - - _createHelper: function(event) { - - var o = this.options, - helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem); - - //Add the helper to the DOM if that didn't happen already - if(!helper.parents("body").length) { - $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]); - } - - if(helper[0] === this.currentItem[0]) { - this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") }; - } - - if(!helper[0].style.width || o.forceHelperSize) { - helper.width(this.currentItem.width()); - } - if(!helper[0].style.height || o.forceHelperSize) { - helper.height(this.currentItem.height()); - } - - return helper; - - }, - - _adjustOffsetFromHelper: function(obj) { - if (typeof obj === "string") { - obj = obj.split(" "); - } - if ($.isArray(obj)) { - obj = {left: +obj[0], top: +obj[1] || 0}; - } - if ("left" in obj) { - this.offset.click.left = obj.left + this.margins.left; - } - if ("right" in obj) { - this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; - } - if ("top" in obj) { - this.offset.click.top = obj.top + this.margins.top; - } - if ("bottom" in obj) { - this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; - } - }, - - _getParentOffset: function() { - - - //Get the offsetParent and cache its position - this.offsetParent = this.helper.offsetParent(); - var po = this.offsetParent.offset(); - - // This is a special case where we need to modify a offset calculated on start, since the following happened: - // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent - // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that - // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag - if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { - po.left += this.scrollParent.scrollLeft(); - po.top += this.scrollParent.scrollTop(); - } - - // This needs to be actually done for all browsers, since pageX/pageY includes this information - // with an ugly IE fix - if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) { - po = { top: 0, left: 0 }; - } - - return { - top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), - left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) - }; - - }, - - _getRelativeOffset: function() { - - if(this.cssPosition === "relative") { - var p = this.currentItem.position(); - return { - top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), - left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() - }; - } else { - return { top: 0, left: 0 }; - } - - }, - - _cacheMargins: function() { - this.margins = { - left: (parseInt(this.currentItem.css("marginLeft"),10) || 0), - top: (parseInt(this.currentItem.css("marginTop"),10) || 0) - }; - }, - - _cacheHelperProportions: function() { - this.helperProportions = { - width: this.helper.outerWidth(), - height: this.helper.outerHeight() - }; - }, - - _setContainment: function() { - - var ce, co, over, - o = this.options; - if(o.containment === "parent") { - o.containment = this.helper[0].parentNode; - } - if(o.containment === "document" || o.containment === "window") { - this.containment = [ - 0 - this.offset.relative.left - this.offset.parent.left, - 0 - this.offset.relative.top - this.offset.parent.top, - $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left, - ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top - ]; - } - - if(!(/^(document|window|parent)$/).test(o.containment)) { - ce = $(o.containment)[0]; - co = $(o.containment).offset(); - over = ($(ce).css("overflow") !== "hidden"); - - this.containment = [ - co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left, - co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top, - co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left, - co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top - ]; - } - - }, - - _convertPositionTo: function(d, pos) { - - if(!pos) { - pos = this.position; - } - var mod = d === "absolute" ? 1 : -1, - scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, - scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); - - return { - top: ( - pos.top + // The absolute mouse position - this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) - ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) - ), - left: ( - pos.left + // The absolute mouse position - this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) - ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) - ) - }; - - }, - - _generatePosition: function(event) { - - var top, left, - o = this.options, - pageX = event.pageX, - pageY = event.pageY, - scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); - - // This is another very weird special case that only happens for relative elements: - // 1. If the css position is relative - // 2. and the scroll parent is the document or similar to the offset parent - // we have to refresh the relative offset during the scroll so there are no jumps - if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) { - this.offset.relative = this._getRelativeOffset(); - } - - /* - * - Position constraining - - * Constrain the position to a mix of grid, containment. - */ - - if(this.originalPosition) { //If we are not dragging yet, we won't check for options - - if(this.containment) { - if(event.pageX - this.offset.click.left < this.containment[0]) { - pageX = this.containment[0] + this.offset.click.left; - } - if(event.pageY - this.offset.click.top < this.containment[1]) { - pageY = this.containment[1] + this.offset.click.top; - } - if(event.pageX - this.offset.click.left > this.containment[2]) { - pageX = this.containment[2] + this.offset.click.left; - } - if(event.pageY - this.offset.click.top > this.containment[3]) { - pageY = this.containment[3] + this.offset.click.top; - } - } - - if(o.grid) { - top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1]; - pageY = this.containment ? ( (top - this.offset.click.top >= this.containment[1] && top - this.offset.click.top <= this.containment[3]) ? top : ((top - this.offset.click.top >= this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top; - - left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0]; - pageX = this.containment ? ( (left - this.offset.click.left >= this.containment[0] && left - this.offset.click.left <= this.containment[2]) ? left : ((left - this.offset.click.left >= this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left; - } - - } - - return { - top: ( - pageY - // The absolute mouse position - this.offset.click.top - // Click offset (relative to the element) - this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.top + // The offsetParent's offset without borders (offset + border) - ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) - ), - left: ( - pageX - // The absolute mouse position - this.offset.click.left - // Click offset (relative to the element) - this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.left + // The offsetParent's offset without borders (offset + border) - ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) - ) - }; - - }, - - _rearrange: function(event, i, a, hardRefresh) { - - a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction === "down" ? i.item[0] : i.item[0].nextSibling)); - - //Various things done here to improve the performance: - // 1. we create a setTimeout, that calls refreshPositions - // 2. on the instance, we have a counter variable, that get's higher after every append - // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same - // 4. this lets only the last addition to the timeout stack through - this.counter = this.counter ? ++this.counter : 1; - var counter = this.counter; - - this._delay(function() { - if(counter === this.counter) { - this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove - } - }); - - }, - - _clear: function(event, noPropagation) { - - this.reverting = false; - // We delay all events that have to be triggered to after the point where the placeholder has been removed and - // everything else normalized again - var i, - delayedTriggers = []; - - // We first have to update the dom position of the actual currentItem - // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088) - if(!this._noFinalSort && this.currentItem.parent().length) { - this.placeholder.before(this.currentItem); - } - this._noFinalSort = null; - - if(this.helper[0] === this.currentItem[0]) { - for(i in this._storedCSS) { - if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") { - this._storedCSS[i] = ""; - } - } - this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); - } else { - this.currentItem.show(); - } - - if(this.fromOutside && !noPropagation) { - delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); }); - } - if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) { - delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed - } - - // Check if the items Container has Changed and trigger appropriate - // events. - if (this !== this.currentContainer) { - if(!noPropagation) { - delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); }); - delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); - delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); - } - } - - - //Post events to containers - for (i = this.containers.length - 1; i >= 0; i--){ - if(!noPropagation) { - delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i])); - } - if(this.containers[i].containerCache.over) { - delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i])); - this.containers[i].containerCache.over = 0; - } - } - - //Do what was originally in plugins - if ( this.storedCursor ) { - this.document.find( "body" ).css( "cursor", this.storedCursor ); - this.storedStylesheet.remove(); - } - if(this._storedOpacity) { - this.helper.css("opacity", this._storedOpacity); - } - if(this._storedZIndex) { - this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex); - } - - this.dragging = false; - if(this.cancelHelperRemoval) { - if(!noPropagation) { - this._trigger("beforeStop", event, this._uiHash()); - for (i=0; i < delayedTriggers.length; i++) { - delayedTriggers[i].call(this, event); - } //Trigger all delayed events - this._trigger("stop", event, this._uiHash()); - } - - this.fromOutside = false; - return false; - } - - if(!noPropagation) { - this._trigger("beforeStop", event, this._uiHash()); - } - - //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! - this.placeholder[0].parentNode.removeChild(this.placeholder[0]); - - if(this.helper[0] !== this.currentItem[0]) { - this.helper.remove(); - } - this.helper = null; - - if(!noPropagation) { - for (i=0; i < delayedTriggers.length; i++) { - delayedTriggers[i].call(this, event); - } //Trigger all delayed events - this._trigger("stop", event, this._uiHash()); - } - - this.fromOutside = false; - return true; - - }, - - _trigger: function() { - if ($.Widget.prototype._trigger.apply(this, arguments) === false) { - this.cancel(); - } - }, - - _uiHash: function(_inst) { - var inst = _inst || this; - return { - helper: inst.helper, - placeholder: inst.placeholder || $([]), - position: inst.position, - originalPosition: inst.originalPosition, - offset: inst.positionAbs, - item: inst.currentItem, - sender: _inst ? _inst.element : null - }; - } - -}); - -})(jQuery); -/* - -Copyright (C) 2011 by Yehuda Katz - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// lib/handlebars/browser-prefix.js -var Handlebars = {}; - -(function(Handlebars, undefined) { -; -// lib/handlebars/base.js - -Handlebars.VERSION = "1.0.0-rc.4"; -Handlebars.COMPILER_REVISION = 3; - -Handlebars.REVISION_CHANGES = { - 1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it - 2: '== 1.0.0-rc.3', - 3: '>= 1.0.0-rc.4' -}; - -Handlebars.helpers = {}; -Handlebars.partials = {}; - -var toString = Object.prototype.toString, - functionType = '[object Function]', - objectType = '[object Object]'; - -Handlebars.registerHelper = function(name, fn, inverse) { - if (toString.call(name) === objectType) { - if (inverse || fn) { throw new Handlebars.Exception('Arg not supported with multiple helpers'); } - Handlebars.Utils.extend(this.helpers, name); - } else { - if (inverse) { fn.not = inverse; } - this.helpers[name] = fn; - } -}; - -Handlebars.registerPartial = function(name, str) { - if (toString.call(name) === objectType) { - Handlebars.Utils.extend(this.partials, name); - } else { - this.partials[name] = str; - } -}; - -Handlebars.registerHelper('helperMissing', function(arg) { - if(arguments.length === 2) { - return undefined; - } else { - throw new Error("Could not find property '" + arg + "'"); - } -}); - -Handlebars.registerHelper('blockHelperMissing', function(context, options) { - var inverse = options.inverse || function() {}, fn = options.fn; - - var type = toString.call(context); - - if(type === functionType) { context = context.call(this); } - - if(context === true) { - return fn(this); - } else if(context === false || context == null) { - return inverse(this); - } else if(type === "[object Array]") { - if(context.length > 0) { - return Handlebars.helpers.each(context, options); - } else { - return inverse(this); - } - } else { - return fn(context); - } -}); - -Handlebars.K = function() {}; - -Handlebars.createFrame = Object.create || function(object) { - Handlebars.K.prototype = object; - var obj = new Handlebars.K(); - Handlebars.K.prototype = null; - return obj; -}; - -Handlebars.logger = { - DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3, level: 3, - - methodMap: {0: 'debug', 1: 'info', 2: 'warn', 3: 'error'}, - - // can be overridden in the host environment - log: function(level, obj) { - if (Handlebars.logger.level <= level) { - var method = Handlebars.logger.methodMap[level]; - if (typeof console !== 'undefined' && console[method]) { - console[method].call(console, obj); - } - } - } -}; - -Handlebars.log = function(level, obj) { Handlebars.logger.log(level, obj); }; - -Handlebars.registerHelper('each', function(context, options) { - var fn = options.fn, inverse = options.inverse; - var i = 0, ret = "", data; - - if (options.data) { - data = Handlebars.createFrame(options.data); - } - - if(context && typeof context === 'object') { - if(context instanceof Array){ - for(var j = context.length; i<j; i++) { - if (data) { data.index = i; } - ret = ret + fn(context[i], { data: data }); - } - } else { - for(var key in context) { - if(context.hasOwnProperty(key)) { - if(data) { data.key = key; } - ret = ret + fn(context[key], {data: data}); - i++; - } - } - } - } - - if(i === 0){ - ret = inverse(this); - } - - return ret; -}); - -Handlebars.registerHelper('if', function(context, options) { - var type = toString.call(context); - if(type === functionType) { context = context.call(this); } - - if(!context || Handlebars.Utils.isEmpty(context)) { - return options.inverse(this); - } else { - return options.fn(this); - } -}); - -Handlebars.registerHelper('unless', function(context, options) { - return Handlebars.helpers['if'].call(this, context, {fn: options.inverse, inverse: options.fn}); -}); - -Handlebars.registerHelper('with', function(context, options) { - if (!Handlebars.Utils.isEmpty(context)) return options.fn(context); -}); - -Handlebars.registerHelper('log', function(context, options) { - var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1; - Handlebars.log(level, context); -}); -; -// lib/handlebars/utils.js - -var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack']; - -Handlebars.Exception = function(message) { - var tmp = Error.prototype.constructor.apply(this, arguments); - - // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work. - for (var idx = 0; idx < errorProps.length; idx++) { - this[errorProps[idx]] = tmp[errorProps[idx]]; - } -}; -Handlebars.Exception.prototype = new Error(); - -// Build out our basic SafeString type -Handlebars.SafeString = function(string) { - this.string = string; -}; -Handlebars.SafeString.prototype.toString = function() { - return this.string.toString(); -}; - -var escape = { - "&": "&amp;", - "<": "&lt;", - ">": "&gt;", - '"': "&quot;", - "'": "&#x27;", - "`": "&#x60;" -}; - -var badChars = /[&<>"'`]/g; -var possible = /[&<>"'`]/; - -var escapeChar = function(chr) { - return escape[chr] || "&amp;"; -}; - -Handlebars.Utils = { - extend: function(obj, value) { - for(var key in value) { - if(value.hasOwnProperty(key)) { - obj[key] = value[key]; - } - } - }, - - escapeExpression: function(string) { - // don't escape SafeStrings, since they're already safe - if (string instanceof Handlebars.SafeString) { - return string.toString(); - } else if (string == null || string === false) { - return ""; - } - - // Force a string conversion as this will be done by the append regardless and - // the regex test will do this transparently behind the scenes, causing issues if - // an object's to string has escaped characters in it. - string = string.toString(); - - if(!possible.test(string)) { return string; } - return string.replace(badChars, escapeChar); - }, - - isEmpty: function(value) { - if (!value && value !== 0) { - return true; - } else if(toString.call(value) === "[object Array]" && value.length === 0) { - return true; - } else { - return false; - } - } -}; -; -// lib/handlebars/runtime.js - -Handlebars.VM = { - template: function(templateSpec) { - // Just add water - var container = { - escapeExpression: Handlebars.Utils.escapeExpression, - invokePartial: Handlebars.VM.invokePartial, - programs: [], - program: function(i, fn, data) { - var programWrapper = this.programs[i]; - if(data) { - programWrapper = Handlebars.VM.program(i, fn, data); - } else if (!programWrapper) { - programWrapper = this.programs[i] = Handlebars.VM.program(i, fn); - } - return programWrapper; - }, - programWithDepth: Handlebars.VM.programWithDepth, - noop: Handlebars.VM.noop, - compilerInfo: null - }; - - return function(context, options) { - options = options || {}; - var result = templateSpec.call(container, Handlebars, context, options.helpers, options.partials, options.data); - - var compilerInfo = container.compilerInfo || [], - compilerRevision = compilerInfo[0] || 1, - currentRevision = Handlebars.COMPILER_REVISION; - - if (compilerRevision !== currentRevision) { - if (compilerRevision < currentRevision) { - var runtimeVersions = Handlebars.REVISION_CHANGES[currentRevision], - compilerVersions = Handlebars.REVISION_CHANGES[compilerRevision]; - throw "Template was precompiled with an older version of Handlebars than the current runtime. "+ - "Please update your precompiler to a newer version ("+runtimeVersions+") or downgrade your runtime to an older version ("+compilerVersions+")."; - } else { - // Use the embedded version info since the runtime doesn't know about this revision yet - throw "Template was precompiled with a newer version of Handlebars than the current runtime. "+ - "Please update your runtime to a newer version ("+compilerInfo[1]+")."; - } - } - - return result; - }; - }, - - programWithDepth: function(i, fn, data /*, $depth */) { - var args = Array.prototype.slice.call(arguments, 3); - - var program = function(context, options) { - options = options || {}; - - return fn.apply(this, [context, options.data || data].concat(args)); - }; - program.program = i; - program.depth = args.length; - return program; - }, - program: function(i, fn, data) { - var program = function(context, options) { - options = options || {}; - - return fn(context, options.data || data); - }; - program.program = i; - program.depth = 0; - return program; - }, - noop: function() { return ""; }, - invokePartial: function(partial, name, context, helpers, partials, data) { - var options = { helpers: helpers, partials: partials, data: data }; - - if(partial === undefined) { - throw new Handlebars.Exception("The partial " + name + " could not be found"); - } else if(partial instanceof Function) { - return partial(context, options); - } else if (!Handlebars.compile) { - throw new Handlebars.Exception("The partial " + name + " could not be compiled when running in runtime-only mode"); - } else { - partials[name] = Handlebars.compile(partial, {data: data !== undefined}); - return partials[name](context, options); - } - } -}; - -Handlebars.template = Handlebars.VM.template; -; -// lib/handlebars/browser-suffix.js -})(Handlebars); -; -/*! - * jQuery Cookie Plugin v1.3.1 - * https://github.com/carhartl/jquery-cookie - * - * Copyright 2013 Klaus Hartl - * Released under the MIT license - */ - -(function (factory) { - if (typeof define === 'function' && define.amd && define.amd.jQuery) { - // AMD. Register as anonymous module. - define(['jquery'], factory); - } else { - // Browser globals. - factory(jQuery); - } -}(function ($) { - - var pluses = /\+/g; - - function raw(s) { - return s; - } - - function decoded(s) { - return decodeURIComponent(s.replace(pluses, ' ')); - } - - function converted(s) { - if (s.indexOf('"') === 0) { - // This is a quoted cookie as according to RFC2068, unescape - s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\'); - } - try { - return config.json ? JSON.parse(s) : s; - } catch(er) {} - } - - var config = $.cookie = function (key, value, options) { - - // write - if (value !== undefined) { - options = $.extend({}, config.defaults, options); - - if (typeof options.expires === 'number') { - var days = options.expires, t = options.expires = new Date(); - t.setDate(t.getDate() + days); - } - - value = config.json ? JSON.stringify(value) : String(value); - - return (document.cookie = [ - encodeURIComponent(key), '=', config.raw ? value : encodeURIComponent(value), - options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE - options.path ? '; path=' + options.path : '', - options.domain ? '; domain=' + options.domain : '', - options.secure ? '; secure' : '' - ].join('')); - } - - // read - var decode = config.raw ? raw : decoded; - var cookies = document.cookie.split('; '); - var result = key ? undefined : {}; - for (var i = 0, l = cookies.length; i < l; i++) { - var parts = cookies[i].split('='); - var name = decode(parts.shift()); - var cookie = decode(parts.join('=')); - - if (key && key === name) { - result = converted(cookie); - break; - } - - if (!key) { - result[name] = converted(cookie); - } - } - - return result; - }; - - config.defaults = {}; - - $.removeCookie = function (key, options) { - if ($.cookie(key) !== undefined) { - $.cookie(key, '', $.extend(options, { expires: -1 })); - return true; - } - return false; - }; - -})); -/** - * jQuery Internationalization library - * - * Copyright (C) 2012 Santhosh Thottingal - * - * jquery.i18n is dual licensed GPLv2 or later and MIT. You don't have to do - * anything special to choose one license or the other and you don't have to - * notify anyone which license you are using. You are free to use - * UniversalLanguageSelector in commercial projects as long as the copyright - * header is left intact. See files GPL-LICENSE and MIT-LICENSE for details. - * - * @licence GNU General Public Licence 2.0 or later - * @licence MIT License - */ - - -( function ( $ ) { - 'use strict'; - - var nav, - slice = Array.prototype.slice; - /** - * @constructor - * @param {Object} options - */ - var I18N = function ( options ) { - // Load defaults - this.options = $.extend( {}, I18N.defaults, options ); - - this.parser = this.options.parser; - this.locale = this.options.locale; - this.messageStore = this.options.messageStore; - this.languages = {}; - - this.init(); - }; - - I18N.prototype = { - /** - * Initialize by loading locales and setting up - * String.prototype.toLocaleString and String.locale. - */ - init: function () { - var i18n; - - i18n = this; - i18n.messageStore.init( i18n.locale ); - // Set locale of String environment - String.locale = i18n.locale; - - // Override String.localeString method - String.prototype.toLocaleString = function () { - var localeParts, messageLocation, localePartIndex, value, locale, fallbackIndex; - - value = this.valueOf(); - locale = i18n.locale; - fallbackIndex = 0; - - while ( locale ) { - // Iterate through locales starting at most-specific until - // localization is found. As in fi-Latn-FI, fi-Latn and fi. - localeParts = locale.toLowerCase().split( '-' ); - localePartIndex = localeParts.length; - - do { - var _locale = localeParts.slice( 0, localePartIndex ).join( '-' ); - - if ( i18n.options.messageLocationResolver ) { - messageLocation = i18n.options.messageLocationResolver( _locale, value ); - - if ( messageLocation && - ( !i18n.messageStore.isLoaded( _locale ,messageLocation ) ) - ) { - i18n.messageStore.load( messageLocation, _locale ); - } - } - - var message = i18n.messageStore.get( _locale, value ); - - if ( message ) { - return message; - } - - localePartIndex--; - } while ( localePartIndex ); - - if ( locale === 'en' ) { - break; - } - - locale = ( $.i18n.fallbacks[i18n.locale] && $.i18n.fallbacks[i18n.locale][fallbackIndex] ) || - i18n.options.fallbackLocale; - i18n.log( 'Trying fallback locale for ' + i18n.locale + ': ' + locale ); - - fallbackIndex++; - } - - // key not found - return ''; - }; - }, - - /* - * Destroy the i18n instance. - */ - destroy: function () { - $.removeData( document, 'i18n' ); - }, - - /** - * General message loading API This can take a URL string for - * the json formatted messages. - * <code>load('path/to/all_localizations.json');</code> - * - * This can also load a localization file for a locale <code> - * load('path/to/de-messages.json', 'de' ); - * </code> - * A data object containing message key- message translation mappings - * can also be passed Eg: - * <code> - * load( { 'hello' : 'Hello' }, optionalLocale ); - * </code> If the data argument is - * null/undefined/false, - * all cached messages for the i18n instance will get reset. - * - * @param {String|Object|null} data - * @param {String} locale Language tag - */ - load: function ( data, locale ) { - this.messageStore.load( data, locale ); - }, - - log: function ( /* arguments */ ) { - if ( window.console && $.i18n.debug ) { - window.console.log.apply( window.console, arguments ); - } - }, - - /** - * Does parameter and magic word substitution. - * - * @param {string} key Message key - * @param {Array} parameters Message parameters - * @return {string} - */ - parse: function ( key, parameters ) { - var message = key.toLocaleString(); - // FIXME: This changes the state of the I18N object, - // should probably not change the 'this.parser' but just - // pass it to the parser. - this.parser.language = $.i18n.languages[$.i18n().locale] || $.i18n.languages['default']; - if( message === '' ) { - message = key; - } - return this.parser.parse( message, parameters ); - } - }; - - - /** - * Process a message from the $.I18N instance - * for the current document, stored in jQuery.data(document). - * - * @param {string} key Key of the message. - * @param {string} param1 [param...] Variadic list of parameters for {key}. - * @return {string|$.I18N} Parsed message, or if no key was given - * the instance of $.I18N is returned. - */ - $.i18n = function ( key, param1 ) { - var parameters, - i18n = $.data( document, 'i18n' ), - options = typeof key === 'object' && key; - - // If the locale option for this call is different then the setup so far, - // update it automatically. This doesn't just change the context for this - // call but for all future call as well. - // If there is no i18n setup yet, don't do this. It will be taken care of - // by the `new I18N` construction below. - // NOTE: It should only change language for this one call. - // Then cache instances of I18N somewhere. - if ( options && options.locale && i18n && i18n.locale !== options.locale ) { - String.locale = i18n.locale = options.locale; - } - - if ( !i18n ) { - i18n = new I18N( options ); - $.data( document, 'i18n', i18n ); - } - - if ( typeof key === 'string' ) { - if ( param1 !== undefined ) { - parameters = slice.call( arguments, 1 ); - } else { - parameters = []; - } - - return i18n.parse( key, parameters ); - } else { - // FIXME: remove this feature/bug. - return i18n; - } - }; - - $.fn.i18n = function () { - var i18n = $.data( document, 'i18n' ); - String.locale = i18n.locale; - if ( !i18n ) { - i18n = new I18N( ); - $.data( document, 'i18n', i18n ); - } - return this.each( function () { - var $this = $( this ); - - if ( $this.data( 'i18n' ) ) { - var messageKey = $this.data( 'i18n' ), - message = messageKey.toLocaleString(); - if ( message !== '' ) { - $this.text( message ); - } - } else { - $this.find( '[data-i18n]' ).i18n(); - } - } ); - }; - - String.locale = String.locale || $( 'html' ).attr( 'lang' ); - - if ( !String.locale ) { - if ( typeof window.navigator !== undefined ) { - nav = window.navigator; - String.locale = nav.language || nav.userLanguage || ''; - } else { - String.locale = ''; - } - } - - $.i18n.languages = {}; - $.i18n.messageStore = $.i18n.messageStore || {}; - $.i18n.parser = { - // The default parser only handles variable substitution - parse: function ( message, parameters ) { - return message.replace( /\$(\d+)/g, function ( str, match ) { - var index = parseInt( match, 10 ) - 1; - return parameters[index] !== undefined ? parameters[index] : '$' + match; - } ); - }, - emitter: {} - }; - - $.i18n.debug = false; - - /* Static members */ - I18N.defaults = { - locale: String.locale, - fallbackLocale: 'en', - parser: $.i18n.parser, - messageStore: $.i18n.messageStore, - /* messageLocationResolver - should be a function taking language code as argument and - * returning absolute or relative path to the localization file - */ - messageLocationResolver: null - }; - - // Expose constructor - $.I18N = I18N; -}( jQuery ) ); - -/** - * jQuery Internationalization library Message loading , parsing, retrieving utilities - * - * Copyright (C) 2012 Santhosh Thottingal - * - * jquery.i18n is dual licensed GPLv2 or later and MIT. You don't have to do anything special to - * choose one license or the other and you don't have to notify anyone which license you are using. - * You are free to use UniversalLanguageSelector in commercial projects as long as the copyright - * header is left intact. See files GPL-LICENSE and MIT-LICENSE for details. - * - * @licence GNU General Public Licence 2.0 or later - * @licence MIT License - */ - -( function ( $, window, undefined ) { - 'use strict'; - - var MessageStore = function () { - this.messages = {}; - this.sources = {}; - this.locale = String.locale; - }; - - MessageStore.prototype = { - - /** - * See https://github.com/wikimedia/jquery.i18n/wiki/Specification#wiki-Message_File_Loading - * - * @param locale - */ - init: function ( locale ) { - var messageStore = this; - - messageStore.locale = locale; - messageStore.log( 'initializing for ' + locale ); - - $( 'link' ).each( function ( index, element ) { - var $link = $( element ), - rel = ( $link.attr( 'rel' ) || '' ).toLowerCase().split( /\s+/ ); - - if ( $.inArray( 'localizations', rel ) !== -1 ) { - // multiple localizations - messageStore.load( $link.attr( 'href' ) ); - } else if ( $.inArray( 'localization', rel ) !== -1 ) { - // single localization - messageStore.queue( ( $link.attr( 'hreflang' ) || '' ).toLowerCase(), - $link.attr( 'href' ) ); - } - } ); - }, - - /** - * General message loading API This can take a URL string for - * the json formatted messages. - * <code>load('path/to/all_localizations.json');</code> - * - * This can also load a localization file for a locale <code> - * load('path/to/de-messages.json', 'de' ); - * </code> - * A data object containing message key- message translation mappings - * can also be passed Eg: - * <code> - * load( { 'hello' : 'Hello' }, optionalLocale ); - * </code> If the data argument is - * null/undefined/false, - * all cached messages for the i18n instance will get reset. - * - * @param {String|Object|null} data - * @param {String} locale Language tag - */ - load: function ( data, locale ) { - var key = null, - messageStore = this, - hasOwn = Object.prototype.hasOwnProperty; - - if ( !data ) { - // reset all localizations - messageStore.log( 'Resetting for locale ' + locale ); - messageStore.messages = {}; - - return; - } - - if ( typeof data === 'string' ) { - // This is a URL to the messages file. - messageStore.log( 'Loading messages from: ' + data ); - - messageStore.jsonMessageLoader( data ).done( function ( localization, textStatus ) { - messageStore.load( localization, locale ); - messageStore.queue( locale, data ); - messageStore.markLoaded( locale, data ); - } ); - } else { - // Data is either a group of messages for {locale}, - // or a group of languages with groups of messages inside. - for ( key in data ) { - if ( hasOwn.call( data, key ) ) { - if ( locale ) { - - // Lazy-init the object - if ( !messageStore.messages[locale] ) { - messageStore.messages[locale] = {}; - } - - // Update message object keys, - // don't overwrite the entire object. - messageStore.messages[locale][key] = data[key]; - - messageStore.log( - '[' + locale + '][' + key + '] : ' + data[key] - ); - - // No {locale} given, assume data is a group of languages, - // call this function again for each langauge. - } else { - messageStore.load( data[key], key ); - } - } - } - } - }, - - log: function ( /* arguments */ ) { - if ( window.console && $.i18n.debug ) { - window.console.log.apply( window.console, arguments ); - } - }, - - /** - * Mark a message Location for a locale loaded - * - * @param locale - * @param messageLocation - */ - markLoaded: function ( locale, messageLocation ) { - var i, - queue = this.sources[locale]; - - if ( !queue ) { - this.queue( locale, messageLocation ); - queue = this.sources[locale]; - } - - this.sources[locale] = this.sources[locale] || []; - - for ( i = 0; i < queue.length; i++ ) { - if ( queue[i].source.url === messageLocation ) { - queue[i].source.loaded = true; - - return; - } - } - }, - - /** - * Register the message location for a locale, will be loaded when required - * - * @param locale - * @param messageLocation - */ - queue: function ( locale, messageLocation ) { - var i, - queue = this.sources[locale]; - - this.sources[locale] = this.sources[locale] || []; - - if ( queue ) { - for ( i = 0; i < queue.length; i++ ) { - if ( queue[i].source.url === messageLocation ) { - return; - } - } - } - - this.log( 'Source for: ' + locale + ' is ' + messageLocation + ' registered' ); - this.sources[locale].push( { - source: { - url: messageLocation, - loaded: false - } - } ); - }, - - /** - * Load the messages from the source queue for the locale - * - * @param {String} locale - */ - loadFromQueue: function ( locale ) { - var i, - queue = this.sources[locale]; - - if ( queue ) { - for ( i = 0; i < queue.length; i++ ) { - if ( !queue[i].source.loaded ) { - this.load( queue[i].source.url, locale ); - this.sources[locale][i].source.loaded = true; - } - } - } - }, - - isLoaded: function ( locale, messageLocation ) { - var i, - sources = this.sources[locale], - result = false; - - if ( sources ) { - for ( i = 0; i < sources.length; i++ ) { - if ( sources[i].source.url === messageLocation ) { - result = true; - } - } - } - - return result; - }, - - jsonMessageLoader: function ( url ) { - var messageStore = this; - - return $.ajax( { - url: url, - dataType: 'json', - async: false - // This is unfortunate. - } ).fail( function ( jqxhr, settings, exception ) { - messageStore.log( 'Error in loading messages from ' + url + ' Exception: ' + exception ); - } ); - }, - - /** - * - * @param locale - * @param messageKey - * @returns {Boolean} - */ - get: function ( locale, messageKey ) { - // load locale if not loaded - if ( !this.messages[locale] ) { - this.loadFromQueue( locale ); - } - - return this.messages[locale] && this.messages[locale][messageKey]; - } - }; - - $.extend( $.i18n.messageStore, new MessageStore() ); - -}( jQuery, window ) ); - -/** - * jQuery Internationalization library - * - * Copyright (C) 2012 Santhosh Thottingal - * - * jquery.i18n is dual licensed GPLv2 or later and MIT. You don't have to do anything special to - * choose one license or the other and you don't have to notify anyone which license you are using. - * You are free to use UniversalLanguageSelector in commercial projects as long as the copyright - * header is left intact. See files GPL-LICENSE and MIT-LICENSE for details. - * - * @licence GNU General Public Licence 2.0 or later - * @licence MIT License - */ -( function ( $, undefined ) { - 'use strict'; - - $.i18n = $.i18n || {}; - $.i18n.fallbacks = { - 'ab': ['ru'], - 'ace': ['id'], - 'aln': ['sq'], - // Not so standard - als is supposed to be Tosk Albanian, - // but in Wikipedia it's used for a Germanic language. - 'als': ['gsw', 'de'], - 'an': ['es'], - 'anp': ['hi'], - 'arn': ['es'], - 'arz': ['ar'], - 'av': ['ru'], - 'ay': ['es'], - 'ba': ['ru'], - 'bar': ['de'], - 'bat-smg': ['sgs', 'lt'], - 'bcc': ['fa'], - 'be-x-old': ['be-tarask'], - 'bh': ['bho'], - 'bjn': ['id'], - 'bm': ['fr'], - 'bpy': ['bn'], - 'bqi': ['fa'], - 'bug': ['id'], - 'cbk-zam': ['es'], - 'ce': ['ru'], - 'crh': ['crh-latn'], - 'crh-cyrl': ['ru'], - 'csb': ['pl'], - 'cv': ['ru'], - 'de-at': ['de'], - 'de-ch': ['de'], - 'de-formal': ['de'], - 'dsb': ['de'], - 'dtp': ['ms'], - 'egl': ['it'], - 'eml': ['it'], - 'ff': ['fr'], - 'fit': ['fi'], - 'fiu-vro': ['vro', 'et'], - 'frc': ['fr'], - 'frp': ['fr'], - 'frr': ['de'], - 'fur': ['it'], - 'gag': ['tr'], - 'gan': ['gan-hant', 'zh-hant', 'zh-hans'], - 'gan-hans': ['zh-hans'], - 'gan-hant': ['zh-hant', 'zh-hans'], - 'gl': ['pt'], - 'glk': ['fa'], - 'gn': ['es'], - 'gsw': ['de'], - 'hif': ['hif-latn'], - 'hsb': ['de'], - 'ht': ['fr'], - 'ii': ['zh-cn', 'zh-hans'], - 'inh': ['ru'], - 'iu': ['ike-cans'], - 'jut': ['da'], - 'jv': ['id'], - 'kaa': ['kk-latn', 'kk-cyrl'], - 'kbd': ['kbd-cyrl'], - 'khw': ['ur'], - 'kiu': ['tr'], - 'kk': ['kk-cyrl'], - 'kk-arab': ['kk-cyrl'], - 'kk-latn': ['kk-cyrl'], - 'kk-cn': ['kk-arab', 'kk-cyrl'], - 'kk-kz': ['kk-cyrl'], - 'kk-tr': ['kk-latn', 'kk-cyrl'], - 'kl': ['da'], - 'ko-kp': ['ko'], - 'koi': ['ru'], - 'krc': ['ru'], - 'ks': ['ks-arab'], - 'ksh': ['de'], - 'ku': ['ku-latn'], - 'ku-arab': ['ckb'], - 'kv': ['ru'], - 'lad': ['es'], - 'lb': ['de'], - 'lbe': ['ru'], - 'lez': ['ru'], - 'li': ['nl'], - 'lij': ['it'], - 'liv': ['et'], - 'lmo': ['it'], - 'ln': ['fr'], - 'ltg': ['lv'], - 'lzz': ['tr'], - 'mai': ['hi'], - 'map-bms': ['jv', 'id'], - 'mg': ['fr'], - 'mhr': ['ru'], - 'min': ['id'], - 'mo': ['ro'], - 'mrj': ['ru'], - 'mwl': ['pt'], - 'myv': ['ru'], - 'mzn': ['fa'], - 'nah': ['es'], - 'nap': ['it'], - 'nds': ['de'], - 'nds-nl': ['nl'], - 'nl-informal': ['nl'], - 'no': ['nb'], - 'os': ['ru'], - 'pcd': ['fr'], - 'pdc': ['de'], - 'pdt': ['de'], - 'pfl': ['de'], - 'pms': ['it'], - 'pt': ['pt-br'], - 'pt-br': ['pt'], - 'qu': ['es'], - 'qug': ['qu', 'es'], - 'rgn': ['it'], - 'rmy': ['ro'], - 'roa-rup': ['rup'], - 'rue': ['uk', 'ru'], - 'ruq': ['ruq-latn', 'ro'], - 'ruq-cyrl': ['mk'], - 'ruq-latn': ['ro'], - 'sa': ['hi'], - 'sah': ['ru'], - 'scn': ['it'], - 'sg': ['fr'], - 'sgs': ['lt'], - 'sli': ['de'], - 'sr': ['sr-ec'], - 'srn': ['nl'], - 'stq': ['de'], - 'su': ['id'], - 'szl': ['pl'], - 'tcy': ['kn'], - 'tg': ['tg-cyrl'], - 'tt': ['tt-cyrl', 'ru'], - 'tt-cyrl': ['ru'], - 'ty': ['fr'], - 'udm': ['ru'], - 'ug': ['ug-arab'], - 'uk': ['ru'], - 'vec': ['it'], - 'vep': ['et'], - 'vls': ['nl'], - 'vmf': ['de'], - 'vot': ['fi'], - 'vro': ['et'], - 'wa': ['fr'], - 'wo': ['fr'], - 'wuu': ['zh-hans'], - 'xal': ['ru'], - 'xmf': ['ka'], - 'yi': ['he'], - 'za': ['zh-hans'], - 'zea': ['nl'], - 'zh': ['zh-hans'], - 'zh-classical': ['lzh'], - 'zh-cn': ['zh-hans'], - 'zh-hant': ['zh-hans'], - 'zh-hk': ['zh-hant', 'zh-hans'], - 'zh-min-nan': ['nan'], - 'zh-mo': ['zh-hk', 'zh-hant', 'zh-hans'], - 'zh-my': ['zh-sg', 'zh-hans'], - 'zh-sg': ['zh-hans'], - 'zh-tw': ['zh-hant', 'zh-hans'], - 'zh-yue': ['yue'] - }; -}( jQuery ) ); - -/** - * jQuery Internationalization library - * - * Copyright (C) 2012 Santhosh Thottingal - * - * jquery.i18n is dual licensed GPLv2 or later and MIT. You don't have to do - * anything special to choose one license or the other and you don't have to - * notify anyone which license you are using. You are free to use - * UniversalLanguageSelector in commercial projects as long as the copyright - * header is left intact. See files GPL-LICENSE and MIT-LICENSE for details. - * - * @licence GNU General Public Licence 2.0 or later - * @licence MIT License - */ - -( function ( $ ) { - 'use strict'; - - var MessageParser = function ( options ) { - this.options = $.extend( {}, $.i18n.parser.defaults, options ); - this.language = $.i18n.languages[String.locale] || $.i18n.languages['default']; - this.emitter = $.i18n.parser.emitter; - }; - - MessageParser.prototype = { - - constructor: MessageParser, - - simpleParse: function ( message, parameters ) { - return message.replace( /\$(\d+)/g, function ( str, match ) { - var index = parseInt( match, 10 ) - 1; - - return parameters[index] !== undefined ? parameters[index] : '$' + match; - } ); - }, - - parse: function ( message, replacements ) { - if ( message.indexOf( '{{' ) < 0 ) { - return this.simpleParse( message, replacements ); - } - - this.emitter.language = $.i18n.languages[$.i18n().locale] || - $.i18n.languages['default']; - - return this.emitter.emit( this.ast( message ), replacements ); - }, - - ast: function ( message ) { - var pos = 0; - - // Try parsers until one works, if none work return null - function choice ( parserSyntax ) { - return function () { - var i, result; - - for ( i = 0; i < parserSyntax.length; i++ ) { - result = parserSyntax[i](); - - if ( result !== null ) { - return result; - } - } - - return null; - }; - } - - // Try several parserSyntax-es in a row. - // All must succeed; otherwise, return null. - // This is the only eager one. - function sequence ( parserSyntax ) { - var i, res, - originalPos = pos, - result = []; - - for ( i = 0; i < parserSyntax.length; i++ ) { - res = parserSyntax[i](); - - if ( res === null ) { - pos = originalPos; - - return null; - } - - result.push( res ); - } - - return result; - } - - // Run the same parser over and over until it fails. - // Must succeed a minimum of n times; otherwise, return null. - function nOrMore ( n, p ) { - return function () { - var originalPos = pos, - result = [], - parsed = p(); - - while ( parsed !== null ) { - result.push( parsed ); - parsed = p(); - } - - if ( result.length < n ) { - pos = originalPos; - - return null; - } - - return result; - }; - } - - // Helpers -- just make parserSyntax out of simpler JS builtin types - - function makeStringParser ( s ) { - var len = s.length; - - return function () { - var result = null; - - if ( message.substr( pos, len ) === s ) { - result = s; - pos += len; - } - - return result; - }; - } - - function makeRegexParser ( regex ) { - return function () { - var matches = message.substr( pos ).match( regex ); - - if ( matches === null ) { - return null; - } - - pos += matches[0].length; - - return matches[0]; - }; - } - - var pipe = makeStringParser( '|' ); - var colon = makeStringParser( ':' ); - var backslash = makeStringParser( '\\' ); - var anyCharacter = makeRegexParser( /^./ ); - var dollar = makeStringParser( '$' ); - var digits = makeRegexParser( /^\d+/ ); - var regularLiteral = makeRegexParser( /^[^{}\[\]$\\]/ ); - var regularLiteralWithoutBar = makeRegexParser( /^[^{}\[\]$\\|]/ ); - var regularLiteralWithoutSpace = makeRegexParser( /^[^{}\[\]$\s]/ ); - - // There is a general pattern: - // parse a thing; - // if it worked, apply transform, - // otherwise return null. - // But using this as a combinator seems to cause problems - // when combined with nOrMore(). - // May be some scoping issue. - function transform ( p, fn ) { - return function () { - var result = p(); - - return result === null ? null : fn( result ); - }; - } - - // Used to define "literals" within template parameters. The pipe - // character is the parameter delimeter, so by default - // it is not a literal in the parameter - function literalWithoutBar () { - var result = nOrMore( 1, escapedOrLiteralWithoutBar )(); - - return result === null ? null : result.join( '' ); - } - - function literal () { - var result = nOrMore( 1, escapedOrRegularLiteral )(); - - return result === null ? null : result.join( '' ); - } - - function escapedLiteral () { - var result = sequence( [ backslash, anyCharacter ] ); - - return result === null ? null : result[1]; - } - - choice( [ escapedLiteral, regularLiteralWithoutSpace ] ); - var escapedOrLiteralWithoutBar = choice( [ escapedLiteral, regularLiteralWithoutBar ] ); - var escapedOrRegularLiteral = choice( [ escapedLiteral, regularLiteral ] ); - - function replacement () { - var result = sequence( [ dollar, digits ] ); - - if ( result === null ) { - return null; - } - - return [ 'REPLACE', parseInt( result[1], 10 ) - 1 ]; - } - - var templateName = transform( - // see $wgLegalTitleChars - // not allowing : due to the need to catch "PLURAL:$1" - makeRegexParser( /^[ !"$&'()*,.\/0-9;=?@A-Z\^_`a-z~\x80-\xFF+\-]+/ ), - - function ( result ) { - return result.toString(); - } - ); - - function templateParam () { - var result = sequence( [ pipe, nOrMore( 0, paramExpression ) ] ); - - if ( result === null ) { - return null; - } - - var expr = result[1]; - - // use a "CONCAT" operator if there are multiple nodes, - // otherwise return the first node, raw. - return expr.length > 1 ? [ 'CONCAT' ].concat( expr ) : expr[0]; - } - - function templateWithReplacement () { - var result = sequence( [ templateName, colon, replacement ] ); - - return result === null ? null : [ result[0], result[2] ]; - } - - function templateWithOutReplacement () { - var result = sequence( [ templateName, colon, paramExpression ] ); - - return result === null ? null : [ result[0], result[2] ]; - } - - var templateContents = choice( [ - function () { - var res = sequence( [ - // templates can have placeholders for dynamic - // replacement eg: {{PLURAL:$1|one car|$1 cars}} - // or no placeholders eg: - // {{GRAMMAR:genitive|{{SITENAME}}} - choice( [ templateWithReplacement, templateWithOutReplacement ] ), - nOrMore( 0, templateParam ) - ] ); - - return res === null ? null : res[0].concat( res[1] ); - }, - function () { - var res = sequence( [ templateName, nOrMore( 0, templateParam ) ] ); - - if ( res === null ) { - return null; - } - - return [ res[0] ].concat( res[1] ); - } - ] ); - - var openTemplate = makeStringParser( '{{' ); - var closeTemplate = makeStringParser( '}}' ); - - function template () { - var result = sequence( [ openTemplate, templateContents, closeTemplate ] ); - - return result === null ? null : result[1]; - } - - var expression = choice( [ template, replacement, literal ] ); - var paramExpression = choice( [ template, replacement, literalWithoutBar ] ); - - function start () { - var result = nOrMore( 0, expression )(); - - if ( result === null ) { - return null; - } - - return [ 'CONCAT' ].concat( result ); - } - - var result = start(); - - /* - * For success, the pos must have gotten to the end of the input - * and returned a non-null. - * n.b. This is part of language infrastructure, so we do not throw an internationalizable message. - */ - if ( result === null || pos !== message.length ) { - throw new Error( 'Parse error at position ' + pos.toString() + ' in input: ' + message ); - } - - return result; - } - - }; - - $.extend( $.i18n.parser, new MessageParser() ); - -}( jQuery ) ); - -/** - * jQuery Internationalization library - * - * Copyright (C) 2012 Santhosh Thottingal - * - * jquery.i18n is dual licensed GPLv2 or later and MIT. You don't have to do - * anything special to choose one license or the other and you don't have to - * notify anyone which license you are using. You are free to use - * UniversalLanguageSelector in commercial projects as long as the copyright - * header is left intact. See files GPL-LICENSE and MIT-LICENSE for details. - * - * @licence GNU General Public Licence 2.0 or later - * @licence MIT License - */ - -( function ( $ ) { - 'use strict'; - - var MessageParserEmitter = function () { - this.language = $.i18n.languages[String.locale] || $.i18n.languages['default']; - }; - - MessageParserEmitter.prototype = { - constructor: MessageParserEmitter, - - /** - * (We put this method definition here, and not in prototype, to make - * sure it's not overwritten by any magic.) Walk entire node structure, - * applying replacements and template functions when appropriate - * - * @param {Mixed} node abstract syntax tree (top node or subnode) - * @param {Array} replacements for $1, $2, ... $n - * @return {Mixed} single-string node or array of nodes suitable for - * jQuery appending. - */ - emit: function ( node, replacements ) { - var ret, subnodes, operation, - messageParserEmitter = this; - - switch ( typeof node ) { - case 'string': - case 'number': - ret = node; - break; - case 'object': - // node is an array of nodes - subnodes = $.map( node.slice( 1 ), function ( n ) { - return messageParserEmitter.emit( n, replacements ); - } ); - - operation = node[0].toLowerCase(); - - if ( typeof messageParserEmitter[operation] === 'function' ) { - ret = messageParserEmitter[operation]( subnodes, replacements ); - } else { - throw new Error( 'unknown operation "' + operation + '"' ); - } - - break; - case 'undefined': - // Parsing the empty string (as an entire expression, or as a - // paramExpression in a template) results in undefined - // Perhaps a more clever parser can detect this, and return the - // empty string? Or is that useful information? - // The logical thing is probably to return the empty string here - // when we encounter undefined. - ret = ''; - break; - default: - throw new Error( 'unexpected type in AST: ' + typeof node ); - } - - return ret; - }, - - /** - * Parsing has been applied depth-first we can assume that all nodes - * here are single nodes Must return a single node to parents -- a - * jQuery with synthetic span However, unwrap any other synthetic spans - * in our children and pass them upwards - * - * @param {Array} nodes Mixed, some single nodes, some arrays of nodes. - * @return String - */ - concat: function ( nodes ) { - var result = ''; - - $.each( nodes, function ( i, node ) { - // strings, integers, anything else - result += node; - } ); - - return result; - }, - - /** - * Return escaped replacement of correct index, or string if - * unavailable. Note that we expect the parsed parameter to be - * zero-based. i.e. $1 should have become [ 0 ]. if the specified - * parameter is not found return the same string (e.g. "$99" -> - * parameter 98 -> not found -> return "$99" ) TODO throw error if - * nodes.length > 1 ? - * - * @param {Array} nodes One element, integer, n >= 0 - * @param {Array} replacements for $1, $2, ... $n - * @return {string} replacement - */ - replace: function ( nodes, replacements ) { - var index = parseInt( nodes[0], 10 ); - - if ( index < replacements.length ) { - // replacement is not a string, don't touch! - return replacements[index]; - } else { - // index not found, fallback to displaying variable - return '$' + ( index + 1 ); - } - }, - - /** - * Transform parsed structure into pluralization n.b. The first node may - * be a non-integer (for instance, a string representing an Arabic - * number). So convert it back with the current language's - * convertNumber. - * - * @param {Array} nodes List [ {String|Number}, {String}, {String} ... ] - * @return {String} selected pluralized form according to current - * language. - */ - plural: function ( nodes ) { - var count = parseFloat( this.language.convertNumber( nodes[0], 10 ) ), - forms = nodes.slice( 1 ); - - return forms.length ? this.language.convertPlural( count, forms ) : ''; - }, - - /** - * Transform parsed structure into gender Usage - * {{gender:gender|masculine|feminine|neutral}}. - * - * @param {Array} nodes List [ {String}, {String}, {String} , {String} ] - * @return {String} selected gender form according to current language - */ - gender: function ( nodes ) { - var gender = nodes[0], - forms = nodes.slice( 1 ); - - return this.language.gender( gender, forms ); - }, - - /** - * Transform parsed structure into grammar conversion. Invoked by - * putting {{grammar:form|word}} in a message - * - * @param {Array} nodes List [{Grammar case eg: genitive}, {String word}] - * @return {String} selected grammatical form according to current - * language. - */ - grammar: function ( nodes ) { - var form = nodes[0], - word = nodes[1]; - - return word && form && this.language.convertGrammar( word, form ); - } - }; - - $.extend( $.i18n.parser.emitter, new MessageParserEmitter() ); - -}( jQuery ) ); - -/*global pluralRuleParser */ -( function ( $ ) { - 'use strict'; - - var language = { - - // CLDR plural rules generated using - // http://i18ndata.appspot.com/cldr/tags/unconfirmed/supplemental/plurals?action=browse&depth=-1 - // and compressed - pluralRules: { - gv: { - one: 'n mod 10 in 1..2 or n mod 20 is 0' - }, - gu: { - one: 'n is 1' - }, - rof: { - one: 'n is 1' - }, - ga: { - few: 'n in 3..6', - many: 'n in 7..10', - two: 'n is 2', - one: 'n is 1' - }, - gl: { - one: 'n is 1' - }, - lg: { - one: 'n is 1' - }, - lb: { - one: 'n is 1' - }, - xog: { - one: 'n is 1' - }, - ln: { - one: 'n in 0..1' - }, - lo: '', - brx: { - one: 'n is 1' - }, - tr: '', - ts: { - one: 'n is 1' - }, - tn: { - one: 'n is 1' - }, - to: '', - lt: { - few: 'n mod 10 in 2..9 and n mod 100 not in 11..19', - one: 'n mod 10 is 1 and n mod 100 not in 11..19' - }, - tk: { - one: 'n is 1' - }, - th: '', - ksb: { - one: 'n is 1' - }, - te: { - one: 'n is 1' - }, - ksh: { - zero: 'n is 0', - one: 'n is 1' - }, - fil: { - one: 'n in 0..1' - }, - haw: { - one: 'n is 1' - }, - kcg: { - one: 'n is 1' - }, - ssy: { - one: 'n is 1' - }, - yo: '', - de: { - one: 'n is 1' - }, - ko: '', - da: { - one: 'n is 1' - }, - dz: '', - dv: { - one: 'n is 1' - }, - guw: { - one: 'n in 0..1' - }, - shi: { - few: 'n in 2..10', - one: 'n within 0..1' - }, - el: { - one: 'n is 1' - }, - eo: { - one: 'n is 1' - }, - en: { - one: 'n is 1' - }, - ses: '', - teo: { - one: 'n is 1' - }, - ee: { - one: 'n is 1' - }, - kde: '', - fr: { - one: 'n within 0..2 and n is not 2' - }, - eu: { - one: 'n is 1' - }, - et: { - one: 'n is 1' - }, - es: { - one: 'n is 1' - }, - seh: { - one: 'n is 1' - }, - ru: { - few: 'n mod 10 in 2..4 and n mod 100 not in 12..14', - many: 'n mod 10 is 0 or n mod 10 in 5..9 or n mod 100 in 11..14', - one: 'n mod 10 is 1 and n mod 100 is not 11' - }, - kl: { - one: 'n is 1' - }, - sms: { - two: 'n is 2', - one: 'n is 1' - }, - smn: { - two: 'n is 2', - one: 'n is 1' - }, - smj: { - two: 'n is 2', - one: 'n is 1' - }, - smi: { - two: 'n is 2', - one: 'n is 1' - }, - fy: { - one: 'n is 1' - }, - rm: { - one: 'n is 1' - }, - ro: { - few: 'n is 0 OR n is not 1 AND n mod 100 in 1..19', - one: 'n is 1' - }, - bn: { - one: 'n is 1' - }, - sma: { - two: 'n is 2', - one: 'n is 1' - }, - be: { - few: 'n mod 10 in 2..4 and n mod 100 not in 12..14', - many: 'n mod 10 is 0 or n mod 10 in 5..9 or n mod 100 in 11..14', - one: 'n mod 10 is 1 and n mod 100 is not 11' - }, - bg: { - one: 'n is 1' - }, - ms: '', - wa: { - one: 'n in 0..1' - }, - ps: { - one: 'n is 1' - }, - wo: '', - bm: '', - jv: '', - bo: '', - bh: { - one: 'n in 0..1' - }, - kea: '', - asa: { - one: 'n is 1' - }, - cgg: { - one: 'n is 1' - }, - br: { - few: 'n mod 10 in 3..4,9 and n mod 100 not in 10..19,70..79,90..99', - many: 'n mod 1000000 is 0 and n is not 0', - two: 'n mod 10 is 2 and n mod 100 not in 12,72,92', - one: 'n mod 10 is 1 and n mod 100 not in 11,71,91' - }, - bs: { - few: 'n mod 10 in 2..4 and n mod 100 not in 12..14', - many: 'n mod 10 is 0 or n mod 10 in 5..9 or n mod 100 in 11..14', - one: 'n mod 10 is 1 and n mod 100 is not 11' - }, - ja: '', - om: { - one: 'n is 1' - }, - fa: '', - vun: { - one: 'n is 1' - }, - or: { - one: 'n is 1' - }, - xh: { - one: 'n is 1' - }, - nso: { - one: 'n in 0..1' - }, - ca: { - one: 'n is 1' - }, - cy: { - few: 'n is 3', - zero: 'n is 0', - many: 'n is 6', - two: 'n is 2', - one: 'n is 1' - }, - cs: { - few: 'n in 2..4', - one: 'n is 1' - }, - zh: '', - lv: { - zero: 'n is 0', - one: 'n mod 10 is 1 and n mod 100 is not 11' - }, - pt: { - one: 'n is 1' - }, - wae: { - one: 'n is 1' - }, - tl: { - one: 'n in 0..1' - }, - chr: { - one: 'n is 1' - }, - pa: { - one: 'n is 1' - }, - ak: { - one: 'n in 0..1' - }, - pl: { - few: 'n mod 10 in 2..4 and n mod 100 not in 12..14', - many: 'n is not 1 and n mod 10 in 0..1 or n mod 10 in 5..9 or n mod 100 in 12..14', - one: 'n is 1' - }, - hr: { - few: 'n mod 10 in 2..4 and n mod 100 not in 12..14', - many: 'n mod 10 is 0 or n mod 10 in 5..9 or n mod 100 in 11..14', - one: 'n mod 10 is 1 and n mod 100 is not 11' - }, - am: { - one: 'n in 0..1' - }, - ti: { - one: 'n in 0..1' - }, - hu: '', - hi: { - one: 'n in 0..1' - }, - jmc: { - one: 'n is 1' - }, - ha: { - one: 'n is 1' - }, - he: { - one: 'n is 1' - }, - mg: { - one: 'n in 0..1' - }, - fur: { - one: 'n is 1' - }, - bem: { - one: 'n is 1' - }, - ml: { - one: 'n is 1' - }, - mo: { - few: 'n is 0 OR n is not 1 AND n mod 100 in 1..19', - one: 'n is 1' - }, - mn: { - one: 'n is 1' - }, - mk: { - one: 'n mod 10 is 1 and n is not 11' - }, - ur: { - one: 'n is 1' - }, - bez: { - one: 'n is 1' - }, - mt: { - few: 'n is 0 or n mod 100 in 2..10', - many: 'n mod 100 in 11..19', - one: 'n is 1' - }, - uk: { - few: 'n mod 10 in 2..4 and n mod 100 not in 12..14', - many: 'n mod 10 is 0 or n mod 10 in 5..9 or n mod 100 in 11..14', - one: 'n mod 10 is 1 and n mod 100 is not 11' - }, - mr: { - one: 'n is 1' - }, - ta: { - one: 'n is 1' - }, - my: '', - sah: '', - ve: { - one: 'n is 1' - }, - af: { - one: 'n is 1' - }, - vi: '', - is: { - one: 'n is 1' - }, - iu: { - two: 'n is 2', - one: 'n is 1' - }, - it: { - one: 'n is 1' - }, - kn: '', - ii: '', - ar: { - few: 'n mod 100 in 3..10', - zero: 'n is 0', - many: 'n mod 100 in 11..99', - two: 'n is 2', - one: 'n is 1' - }, - zu: { - one: 'n is 1' - }, - saq: { - one: 'n is 1' - }, - az: '', - tzm: { - one: 'n in 0..1 or n in 11..99' - }, - id: '', - ig: '', - pap: { - one: 'n is 1' - }, - nl: { - one: 'n is 1' - }, - nn: { - one: 'n is 1' - }, - no: { - one: 'n is 1' - }, - nah: { - one: 'n is 1' - }, - nd: { - one: 'n is 1' - }, - ne: { - one: 'n is 1' - }, - ny: { - one: 'n is 1' - }, - naq: { - two: 'n is 2', - one: 'n is 1' - }, - nyn: { - one: 'n is 1' - }, - kw: { - two: 'n is 2', - one: 'n is 1' - }, - nr: { - one: 'n is 1' - }, - tig: { - one: 'n is 1' - }, - kab: { - one: 'n within 0..2 and n is not 2' - }, - mas: { - one: 'n is 1' - }, - rwk: { - one: 'n is 1' - }, - kaj: { - one: 'n is 1' - }, - lag: { - zero: 'n is 0', - one: 'n within 0..2 and n is not 0 and n is not 2' - }, - syr: { - one: 'n is 1' - }, - kk: { - one: 'n is 1' - }, - ff: { - one: 'n within 0..2 and n is not 2' - }, - fi: { - one: 'n is 1' - }, - fo: { - one: 'n is 1' - }, - ka: '', - gsw: { - one: 'n is 1' - }, - ckb: { - one: 'n is 1' - }, - ss: { - one: 'n is 1' - }, - sr: { - few: 'n mod 10 in 2..4 and n mod 100 not in 12..14', - many: 'n mod 10 is 0 or n mod 10 in 5..9 or n mod 100 in 11..14', - one: 'n mod 10 is 1 and n mod 100 is not 11' - }, - sq: { - one: 'n is 1' - }, - sw: { - one: 'n is 1' - }, - sv: { - one: 'n is 1' - }, - km: '', - st: { - one: 'n is 1' - }, - sk: { - few: 'n in 2..4', - one: 'n is 1' - }, - sh: { - few: 'n mod 10 in 2..4 and n mod 100 not in 12..14', - many: 'n mod 10 is 0 or n mod 10 in 5..9 or n mod 100 in 11..14', - one: 'n mod 10 is 1 and n mod 100 is not 11' - }, - so: { - one: 'n is 1' - }, - sn: { - one: 'n is 1' - }, - ku: { - one: 'n is 1' - }, - sl: { - few: 'n mod 100 in 3..4', - two: 'n mod 100 is 2', - one: 'n mod 100 is 1' - }, - sg: '', - nb: { - one: 'n is 1' - }, - se: { - two: 'n is 2', - one: 'n is 1' - } - }, - - /** - * Plural form transformations, needed for some languages. - * - * @param count - * integer Non-localized quantifier - * @param forms - * array List of plural forms - * @return string Correct form for quantifier in this language - */ - convertPlural: function ( count, forms ) { - var pluralRules, - pluralFormIndex = 0; - - if ( !forms || forms.length === 0 ) { - return ''; - } - - pluralRules = this.pluralRules[$.i18n().locale]; - - if ( !pluralRules ) { - // default fallback. - return ( count === 1 ) ? forms[0] : forms[1]; - } - - pluralFormIndex = this.getPluralForm( count, pluralRules ); - pluralFormIndex = Math.min( pluralFormIndex, forms.length - 1 ); - - return forms[pluralFormIndex]; - }, - - /** - * For the number, get the plural for index - * - * @param number - * @param pluralRules - * @return plural form index - */ - getPluralForm: function ( number, pluralRules ) { - var i, - pluralForms = [ 'zero', 'one', 'two', 'few', 'many', 'other' ], - pluralFormIndex = 0; - - for ( i = 0; i < pluralForms.length; i++ ) { - if ( pluralRules[pluralForms[i]] ) { - if ( pluralRuleParser( pluralRules[pluralForms[i]], number ) ) { - return pluralFormIndex; - } - - pluralFormIndex++; - } - } - - return pluralFormIndex; - }, - - /** - * Converts a number using digitTransformTable. - * - * @param {number} num Value to be converted - * @param {boolean} integer Convert the return value to an integer - */ - 'convertNumber': function ( num, integer ) { - var tmp, item, i, - transformTable, numberString, convertedNumber; - - // Set the target Transform table: - transformTable = this.digitTransformTable( $.i18n().locale ); - numberString = '' + num; - convertedNumber = ''; - - if ( !transformTable ) { - return num; - } - - // Check if the restore to Latin number flag is set: - if ( integer ) { - if ( parseFloat( num, 10 ) === num ) { - return num; - } - - tmp = []; - - for ( item in transformTable ) { - tmp[transformTable[item]] = item; - } - - transformTable = tmp; - } - - for ( i = 0; i < numberString.length; i++ ) { - if ( transformTable[numberString[i]] ) { - convertedNumber += transformTable[numberString[i]]; - } else { - convertedNumber += numberString[i]; - } - } - - return integer ? parseFloat( convertedNumber, 10 ) : convertedNumber; - }, - - /** - * Grammatical transformations, needed for inflected languages. - * Invoked by putting {{grammar:form|word}} in a message. - * Override this method for languages that need special grammar rules - * applied dynamically. - * - * @param word {String} - * @param form {String} - * @return {String} - */ - convertGrammar: function ( word, form ) { - return word; - }, - - /** - * Provides an alternative text depending on specified gender. Usage - * {{gender:[gender|user object]|masculine|feminine|neutral}}. If second - * or third parameter are not specified, masculine is used. - * - * These details may be overriden per language. - * - * @param gender - * string male, female, or anything else for neutral. - * @param forms - * array List of gender forms - * - * @return string - */ - 'gender': function ( gender, forms ) { - if ( !forms || forms.length === 0 ) { - return ''; - } - - while ( forms.length < 2 ) { - forms.push( forms[forms.length - 1] ); - } - - if ( gender === 'male' ) { - return forms[0]; - } - - if ( gender === 'female' ) { - return forms[1]; - } - - return ( forms.length === 3 ) ? forms[2] : forms[0]; - }, - - /** - * Get the digit transform table for the given language - * See http://cldr.unicode.org/translation/numbering-systems - * @param language - * @returns {Array|boolean} List of digits in the passed language or false - * representation, or boolean false if there is no information. - */ - digitTransformTable: function ( language ) { - var tables = { - ar: '٠١٢٣٤٥٦٧٨٩', - fa: '۰۱۲۳۴۵۶۷۸۹', - ml: '൦൧൨൩൪൫൬൭൮൯', - kn: '೦೧೨೩೪೫೬೭೮೯', - lo: '໐໑໒໓໔໕໖໗໘໙', - or: '୦୧୨୩୪୫୬୭୮୯', - kh: '០១២៣៤៥៦៧៨៩', - pa: '੦੧੨੩੪੫੬੭੮੯', - gu: '૦૧૨૩૪૫૬૭૮૯', - hi: '०१२३४५६७८९', - my: '၀၁၂၃၄၅၆၇၈၉', - ta: '௦௧௨௩௪௫௬௭௮௯', - te: '౦౧౨౩౪౫౬౭౮౯', - th: '๐๑๒๓๔๕๖๗๘๙', //FIXME use iso 639 codes - bo: '༠༡༢༣༤༥༦༧༨༩' //FIXME use iso 639 codes - }; - - if ( !tables[language] ) { - return false; - } - - return tables[language].split( '' ); - } - }; - - $.extend( $.i18n.languages, { - 'default': language - } ); -}( jQuery ) ); - -/** - * Bosnian (bosanski) language functions - */ -( function ( $ ) { - 'use strict'; - - $.i18n.languages.bs = $.extend( {}, $.i18n.languages['default'], { - convertGrammar: function ( word, form ) { - switch ( form ) { - case 'instrumental': // instrumental - word = 's ' + word; - break; - case 'lokativ': // locative - word = 'o ' + word; - break; - } - - return word; - } - } ); - -}( jQuery ) ); - -/** - * Lower Sorbian (Dolnoserbski) language functions - */ -( function ( $ ) { - 'use strict'; - - $.i18n.languages.dsb = $.extend( {}, $.i18n.languages['default'], { - convertGrammar: function ( word, form ) { - switch ( form ) { - case 'instrumental': // instrumental - word = 'z ' + word; - break; - case 'lokatiw': // lokatiw - word = 'wo ' + word; - break; - } - - return word; - } - } ); - -}( jQuery ) ); - -/** - * Finnish (Suomi) language functions - * - * @author Santhosh Thottingal - */ - -( function ( $ ) { - 'use strict'; - - $.i18n.languages.fi = $.extend( {}, $.i18n.languages['default'], { - convertGrammar: function ( word, form ) { - // vowel harmony flag - var aou = word.match( /[aou][^äöy]*$/i ), - origWord = word; - if ( word.match( /wiki$/i ) ) { - aou = false; - } - - // append i after final consonant - if ( word.match( /[bcdfghjklmnpqrstvwxz]$/i ) ) { - word += 'i'; - } - - switch ( form ) { - case 'genitive': - word += 'n'; - break; - case 'elative': - word += ( aou ? 'sta' : 'stä' ); - break; - case 'partitive': - word += ( aou ? 'a' : 'ä' ); - break; - case 'illative': - // Double the last letter and add 'n' - word += word.substr( word.length - 1 ) + 'n'; - break; - case 'inessive': - word += ( aou ? 'ssa' : 'ssä' ); - break; - default: - word = origWord; - break; - } - - return word; - } - } ); -}( jQuery ) ); - -/** - * Irish (Gaeilge) language functions - */ -( function ( $ ) { - 'use strict'; - - $.i18n.languages.ga = $.extend( {}, $.i18n.languages['default'], { - convertGrammar: function ( word, form ) { - if ( form === 'ainmlae' ) { - switch ( word ) { - case 'an Domhnach': - word = 'Dé Domhnaigh'; - break; - case 'an Luan': - word = 'Dé Luain'; - break; - case 'an Mháirt': - word = 'Dé Mháirt'; - break; - case 'an Chéadaoin': - word = 'Dé Chéadaoin'; - break; - case 'an Déardaoin': - word = 'Déardaoin'; - break; - case 'an Aoine': - word = 'Dé hAoine'; - break; - case 'an Satharn': - word = 'Dé Sathairn'; - break; - } - } - - return word; - } - } ); -}( jQuery ) ); - -/** - * Hebrew (עברית) language functions - */ -( function ( $ ) { - 'use strict'; - - $.i18n.languages.he = $.extend( {}, $.i18n.languages['default'], { - convertGrammar: function ( word, form ) { - switch ( form ) { - case 'prefixed': - case 'תחילית': // the same word in Hebrew - // Duplicate prefixed "Waw", but only if it's not already double - if ( word.substr( 0, 1 ) === 'ו' && word.substr( 0, 2 ) !== 'וו' ) { - word = 'ו' + word; - } - - // Remove the "He" if prefixed - if ( word.substr( 0, 1 ) === 'ה' ) { - word = word.substr( 1, word.length ); - } - - // Add a hyphen (maqaf) before numbers and non-Hebrew letters - if ( word.substr( 0, 1 ) < 'א' || word.substr( 0, 1 ) > 'ת' ) { - word = '־' + word; - } - } - - return word; - } - } ); -}( jQuery ) ); - -/** - * Upper Sorbian (Hornjoserbsce) language functions - */ -( function ( $ ) { - 'use strict'; - - $.i18n.languages.hsb = $.extend( {}, $.i18n.languages['default'], { - convertGrammar: function ( word, form ) { - switch ( form ) { - case 'instrumental': // instrumental - word = 'z ' + word; - break; - case 'lokatiw': // lokatiw - word = 'wo ' + word; - break; - } - - return word; - } - } ); -}( jQuery ) ); - -/** - * Hungarian language functions - * - * @author Santhosh Thottingal - */ -( function ( $ ) { - 'use strict'; - - $.i18n.languages.hu = $.extend( {}, $.i18n.languages['default'], { - convertGrammar: function ( word, form ) { - switch ( form ) { - case 'rol': - word += 'ról'; - break; - case 'ba': - word += 'ba'; - break; - case 'k': - word += 'k'; - break; - } - - return word; - } - } ); -}( jQuery ) ); - -/** - * Armenian (Հայերեն) language functions - */ - -( function ( $ ) { - 'use strict'; - - $.i18n.languages.hy = $.extend( {}, $.i18n.languages['default'], { - convertGrammar: function ( word, form ) { - if ( form === 'genitive' ) { // սեռական հոլով - if ( word.substr( -1 ) === 'ա' ) { - word = word.substr( 0, word.length - 1 ) + 'այի'; - } else if ( word.substr( -1 ) === 'ո' ) { - word = word.substr( 0, word.length - 1 ) + 'ոյի'; - } else if ( word.substr( -4 ) === 'գիրք' ) { - word = word.substr( 0, word.length - 4 ) + 'գրքի'; - } else { - word = word + 'ի'; - } - } - - return word; - } - } ); -}( jQuery ) ); - -/** - * Latin (lingua Latina) language functions - * - * @author Santhosh Thottingal - */ - -( function ( $ ) { - 'use strict'; - - $.i18n.languages.la = $.extend( {}, $.i18n.languages['default'], { - convertGrammar: function ( word, form ) { - switch ( form ) { - case 'genitive': - // only a few declensions, and even for those mostly the singular only - word = word.replace( /u[ms]$/i, 'i' ); // 2nd declension singular - word = word.replace( /ommunia$/i, 'ommunium' ); // 3rd declension neuter plural (partly) - word = word.replace( /a$/i, 'ae' ); // 1st declension singular - word = word.replace( /libri$/i, 'librorum' ); // 2nd declension plural (partly) - word = word.replace( /nuntii$/i, 'nuntiorum' ); // 2nd declension plural (partly) - word = word.replace( /tio$/i, 'tionis' ); // 3rd declension singular (partly) - word = word.replace( /ns$/i, 'ntis' ); - word = word.replace( /as$/i, 'atis' ); - word = word.replace( /es$/i, 'ei' ); // 5th declension singular - break; - case 'accusative': - // only a few declensions, and even for those mostly the singular only - word = word.replace( /u[ms]$/i, 'um' ); // 2nd declension singular - word = word.replace( /ommunia$/i, 'am' ); // 3rd declension neuter plural (partly) - word = word.replace( /a$/i, 'ommunia' ); // 1st declension singular - word = word.replace( /libri$/i, 'libros' ); // 2nd declension plural (partly) - word = word.replace( /nuntii$/i, 'nuntios' );// 2nd declension plural (partly) - word = word.replace( /tio$/i, 'tionem' ); // 3rd declension singular (partly) - word = word.replace( /ns$/i, 'ntem' ); - word = word.replace( /as$/i, 'atem' ); - word = word.replace( /es$/i, 'em' ); // 5th declension singular - break; - case 'ablative': - // only a few declensions, and even for those mostly the singular only - word = word.replace( /u[ms]$/i, 'o' ); // 2nd declension singular - word = word.replace( /ommunia$/i, 'ommunibus' ); // 3rd declension neuter plural (partly) - word = word.replace( /a$/i, 'a' ); // 1st declension singular - word = word.replace( /libri$/i, 'libris' ); // 2nd declension plural (partly) - word = word.replace( /nuntii$/i, 'nuntiis' ); // 2nd declension plural (partly) - word = word.replace( /tio$/i, 'tione' ); // 3rd declension singular (partly) - word = word.replace( /ns$/i, 'nte' ); - word = word.replace( /as$/i, 'ate' ); - word = word.replace( /es$/i, 'e' ); // 5th declension singular - break; - } - - return word; - } - } ); -}( jQuery ) ); - -/** - * Ossetian (Ирон) language functions - * - * @author Santhosh Thottingal - */ - -( function ( $ ) { - 'use strict'; - - $.i18n.languages.os = $.extend( {}, $.i18n.languages['default'], { - convertGrammar: function ( word, form ) { - // Ending for allative case - var endAllative = 'мæ'; - // Variable for 'j' beetwen vowels - var jot = ''; - // Variable for "-" for not Ossetic words - var hyphen = ''; - // Variable for ending - var ending = ''; - // Checking if the $word is in plural form - if ( word.match( /тæ$/i ) ) { - word = word.substring( 0, word.length - 1 ); - endAllative = 'æм'; - } - // Works if word is in singular form. - // Checking if word ends on one of the vowels: е, ё, и, о, ы, э, ю, - // я. - else if ( word.match( /[аæеёиоыэюя]$/i ) ) { - jot = 'й'; - } - // Checking if word ends on 'у'. 'У' can be either consonant 'W' or - // vowel 'U' in cyrillic Ossetic. - // Examples: {{grammar:genitive|аунеу}} = аунеуы, - // {{grammar:genitive|лæппу}} = лæппуйы. - else if ( word.match( /у$/i ) ) { - if ( !word.substring( word.length - 2, word.length - 1 ) - .match( /[аæеёиоыэюя]$/i ) ) { - jot = 'й'; - } - } else if ( !word.match( /[бвгджзйклмнопрстфхцчшщьъ]$/i ) ) { - hyphen = '-'; - } - - switch ( form ) { - case 'genitive': - ending = hyphen + jot + 'ы'; - break; - case 'dative': - ending = hyphen + jot + 'æн'; - break; - case 'allative': - ending = hyphen + endAllative; - break; - case 'ablative': - if ( jot === 'й' ) { - ending = hyphen + jot + 'æ'; - } else { - ending = hyphen + jot + 'æй'; - } - break; - case 'superessive': - ending = hyphen + jot + 'ыл'; - break; - case 'equative': - ending = hyphen + jot + 'ау'; - break; - case 'comitative': - ending = hyphen + 'имæ'; - break; - } - - return word + ending; - } - } ); -}( jQuery ) ); - -/** - * Russian (Русский) language functions - */ - -( function ( $ ) { - 'use strict'; - - $.i18n.languages.ru = $.extend( {}, $.i18n.languages['default'], { - convertGrammar: function ( word, form ) { - if ( form === 'genitive' ) { // родительный падеж - if ( ( word.substr( word.length - 4 ) === 'вики' ) || - ( word.substr( word.length - 4 ) === 'Вики' ) - ) { - // ... - } else if ( word.substr( word.length - 1 ) === 'ь' ) { - word = word.substr( 0, word.length - 1 ) + 'я'; - } else if ( word.substr( word.length - 2 ) === 'ия' ) { - word = word.substr( 0, word.length - 2 ) + 'ии'; - } else if ( word.substr( word.length - 2 ) === 'ка' ) { - word = word.substr( 0, word.length - 2 ) + 'ки'; - } else if ( word.substr( word.length - 2 ) === 'ти' ) { - word = word.substr( 0, word.length - 2 ) + 'тей'; - } else if ( word.substr( word.length - 2 ) === 'ды' ) { - word = word.substr( 0, word.length - 2 ) + 'дов'; - } else if ( word.substr( word.length - 3 ) === 'ник' ) { - word = word.substr( 0, word.length - 3 ) + 'ника'; - } - } - - return word; - } - } ); -}( jQuery ) ); - -/** - * Slovenian (Slovenščina) language functions - */ - -( function ( $ ) { - 'use strict'; - - $.i18n.languages.sl = $.extend( {}, $.i18n.languages['default'], { - convertGrammar: function ( word, form ) { - switch ( form ) { - // locative - case 'mestnik': - word = 'o ' + word; - - break; - // instrumental - case 'orodnik': - word = 'z ' + word; - - break; - } - - return word; - } - } ); -}( jQuery ) ); - -/** - * Ukrainian (Українська) language functions - */ - -( function ( $ ) { - 'use strict'; - - $.i18n.languages.uk = $.extend( {}, $.i18n.languages['default'], { - convertGrammar: function ( word, form ) { - switch ( form ) { - case 'genitive': // родовий відмінок - if ( ( word.substr( word.length - 4 ) === 'вікі' ) || - ( word.substr( word.length - 4 ) === 'Вікі' ) - ) { - // ... - } else if ( word.substr( word.length - 1 ) === 'ь' ) { - word = word.substr( 0, word.length - 1 ) + 'я'; - } else if ( word.substr( word.length - 2 ) === 'ія' ) { - word = word.substr( 0, word.length - 2 ) + 'ії'; - } else if ( word.substr( word.length - 2 ) === 'ка' ) { - word = word.substr( 0, word.length - 2 ) + 'ки'; - } else if ( word.substr( word.length - 2 ) === 'ти' ) { - word = word.substr( 0, word.length - 2 ) + 'тей'; - } else if ( word.substr( word.length - 2 ) === 'ды' ) { - word = word.substr( 0, word.length - 2 ) + 'дов'; - } else if ( word.substr( word.length - 3 ) === 'ник' ) { - word = word.substr( 0, word.length - 3 ) + 'ника'; - } - - break; - case 'accusative': // знахідний відмінок - if ( ( word.substr( word.length - 4 ) === 'вікі' ) || - ( word.substr( word.length - 4 ) === 'Вікі' ) - ) { - // ... - } else if ( word.substr( word.length - 2 ) === 'ія' ) { - word = word.substr( 0, word.length - 2 ) + 'ію'; - } - - break; - } - - return word; - } - } ); - -}( jQuery ) ); - -/** - * cldrpluralparser.js - * A parser engine for CLDR plural rules. - * - * Copyright 2012 GPLV3+, Santhosh Thottingal - * - * @version 0.1.0-alpha - * @source https://github.com/santhoshtr/CLDRPluralRuleParser - * @author Santhosh Thottingal <santhosh.thottingal@gmail.com> - * @author Timo Tijhof - * @author Amir Aharoni - */ - -/** - * Evaluates a plural rule in CLDR syntax for a number - * @param rule - * @param number - * @return true|false|null - */ -function pluralRuleParser(rule, number) { - /* - Syntax: see http://unicode.org/reports/tr35/#Language_Plural_Rules - ----------------------------------------------------------------- - - condition = and_condition ('or' and_condition)* - and_condition = relation ('and' relation)* - relation = is_relation | in_relation | within_relation | 'n' <EOL> - is_relation = expr 'is' ('not')? value - in_relation = expr ('not')? 'in' range_list - within_relation = expr ('not')? 'within' range_list - expr = 'n' ('mod' value)? - range_list = (range | value) (',' range_list)* - value = digit+ - digit = 0|1|2|3|4|5|6|7|8|9 - range = value'..'value - - */ - // Indicates current position in the rule as we parse through it. - // Shared among all parsing functions below. - var pos = 0; - - var whitespace = makeRegexParser(/^\s+/); - var digits = makeRegexParser(/^\d+/); - - var _n_ = makeStringParser('n'); - var _is_ = makeStringParser('is'); - var _mod_ = makeStringParser('mod'); - var _not_ = makeStringParser('not'); - var _in_ = makeStringParser('in'); - var _within_ = makeStringParser('within'); - var _range_ = makeStringParser('..'); - var _comma_ = makeStringParser(','); - var _or_ = makeStringParser('or'); - var _and_ = makeStringParser('and'); - - function debug() { - /* console.log.apply(console, arguments);*/ - } - - debug('pluralRuleParser', rule, number); - - // Try parsers until one works, if none work return null - function choice(parserSyntax) { - return function () { - for (var i = 0; i < parserSyntax.length; i++) { - var result = parserSyntax[i](); - if (result !== null) { - return result; - } - } - return null; - }; - } - - // Try several parserSyntax-es in a row. - // All must succeed; otherwise, return null. - // This is the only eager one. - function sequence(parserSyntax) { - var originalPos = pos; - var result = []; - for (var i = 0; i < parserSyntax.length; i++) { - var res = parserSyntax[i](); - if (res === null) { - pos = originalPos; - return null; - } - result.push(res); - } - return result; - } - - // Run the same parser over and over until it fails. - // Must succeed a minimum of n times; otherwise, return null. - function nOrMore(n, p) { - return function () { - var originalPos = pos; - var result = []; - var parsed = p(); - while (parsed !== null) { - result.push(parsed); - parsed = p(); - } - if (result.length < n) { - pos = originalPos; - return null; - } - return result; - }; - } - - // Helpers -- just make parserSyntax out of simpler JS builtin types - - function makeStringParser(s) { - var len = s.length; - return function () { - var result = null; - if (rule.substr(pos, len) === s) { - result = s; - pos += len; - } - return result; - }; - } - - function makeRegexParser(regex) { - return function () { - var matches = rule.substr(pos).match(regex); - if (matches === null) { - return null; - } - pos += matches[0].length; - return matches[0]; - }; - } - - function n() { - var result = _n_(); - if (result === null) { - debug(" -- failed n"); - return result; - } - result = parseInt(number, 10); - debug(" -- passed n ", result); - return result; - } - - var expression = choice([mod, n]); - - function mod() { - var result = sequence([n, whitespace, _mod_, whitespace, digits]); - if (result === null) { - debug(" -- failed mod"); - return null; - } - debug(" -- passed mod"); - return parseInt(result[0], 10) % parseInt(result[4], 10); - } - - function not() { - var result = sequence([whitespace, _not_]); - if (result === null) { - debug(" -- failed not"); - return null; - } else { - return result[1]; - } - } - - function is() { - var result = sequence([expression, whitespace, _is_, nOrMore(0, not), whitespace, digits]); - if (result !== null) { - debug(" -- passed is"); - if (result[3][0] === 'not') { - return result[0] !== parseInt(result[5], 10); - } else { - return result[0] === parseInt(result[5], 10); - } - } - debug(" -- failed is"); - return null; - } - - function rangeList() { - // range_list = (range | value) (',' range_list)* - var result = sequence([choice([range, digits]), nOrMore(0, rangeTail)]); - var resultList = []; - if (result !== null) { - resultList = resultList.concat(result[0], result[1][0]); - return resultList; - } - debug(" -- failed rangeList"); - return null; - } - - function rangeTail() { - // ',' range_list - var result = sequence([_comma_, rangeList]); - if (result !== null) { - return result[1]; - } - debug(" -- failed rangeTail"); - return null; - } - - function range() { - var result = sequence([digits, _range_, digits]); - if (result !== null) { - debug(" -- passed range"); - var array = []; - var left = parseInt(result[0], 10); - var right = parseInt(result[2], 10); - for ( i = left; i <= right; i++) { - array.push(i); - } - return array; - } - debug(" -- failed range"); - return null; - } - - function _in() { - // in_relation = expr ('not')? 'in' range_list - var result = sequence([expression, nOrMore(0, not), whitespace, _in_, whitespace, rangeList]); - if (result !== null) { - debug(" -- passed _in"); - var range_list = result[5]; - for (var i = 0; i < range_list.length; i++) { - if (parseInt(range_list[i], 10) === result[0]) { - return (result[1][0] !== 'not'); - } - } - return (result[1][0] === 'not'); - } - debug(" -- failed _in "); - return null; - } - - function within() { - var result = sequence([expression, whitespace, _within_, whitespace, rangeList]); - if (result !== null) { - debug(" -- passed within "); - var range_list = result[4]; - return (parseInt( range_list[0],10 )<= result[0] && result[0] <= parseInt( range_list[1], 10)); - } - debug(" -- failed within "); - return null; - } - - - var relation = choice([is, _in, within]); - - function and() { - var result = sequence([relation, whitespace, _and_, whitespace, condition]); - if (result) { - debug(" -- passed and"); - return result[0] && result[4]; - } - debug(" -- failed and"); - return null; - } - - function or() { - var result = sequence([relation, whitespace, _or_, whitespace, condition]); - if (result) { - debug(" -- passed or"); - return result[0] || result[4]; - } - debug(" -- failed or"); - return null; - } - - var condition = choice([and, or, relation]); - - function isInt(n) { - return parseFloat(n) % 1 === 0; - } - - - function start() { - if (!isInt(number)) { - return false; - } - var result = condition(); - return result; - } - - - var result = start(); - - /* - * For success, the pos must have gotten to the end of the rule - * and returned a non-null. - * n.b. This is part of language infrastructure, so we do not throw an internationalizable message. - */ - if (result === null || pos !== rule.length) { - // throw new Error("Parse error at position " + pos.toString() + " in input: " + rule + " result is " + result); - } - - return result; -} - -/* For module loaders, e.g. NodeJS, NPM */ -if (typeof module !== 'undefined' && module.exports) { - module.exports = pluralRuleParser; -} - -; -// Underscore.js 1.7.0 -// http://underscorejs.org -// (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors -// Underscore may be freely distributed under the MIT license. - (function() { - - // Baseline setup - // -------------- - - // Establish the root object, `window` in the browser, or `exports` on the server. - var root = this; - - // Save the previous value of the `_` variable. - var previousUnderscore = root._; - - // Save bytes in the minified (but not gzipped) version: - var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; - - // Create quick reference variables for speed access to core prototypes. - var - push = ArrayProto.push, - slice = ArrayProto.slice, - concat = ArrayProto.concat, - toString = ObjProto.toString, - hasOwnProperty = ObjProto.hasOwnProperty; - - // All **ECMAScript 5** native function implementations that we hope to use - // are declared here. - var - nativeIsArray = Array.isArray, - nativeKeys = Object.keys, - nativeBind = FuncProto.bind; - - // Create a safe reference to the Underscore object for use below. - var _ = function(obj) { - if (obj instanceof _) return obj; - if (!(this instanceof _)) return new _(obj); - this._wrapped = obj; - }; - - // Export the Underscore object for **Node.js**, with - // backwards-compatibility for the old `require()` API. If we're in - // the browser, add `_` as a global object. - if (typeof exports !== 'undefined') { - if (typeof module !== 'undefined' && module.exports) { - exports = module.exports = _; - } - exports._ = _; - } else { - root._ = _; - } - - // Current version. - _.VERSION = '1.7.0'; - - // Internal function that returns an efficient (for current engines) version - // of the passed-in callback, to be repeatedly applied in other Underscore - // functions. - var createCallback = function(func, context, argCount) { - if (context === void 0) return func; - switch (argCount == null ? 3 : argCount) { - case 1: return function(value) { - return func.call(context, value); - }; - case 2: return function(value, other) { - return func.call(context, value, other); - }; - case 3: return function(value, index, collection) { - return func.call(context, value, index, collection); - }; - case 4: return function(accumulator, value, index, collection) { - return func.call(context, accumulator, value, index, collection); - }; - } - return function() { - return func.apply(context, arguments); - }; - }; - - // A mostly-internal function to generate callbacks that can be applied - // to each element in a collection, returning the desired result — either - // identity, an arbitrary callback, a property matcher, or a property accessor. - _.iteratee = function(value, context, argCount) { - if (value == null) return _.identity; - if (_.isFunction(value)) return createCallback(value, context, argCount); - if (_.isObject(value)) return _.matches(value); - return _.property(value); - }; - - // Collection Functions - // -------------------- - - // The cornerstone, an `each` implementation, aka `forEach`. - // Handles raw objects in addition to array-likes. Treats all - // sparse array-likes as if they were dense. - _.each = _.forEach = function(obj, iteratee, context) { - if (obj == null) return obj; - iteratee = createCallback(iteratee, context); - var i, length = obj.length; - if (length === +length) { - for (i = 0; i < length; i++) { - iteratee(obj[i], i, obj); - } - } else { - var keys = _.keys(obj); - for (i = 0, length = keys.length; i < length; i++) { - iteratee(obj[keys[i]], keys[i], obj); - } - } - return obj; - }; - - // Return the results of applying the iteratee to each element. - _.map = _.collect = function(obj, iteratee, context) { - if (obj == null) return []; - iteratee = _.iteratee(iteratee, context); - var keys = obj.length !== +obj.length && _.keys(obj), - length = (keys || obj).length, - results = Array(length), - currentKey; - for (var index = 0; index < length; index++) { - currentKey = keys ? keys[index] : index; - results[index] = iteratee(obj[currentKey], currentKey, obj); - } - return results; - }; - - var reduceError = 'Reduce of empty array with no initial value'; - - // **Reduce** builds up a single result from a list of values, aka `inject`, - // or `foldl`. - _.reduce = _.foldl = _.inject = function(obj, iteratee, memo, context) { - if (obj == null) obj = []; - iteratee = createCallback(iteratee, context, 4); - var keys = obj.length !== +obj.length && _.keys(obj), - length = (keys || obj).length, - index = 0, currentKey; - if (arguments.length < 3) { - if (!length) throw new TypeError(reduceError); - memo = obj[keys ? keys[index++] : index++]; - } - for (; index < length; index++) { - currentKey = keys ? keys[index] : index; - memo = iteratee(memo, obj[currentKey], currentKey, obj); - } - return memo; - }; - - // The right-associative version of reduce, also known as `foldr`. - _.reduceRight = _.foldr = function(obj, iteratee, memo, context) { - if (obj == null) obj = []; - iteratee = createCallback(iteratee, context, 4); - var keys = obj.length !== + obj.length && _.keys(obj), - index = (keys || obj).length, - currentKey; - if (arguments.length < 3) { - if (!index) throw new TypeError(reduceError); - memo = obj[keys ? keys[--index] : --index]; - } - while (index--) { - currentKey = keys ? keys[index] : index; - memo = iteratee(memo, obj[currentKey], currentKey, obj); - } - return memo; - }; - - // Return the first value which passes a truth test. Aliased as `detect`. - _.find = _.detect = function(obj, predicate, context) { - var result; - predicate = _.iteratee(predicate, context); - _.some(obj, function(value, index, list) { - if (predicate(value, index, list)) { - result = value; - return true; - } - }); - return result; - }; - - // Return all the elements that pass a truth test. - // Aliased as `select`. - _.filter = _.select = function(obj, predicate, context) { - var results = []; - if (obj == null) return results; - predicate = _.iteratee(predicate, context); - _.each(obj, function(value, index, list) { - if (predicate(value, index, list)) results.push(value); - }); - return results; - }; - - // Return all the elements for which a truth test fails. - _.reject = function(obj, predicate, context) { - return _.filter(obj, _.negate(_.iteratee(predicate)), context); - }; - - // Determine whether all of the elements match a truth test. - // Aliased as `all`. - _.every = _.all = function(obj, predicate, context) { - if (obj == null) return true; - predicate = _.iteratee(predicate, context); - var keys = obj.length !== +obj.length && _.keys(obj), - length = (keys || obj).length, - index, currentKey; - for (index = 0; index < length; index++) { - currentKey = keys ? keys[index] : index; - if (!predicate(obj[currentKey], currentKey, obj)) return false; - } - return true; - }; - - // Determine if at least one element in the object matches a truth test. - // Aliased as `any`. - _.some = _.any = function(obj, predicate, context) { - if (obj == null) return false; - predicate = _.iteratee(predicate, context); - var keys = obj.length !== +obj.length && _.keys(obj), - length = (keys || obj).length, - index, currentKey; - for (index = 0; index < length; index++) { - currentKey = keys ? keys[index] : index; - if (predicate(obj[currentKey], currentKey, obj)) return true; - } - return false; - }; - - // Determine if the array or object contains a given value (using `===`). - // Aliased as `include`. - _.contains = _.include = function(obj, target) { - if (obj == null) return false; - if (obj.length !== +obj.length) obj = _.values(obj); - return _.indexOf(obj, target) >= 0; - }; - - // Invoke a method (with arguments) on every item in a collection. - _.invoke = function(obj, method) { - var args = slice.call(arguments, 2); - var isFunc = _.isFunction(method); - return _.map(obj, function(value) { - return (isFunc ? method : value[method]).apply(value, args); - }); - }; - - // Convenience version of a common use case of `map`: fetching a property. - _.pluck = function(obj, key) { - return _.map(obj, _.property(key)); - }; - - // Convenience version of a common use case of `filter`: selecting only objects - // containing specific `key:value` pairs. - _.where = function(obj, attrs) { - return _.filter(obj, _.matches(attrs)); - }; - - // Convenience version of a common use case of `find`: getting the first object - // containing specific `key:value` pairs. - _.findWhere = function(obj, attrs) { - return _.find(obj, _.matches(attrs)); - }; - - // Return the maximum element (or element-based computation). - _.max = function(obj, iteratee, context) { - var result = -Infinity, lastComputed = -Infinity, - value, computed; - if (iteratee == null && obj != null) { - obj = obj.length === +obj.length ? obj : _.values(obj); - for (var i = 0, length = obj.length; i < length; i++) { - value = obj[i]; - if (value > result) { - result = value; + if (window.parent !== window) { + var scrivito_ui = window.parent.scrivito; + if (scrivito_ui) { + var cms_document = scrivito_ui.cms_element.from_dom_element($(document)); + cms_document.install_public_api(); + $(function() { + if (!scrivito_ui.is_inited()) { + var config = scrivito_ui.dom_config.read($('body')); + if (!config) { + $.error('Scrivito config missing. Did you forget to include scrivito_body_tags in layout?'); + } + scrivito_ui.init(config); + scrivito_ui.gui.start(); } - } - } else { - iteratee = _.iteratee(iteratee, context); - _.each(obj, function(value, index, list) { - computed = iteratee(value, index, list); - if (computed > lastComputed || computed === -Infinity && result === -Infinity) { - result = value; - lastComputed = computed; - } + cms_document.connect(); }); } - return result; - }; - - // Return the minimum element (or element-based computation). - _.min = function(obj, iteratee, context) { - var result = Infinity, lastComputed = Infinity, - value, computed; - if (iteratee == null && obj != null) { - obj = obj.length === +obj.length ? obj : _.values(obj); - for (var i = 0, length = obj.length; i < length; i++) { - value = obj[i]; - if (value < result) { - result = value; - } + } else { + $(function() { + if ($('*[data-scrivito-private-config]').length) { + console.log('Scrivito config found: redirecting to the UI...'); + window.location = '/scrivito'+window.location.pathname; } - } else { - iteratee = _.iteratee(iteratee, context); - _.each(obj, function(value, index, list) { - computed = iteratee(value, index, list); - if (computed < lastComputed || computed === Infinity && result === Infinity) { - result = value; - lastComputed = computed; - } - }); - } - return result; - }; - - // Shuffle a collection, using the modern version of the - // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle). - _.shuffle = function(obj) { - var set = obj && obj.length === +obj.length ? obj : _.values(obj); - var length = set.length; - var shuffled = Array(length); - for (var index = 0, rand; index < length; index++) { - rand = _.random(0, index); - if (rand !== index) shuffled[index] = shuffled[rand]; - shuffled[rand] = set[index]; - } - return shuffled; - }; - - // Sample **n** random values from a collection. - // If **n** is not specified, returns a single random element. - // The internal `guard` argument allows it to work with `map`. - _.sample = function(obj, n, guard) { - if (n == null || guard) { - if (obj.length !== +obj.length) obj = _.values(obj); - return obj[_.random(obj.length - 1)]; - } - return _.shuffle(obj).slice(0, Math.max(0, n)); - }; - - // Sort the object's values by a criterion produced by an iteratee. - _.sortBy = function(obj, iteratee, context) { - iteratee = _.iteratee(iteratee, context); - return _.pluck(_.map(obj, function(value, index, list) { - return { - value: value, - index: index, - criteria: iteratee(value, index, list) - }; - }).sort(function(left, right) { - var a = left.criteria; - var b = right.criteria; - if (a !== b) { - if (a > b || a === void 0) return 1; - if (a < b || b === void 0) return -1; - } - return left.index - right.index; - }), 'value'); - }; - - // An internal function used for aggregate "group by" operations. - var group = function(behavior) { - return function(obj, iteratee, context) { - var result = {}; - iteratee = _.iteratee(iteratee, context); - _.each(obj, function(value, index) { - var key = iteratee(value, index, obj); - behavior(result, value, key); - }); - return result; - }; - }; - - // Groups the object's values by a criterion. Pass either a string attribute - // to group by, or a function that returns the criterion. - _.groupBy = group(function(result, value, key) { - if (_.has(result, key)) result[key].push(value); else result[key] = [value]; - }); - - // Indexes the object's values by a criterion, similar to `groupBy`, but for - // when you know that your index values will be unique. - _.indexBy = group(function(result, value, key) { - result[key] = value; - }); - - // Counts instances of an object that group by a certain criterion. Pass - // either a string attribute to count by, or a function that returns the - // criterion. - _.countBy = group(function(result, value, key) { - if (_.has(result, key)) result[key]++; else result[key] = 1; - }); - - // Use a comparator function to figure out the smallest index at which - // an object should be inserted so as to maintain order. Uses binary search. - _.sortedIndex = function(array, obj, iteratee, context) { - iteratee = _.iteratee(iteratee, context, 1); - var value = iteratee(obj); - var low = 0, high = array.length; - while (low < high) { - var mid = low + high >>> 1; - if (iteratee(array[mid]) < value) low = mid + 1; else high = mid; - } - return low; - }; - - // Safely create a real, live array from anything iterable. - _.toArray = function(obj) { - if (!obj) return []; - if (_.isArray(obj)) return slice.call(obj); - if (obj.length === +obj.length) return _.map(obj, _.identity); - return _.values(obj); - }; - - // Return the number of elements in an object. - _.size = function(obj) { - if (obj == null) return 0; - return obj.length === +obj.length ? obj.length : _.keys(obj).length; - }; - - // Split a collection into two arrays: one whose elements all satisfy the given - // predicate, and one whose elements all do not satisfy the predicate. - _.partition = function(obj, predicate, context) { - predicate = _.iteratee(predicate, context); - var pass = [], fail = []; - _.each(obj, function(value, key, obj) { - (predicate(value, key, obj) ? pass : fail).push(value); }); - return [pass, fail]; - }; - - // Array Functions - // --------------- - - // Get the first element of an array. Passing **n** will return the first N - // values in the array. Aliased as `head` and `take`. The **guard** check - // allows it to work with `_.map`. - _.first = _.head = _.take = function(array, n, guard) { - if (array == null) return void 0; - if (n == null || guard) return array[0]; - if (n < 0) return []; - return slice.call(array, 0, n); - }; - - // Returns everything but the last entry of the array. Especially useful on - // the arguments object. Passing **n** will return all the values in - // the array, excluding the last N. The **guard** check allows it to work with - // `_.map`. - _.initial = function(array, n, guard) { - return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n))); - }; - - // Get the last element of an array. Passing **n** will return the last N - // values in the array. The **guard** check allows it to work with `_.map`. - _.last = function(array, n, guard) { - if (array == null) return void 0; - if (n == null || guard) return array[array.length - 1]; - return slice.call(array, Math.max(array.length - n, 0)); - }; - - // Returns everything but the first entry of the array. Aliased as `tail` and `drop`. - // Especially useful on the arguments object. Passing an **n** will return - // the rest N values in the array. The **guard** - // check allows it to work with `_.map`. - _.rest = _.tail = _.drop = function(array, n, guard) { - return slice.call(array, n == null || guard ? 1 : n); - }; - - // Trim out all falsy values from an array. - _.compact = function(array) { - return _.filter(array, _.identity); - }; - - // Internal implementation of a recursive `flatten` function. - var flatten = function(input, shallow, strict, output) { - if (shallow && _.every(input, _.isArray)) { - return concat.apply(output, input); - } - for (var i = 0, length = input.length; i < length; i++) { - var value = input[i]; - if (!_.isArray(value) && !_.isArguments(value)) { - if (!strict) output.push(value); - } else if (shallow) { - push.apply(output, value); - } else { - flatten(value, shallow, strict, output); - } - } - return output; - }; - - // Flatten out an array, either recursively (by default), or just one level. - _.flatten = function(array, shallow) { - return flatten(array, shallow, false, []); - }; - - // Return a version of the array that does not contain the specified value(s). - _.without = function(array) { - return _.difference(array, slice.call(arguments, 1)); - }; - - // Produce a duplicate-free version of the array. If the array has already - // been sorted, you have the option of using a faster algorithm. - // Aliased as `unique`. - _.uniq = _.unique = function(array, isSorted, iteratee, context) { - if (array == null) return []; - if (!_.isBoolean(isSorted)) { - context = iteratee; - iteratee = isSorted; - isSorted = false; - } - if (iteratee != null) iteratee = _.iteratee(iteratee, context); - var result = []; - var seen = []; - for (var i = 0, length = array.length; i < length; i++) { - var value = array[i]; - if (isSorted) { - if (!i || seen !== value) result.push(value); - seen = value; - } else if (iteratee) { - var computed = iteratee(value, i, array); - if (_.indexOf(seen, computed) < 0) { - seen.push(computed); - result.push(value); - } - } else if (_.indexOf(result, value) < 0) { - result.push(value); - } - } - return result; - }; - - // Produce an array that contains the union: each distinct element from all of - // the passed-in arrays. - _.union = function() { - return _.uniq(flatten(arguments, true, true, [])); - }; - - // Produce an array that contains every item shared between all the - // passed-in arrays. - _.intersection = function(array) { - if (array == null) return []; - var result = []; - var argsLength = arguments.length; - for (var i = 0, length = array.length; i < length; i++) { - var item = array[i]; - if (_.contains(result, item)) continue; - for (var j = 1; j < argsLength; j++) { - if (!_.contains(arguments[j], item)) break; - } - if (j === argsLength) result.push(item); - } - return result; - }; - - // Take the difference between one array and a number of other arrays. - // Only the elements present in just the first array will remain. - _.difference = function(array) { - var rest = flatten(slice.call(arguments, 1), true, true, []); - return _.filter(array, function(value){ - return !_.contains(rest, value); - }); - }; - - // Zip together multiple lists into a single array -- elements that share - // an index go together. - _.zip = function(array) { - if (array == null) return []; - var length = _.max(arguments, 'length').length; - var results = Array(length); - for (var i = 0; i < length; i++) { - results[i] = _.pluck(arguments, i); - } - return results; - }; - - // Converts lists into objects. Pass either a single array of `[key, value]` - // pairs, or two parallel arrays of the same length -- one of keys, and one of - // the corresponding values. - _.object = function(list, values) { - if (list == null) return {}; - var result = {}; - for (var i = 0, length = list.length; i < length; i++) { - if (values) { - result[list[i]] = values[i]; - } else { - result[list[i][0]] = list[i][1]; - } - } - return result; - }; - - // Return the position of the first occurrence of an item in an array, - // or -1 if the item is not included in the array. - // If the array is large and already in sort order, pass `true` - // for **isSorted** to use binary search. - _.indexOf = function(array, item, isSorted) { - if (array == null) return -1; - var i = 0, length = array.length; - if (isSorted) { - if (typeof isSorted == 'number') { - i = isSorted < 0 ? Math.max(0, length + isSorted) : isSorted; - } else { - i = _.sortedIndex(array, item); - return array[i] === item ? i : -1; - } - } - for (; i < length; i++) if (array[i] === item) return i; - return -1; - }; - - _.lastIndexOf = function(array, item, from) { - if (array == null) return -1; - var idx = array.length; - if (typeof from == 'number') { - idx = from < 0 ? idx + from + 1 : Math.min(idx, from + 1); - } - while (--idx >= 0) if (array[idx] === item) return idx; - return -1; - }; - - // Generate an integer Array containing an arithmetic progression. A port of - // the native Python `range()` function. See - // [the Python documentation](http://docs.python.org/library/functions.html#range). - _.range = function(start, stop, step) { - if (arguments.length <= 1) { - stop = start || 0; - start = 0; - } - step = step || 1; - - var length = Math.max(Math.ceil((stop - start) / step), 0); - var range = Array(length); - - for (var idx = 0; idx < length; idx++, start += step) { - range[idx] = start; - } - - return range; - }; - - // Function (ahem) Functions - // ------------------ - - // Reusable constructor function for prototype setting. - var Ctor = function(){}; - - // Create a function bound to a given object (assigning `this`, and arguments, - // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if - // available. - _.bind = function(func, context) { - var args, bound; - if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); - if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function'); - args = slice.call(arguments, 2); - bound = function() { - if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments))); - Ctor.prototype = func.prototype; - var self = new Ctor; - Ctor.prototype = null; - var result = func.apply(self, args.concat(slice.call(arguments))); - if (_.isObject(result)) return result; - return self; - }; - return bound; - }; - - // Partially apply a function by creating a version that has had some of its - // arguments pre-filled, without changing its dynamic `this` context. _ acts - // as a placeholder, allowing any combination of arguments to be pre-filled. - _.partial = function(func) { - var boundArgs = slice.call(arguments, 1); - return function() { - var position = 0; - var args = boundArgs.slice(); - for (var i = 0, length = args.length; i < length; i++) { - if (args[i] === _) args[i] = arguments[position++]; - } - while (position < arguments.length) args.push(arguments[position++]); - return func.apply(this, args); - }; - }; - - // Bind a number of an object's methods to that object. Remaining arguments - // are the method names to be bound. Useful for ensuring that all callbacks - // defined on an object belong to it. - _.bindAll = function(obj) { - var i, length = arguments.length, key; - if (length <= 1) throw new Error('bindAll must be passed function names'); - for (i = 1; i < length; i++) { - key = arguments[i]; - obj[key] = _.bind(obj[key], obj); - } - return obj; - }; - - // Memoize an expensive function by storing its results. - _.memoize = function(func, hasher) { - var memoize = function(key) { - var cache = memoize.cache; - var address = hasher ? hasher.apply(this, arguments) : key; - if (!_.has(cache, address)) cache[address] = func.apply(this, arguments); - return cache[address]; - }; - memoize.cache = {}; - return memoize; - }; - - // Delays a function for the given number of milliseconds, and then calls - // it with the arguments supplied. - _.delay = function(func, wait) { - var args = slice.call(arguments, 2); - return setTimeout(function(){ - return func.apply(null, args); - }, wait); - }; - - // Defers a function, scheduling it to run after the current call stack has - // cleared. - _.defer = function(func) { - return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1))); - }; - - // Returns a function, that, when invoked, will only be triggered at most once - // during a given window of time. Normally, the throttled function will run - // as much as it can, without ever going more than once per `wait` duration; - // but if you'd like to disable the execution on the leading edge, pass - // `{leading: false}`. To disable execution on the trailing edge, ditto. - _.throttle = function(func, wait, options) { - var context, args, result; - var timeout = null; - var previous = 0; - if (!options) options = {}; - var later = function() { - previous = options.leading === false ? 0 : _.now(); - timeout = null; - result = func.apply(context, args); - if (!timeout) context = args = null; - }; - return function() { - var now = _.now(); - if (!previous && options.leading === false) previous = now; - var remaining = wait - (now - previous); - context = this; - args = arguments; - if (remaining <= 0 || remaining > wait) { - clearTimeout(timeout); - timeout = null; - previous = now; - result = func.apply(context, args); - if (!timeout) context = args = null; - } else if (!timeout && options.trailing !== false) { - timeout = setTimeout(later, remaining); - } - return result; - }; - }; - - // Returns a function, that, as long as it continues to be invoked, will not - // be triggered. The function will be called after it stops being called for - // N milliseconds. If `immediate` is passed, trigger the function on the - // leading edge, instead of the trailing. - _.debounce = function(func, wait, immediate) { - var timeout, args, context, timestamp, result; - - var later = function() { - var last = _.now() - timestamp; - - if (last < wait && last > 0) { - timeout = setTimeout(later, wait - last); - } else { - timeout = null; - if (!immediate) { - result = func.apply(context, args); - if (!timeout) context = args = null; - } - } - }; - - return function() { - context = this; - args = arguments; - timestamp = _.now(); - var callNow = immediate && !timeout; - if (!timeout) timeout = setTimeout(later, wait); - if (callNow) { - result = func.apply(context, args); - context = args = null; - } - - return result; - }; - }; - - // Returns the first function passed as an argument to the second, - // allowing you to adjust arguments, run code before and after, and - // conditionally execute the original function. - _.wrap = function(func, wrapper) { - return _.partial(wrapper, func); - }; - - // Returns a negated version of the passed-in predicate. - _.negate = function(predicate) { - return function() { - return !predicate.apply(this, arguments); - }; - }; - - // Returns a function that is the composition of a list of functions, each - // consuming the return value of the function that follows. - _.compose = function() { - var args = arguments; - var start = args.length - 1; - return function() { - var i = start; - var result = args[start].apply(this, arguments); - while (i--) result = args[i].call(this, result); - return result; - }; - }; - - // Returns a function that will only be executed after being called N times. - _.after = function(times, func) { - return function() { - if (--times < 1) { - return func.apply(this, arguments); - } - }; - }; - - // Returns a function that will only be executed before being called N times. - _.before = function(times, func) { - var memo; - return function() { - if (--times > 0) { - memo = func.apply(this, arguments); - } else { - func = null; - } - return memo; - }; - }; - - // Returns a function that will be executed at most one time, no matter how - // often you call it. Useful for lazy initialization. - _.once = _.partial(_.before, 2); - - // Object Functions - // ---------------- - - // Retrieve the names of an object's properties. - // Delegates to **ECMAScript 5**'s native `Object.keys` - _.keys = function(obj) { - if (!_.isObject(obj)) return []; - if (nativeKeys) return nativeKeys(obj); - var keys = []; - for (var key in obj) if (_.has(obj, key)) keys.push(key); - return keys; - }; - - // Retrieve the values of an object's properties. - _.values = function(obj) { - var keys = _.keys(obj); - var length = keys.length; - var values = Array(length); - for (var i = 0; i < length; i++) { - values[i] = obj[keys[i]]; - } - return values; - }; - - // Convert an object into a list of `[key, value]` pairs. - _.pairs = function(obj) { - var keys = _.keys(obj); - var length = keys.length; - var pairs = Array(length); - for (var i = 0; i < length; i++) { - pairs[i] = [keys[i], obj[keys[i]]]; - } - return pairs; - }; - - // Invert the keys and values of an object. The values must be serializable. - _.invert = function(obj) { - var result = {}; - var keys = _.keys(obj); - for (var i = 0, length = keys.length; i < length; i++) { - result[obj[keys[i]]] = keys[i]; - } - return result; - }; - - // Return a sorted list of the function names available on the object. - // Aliased as `methods` - _.functions = _.methods = function(obj) { - var names = []; - for (var key in obj) { - if (_.isFunction(obj[key])) names.push(key); - } - return names.sort(); - }; - - // Extend a given object with all the properties in passed-in object(s). - _.extend = function(obj) { - if (!_.isObject(obj)) return obj; - var source, prop; - for (var i = 1, length = arguments.length; i < length; i++) { - source = arguments[i]; - for (prop in source) { - if (hasOwnProperty.call(source, prop)) { - obj[prop] = source[prop]; - } - } - } - return obj; - }; - - // Return a copy of the object only containing the whitelisted properties. - _.pick = function(obj, iteratee, context) { - var result = {}, key; - if (obj == null) return result; - if (_.isFunction(iteratee)) { - iteratee = createCallback(iteratee, context); - for (key in obj) { - var value = obj[key]; - if (iteratee(value, key, obj)) result[key] = value; - } - } else { - var keys = concat.apply([], slice.call(arguments, 1)); - obj = new Object(obj); - for (var i = 0, length = keys.length; i < length; i++) { - key = keys[i]; - if (key in obj) result[key] = obj[key]; - } - } - return result; - }; - - // Return a copy of the object without the blacklisted properties. - _.omit = function(obj, iteratee, context) { - if (_.isFunction(iteratee)) { - iteratee = _.negate(iteratee); - } else { - var keys = _.map(concat.apply([], slice.call(arguments, 1)), String); - iteratee = function(value, key) { - return !_.contains(keys, key); - }; - } - return _.pick(obj, iteratee, context); - }; - - // Fill in a given object with default properties. - _.defaults = function(obj) { - if (!_.isObject(obj)) return obj; - for (var i = 1, length = arguments.length; i < length; i++) { - var source = arguments[i]; - for (var prop in source) { - if (obj[prop] === void 0) obj[prop] = source[prop]; - } - } - return obj; - }; - - // Create a (shallow-cloned) duplicate of an object. - _.clone = function(obj) { - if (!_.isObject(obj)) return obj; - return _.isArray(obj) ? obj.slice() : _.extend({}, obj); - }; - - // Invokes interceptor with the obj, and then returns obj. - // The primary purpose of this method is to "tap into" a method chain, in - // order to perform operations on intermediate results within the chain. - _.tap = function(obj, interceptor) { - interceptor(obj); - return obj; - }; - - // Internal recursive comparison function for `isEqual`. - var eq = function(a, b, aStack, bStack) { - // Identical objects are equal. `0 === -0`, but they aren't identical. - // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). - if (a === b) return a !== 0 || 1 / a === 1 / b; - // A strict comparison is necessary because `null == undefined`. - if (a == null || b == null) return a === b; - // Unwrap any wrapped objects. - if (a instanceof _) a = a._wrapped; - if (b instanceof _) b = b._wrapped; - // Compare `[[Class]]` names. - var className = toString.call(a); - if (className !== toString.call(b)) return false; - switch (className) { - // Strings, numbers, regular expressions, dates, and booleans are compared by value. - case '[object RegExp]': - // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i') - case '[object String]': - // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is - // equivalent to `new String("5")`. - return '' + a === '' + b; - case '[object Number]': - // `NaN`s are equivalent, but non-reflexive. - // Object(NaN) is equivalent to NaN - if (+a !== +a) return +b !== +b; - // An `egal` comparison is performed for other numeric values. - return +a === 0 ? 1 / +a === 1 / b : +a === +b; - case '[object Date]': - case '[object Boolean]': - // Coerce dates and booleans to numeric primitive values. Dates are compared by their - // millisecond representations. Note that invalid dates with millisecond representations - // of `NaN` are not equivalent. - return +a === +b; - } - if (typeof a != 'object' || typeof b != 'object') return false; - // Assume equality for cyclic structures. The algorithm for detecting cyclic - // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. - var length = aStack.length; - while (length--) { - // Linear search. Performance is inversely proportional to the number of - // unique nested structures. - if (aStack[length] === a) return bStack[length] === b; - } - // Objects with different constructors are not equivalent, but `Object`s - // from different frames are. - var aCtor = a.constructor, bCtor = b.constructor; - if ( - aCtor !== bCtor && - // Handle Object.create(x) cases - 'constructor' in a && 'constructor' in b && - !(_.isFunction(aCtor) && aCtor instanceof aCtor && - _.isFunction(bCtor) && bCtor instanceof bCtor) - ) { - return false; - } - // Add the first object to the stack of traversed objects. - aStack.push(a); - bStack.push(b); - var size, result; - // Recursively compare objects and arrays. - if (className === '[object Array]') { - // Compare array lengths to determine if a deep comparison is necessary. - size = a.length; - result = size === b.length; - if (result) { - // Deep compare the contents, ignoring non-numeric properties. - while (size--) { - if (!(result = eq(a[size], b[size], aStack, bStack))) break; - } - } - } else { - // Deep compare objects. - var keys = _.keys(a), key; - size = keys.length; - // Ensure that both objects contain the same number of properties before comparing deep equality. - result = _.keys(b).length === size; - if (result) { - while (size--) { - // Deep compare each member - key = keys[size]; - if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break; - } - } - } - // Remove the first object from the stack of traversed objects. - aStack.pop(); - bStack.pop(); - return result; - }; - - // Perform a deep comparison to check if two objects are equal. - _.isEqual = function(a, b) { - return eq(a, b, [], []); - }; - - // Is a given array, string, or object empty? - // An "empty" object has no enumerable own-properties. - _.isEmpty = function(obj) { - if (obj == null) return true; - if (_.isArray(obj) || _.isString(obj) || _.isArguments(obj)) return obj.length === 0; - for (var key in obj) if (_.has(obj, key)) return false; - return true; - }; - - // Is a given value a DOM element? - _.isElement = function(obj) { - return !!(obj && obj.nodeType === 1); - }; - - // Is a given value an array? - // Delegates to ECMA5's native Array.isArray - _.isArray = nativeIsArray || function(obj) { - return toString.call(obj) === '[object Array]'; - }; - - // Is a given variable an object? - _.isObject = function(obj) { - var type = typeof obj; - return type === 'function' || type === 'object' && !!obj; - }; - - // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp. - _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) { - _['is' + name] = function(obj) { - return toString.call(obj) === '[object ' + name + ']'; - }; - }); - - // Define a fallback version of the method in browsers (ahem, IE), where - // there isn't any inspectable "Arguments" type. - if (!_.isArguments(arguments)) { - _.isArguments = function(obj) { - return _.has(obj, 'callee'); - }; } - // Optimize `isFunction` if appropriate. Work around an IE 11 bug. - if (typeof /./ !== 'function') { - _.isFunction = function(obj) { - return typeof obj == 'function' || false; - }; - } - - // Is a given object a finite number? - _.isFinite = function(obj) { - return isFinite(obj) && !isNaN(parseFloat(obj)); - }; - - // Is the given value `NaN`? (NaN is the only number which does not equal itself). - _.isNaN = function(obj) { - return _.isNumber(obj) && obj !== +obj; - }; - - // Is a given value a boolean? - _.isBoolean = function(obj) { - return obj === true || obj === false || toString.call(obj) === '[object Boolean]'; - }; - - // Is a given value equal to null? - _.isNull = function(obj) { - return obj === null; - }; - - // Is a given variable undefined? - _.isUndefined = function(obj) { - return obj === void 0; - }; - - // Shortcut function for checking if an object has a given property directly - // on itself (in other words, not on a prototype). - _.has = function(obj, key) { - return obj != null && hasOwnProperty.call(obj, key); - }; - - // Utility Functions - // ----------------- - - // Run Underscore.js in *noConflict* mode, returning the `_` variable to its - // previous owner. Returns a reference to the Underscore object. - _.noConflict = function() { - root._ = previousUnderscore; - return this; - }; - - // Keep the identity function around for default iteratees. - _.identity = function(value) { - return value; - }; - - // Predicate-generating functions. Often useful outside of Underscore. - _.constant = function(value) { - return function() { - return value; - }; - }; - - _.noop = function(){}; - - _.property = function(key) { - return function(obj) { - return obj[key]; - }; - }; - - // Returns a predicate for checking whether an object has a given set of `key:value` pairs. - _.matches = function(attrs) { - var pairs = _.pairs(attrs), length = pairs.length; - return function(obj) { - if (obj == null) return !length; - obj = new Object(obj); - for (var i = 0; i < length; i++) { - var pair = pairs[i], key = pair[0]; - if (pair[1] !== obj[key] || !(key in obj)) return false; - } - return true; - }; - }; - - // Run a function **n** times. - _.times = function(n, iteratee, context) { - var accum = Array(Math.max(0, n)); - iteratee = createCallback(iteratee, context, 1); - for (var i = 0; i < n; i++) accum[i] = iteratee(i); - return accum; - }; - - // Return a random integer between min and max (inclusive). - _.random = function(min, max) { - if (max == null) { - max = min; - min = 0; - } - return min + Math.floor(Math.random() * (max - min + 1)); - }; - - // A (possibly faster) way to get the current timestamp as an integer. - _.now = Date.now || function() { - return new Date().getTime(); - }; - - // List of HTML entities for escaping. - var escapeMap = { - '&': '&amp;', - '<': '&lt;', - '>': '&gt;', - '"': '&quot;', - "'": '&#x27;', - '`': '&#x60;' - }; - var unescapeMap = _.invert(escapeMap); - - // Functions for escaping and unescaping strings to/from HTML interpolation. - var createEscaper = function(map) { - var escaper = function(match) { - return map[match]; - }; - // Regexes for identifying a key that needs to be escaped - var source = '(?:' + _.keys(map).join('|') + ')'; - var testRegexp = RegExp(source); - var replaceRegexp = RegExp(source, 'g'); - return function(string) { - string = string == null ? '' : '' + string; - return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string; - }; - }; - _.escape = createEscaper(escapeMap); - _.unescape = createEscaper(unescapeMap); - - // If the value of the named `property` is a function then invoke it with the - // `object` as context; otherwise, return it. - _.result = function(object, property) { - if (object == null) return void 0; - var value = object[property]; - return _.isFunction(value) ? object[property]() : value; - }; - - // Generate a unique integer id (unique within the entire client session). - // Useful for temporary DOM ids. - var idCounter = 0; - _.uniqueId = function(prefix) { - var id = ++idCounter + ''; - return prefix ? prefix + id : id; - }; - - // By default, Underscore uses ERB-style template delimiters, change the - // following template settings to use alternative delimiters. - _.templateSettings = { - evaluate : /<%([\s\S]+?)%>/g, - interpolate : /<%=([\s\S]+?)%>/g, - escape : /<%-([\s\S]+?)%>/g - }; - - // When customizing `templateSettings`, if you don't want to define an - // interpolation, evaluation or escaping regex, we need one that is - // guaranteed not to match. - var noMatch = /(.)^/; - - // Certain characters need to be escaped so that they can be put into a - // string literal. - var escapes = { - "'": "'", - '\\': '\\', - '\r': 'r', - '\n': 'n', - '\u2028': 'u2028', - '\u2029': 'u2029' - }; - - var escaper = /\\|'|\r|\n|\u2028|\u2029/g; - - var escapeChar = function(match) { - return '\\' + escapes[match]; - }; - - // JavaScript micro-templating, similar to John Resig's implementation. - // Underscore templating handles arbitrary delimiters, preserves whitespace, - // and correctly escapes quotes within interpolated code. - // NB: `oldSettings` only exists for backwards compatibility. - _.template = function(text, settings, oldSettings) { - if (!settings && oldSettings) settings = oldSettings; - settings = _.defaults({}, settings, _.templateSettings); - - // Combine delimiters into one regular expression via alternation. - var matcher = RegExp([ - (settings.escape || noMatch).source, - (settings.interpolate || noMatch).source, - (settings.evaluate || noMatch).source - ].join('|') + '|$', 'g'); - - // Compile the template source, escaping string literals appropriately. - var index = 0; - var source = "__p+='"; - text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { - source += text.slice(index, offset).replace(escaper, escapeChar); - index = offset + match.length; - - if (escape) { - source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; - } else if (interpolate) { - source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; - } else if (evaluate) { - source += "';\n" + evaluate + "\n__p+='"; - } - - // Adobe VMs need the match returned to produce the correct offest. - return match; - }); - source += "';\n"; - - // If a variable is not specified, place data values in local scope. - if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; - - source = "var __t,__p='',__j=Array.prototype.join," + - "print=function(){__p+=__j.call(arguments,'');};\n" + - source + 'return __p;\n'; - - try { - var render = new Function(settings.variable || 'obj', '_', source); - } catch (e) { - e.source = source; - throw e; - } - - var template = function(data) { - return render.call(this, data, _); - }; - - // Provide the compiled source as a convenience for precompilation. - var argument = settings.variable || 'obj'; - template.source = 'function(' + argument + '){\n' + source + '}'; - - return template; - }; - - // Add a "chain" function. Start chaining a wrapped Underscore object. - _.chain = function(obj) { - var instance = _(obj); - instance._chain = true; - return instance; - }; - - // OOP - // --------------- - // If Underscore is called as a function, it returns a wrapped object that - // can be used OO-style. This wrapper holds altered versions of all the - // underscore functions. Wrapped objects may be chained. - - // Helper function to continue chaining intermediate results. - var result = function(obj) { - return this._chain ? _(obj).chain() : obj; - }; - - // Add your own custom functions to the Underscore object. - _.mixin = function(obj) { - _.each(_.functions(obj), function(name) { - var func = _[name] = obj[name]; - _.prototype[name] = function() { - var args = [this._wrapped]; - push.apply(args, arguments); - return result.call(this, func.apply(_, args)); - }; - }); - }; - - // Add all of the Underscore functions to the wrapper object. - _.mixin(_); - - // Add all mutator Array functions to the wrapper. - _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { - var method = ArrayProto[name]; - _.prototype[name] = function() { - var obj = this._wrapped; - method.apply(obj, arguments); - if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0]; - return result.call(this, obj); - }; - }); - - // Add all accessor Array functions to the wrapper. - _.each(['concat', 'join', 'slice'], function(name) { - var method = ArrayProto[name]; - _.prototype[name] = function() { - return result.call(this, method.apply(this._wrapped, arguments)); - }; - }); - - // Extracts the result from a wrapped and chained object. - _.prototype.value = function() { - return this._wrapped; - }; - - // AMD registration happens at the end for compatibility with AMD loaders - // that may not enforce next-turn semantics on modules. Even though general - // practice for AMD registration is to be anonymous, underscore registers - // as a named module because, like jQuery, it is a base library that is - // popular enough to be bundled in a third party lib, but not be part of - // an AMD load request. Those cases could generate an error when an - // anonymous define() is called outside of a loader request. - if (typeof define === 'function' && define.amd) { - define('underscore', [], function() { - return _; - }); - } -}.call(this)); -//! moment.js -//! version : 2.6.0 -//! authors : Tim Wood, Iskren Chernev, Moment.js contributors -//! license : MIT -//! momentjs.com - -(function (undefined) { - - /************************************ - Constants - ************************************/ - - var moment, - VERSION = "2.6.0", - // the global-scope this is NOT the global object in Node.js - globalScope = typeof global !== 'undefined' ? global : this, - oldGlobalMoment, - round = Math.round, - i, - - YEAR = 0, - MONTH = 1, - DATE = 2, - HOUR = 3, - MINUTE = 4, - SECOND = 5, - MILLISECOND = 6, - - // internal storage for language config files - languages = {}, - - // moment internal properties - momentProperties = { - _isAMomentObject: null, - _i : null, - _f : null, - _l : null, - _strict : null, - _isUTC : null, - _offset : null, // optional. Combine with _isUTC - _pf : null, - _lang : null // optional - }, - - // check for nodeJS - hasModule = (typeof module !== 'undefined' && module.exports), - - // ASP.NET json date format regex - aspNetJsonRegex = /^\/?Date\((\-?\d+)/i, - aspNetTimeSpanJsonRegex = /(\-)?(?:(\d*)\.)?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?)?/, - - // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html - // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere - isoDurationRegex = /^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/, - - // format tokens - formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|X|zz?|ZZ?|.)/g, - localFormattingTokens = /(\[[^\[]*\])|(\\)?(LT|LL?L?L?|l{1,4})/g, - - // parsing token regexes - parseTokenOneOrTwoDigits = /\d\d?/, // 0 - 99 - parseTokenOneToThreeDigits = /\d{1,3}/, // 0 - 999 - parseTokenOneToFourDigits = /\d{1,4}/, // 0 - 9999 - parseTokenOneToSixDigits = /[+\-]?\d{1,6}/, // -999,999 - 999,999 - parseTokenDigits = /\d+/, // nonzero number of digits - parseTokenWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i, // any word (or two) characters or numbers including two/three word month in arabic. - parseTokenTimezone = /Z|[\+\-]\d\d:?\d\d/gi, // +00:00 -00:00 +0000 -0000 or Z - parseTokenT = /T/i, // T (ISO separator) - parseTokenTimestampMs = /[\+\-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123 - parseTokenOrdinal = /\d{1,2}/, - - //strict parsing regexes - parseTokenOneDigit = /\d/, // 0 - 9 - parseTokenTwoDigits = /\d\d/, // 00 - 99 - parseTokenThreeDigits = /\d{3}/, // 000 - 999 - parseTokenFourDigits = /\d{4}/, // 0000 - 9999 - parseTokenSixDigits = /[+-]?\d{6}/, // -999,999 - 999,999 - parseTokenSignedNumber = /[+-]?\d+/, // -inf - inf - - // iso 8601 regex - // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00) - isoRegex = /^\s*(?:[+-]\d{6}|\d{4})-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/, - - isoFormat = 'YYYY-MM-DDTHH:mm:ssZ', - - isoDates = [ - ['YYYYYY-MM-DD', /[+-]\d{6}-\d{2}-\d{2}/], - ['YYYY-MM-DD', /\d{4}-\d{2}-\d{2}/], - ['GGGG-[W]WW-E', /\d{4}-W\d{2}-\d/], - ['GGGG-[W]WW', /\d{4}-W\d{2}/], - ['YYYY-DDD', /\d{4}-\d{3}/] - ], - - // iso time formats and regexes - isoTimes = [ - ['HH:mm:ss.SSSS', /(T| )\d\d:\d\d:\d\d\.\d+/], - ['HH:mm:ss', /(T| )\d\d:\d\d:\d\d/], - ['HH:mm', /(T| )\d\d:\d\d/], - ['HH', /(T| )\d\d/] - ], - - // timezone chunker "+10:00" > ["10", "00"] or "-1530" > ["-15", "30"] - parseTimezoneChunker = /([\+\-]|\d\d)/gi, - - // getter and setter names - proxyGettersAndSetters = 'Date|Hours|Minutes|Seconds|Milliseconds'.split('|'), - unitMillisecondFactors = { - 'Milliseconds' : 1, - 'Seconds' : 1e3, - 'Minutes' : 6e4, - 'Hours' : 36e5, - 'Days' : 864e5, - 'Months' : 2592e6, - 'Years' : 31536e6 - }, - - unitAliases = { - ms : 'millisecond', - s : 'second', - m : 'minute', - h : 'hour', - d : 'day', - D : 'date', - w : 'week', - W : 'isoWeek', - M : 'month', - Q : 'quarter', - y : 'year', - DDD : 'dayOfYear', - e : 'weekday', - E : 'isoWeekday', - gg: 'weekYear', - GG: 'isoWeekYear' - }, - - camelFunctions = { - dayofyear : 'dayOfYear', - isoweekday : 'isoWeekday', - isoweek : 'isoWeek', - weekyear : 'weekYear', - isoweekyear : 'isoWeekYear' - }, - - // format function strings - formatFunctions = {}, - - // tokens to ordinalize and pad - ordinalizeTokens = 'DDD w W M D d'.split(' '), - paddedTokens = 'M D H h m s w W'.split(' '), - - formatTokenFunctions = { - M : function () { - return this.month() + 1; - }, - MMM : function (format) { - return this.lang().monthsShort(this, format); - }, - MMMM : function (format) { - return this.lang().months(this, format); - }, - D : function () { - return this.date(); - }, - DDD : function () { - return this.dayOfYear(); - }, - d : function () { - return this.day(); - }, - dd : function (format) { - return this.lang().weekdaysMin(this, format); - }, - ddd : function (format) { - return this.lang().weekdaysShort(this, format); - }, - dddd : function (format) { - return this.lang().weekdays(this, format); - }, - w : function () { - return this.week(); - }, - W : function () { - return this.isoWeek(); - }, - YY : function () { - return leftZeroFill(this.year() % 100, 2); - }, - YYYY : function () { - return leftZeroFill(this.year(), 4); - }, - YYYYY : function () { - return leftZeroFill(this.year(), 5); - }, - YYYYYY : function () { - var y = this.year(), sign = y >= 0 ? '+' : '-'; - return sign + leftZeroFill(Math.abs(y), 6); - }, - gg : function () { - return leftZeroFill(this.weekYear() % 100, 2); - }, - gggg : function () { - return leftZeroFill(this.weekYear(), 4); - }, - ggggg : function () { - return leftZeroFill(this.weekYear(), 5); - }, - GG : function () { - return leftZeroFill(this.isoWeekYear() % 100, 2); - }, - GGGG : function () { - return leftZeroFill(this.isoWeekYear(), 4); - }, - GGGGG : function () { - return leftZeroFill(this.isoWeekYear(), 5); - }, - e : function () { - return this.weekday(); - }, - E : function () { - return this.isoWeekday(); - }, - a : function () { - return this.lang().meridiem(this.hours(), this.minutes(), true); - }, - A : function () { - return this.lang().meridiem(this.hours(), this.minutes(), false); - }, - H : function () { - return this.hours(); - }, - h : function () { - return this.hours() % 12 || 12; - }, - m : function () { - return this.minutes(); - }, - s : function () { - return this.seconds(); - }, - S : function () { - return toInt(this.milliseconds() / 100); - }, - SS : function () { - return leftZeroFill(toInt(this.milliseconds() / 10), 2); - }, - SSS : function () { - return leftZeroFill(this.milliseconds(), 3); - }, - SSSS : function () { - return leftZeroFill(this.milliseconds(), 3); - }, - Z : function () { - var a = -this.zone(), - b = "+"; - if (a < 0) { - a = -a; - b = "-"; - } - return b + leftZeroFill(toInt(a / 60), 2) + ":" + leftZeroFill(toInt(a) % 60, 2); - }, - ZZ : function () { - var a = -this.zone(), - b = "+"; - if (a < 0) { - a = -a; - b = "-"; - } - return b + leftZeroFill(toInt(a / 60), 2) + leftZeroFill(toInt(a) % 60, 2); - }, - z : function () { - return this.zoneAbbr(); - }, - zz : function () { - return this.zoneName(); - }, - X : function () { - return this.unix(); - }, - Q : function () { - return this.quarter(); - } - }, - - lists = ['months', 'monthsShort', 'weekdays', 'weekdaysShort', 'weekdaysMin']; - - function defaultParsingFlags() { - // We need to deep clone this object, and es5 standard is not very - // helpful. - return { - empty : false, - unusedTokens : [], - unusedInput : [], - overflow : -2, - charsLeftOver : 0, - nullInput : false, - invalidMonth : null, - invalidFormat : false, - userInvalidated : false, - iso: false - }; - } - - function deprecate(msg, fn) { - var firstTime = true; - function printMsg() { - if (moment.suppressDeprecationWarnings === false && - typeof console !== 'undefined' && console.warn) { - console.warn("Deprecation warning: " + msg); - } - } - return extend(function () { - if (firstTime) { - printMsg(); - firstTime = false; - } - return fn.apply(this, arguments); - }, fn); - } - - function padToken(func, count) { - return function (a) { - return leftZeroFill(func.call(this, a), count); - }; - } - function ordinalizeToken(func, period) { - return function (a) { - return this.lang().ordinal(func.call(this, a), period); - }; - } - - while (ordinalizeTokens.length) { - i = ordinalizeTokens.pop(); - formatTokenFunctions[i + 'o'] = ordinalizeToken(formatTokenFunctions[i], i); - } - while (paddedTokens.length) { - i = paddedTokens.pop(); - formatTokenFunctions[i + i] = padToken(formatTokenFunctions[i], 2); - } - formatTokenFunctions.DDDD = padToken(formatTokenFunctions.DDD, 3); - - - /************************************ - Constructors - ************************************/ - - function Language() { - - } - - // Moment prototype object - function Moment(config) { - checkOverflow(config); - extend(this, config); - } - - // Duration Constructor - function Duration(duration) { - var normalizedInput = normalizeObjectUnits(duration), - years = normalizedInput.year || 0, - quarters = normalizedInput.quarter || 0, - months = normalizedInput.month || 0, - weeks = normalizedInput.week || 0, - days = normalizedInput.day || 0, - hours = normalizedInput.hour || 0, - minutes = normalizedInput.minute || 0, - seconds = normalizedInput.second || 0, - milliseconds = normalizedInput.millisecond || 0; - - // representation for dateAddRemove - this._milliseconds = +milliseconds + - seconds * 1e3 + // 1000 - minutes * 6e4 + // 1000 * 60 - hours * 36e5; // 1000 * 60 * 60 - // Because of dateAddRemove treats 24 hours as different from a - // day when working around DST, we need to store them separately - this._days = +days + - weeks * 7; - // It is impossible translate months into days without knowing - // which months you are are talking about, so we have to store - // it separately. - this._months = +months + - quarters * 3 + - years * 12; - - this._data = {}; - - this._bubble(); - } - - /************************************ - Helpers - ************************************/ - - - function extend(a, b) { - for (var i in b) { - if (b.hasOwnProperty(i)) { - a[i] = b[i]; - } - } - - if (b.hasOwnProperty("toString")) { - a.toString = b.toString; - } - - if (b.hasOwnProperty("valueOf")) { - a.valueOf = b.valueOf; - } - - return a; - } - - function cloneMoment(m) { - var result = {}, i; - for (i in m) { - if (m.hasOwnProperty(i) && momentProperties.hasOwnProperty(i)) { - result[i] = m[i]; - } - } - - return result; - } - - function absRound(number) { - if (number < 0) { - return Math.ceil(number); - } else { - return Math.floor(number); - } - } - - // left zero fill a number - // see http://jsperf.com/left-zero-filling for performance comparison - function leftZeroFill(number, targetLength, forceSign) { - var output = '' + Math.abs(number), - sign = number >= 0; - - while (output.length < targetLength) { - output = '0' + output; - } - return (sign ? (forceSign ? '+' : '') : '-') + output; - } - - // helper function for _.addTime and _.subtractTime - function addOrSubtractDurationFromMoment(mom, duration, isAdding, updateOffset) { - var milliseconds = duration._milliseconds, - days = duration._days, - months = duration._months; - updateOffset = updateOffset == null ? true : updateOffset; - - if (milliseconds) { - mom._d.setTime(+mom._d + milliseconds * isAdding); - } - if (days) { - rawSetter(mom, 'Date', rawGetter(mom, 'Date') + days * isAdding); - } - if (months) { - rawMonthSetter(mom, rawGetter(mom, 'Month') + months * isAdding); - } - if (updateOffset) { - moment.updateOffset(mom, days || months); - } - } - - // check if is an array - function isArray(input) { - return Object.prototype.toString.call(input) === '[object Array]'; - } - - function isDate(input) { - return Object.prototype.toString.call(input) === '[object Date]' || - input instanceof Date; - } - - // compare two arrays, return the number of differences - function compareArrays(array1, array2, dontConvert) { - var len = Math.min(array1.length, array2.length), - lengthDiff = Math.abs(array1.length - array2.length), - diffs = 0, - i; - for (i = 0; i < len; i++) { - if ((dontConvert && array1[i] !== array2[i]) || - (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) { - diffs++; - } - } - return diffs + lengthDiff; - } - - function normalizeUnits(units) { - if (units) { - var lowered = units.toLowerCase().replace(/(.)s$/, '$1'); - units = unitAliases[units] || camelFunctions[lowered] || lowered; - } - return units; - } - - function normalizeObjectUnits(inputObject) { - var normalizedInput = {}, - normalizedProp, - prop; - - for (prop in inputObject) { - if (inputObject.hasOwnProperty(prop)) { - normalizedProp = normalizeUnits(prop); - if (normalizedProp) { - normalizedInput[normalizedProp] = inputObject[prop]; - } - } - } - - return normalizedInput; - } - - function makeList(field) { - var count, setter; - - if (field.indexOf('week') === 0) { - count = 7; - setter = 'day'; - } - else if (field.indexOf('month') === 0) { - count = 12; - setter = 'month'; - } - else { - return; - } - - moment[field] = function (format, index) { - var i, getter, - method = moment.fn._lang[field], - results = []; - - if (typeof format === 'number') { - index = format; - format = undefined; - } - - getter = function (i) { - var m = moment().utc().set(setter, i); - return method.call(moment.fn._lang, m, format || ''); - }; - - if (index != null) { - return getter(index); - } - else { - for (i = 0; i < count; i++) { - results.push(getter(i)); - } - return results; - } - }; - } - - function toInt(argumentForCoercion) { - var coercedNumber = +argumentForCoercion, - value = 0; - - if (coercedNumber !== 0 && isFinite(coercedNumber)) { - if (coercedNumber >= 0) { - value = Math.floor(coercedNumber); - } else { - value = Math.ceil(coercedNumber); - } - } - - return value; - } - - function daysInMonth(year, month) { - return new Date(Date.UTC(year, month + 1, 0)).getUTCDate(); - } - - function weeksInYear(year, dow, doy) { - return weekOfYear(moment([year, 11, 31 + dow - doy]), dow, doy).week; - } - - function daysInYear(year) { - return isLeapYear(year) ? 366 : 365; - } - - function isLeapYear(year) { - return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; - } - - function checkOverflow(m) { - var overflow; - if (m._a && m._pf.overflow === -2) { - overflow = - m._a[MONTH] < 0 || m._a[MONTH] > 11 ? MONTH : - m._a[DATE] < 1 || m._a[DATE] > daysInMonth(m._a[YEAR], m._a[MONTH]) ? DATE : - m._a[HOUR] < 0 || m._a[HOUR] > 23 ? HOUR : - m._a[MINUTE] < 0 || m._a[MINUTE] > 59 ? MINUTE : - m._a[SECOND] < 0 || m._a[SECOND] > 59 ? SECOND : - m._a[MILLISECOND] < 0 || m._a[MILLISECOND] > 999 ? MILLISECOND : - -1; - - if (m._pf._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) { - overflow = DATE; - } - - m._pf.overflow = overflow; - } - } - - function isValid(m) { - if (m._isValid == null) { - m._isValid = !isNaN(m._d.getTime()) && - m._pf.overflow < 0 && - !m._pf.empty && - !m._pf.invalidMonth && - !m._pf.nullInput && - !m._pf.invalidFormat && - !m._pf.userInvalidated; - - if (m._strict) { - m._isValid = m._isValid && - m._pf.charsLeftOver === 0 && - m._pf.unusedTokens.length === 0; - } - } - return m._isValid; - } - - function normalizeLanguage(key) { - return key ? key.toLowerCase().replace('_', '-') : key; - } - - // Return a moment from input, that is local/utc/zone equivalent to model. - function makeAs(input, model) { - return model._isUTC ? moment(input).zone(model._offset || 0) : - moment(input).local(); - } - - /************************************ - Languages - ************************************/ - - - extend(Language.prototype, { - - set : function (config) { - var prop, i; - for (i in config) { - prop = config[i]; - if (typeof prop === 'function') { - this[i] = prop; - } else { - this['_' + i] = prop; - } - } - }, - - _months : "January_February_March_April_May_June_July_August_September_October_November_December".split("_"), - months : function (m) { - return this._months[m.month()]; - }, - - _monthsShort : "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"), - monthsShort : function (m) { - return this._monthsShort[m.month()]; - }, - - monthsParse : function (monthName) { - var i, mom, regex; - - if (!this._monthsParse) { - this._monthsParse = []; - } - - for (i = 0; i < 12; i++) { - // make the regex if we don't have it already - if (!this._monthsParse[i]) { - mom = moment.utc([2000, i]); - regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, ''); - this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i'); - } - // test the regex - if (this._monthsParse[i].test(monthName)) { - return i; - } - } - }, - - _weekdays : "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), - weekdays : function (m) { - return this._weekdays[m.day()]; - }, - - _weekdaysShort : "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"), - weekdaysShort : function (m) { - return this._weekdaysShort[m.day()]; - }, - - _weekdaysMin : "Su_Mo_Tu_We_Th_Fr_Sa".split("_"), - weekdaysMin : function (m) { - return this._weekdaysMin[m.day()]; - }, - - weekdaysParse : function (weekdayName) { - var i, mom, regex; - - if (!this._weekdaysParse) { - this._weekdaysParse = []; - } - - for (i = 0; i < 7; i++) { - // make the regex if we don't have it already - if (!this._weekdaysParse[i]) { - mom = moment([2000, 1]).day(i); - regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, ''); - this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i'); - } - // test the regex - if (this._weekdaysParse[i].test(weekdayName)) { - return i; - } - } - }, - - _longDateFormat : { - LT : "h:mm A", - L : "MM/DD/YYYY", - LL : "MMMM D YYYY", - LLL : "MMMM D YYYY LT", - LLLL : "dddd, MMMM D YYYY LT" - }, - longDateFormat : function (key) { - var output = this._longDateFormat[key]; - if (!output && this._longDateFormat[key.toUpperCase()]) { - output = this._longDateFormat[key.toUpperCase()].replace(/MMMM|MM|DD|dddd/g, function (val) { - return val.slice(1); - }); - this._longDateFormat[key] = output; - } - return output; - }, - - isPM : function (input) { - // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays - // Using charAt should be more compatible. - return ((input + '').toLowerCase().charAt(0) === 'p'); - }, - - _meridiemParse : /[ap]\.?m?\.?/i, - meridiem : function (hours, minutes, isLower) { - if (hours > 11) { - return isLower ? 'pm' : 'PM'; - } else { - return isLower ? 'am' : 'AM'; - } - }, - - _calendar : { - sameDay : '[Today at] LT', - nextDay : '[Tomorrow at] LT', - nextWeek : 'dddd [at] LT', - lastDay : '[Yesterday at] LT', - lastWeek : '[Last] dddd [at] LT', - sameElse : 'L' - }, - calendar : function (key, mom) { - var output = this._calendar[key]; - return typeof output === 'function' ? output.apply(mom) : output; - }, - - _relativeTime : { - future : "in %s", - past : "%s ago", - s : "a few seconds", - m : "a minute", - mm : "%d minutes", - h : "an hour", - hh : "%d hours", - d : "a day", - dd : "%d days", - M : "a month", - MM : "%d months", - y : "a year", - yy : "%d years" - }, - relativeTime : function (number, withoutSuffix, string, isFuture) { - var output = this._relativeTime[string]; - return (typeof output === 'function') ? - output(number, withoutSuffix, string, isFuture) : - output.replace(/%d/i, number); - }, - pastFuture : function (diff, output) { - var format = this._relativeTime[diff > 0 ? 'future' : 'past']; - return typeof format === 'function' ? format(output) : format.replace(/%s/i, output); - }, - - ordinal : function (number) { - return this._ordinal.replace("%d", number); - }, - _ordinal : "%d", - - preparse : function (string) { - return string; - }, - - postformat : function (string) { - return string; - }, - - week : function (mom) { - return weekOfYear(mom, this._week.dow, this._week.doy).week; - }, - - _week : { - dow : 0, // Sunday is the first day of the week. - doy : 6 // The week that contains Jan 1st is the first week of the year. - }, - - _invalidDate: 'Invalid date', - invalidDate: function () { - return this._invalidDate; - } - }); - - // Loads a language definition into the `languages` cache. The function - // takes a key and optionally values. If not in the browser and no values - // are provided, it will load the language file module. As a convenience, - // this function also returns the language values. - function loadLang(key, values) { - values.abbr = key; - if (!languages[key]) { - languages[key] = new Language(); - } - languages[key].set(values); - return languages[key]; - } - - // Remove a language from the `languages` cache. Mostly useful in tests. - function unloadLang(key) { - delete languages[key]; - } - - // Determines which language definition to use and returns it. - // - // With no parameters, it will return the global language. If you - // pass in a language key, such as 'en', it will return the - // definition for 'en', so long as 'en' has already been loaded using - // moment.lang. - function getLangDefinition(key) { - var i = 0, j, lang, next, split, - get = function (k) { - if (!languages[k] && hasModule) { - try { - require('./lang/' + k); - } catch (e) { } - } - return languages[k]; - }; - - if (!key) { - return moment.fn._lang; - } - - if (!isArray(key)) { - //short-circuit everything else - lang = get(key); - if (lang) { - return lang; - } - key = [key]; - } - - //pick the language from the array - //try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each - //substring from most specific to least, but move to the next array item if it's a more specific variant than the current root - while (i < key.length) { - split = normalizeLanguage(key[i]).split('-'); - j = split.length; - next = normalizeLanguage(key[i + 1]); - next = next ? next.split('-') : null; - while (j > 0) { - lang = get(split.slice(0, j).join('-')); - if (lang) { - return lang; - } - if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) { - //the next array item is better than a shallower substring of this one - break; - } - j--; - } - i++; - } - return moment.fn._lang; - } - - /************************************ - Formatting - ************************************/ - - - function removeFormattingTokens(input) { - if (input.match(/\[[\s\S]/)) { - return input.replace(/^\[|\]$/g, ""); - } - return input.replace(/\\/g, ""); - } - - function makeFormatFunction(format) { - var array = format.match(formattingTokens), i, length; - - for (i = 0, length = array.length; i < length; i++) { - if (formatTokenFunctions[array[i]]) { - array[i] = formatTokenFunctions[array[i]]; - } else { - array[i] = removeFormattingTokens(array[i]); - } - } - - return function (mom) { - var output = ""; - for (i = 0; i < length; i++) { - output += array[i] instanceof Function ? array[i].call(mom, format) : array[i]; - } - return output; - }; - } - - // format date using native date object - function formatMoment(m, format) { - - if (!m.isValid()) { - return m.lang().invalidDate(); - } - - format = expandFormat(format, m.lang()); - - if (!formatFunctions[format]) { - formatFunctions[format] = makeFormatFunction(format); - } - - return formatFunctions[format](m); - } - - function expandFormat(format, lang) { - var i = 5; - - function replaceLongDateFormatTokens(input) { - return lang.longDateFormat(input) || input; - } - - localFormattingTokens.lastIndex = 0; - while (i >= 0 && localFormattingTokens.test(format)) { - format = format.replace(localFormattingTokens, replaceLongDateFormatTokens); - localFormattingTokens.lastIndex = 0; - i -= 1; - } - - return format; - } - - - /************************************ - Parsing - ************************************/ - - - // get the regex to find the next token - function getParseRegexForToken(token, config) { - var a, strict = config._strict; - switch (token) { - case 'Q': - return parseTokenOneDigit; - case 'DDDD': - return parseTokenThreeDigits; - case 'YYYY': - case 'GGGG': - case 'gggg': - return strict ? parseTokenFourDigits : parseTokenOneToFourDigits; - case 'Y': - case 'G': - case 'g': - return parseTokenSignedNumber; - case 'YYYYYY': - case 'YYYYY': - case 'GGGGG': - case 'ggggg': - return strict ? parseTokenSixDigits : parseTokenOneToSixDigits; - case 'S': - if (strict) { return parseTokenOneDigit; } - /* falls through */ - case 'SS': - if (strict) { return parseTokenTwoDigits; } - /* falls through */ - case 'SSS': - if (strict) { return parseTokenThreeDigits; } - /* falls through */ - case 'DDD': - return parseTokenOneToThreeDigits; - case 'MMM': - case 'MMMM': - case 'dd': - case 'ddd': - case 'dddd': - return parseTokenWord; - case 'a': - case 'A': - return getLangDefinition(config._l)._meridiemParse; - case 'X': - return parseTokenTimestampMs; - case 'Z': - case 'ZZ': - return parseTokenTimezone; - case 'T': - return parseTokenT; - case 'SSSS': - return parseTokenDigits; - case 'MM': - case 'DD': - case 'YY': - case 'GG': - case 'gg': - case 'HH': - case 'hh': - case 'mm': - case 'ss': - case 'ww': - case 'WW': - return strict ? parseTokenTwoDigits : parseTokenOneOrTwoDigits; - case 'M': - case 'D': - case 'd': - case 'H': - case 'h': - case 'm': - case 's': - case 'w': - case 'W': - case 'e': - case 'E': - return parseTokenOneOrTwoDigits; - case 'Do': - return parseTokenOrdinal; - default : - a = new RegExp(regexpEscape(unescapeFormat(token.replace('\\', '')), "i")); - return a; - } - } - - function timezoneMinutesFromString(string) { - string = string || ""; - var possibleTzMatches = (string.match(parseTokenTimezone) || []), - tzChunk = possibleTzMatches[possibleTzMatches.length - 1] || [], - parts = (tzChunk + '').match(parseTimezoneChunker) || ['-', 0, 0], - minutes = +(parts[1] * 60) + toInt(parts[2]); - - return parts[0] === '+' ? -minutes : minutes; - } - - // function to convert string input to date - function addTimeToArrayFromToken(token, input, config) { - var a, datePartArray = config._a; - - switch (token) { - // QUARTER - case 'Q': - if (input != null) { - datePartArray[MONTH] = (toInt(input) - 1) * 3; - } - break; - // MONTH - case 'M' : // fall through to MM - case 'MM' : - if (input != null) { - datePartArray[MONTH] = toInt(input) - 1; - } - break; - case 'MMM' : // fall through to MMMM - case 'MMMM' : - a = getLangDefinition(config._l).monthsParse(input); - // if we didn't find a month name, mark the date as invalid. - if (a != null) { - datePartArray[MONTH] = a; - } else { - config._pf.invalidMonth = input; - } - break; - // DAY OF MONTH - case 'D' : // fall through to DD - case 'DD' : - if (input != null) { - datePartArray[DATE] = toInt(input); - } - break; - case 'Do' : - if (input != null) { - datePartArray[DATE] = toInt(parseInt(input, 10)); - } - break; - // DAY OF YEAR - case 'DDD' : // fall through to DDDD - case 'DDDD' : - if (input != null) { - config._dayOfYear = toInt(input); - } - - break; - // YEAR - case 'YY' : - datePartArray[YEAR] = moment.parseTwoDigitYear(input); - break; - case 'YYYY' : - case 'YYYYY' : - case 'YYYYYY' : - datePartArray[YEAR] = toInt(input); - break; - // AM / PM - case 'a' : // fall through to A - case 'A' : - config._isPm = getLangDefinition(config._l).isPM(input); - break; - // 24 HOUR - case 'H' : // fall through to hh - case 'HH' : // fall through to hh - case 'h' : // fall through to hh - case 'hh' : - datePartArray[HOUR] = toInt(input); - break; - // MINUTE - case 'm' : // fall through to mm - case 'mm' : - datePartArray[MINUTE] = toInt(input); - break; - // SECOND - case 's' : // fall through to ss - case 'ss' : - datePartArray[SECOND] = toInt(input); - break; - // MILLISECOND - case 'S' : - case 'SS' : - case 'SSS' : - case 'SSSS' : - datePartArray[MILLISECOND] = toInt(('0.' + input) * 1000); - break; - // UNIX TIMESTAMP WITH MS - case 'X': - config._d = new Date(parseFloat(input) * 1000); - break; - // TIMEZONE - case 'Z' : // fall through to ZZ - case 'ZZ' : - config._useUTC = true; - config._tzm = timezoneMinutesFromString(input); - break; - case 'w': - case 'ww': - case 'W': - case 'WW': - case 'd': - case 'dd': - case 'ddd': - case 'dddd': - case 'e': - case 'E': - token = token.substr(0, 1); - /* falls through */ - case 'gg': - case 'gggg': - case 'GG': - case 'GGGG': - case 'GGGGG': - token = token.substr(0, 2); - if (input) { - config._w = config._w || {}; - config._w[token] = input; - } - break; - } - } - - // convert an array to a date. - // the array should mirror the parameters below - // note: all values past the year are optional and will default to the lowest possible value. - // [year, month, day , hour, minute, second, millisecond] - function dateFromConfig(config) { - var i, date, input = [], currentDate, - yearToUse, fixYear, w, temp, lang, weekday, week; - - if (config._d) { - return; - } - - currentDate = currentDateArray(config); - - //compute day of the year from weeks and weekdays - if (config._w && config._a[DATE] == null && config._a[MONTH] == null) { - fixYear = function (val) { - var intVal = parseInt(val, 10); - return val ? - (val.length < 3 ? (intVal > 68 ? 1900 + intVal : 2000 + intVal) : intVal) : - (config._a[YEAR] == null ? moment().weekYear() : config._a[YEAR]); - }; - - w = config._w; - if (w.GG != null || w.W != null || w.E != null) { - temp = dayOfYearFromWeeks(fixYear(w.GG), w.W || 1, w.E, 4, 1); - } - else { - lang = getLangDefinition(config._l); - weekday = w.d != null ? parseWeekday(w.d, lang) : - (w.e != null ? parseInt(w.e, 10) + lang._week.dow : 0); - - week = parseInt(w.w, 10) || 1; - - //if we're parsing 'd', then the low day numbers may be next week - if (w.d != null && weekday < lang._week.dow) { - week++; - } - - temp = dayOfYearFromWeeks(fixYear(w.gg), week, weekday, lang._week.doy, lang._week.dow); - } - - config._a[YEAR] = temp.year; - config._dayOfYear = temp.dayOfYear; - } - - //if the day of the year is set, figure out what it is - if (config._dayOfYear) { - yearToUse = config._a[YEAR] == null ? currentDate[YEAR] : config._a[YEAR]; - - if (config._dayOfYear > daysInYear(yearToUse)) { - config._pf._overflowDayOfYear = true; - } - - date = makeUTCDate(yearToUse, 0, config._dayOfYear); - config._a[MONTH] = date.getUTCMonth(); - config._a[DATE] = date.getUTCDate(); - } - - // Default to current date. - // * if no year, month, day of month are given, default to today - // * if day of month is given, default month and year - // * if month is given, default only year - // * if year is given, don't default anything - for (i = 0; i < 3 && config._a[i] == null; ++i) { - config._a[i] = input[i] = currentDate[i]; - } - - // Zero out whatever was not defaulted, including time - for (; i < 7; i++) { - config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i]; - } - - // add the offsets to the time to be parsed so that we can have a clean array for checking isValid - input[HOUR] += toInt((config._tzm || 0) / 60); - input[MINUTE] += toInt((config._tzm || 0) % 60); - - config._d = (config._useUTC ? makeUTCDate : makeDate).apply(null, input); - } - - function dateFromObject(config) { - var normalizedInput; - - if (config._d) { - return; - } - - normalizedInput = normalizeObjectUnits(config._i); - config._a = [ - normalizedInput.year, - normalizedInput.month, - normalizedInput.day, - normalizedInput.hour, - normalizedInput.minute, - normalizedInput.second, - normalizedInput.millisecond - ]; - - dateFromConfig(config); - } - - function currentDateArray(config) { - var now = new Date(); - if (config._useUTC) { - return [ - now.getUTCFullYear(), - now.getUTCMonth(), - now.getUTCDate() - ]; - } else { - return [now.getFullYear(), now.getMonth(), now.getDate()]; - } - } - - // date from string and format string - function makeDateFromStringAndFormat(config) { - - config._a = []; - config._pf.empty = true; - - // This array is used to make a Date, either with `new Date` or `Date.UTC` - var lang = getLangDefinition(config._l), - string = '' + config._i, - i, parsedInput, tokens, token, skipped, - stringLength = string.length, - totalParsedInputLength = 0; - - tokens = expandFormat(config._f, lang).match(formattingTokens) || []; - - for (i = 0; i < tokens.length; i++) { - token = tokens[i]; - parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0]; - if (parsedInput) { - skipped = string.substr(0, string.indexOf(parsedInput)); - if (skipped.length > 0) { - config._pf.unusedInput.push(skipped); - } - string = string.slice(string.indexOf(parsedInput) + parsedInput.length); - totalParsedInputLength += parsedInput.length; - } - // don't parse if it's not a known token - if (formatTokenFunctions[token]) { - if (parsedInput) { - config._pf.empty = false; - } - else { - config._pf.unusedTokens.push(token); - } - addTimeToArrayFromToken(token, parsedInput, config); - } - else if (config._strict && !parsedInput) { - config._pf.unusedTokens.push(token); - } - } - - // add remaining unparsed input length to the string - config._pf.charsLeftOver = stringLength - totalParsedInputLength; - if (string.length > 0) { - config._pf.unusedInput.push(string); - } - - // handle am pm - if (config._isPm && config._a[HOUR] < 12) { - config._a[HOUR] += 12; - } - // if is 12 am, change hours to 0 - if (config._isPm === false && config._a[HOUR] === 12) { - config._a[HOUR] = 0; - } - - dateFromConfig(config); - checkOverflow(config); - } - - function unescapeFormat(s) { - return s.replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) { - return p1 || p2 || p3 || p4; - }); - } - - // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript - function regexpEscape(s) { - return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); - } - - // date from string and array of format strings - function makeDateFromStringAndArray(config) { - var tempConfig, - bestMoment, - - scoreToBeat, - i, - currentScore; - - if (config._f.length === 0) { - config._pf.invalidFormat = true; - config._d = new Date(NaN); - return; - } - - for (i = 0; i < config._f.length; i++) { - currentScore = 0; - tempConfig = extend({}, config); - tempConfig._pf = defaultParsingFlags(); - tempConfig._f = config._f[i]; - makeDateFromStringAndFormat(tempConfig); - - if (!isValid(tempConfig)) { - continue; - } - - // if there is any input that was not parsed add a penalty for that format - currentScore += tempConfig._pf.charsLeftOver; - - //or tokens - currentScore += tempConfig._pf.unusedTokens.length * 10; - - tempConfig._pf.score = currentScore; - - if (scoreToBeat == null || currentScore < scoreToBeat) { - scoreToBeat = currentScore; - bestMoment = tempConfig; - } - } - - extend(config, bestMoment || tempConfig); - } - - // date from iso format - function makeDateFromString(config) { - var i, l, - string = config._i, - match = isoRegex.exec(string); - - if (match) { - config._pf.iso = true; - for (i = 0, l = isoDates.length; i < l; i++) { - if (isoDates[i][1].exec(string)) { - // match[5] should be "T" or undefined - config._f = isoDates[i][0] + (match[6] || " "); - break; - } - } - for (i = 0, l = isoTimes.length; i < l; i++) { - if (isoTimes[i][1].exec(string)) { - config._f += isoTimes[i][0]; - break; - } - } - if (string.match(parseTokenTimezone)) { - config._f += "Z"; - } - makeDateFromStringAndFormat(config); - } - else { - moment.createFromInputFallback(config); - } - } - - function makeDateFromInput(config) { - var input = config._i, - matched = aspNetJsonRegex.exec(input); - - if (input === undefined) { - config._d = new Date(); - } else if (matched) { - config._d = new Date(+matched[1]); - } else if (typeof input === 'string') { - makeDateFromString(config); - } else if (isArray(input)) { - config._a = input.slice(0); - dateFromConfig(config); - } else if (isDate(input)) { - config._d = new Date(+input); - } else if (typeof(input) === 'object') { - dateFromObject(config); - } else if (typeof(input) === 'number') { - // from milliseconds - config._d = new Date(input); - } else { - moment.createFromInputFallback(config); - } - } - - function makeDate(y, m, d, h, M, s, ms) { - //can't just apply() to create a date: - //http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply - var date = new Date(y, m, d, h, M, s, ms); - - //the date constructor doesn't accept years < 1970 - if (y < 1970) { - date.setFullYear(y); - } - return date; - } - - function makeUTCDate(y) { - var date = new Date(Date.UTC.apply(null, arguments)); - if (y < 1970) { - date.setUTCFullYear(y); - } - return date; - } - - function parseWeekday(input, language) { - if (typeof input === 'string') { - if (!isNaN(input)) { - input = parseInt(input, 10); - } - else { - input = language.weekdaysParse(input); - if (typeof input !== 'number') { - return null; - } - } - } - return input; - } - - /************************************ - Relative Time - ************************************/ - - - // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize - function substituteTimeAgo(string, number, withoutSuffix, isFuture, lang) { - return lang.relativeTime(number || 1, !!withoutSuffix, string, isFuture); - } - - function relativeTime(milliseconds, withoutSuffix, lang) { - var seconds = round(Math.abs(milliseconds) / 1000), - minutes = round(seconds / 60), - hours = round(minutes / 60), - days = round(hours / 24), - years = round(days / 365), - args = seconds < 45 && ['s', seconds] || - minutes === 1 && ['m'] || - minutes < 45 && ['mm', minutes] || - hours === 1 && ['h'] || - hours < 22 && ['hh', hours] || - days === 1 && ['d'] || - days <= 25 && ['dd', days] || - days <= 45 && ['M'] || - days < 345 && ['MM', round(days / 30)] || - years === 1 && ['y'] || ['yy', years]; - args[2] = withoutSuffix; - args[3] = milliseconds > 0; - args[4] = lang; - return substituteTimeAgo.apply({}, args); - } - - - /************************************ - Week of Year - ************************************/ - - - // firstDayOfWeek 0 = sun, 6 = sat - // the day of the week that starts the week - // (usually sunday or monday) - // firstDayOfWeekOfYear 0 = sun, 6 = sat - // the first week is the week that contains the first - // of this day of the week - // (eg. ISO weeks use thursday (4)) - function weekOfYear(mom, firstDayOfWeek, firstDayOfWeekOfYear) { - var end = firstDayOfWeekOfYear - firstDayOfWeek, - daysToDayOfWeek = firstDayOfWeekOfYear - mom.day(), - adjustedMoment; - - - if (daysToDayOfWeek > end) { - daysToDayOfWeek -= 7; - } - - if (daysToDayOfWeek < end - 7) { - daysToDayOfWeek += 7; - } - - adjustedMoment = moment(mom).add('d', daysToDayOfWeek); - return { - week: Math.ceil(adjustedMoment.dayOfYear() / 7), - year: adjustedMoment.year() - }; - } - - //http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday - function dayOfYearFromWeeks(year, week, weekday, firstDayOfWeekOfYear, firstDayOfWeek) { - var d = makeUTCDate(year, 0, 1).getUTCDay(), daysToAdd, dayOfYear; - - weekday = weekday != null ? weekday : firstDayOfWeek; - daysToAdd = firstDayOfWeek - d + (d > firstDayOfWeekOfYear ? 7 : 0) - (d < firstDayOfWeek ? 7 : 0); - dayOfYear = 7 * (week - 1) + (weekday - firstDayOfWeek) + daysToAdd + 1; - - return { - year: dayOfYear > 0 ? year : year - 1, - dayOfYear: dayOfYear > 0 ? dayOfYear : daysInYear(year - 1) + dayOfYear - }; - } - - /************************************ - Top Level Functions - ************************************/ - - function makeMoment(config) { - var input = config._i, - format = config._f; - - if (input === null || (format === undefined && input === '')) { - return moment.invalid({nullInput: true}); - } - - if (typeof input === 'string') { - config._i = input = getLangDefinition().preparse(input); - } - - if (moment.isMoment(input)) { - config = cloneMoment(input); - - config._d = new Date(+input._d); - } else if (format) { - if (isArray(format)) { - makeDateFromStringAndArray(config); - } else { - makeDateFromStringAndFormat(config); - } - } else { - makeDateFromInput(config); - } - - return new Moment(config); - } - - moment = function (input, format, lang, strict) { - var c; - - if (typeof(lang) === "boolean") { - strict = lang; - lang = undefined; - } - // object construction must be done this way. - // https://github.com/moment/moment/issues/1423 - c = {}; - c._isAMomentObject = true; - c._i = input; - c._f = format; - c._l = lang; - c._strict = strict; - c._isUTC = false; - c._pf = defaultParsingFlags(); - - return makeMoment(c); - }; - - moment.suppressDeprecationWarnings = false; - - moment.createFromInputFallback = deprecate( - "moment construction falls back to js Date. This is " + - "discouraged and will be removed in upcoming major " + - "release. Please refer to " + - "https://github.com/moment/moment/issues/1407 for more info.", - function (config) { - config._d = new Date(config._i); - }); - - // creating with utc - moment.utc = function (input, format, lang, strict) { - var c; - - if (typeof(lang) === "boolean") { - strict = lang; - lang = undefined; - } - // object construction must be done this way. - // https://github.com/moment/moment/issues/1423 - c = {}; - c._isAMomentObject = true; - c._useUTC = true; - c._isUTC = true; - c._l = lang; - c._i = input; - c._f = format; - c._strict = strict; - c._pf = defaultParsingFlags(); - - return makeMoment(c).utc(); - }; - - // creating with unix timestamp (in seconds) - moment.unix = function (input) { - return moment(input * 1000); - }; - - // duration - moment.duration = function (input, key) { - var duration = input, - // matching against regexp is expensive, do it on demand - match = null, - sign, - ret, - parseIso; - - if (moment.isDuration(input)) { - duration = { - ms: input._milliseconds, - d: input._days, - M: input._months - }; - } else if (typeof input === 'number') { - duration = {}; - if (key) { - duration[key] = input; - } else { - duration.milliseconds = input; - } - } else if (!!(match = aspNetTimeSpanJsonRegex.exec(input))) { - sign = (match[1] === "-") ? -1 : 1; - duration = { - y: 0, - d: toInt(match[DATE]) * sign, - h: toInt(match[HOUR]) * sign, - m: toInt(match[MINUTE]) * sign, - s: toInt(match[SECOND]) * sign, - ms: toInt(match[MILLISECOND]) * sign - }; - } else if (!!(match = isoDurationRegex.exec(input))) { - sign = (match[1] === "-") ? -1 : 1; - parseIso = function (inp) { - // We'd normally use ~~inp for this, but unfortunately it also - // converts floats to ints. - // inp may be undefined, so careful calling replace on it. - var res = inp && parseFloat(inp.replace(',', '.')); - // apply sign while we're at it - return (isNaN(res) ? 0 : res) * sign; - }; - duration = { - y: parseIso(match[2]), - M: parseIso(match[3]), - d: parseIso(match[4]), - h: parseIso(match[5]), - m: parseIso(match[6]), - s: parseIso(match[7]), - w: parseIso(match[8]) - }; - } - - ret = new Duration(duration); - - if (moment.isDuration(input) && input.hasOwnProperty('_lang')) { - ret._lang = input._lang; - } - - return ret; - }; - - // version number - moment.version = VERSION; - - // default format - moment.defaultFormat = isoFormat; - - // Plugins that add properties should also add the key here (null value), - // so we can properly clone ourselves. - moment.momentProperties = momentProperties; - - // This function will be called whenever a moment is mutated. - // It is intended to keep the offset in sync with the timezone. - moment.updateOffset = function () {}; - - // This function will load languages and then set the global language. If - // no arguments are passed in, it will simply return the current global - // language key. - moment.lang = function (key, values) { - var r; - if (!key) { - return moment.fn._lang._abbr; - } - if (values) { - loadLang(normalizeLanguage(key), values); - } else if (values === null) { - unloadLang(key); - key = 'en'; - } else if (!languages[key]) { - getLangDefinition(key); - } - r = moment.duration.fn._lang = moment.fn._lang = getLangDefinition(key); - return r._abbr; - }; - - // returns language data - moment.langData = function (key) { - if (key && key._lang && key._lang._abbr) { - key = key._lang._abbr; - } - return getLangDefinition(key); - }; - - // compare moment object - moment.isMoment = function (obj) { - return obj instanceof Moment || - (obj != null && obj.hasOwnProperty('_isAMomentObject')); - }; - - // for typechecking Duration objects - moment.isDuration = function (obj) { - return obj instanceof Duration; - }; - - for (i = lists.length - 1; i >= 0; --i) { - makeList(lists[i]); - } - - moment.normalizeUnits = function (units) { - return normalizeUnits(units); - }; - - moment.invalid = function (flags) { - var m = moment.utc(NaN); - if (flags != null) { - extend(m._pf, flags); - } - else { - m._pf.userInvalidated = true; - } - - return m; - }; - - moment.parseZone = function () { - return moment.apply(null, arguments).parseZone(); - }; - - moment.parseTwoDigitYear = function (input) { - return toInt(input) + (toInt(input) > 68 ? 1900 : 2000); - }; - - /************************************ - Moment Prototype - ************************************/ - - - extend(moment.fn = Moment.prototype, { - - clone : function () { - return moment(this); - }, - - valueOf : function () { - return +this._d + ((this._offset || 0) * 60000); - }, - - unix : function () { - return Math.floor(+this / 1000); - }, - - toString : function () { - return this.clone().lang('en').format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ"); - }, - - toDate : function () { - return this._offset ? new Date(+this) : this._d; - }, - - toISOString : function () { - var m = moment(this).utc(); - if (0 < m.year() && m.year() <= 9999) { - return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); - } else { - return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); - } - }, - - toArray : function () { - var m = this; - return [ - m.year(), - m.month(), - m.date(), - m.hours(), - m.minutes(), - m.seconds(), - m.milliseconds() - ]; - }, - - isValid : function () { - return isValid(this); - }, - - isDSTShifted : function () { - - if (this._a) { - return this.isValid() && compareArrays(this._a, (this._isUTC ? moment.utc(this._a) : moment(this._a)).toArray()) > 0; - } - - return false; - }, - - parsingFlags : function () { - return extend({}, this._pf); - }, - - invalidAt: function () { - return this._pf.overflow; - }, - - utc : function () { - return this.zone(0); - }, - - local : function () { - this.zone(0); - this._isUTC = false; - return this; - }, - - format : function (inputString) { - var output = formatMoment(this, inputString || moment.defaultFormat); - return this.lang().postformat(output); - }, - - add : function (input, val) { - var dur; - // switch args to support add('s', 1) and add(1, 's') - if (typeof input === 'string') { - dur = moment.duration(+val, input); - } else { - dur = moment.duration(input, val); - } - addOrSubtractDurationFromMoment(this, dur, 1); - return this; - }, - - subtract : function (input, val) { - var dur; - // switch args to support subtract('s', 1) and subtract(1, 's') - if (typeof input === 'string') { - dur = moment.duration(+val, input); - } else { - dur = moment.duration(input, val); - } - addOrSubtractDurationFromMoment(this, dur, -1); - return this; - }, - - diff : function (input, units, asFloat) { - var that = makeAs(input, this), - zoneDiff = (this.zone() - that.zone()) * 6e4, - diff, output; - - units = normalizeUnits(units); - - if (units === 'year' || units === 'month') { - // average number of days in the months in the given dates - diff = (this.daysInMonth() + that.daysInMonth()) * 432e5; // 24 * 60 * 60 * 1000 / 2 - // difference in months - output = ((this.year() - that.year()) * 12) + (this.month() - that.month()); - // adjust by taking difference in days, average number of days - // and dst in the given months. - output += ((this - moment(this).startOf('month')) - - (that - moment(that).startOf('month'))) / diff; - // same as above but with zones, to negate all dst - output -= ((this.zone() - moment(this).startOf('month').zone()) - - (that.zone() - moment(that).startOf('month').zone())) * 6e4 / diff; - if (units === 'year') { - output = output / 12; - } - } else { - diff = (this - that); - output = units === 'second' ? diff / 1e3 : // 1000 - units === 'minute' ? diff / 6e4 : // 1000 * 60 - units === 'hour' ? diff / 36e5 : // 1000 * 60 * 60 - units === 'day' ? (diff - zoneDiff) / 864e5 : // 1000 * 60 * 60 * 24, negate dst - units === 'week' ? (diff - zoneDiff) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst - diff; - } - return asFloat ? output : absRound(output); - }, - - from : function (time, withoutSuffix) { - return moment.duration(this.diff(time)).lang(this.lang()._abbr).humanize(!withoutSuffix); - }, - - fromNow : function (withoutSuffix) { - return this.from(moment(), withoutSuffix); - }, - - calendar : function () { - // We want to compare the start of today, vs this. - // Getting start-of-today depends on whether we're zone'd or not. - var sod = makeAs(moment(), this).startOf('day'), - diff = this.diff(sod, 'days', true), - format = diff < -6 ? 'sameElse' : - diff < -1 ? 'lastWeek' : - diff < 0 ? 'lastDay' : - diff < 1 ? 'sameDay' : - diff < 2 ? 'nextDay' : - diff < 7 ? 'nextWeek' : 'sameElse'; - return this.format(this.lang().calendar(format, this)); - }, - - isLeapYear : function () { - return isLeapYear(this.year()); - }, - - isDST : function () { - return (this.zone() < this.clone().month(0).zone() || - this.zone() < this.clone().month(5).zone()); - }, - - day : function (input) { - var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay(); - if (input != null) { - input = parseWeekday(input, this.lang()); - return this.add({ d : input - day }); - } else { - return day; - } - }, - - month : makeAccessor('Month', true), - - startOf: function (units) { - units = normalizeUnits(units); - // the following switch intentionally omits break keywords - // to utilize falling through the cases. - switch (units) { - case 'year': - this.month(0); - /* falls through */ - case 'quarter': - case 'month': - this.date(1); - /* falls through */ - case 'week': - case 'isoWeek': - case 'day': - this.hours(0); - /* falls through */ - case 'hour': - this.minutes(0); - /* falls through */ - case 'minute': - this.seconds(0); - /* falls through */ - case 'second': - this.milliseconds(0); - /* falls through */ - } - - // weeks are a special case - if (units === 'week') { - this.weekday(0); - } else if (units === 'isoWeek') { - this.isoWeekday(1); - } - - // quarters are also special - if (units === 'quarter') { - this.month(Math.floor(this.month() / 3) * 3); - } - - return this; - }, - - endOf: function (units) { - units = normalizeUnits(units); - return this.startOf(units).add((units === 'isoWeek' ? 'week' : units), 1).subtract('ms', 1); - }, - - isAfter: function (input, units) { - units = typeof units !== 'undefined' ? units : 'millisecond'; - return +this.clone().startOf(units) > +moment(input).startOf(units); - }, - - isBefore: function (input, units) { - units = typeof units !== 'undefined' ? units : 'millisecond'; - return +this.clone().startOf(units) < +moment(input).startOf(units); - }, - - isSame: function (input, units) { - units = units || 'ms'; - return +this.clone().startOf(units) === +makeAs(input, this).startOf(units); - }, - - min: function (other) { - other = moment.apply(null, arguments); - return other < this ? this : other; - }, - - max: function (other) { - other = moment.apply(null, arguments); - return other > this ? this : other; - }, - - // keepTime = true means only change the timezone, without affecting - // the local hour. So 5:31:26 +0300 --[zone(2, true)]--> 5:31:26 +0200 - // It is possible that 5:31:26 doesn't exist int zone +0200, so we - // adjust the time as needed, to be valid. - // - // Keeping the time actually adds/subtracts (one hour) - // from the actual represented time. That is why we call updateOffset - // a second time. In case it wants us to change the offset again - // _changeInProgress == true case, then we have to adjust, because - // there is no such time in the given timezone. - zone : function (input, keepTime) { - var offset = this._offset || 0; - if (input != null) { - if (typeof input === "string") { - input = timezoneMinutesFromString(input); - } - if (Math.abs(input) < 16) { - input = input * 60; - } - this._offset = input; - this._isUTC = true; - if (offset !== input) { - if (!keepTime || this._changeInProgress) { - addOrSubtractDurationFromMoment(this, - moment.duration(offset - input, 'm'), 1, false); - } else if (!this._changeInProgress) { - this._changeInProgress = true; - moment.updateOffset(this, true); - this._changeInProgress = null; - } - } - } else { - return this._isUTC ? offset : this._d.getTimezoneOffset(); - } - return this; - }, - - zoneAbbr : function () { - return this._isUTC ? "UTC" : ""; - }, - - zoneName : function () { - return this._isUTC ? "Coordinated Universal Time" : ""; - }, - - parseZone : function () { - if (this._tzm) { - this.zone(this._tzm); - } else if (typeof this._i === 'string') { - this.zone(this._i); - } - return this; - }, - - hasAlignedHourOffset : function (input) { - if (!input) { - input = 0; - } - else { - input = moment(input).zone(); - } - - return (this.zone() - input) % 60 === 0; - }, - - daysInMonth : function () { - return daysInMonth(this.year(), this.month()); - }, - - dayOfYear : function (input) { - var dayOfYear = round((moment(this).startOf('day') - moment(this).startOf('year')) / 864e5) + 1; - return input == null ? dayOfYear : this.add("d", (input - dayOfYear)); - }, - - quarter : function (input) { - return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3); - }, - - weekYear : function (input) { - var year = weekOfYear(this, this.lang()._week.dow, this.lang()._week.doy).year; - return input == null ? year : this.add("y", (input - year)); - }, - - isoWeekYear : function (input) { - var year = weekOfYear(this, 1, 4).year; - return input == null ? year : this.add("y", (input - year)); - }, - - week : function (input) { - var week = this.lang().week(this); - return input == null ? week : this.add("d", (input - week) * 7); - }, - - isoWeek : function (input) { - var week = weekOfYear(this, 1, 4).week; - return input == null ? week : this.add("d", (input - week) * 7); - }, - - weekday : function (input) { - var weekday = (this.day() + 7 - this.lang()._week.dow) % 7; - return input == null ? weekday : this.add("d", input - weekday); - }, - - isoWeekday : function (input) { - // behaves the same as moment#day except - // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6) - // as a setter, sunday should belong to the previous week. - return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7); - }, - - isoWeeksInYear : function () { - return weeksInYear(this.year(), 1, 4); - }, - - weeksInYear : function () { - var weekInfo = this._lang._week; - return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy); - }, - - get : function (units) { - units = normalizeUnits(units); - return this[units](); - }, - - set : function (units, value) { - units = normalizeUnits(units); - if (typeof this[units] === 'function') { - this[units](value); - } - return this; - }, - - // If passed a language key, it will set the language for this - // instance. Otherwise, it will return the language configuration - // variables for this instance. - lang : function (key) { - if (key === undefined) { - return this._lang; - } else { - this._lang = getLangDefinition(key); - return this; - } - } - }); - - function rawMonthSetter(mom, value) { - var dayOfMonth; - - // TODO: Move this out of here! - if (typeof value === 'string') { - value = mom.lang().monthsParse(value); - // TODO: Another silent failure? - if (typeof value !== 'number') { - return mom; - } - } - - dayOfMonth = Math.min(mom.date(), - daysInMonth(mom.year(), value)); - mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth); - return mom; - } - - function rawGetter(mom, unit) { - return mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit](); - } - - function rawSetter(mom, unit, value) { - if (unit === 'Month') { - return rawMonthSetter(mom, value); - } else { - return mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value); - } - } - - function makeAccessor(unit, keepTime) { - return function (value) { - if (value != null) { - rawSetter(this, unit, value); - moment.updateOffset(this, keepTime); - return this; - } else { - return rawGetter(this, unit); - } - }; - } - - moment.fn.millisecond = moment.fn.milliseconds = makeAccessor('Milliseconds', false); - moment.fn.second = moment.fn.seconds = makeAccessor('Seconds', false); - moment.fn.minute = moment.fn.minutes = makeAccessor('Minutes', false); - // Setting the hour should keep the time, because the user explicitly - // specified which hour he wants. So trying to maintain the same hour (in - // a new timezone) makes sense. Adding/subtracting hours does not follow - // this rule. - moment.fn.hour = moment.fn.hours = makeAccessor('Hours', true); - // moment.fn.month is defined separately - moment.fn.date = makeAccessor('Date', true); - moment.fn.dates = deprecate("dates accessor is deprecated. Use date instead.", makeAccessor('Date', true)); - moment.fn.year = makeAccessor('FullYear', true); - moment.fn.years = deprecate("years accessor is deprecated. Use year instead.", makeAccessor('FullYear', true)); - - // add plural methods - moment.fn.days = moment.fn.day; - moment.fn.months = moment.fn.month; - moment.fn.weeks = moment.fn.week; - moment.fn.isoWeeks = moment.fn.isoWeek; - moment.fn.quarters = moment.fn.quarter; - - // add aliased format methods - moment.fn.toJSON = moment.fn.toISOString; - - /************************************ - Duration Prototype - ************************************/ - - - extend(moment.duration.fn = Duration.prototype, { - - _bubble : function () { - var milliseconds = this._milliseconds, - days = this._days, - months = this._months, - data = this._data, - seconds, minutes, hours, years; - - // The following code bubbles up values, see the tests for - // examples of what that means. - data.milliseconds = milliseconds % 1000; - - seconds = absRound(milliseconds / 1000); - data.seconds = seconds % 60; - - minutes = absRound(seconds / 60); - data.minutes = minutes % 60; - - hours = absRound(minutes / 60); - data.hours = hours % 24; - - days += absRound(hours / 24); - data.days = days % 30; - - months += absRound(days / 30); - data.months = months % 12; - - years = absRound(months / 12); - data.years = years; - }, - - weeks : function () { - return absRound(this.days() / 7); - }, - - valueOf : function () { - return this._milliseconds + - this._days * 864e5 + - (this._months % 12) * 2592e6 + - toInt(this._months / 12) * 31536e6; - }, - - humanize : function (withSuffix) { - var difference = +this, - output = relativeTime(difference, !withSuffix, this.lang()); - - if (withSuffix) { - output = this.lang().pastFuture(difference, output); - } - - return this.lang().postformat(output); - }, - - add : function (input, val) { - // supports only 2.0-style add(1, 's') or add(moment) - var dur = moment.duration(input, val); - - this._milliseconds += dur._milliseconds; - this._days += dur._days; - this._months += dur._months; - - this._bubble(); - - return this; - }, - - subtract : function (input, val) { - var dur = moment.duration(input, val); - - this._milliseconds -= dur._milliseconds; - this._days -= dur._days; - this._months -= dur._months; - - this._bubble(); - - return this; - }, - - get : function (units) { - units = normalizeUnits(units); - return this[units.toLowerCase() + 's'](); - }, - - as : function (units) { - units = normalizeUnits(units); - return this['as' + units.charAt(0).toUpperCase() + units.slice(1) + 's'](); - }, - - lang : moment.fn.lang, - - toIsoString : function () { - // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js - var years = Math.abs(this.years()), - months = Math.abs(this.months()), - days = Math.abs(this.days()), - hours = Math.abs(this.hours()), - minutes = Math.abs(this.minutes()), - seconds = Math.abs(this.seconds() + this.milliseconds() / 1000); - - if (!this.asSeconds()) { - // this is the same as C#'s (Noda) and python (isodate)... - // but not other JS (goog.date) - return 'P0D'; - } - - return (this.asSeconds() < 0 ? '-' : '') + - 'P' + - (years ? years + 'Y' : '') + - (months ? months + 'M' : '') + - (days ? days + 'D' : '') + - ((hours || minutes || seconds) ? 'T' : '') + - (hours ? hours + 'H' : '') + - (minutes ? minutes + 'M' : '') + - (seconds ? seconds + 'S' : ''); - } - }); - - function makeDurationGetter(name) { - moment.duration.fn[name] = function () { - return this._data[name]; - }; - } - - function makeDurationAsGetter(name, factor) { - moment.duration.fn['as' + name] = function () { - return +this / factor; - }; - } - - for (i in unitMillisecondFactors) { - if (unitMillisecondFactors.hasOwnProperty(i)) { - makeDurationAsGetter(i, unitMillisecondFactors[i]); - makeDurationGetter(i.toLowerCase()); - } - } - - makeDurationAsGetter('Weeks', 6048e5); - moment.duration.fn.asMonths = function () { - return (+this - this.years() * 31536e6) / 2592e6 + this.years() * 12; - }; - - - /************************************ - Default Lang - ************************************/ - - - // Set default language, other languages will inherit from English. - moment.lang('en', { - ordinal : function (number) { - var b = number % 10, - output = (toInt(number % 100 / 10) === 1) ? 'th' : - (b === 1) ? 'st' : - (b === 2) ? 'nd' : - (b === 3) ? 'rd' : 'th'; - return number + output; - } - }); - - /* EMBED_LANGUAGES */ - - /************************************ - Exposing Moment - ************************************/ - - function makeGlobal(shouldDeprecate) { - /*global ender:false */ - if (typeof ender !== 'undefined') { - return; - } - oldGlobalMoment = globalScope.moment; - if (shouldDeprecate) { - globalScope.moment = deprecate( - "Accessing Moment through the global scope is " + - "deprecated, and will be removed in an upcoming " + - "release.", - moment); - } else { - globalScope.moment = moment; - } - } - - // CommonJS module is defined - if (hasModule) { - module.exports = moment; - } else if (typeof define === "function" && define.amd) { - define("moment", function (require, exports, module) { - if (module.config && module.config() && module.config().noGlobal === true) { - // release the global variable - globalScope.moment = oldGlobalMoment; - } - - return moment; - }); - makeGlobal(true); - } else { - makeGlobal(); - } -}).call(this); -// moment.js language configuration -// language : german (de) -// author : lluchs : https://github.com/lluchs -// author: Menelion Elensúle: https://github.com/Oire - -(function (factory) { - if (typeof define === 'function' && define.amd) { - define(['moment'], factory); // AMD - } else if (typeof exports === 'object') { - module.exports = factory(require('../moment')); // Node - } else { - factory(window.moment); // Browser global - } -}(function (moment) { - function processRelativeTime(number, withoutSuffix, key, isFuture) { - var format = { - 'm': ['eine Minute', 'einer Minute'], - 'h': ['eine Stunde', 'einer Stunde'], - 'd': ['ein Tag', 'einem Tag'], - 'dd': [number + ' Tage', number + ' Tagen'], - 'M': ['ein Monat', 'einem Monat'], - 'MM': [number + ' Monate', number + ' Monaten'], - 'y': ['ein Jahr', 'einem Jahr'], - 'yy': [number + ' Jahre', number + ' Jahren'] - }; - return withoutSuffix ? format[key][0] : format[key][1]; - } - - return moment.lang('de', { - months : "Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"), - monthsShort : "Jan._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"), - weekdays : "Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"), - weekdaysShort : "So._Mo._Di._Mi._Do._Fr._Sa.".split("_"), - weekdaysMin : "So_Mo_Di_Mi_Do_Fr_Sa".split("_"), - longDateFormat : { - LT: "HH:mm [Uhr]", - L : "DD.MM.YYYY", - LL : "D. MMMM YYYY", - LLL : "D. MMMM YYYY LT", - LLLL : "dddd, D. MMMM YYYY LT" - }, - calendar : { - sameDay: "[Heute um] LT", - sameElse: "L", - nextDay: '[Morgen um] LT', - nextWeek: 'dddd [um] LT', - lastDay: '[Gestern um] LT', - lastWeek: '[letzten] dddd [um] LT' - }, - relativeTime : { - future : "in %s", - past : "vor %s", - s : "ein paar Sekunden", - m : processRelativeTime, - mm : "%d Minuten", - h : processRelativeTime, - hh : "%d Stunden", - d : processRelativeTime, - dd : processRelativeTime, - M : processRelativeTime, - MM : processRelativeTime, - y : processRelativeTime, - yy : processRelativeTime - }, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); -})); -/* -Copyright 2012 Igor Vaynberg - -Version: 3.5.0 Timestamp: Mon Jun 16 19:29:44 EDT 2014 - -This software is licensed under the Apache License, Version 2.0 (the "Apache License") or the GNU -General Public License version 2 (the "GPL License"). You may choose either license to govern your -use of this software only upon the condition that you accept all of the terms of either the Apache -License or the GPL License. - -You may obtain a copy of the Apache License and the GPL License at: - - http://www.apache.org/licenses/LICENSE-2.0 - http://www.gnu.org/licenses/gpl-2.0.html - -Unless required by applicable law or agreed to in writing, software distributed under the -Apache License or the GPL License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -CONDITIONS OF ANY KIND, either express or implied. See the Apache License and the GPL License for -the specific language governing permissions and limitations under the Apache License and the GPL License. -*/ - -(function ($) { - if(typeof $.fn.each2 == "undefined") { - $.extend($.fn, { - /* - * 4-10 times faster .each replacement - * use it carefully, as it overrides jQuery context of element on each iteration - */ - each2 : function (c) { - var j = $([0]), i = -1, l = this.length; - while ( - ++i < l - && (j.context = j[0] = this[i]) - && c.call(j[0], i, j) !== false //"this"=DOM, i=index, j=jQuery object - ); - return this; - } - }); - } -})(jQuery); - -(function ($, undefined) { - "use strict"; - /*global document, window, jQuery, console */ - - if (window.Select2 !== undefined) { - return; - } - - var KEY, AbstractSelect2, SingleSelect2, MultiSelect2, nextUid, sizer, - lastMousePosition={x:0,y:0}, $document, scrollBarDimensions, - - KEY = { - TAB: 9, - ENTER: 13, - ESC: 27, - SPACE: 32, - LEFT: 37, - UP: 38, - RIGHT: 39, - DOWN: 40, - SHIFT: 16, - CTRL: 17, - ALT: 18, - PAGE_UP: 33, - PAGE_DOWN: 34, - HOME: 36, - END: 35, - BACKSPACE: 8, - DELETE: 46, - isArrow: function (k) { - k = k.which ? k.which : k; - switch (k) { - case KEY.LEFT: - case KEY.RIGHT: - case KEY.UP: - case KEY.DOWN: - return true; - } - return false; - }, - isControl: function (e) { - var k = e.which; - switch (k) { - case KEY.SHIFT: - case KEY.CTRL: - case KEY.ALT: - return true; - } - - if (e.metaKey) return true; - - return false; - }, - isFunctionKey: function (k) { - k = k.which ? k.which : k; - return k >= 112 && k <= 123; - } - }, - MEASURE_SCROLLBAR_TEMPLATE = "<div class='select2-measure-scrollbar'></div>", - - DIACRITICS = {"\u24B6":"A","\uFF21":"A","\u00C0":"A","\u00C1":"A","\u00C2":"A","\u1EA6":"A","\u1EA4":"A","\u1EAA":"A","\u1EA8":"A","\u00C3":"A","\u0100":"A","\u0102":"A","\u1EB0":"A","\u1EAE":"A","\u1EB4":"A","\u1EB2":"A","\u0226":"A","\u01E0":"A","\u00C4":"A","\u01DE":"A","\u1EA2":"A","\u00C5":"A","\u01FA":"A","\u01CD":"A","\u0200":"A","\u0202":"A","\u1EA0":"A","\u1EAC":"A","\u1EB6":"A","\u1E00":"A","\u0104":"A","\u023A":"A","\u2C6F":"A","\uA732":"AA","\u00C6":"AE","\u01FC":"AE","\u01E2":"AE","\uA734":"AO","\uA736":"AU","\uA738":"AV","\uA73A":"AV","\uA73C":"AY","\u24B7":"B","\uFF22":"B","\u1E02":"B","\u1E04":"B","\u1E06":"B","\u0243":"B","\u0182":"B","\u0181":"B","\u24B8":"C","\uFF23":"C","\u0106":"C","\u0108":"C","\u010A":"C","\u010C":"C","\u00C7":"C","\u1E08":"C","\u0187":"C","\u023B":"C","\uA73E":"C","\u24B9":"D","\uFF24":"D","\u1E0A":"D","\u010E":"D","\u1E0C":"D","\u1E10":"D","\u1E12":"D","\u1E0E":"D","\u0110":"D","\u018B":"D","\u018A":"D","\u0189":"D","\uA779":"D","\u01F1":"DZ","\u01C4":"DZ","\u01F2":"Dz","\u01C5":"Dz","\u24BA":"E","\uFF25":"E","\u00C8":"E","\u00C9":"E","\u00CA":"E","\u1EC0":"E","\u1EBE":"E","\u1EC4":"E","\u1EC2":"E","\u1EBC":"E","\u0112":"E","\u1E14":"E","\u1E16":"E","\u0114":"E","\u0116":"E","\u00CB":"E","\u1EBA":"E","\u011A":"E","\u0204":"E","\u0206":"E","\u1EB8":"E","\u1EC6":"E","\u0228":"E","\u1E1C":"E","\u0118":"E","\u1E18":"E","\u1E1A":"E","\u0190":"E","\u018E":"E","\u24BB":"F","\uFF26":"F","\u1E1E":"F","\u0191":"F","\uA77B":"F","\u24BC":"G","\uFF27":"G","\u01F4":"G","\u011C":"G","\u1E20":"G","\u011E":"G","\u0120":"G","\u01E6":"G","\u0122":"G","\u01E4":"G","\u0193":"G","\uA7A0":"G","\uA77D":"G","\uA77E":"G","\u24BD":"H","\uFF28":"H","\u0124":"H","\u1E22":"H","\u1E26":"H","\u021E":"H","\u1E24":"H","\u1E28":"H","\u1E2A":"H","\u0126":"H","\u2C67":"H","\u2C75":"H","\uA78D":"H","\u24BE":"I","\uFF29":"I","\u00CC":"I","\u00CD":"I","\u00CE":"I","\u0128":"I","\u012A":"I","\u012C":"I","\u0130":"I","\u00CF":"I","\u1E2E":"I","\u1EC8":"I","\u01CF":"I","\u0208":"I","\u020A":"I","\u1ECA":"I","\u012E":"I","\u1E2C":"I","\u0197":"I","\u24BF":"J","\uFF2A":"J","\u0134":"J","\u0248":"J","\u24C0":"K","\uFF2B":"K","\u1E30":"K","\u01E8":"K","\u1E32":"K","\u0136":"K","\u1E34":"K","\u0198":"K","\u2C69":"K","\uA740":"K","\uA742":"K","\uA744":"K","\uA7A2":"K","\u24C1":"L","\uFF2C":"L","\u013F":"L","\u0139":"L","\u013D":"L","\u1E36":"L","\u1E38":"L","\u013B":"L","\u1E3C":"L","\u1E3A":"L","\u0141":"L","\u023D":"L","\u2C62":"L","\u2C60":"L","\uA748":"L","\uA746":"L","\uA780":"L","\u01C7":"LJ","\u01C8":"Lj","\u24C2":"M","\uFF2D":"M","\u1E3E":"M","\u1E40":"M","\u1E42":"M","\u2C6E":"M","\u019C":"M","\u24C3":"N","\uFF2E":"N","\u01F8":"N","\u0143":"N","\u00D1":"N","\u1E44":"N","\u0147":"N","\u1E46":"N","\u0145":"N","\u1E4A":"N","\u1E48":"N","\u0220":"N","\u019D":"N","\uA790":"N","\uA7A4":"N","\u01CA":"NJ","\u01CB":"Nj","\u24C4":"O","\uFF2F":"O","\u00D2":"O","\u00D3":"O","\u00D4":"O","\u1ED2":"O","\u1ED0":"O","\u1ED6":"O","\u1ED4":"O","\u00D5":"O","\u1E4C":"O","\u022C":"O","\u1E4E":"O","\u014C":"O","\u1E50":"O","\u1E52":"O","\u014E":"O","\u022E":"O","\u0230":"O","\u00D6":"O","\u022A":"O","\u1ECE":"O","\u0150":"O","\u01D1":"O","\u020C":"O","\u020E":"O","\u01A0":"O","\u1EDC":"O","\u1EDA":"O","\u1EE0":"O","\u1EDE":"O","\u1EE2":"O","\u1ECC":"O","\u1ED8":"O","\u01EA":"O","\u01EC":"O","\u00D8":"O","\u01FE":"O","\u0186":"O","\u019F":"O","\uA74A":"O","\uA74C":"O","\u01A2":"OI","\uA74E":"OO","\u0222":"OU","\u24C5":"P","\uFF30":"P","\u1E54":"P","\u1E56":"P","\u01A4":"P","\u2C63":"P","\uA750":"P","\uA752":"P","\uA754":"P","\u24C6":"Q","\uFF31":"Q","\uA756":"Q","\uA758":"Q","\u024A":"Q","\u24C7":"R","\uFF32":"R","\u0154":"R","\u1E58":"R","\u0158":"R","\u0210":"R","\u0212":"R","\u1E5A":"R","\u1E5C":"R","\u0156":"R","\u1E5E":"R","\u024C":"R","\u2C64":"R","\uA75A":"R","\uA7A6":"R","\uA782":"R","\u24C8":"S","\uFF33":"S","\u1E9E":"S","\u015A":"S","\u1E64":"S","\u015C":"S","\u1E60":"S","\u0160":"S","\u1E66":"S","\u1E62":"S","\u1E68":"S","\u0218":"S","\u015E":"S","\u2C7E":"S","\uA7A8":"S","\uA784":"S","\u24C9":"T","\uFF34":"T","\u1E6A":"T","\u0164":"T","\u1E6C":"T","\u021A":"T","\u0162":"T","\u1E70":"T","\u1E6E":"T","\u0166":"T","\u01AC":"T","\u01AE":"T","\u023E":"T","\uA786":"T","\uA728":"TZ","\u24CA":"U","\uFF35":"U","\u00D9":"U","\u00DA":"U","\u00DB":"U","\u0168":"U","\u1E78":"U","\u016A":"U","\u1E7A":"U","\u016C":"U","\u00DC":"U","\u01DB":"U","\u01D7":"U","\u01D5":"U","\u01D9":"U","\u1EE6":"U","\u016E":"U","\u0170":"U","\u01D3":"U","\u0214":"U","\u0216":"U","\u01AF":"U","\u1EEA":"U","\u1EE8":"U","\u1EEE":"U","\u1EEC":"U","\u1EF0":"U","\u1EE4":"U","\u1E72":"U","\u0172":"U","\u1E76":"U","\u1E74":"U","\u0244":"U","\u24CB":"V","\uFF36":"V","\u1E7C":"V","\u1E7E":"V","\u01B2":"V","\uA75E":"V","\u0245":"V","\uA760":"VY","\u24CC":"W","\uFF37":"W","\u1E80":"W","\u1E82":"W","\u0174":"W","\u1E86":"W","\u1E84":"W","\u1E88":"W","\u2C72":"W","\u24CD":"X","\uFF38":"X","\u1E8A":"X","\u1E8C":"X","\u24CE":"Y","\uFF39":"Y","\u1EF2":"Y","\u00DD":"Y","\u0176":"Y","\u1EF8":"Y","\u0232":"Y","\u1E8E":"Y","\u0178":"Y","\u1EF6":"Y","\u1EF4":"Y","\u01B3":"Y","\u024E":"Y","\u1EFE":"Y","\u24CF":"Z","\uFF3A":"Z","\u0179":"Z","\u1E90":"Z","\u017B":"Z","\u017D":"Z","\u1E92":"Z","\u1E94":"Z","\u01B5":"Z","\u0224":"Z","\u2C7F":"Z","\u2C6B":"Z","\uA762":"Z","\u24D0":"a","\uFF41":"a","\u1E9A":"a","\u00E0":"a","\u00E1":"a","\u00E2":"a","\u1EA7":"a","\u1EA5":"a","\u1EAB":"a","\u1EA9":"a","\u00E3":"a","\u0101":"a","\u0103":"a","\u1EB1":"a","\u1EAF":"a","\u1EB5":"a","\u1EB3":"a","\u0227":"a","\u01E1":"a","\u00E4":"a","\u01DF":"a","\u1EA3":"a","\u00E5":"a","\u01FB":"a","\u01CE":"a","\u0201":"a","\u0203":"a","\u1EA1":"a","\u1EAD":"a","\u1EB7":"a","\u1E01":"a","\u0105":"a","\u2C65":"a","\u0250":"a","\uA733":"aa","\u00E6":"ae","\u01FD":"ae","\u01E3":"ae","\uA735":"ao","\uA737":"au","\uA739":"av","\uA73B":"av","\uA73D":"ay","\u24D1":"b","\uFF42":"b","\u1E03":"b","\u1E05":"b","\u1E07":"b","\u0180":"b","\u0183":"b","\u0253":"b","\u24D2":"c","\uFF43":"c","\u0107":"c","\u0109":"c","\u010B":"c","\u010D":"c","\u00E7":"c","\u1E09":"c","\u0188":"c","\u023C":"c","\uA73F":"c","\u2184":"c","\u24D3":"d","\uFF44":"d","\u1E0B":"d","\u010F":"d","\u1E0D":"d","\u1E11":"d","\u1E13":"d","\u1E0F":"d","\u0111":"d","\u018C":"d","\u0256":"d","\u0257":"d","\uA77A":"d","\u01F3":"dz","\u01C6":"dz","\u24D4":"e","\uFF45":"e","\u00E8":"e","\u00E9":"e","\u00EA":"e","\u1EC1":"e","\u1EBF":"e","\u1EC5":"e","\u1EC3":"e","\u1EBD":"e","\u0113":"e","\u1E15":"e","\u1E17":"e","\u0115":"e","\u0117":"e","\u00EB":"e","\u1EBB":"e","\u011B":"e","\u0205":"e","\u0207":"e","\u1EB9":"e","\u1EC7":"e","\u0229":"e","\u1E1D":"e","\u0119":"e","\u1E19":"e","\u1E1B":"e","\u0247":"e","\u025B":"e","\u01DD":"e","\u24D5":"f","\uFF46":"f","\u1E1F":"f","\u0192":"f","\uA77C":"f","\u24D6":"g","\uFF47":"g","\u01F5":"g","\u011D":"g","\u1E21":"g","\u011F":"g","\u0121":"g","\u01E7":"g","\u0123":"g","\u01E5":"g","\u0260":"g","\uA7A1":"g","\u1D79":"g","\uA77F":"g","\u24D7":"h","\uFF48":"h","\u0125":"h","\u1E23":"h","\u1E27":"h","\u021F":"h","\u1E25":"h","\u1E29":"h","\u1E2B":"h","\u1E96":"h","\u0127":"h","\u2C68":"h","\u2C76":"h","\u0265":"h","\u0195":"hv","\u24D8":"i","\uFF49":"i","\u00EC":"i","\u00ED":"i","\u00EE":"i","\u0129":"i","\u012B":"i","\u012D":"i","\u00EF":"i","\u1E2F":"i","\u1EC9":"i","\u01D0":"i","\u0209":"i","\u020B":"i","\u1ECB":"i","\u012F":"i","\u1E2D":"i","\u0268":"i","\u0131":"i","\u24D9":"j","\uFF4A":"j","\u0135":"j","\u01F0":"j","\u0249":"j","\u24DA":"k","\uFF4B":"k","\u1E31":"k","\u01E9":"k","\u1E33":"k","\u0137":"k","\u1E35":"k","\u0199":"k","\u2C6A":"k","\uA741":"k","\uA743":"k","\uA745":"k","\uA7A3":"k","\u24DB":"l","\uFF4C":"l","\u0140":"l","\u013A":"l","\u013E":"l","\u1E37":"l","\u1E39":"l","\u013C":"l","\u1E3D":"l","\u1E3B":"l","\u017F":"l","\u0142":"l","\u019A":"l","\u026B":"l","\u2C61":"l","\uA749":"l","\uA781":"l","\uA747":"l","\u01C9":"lj","\u24DC":"m","\uFF4D":"m","\u1E3F":"m","\u1E41":"m","\u1E43":"m","\u0271":"m","\u026F":"m","\u24DD":"n","\uFF4E":"n","\u01F9":"n","\u0144":"n","\u00F1":"n","\u1E45":"n","\u0148":"n","\u1E47":"n","\u0146":"n","\u1E4B":"n","\u1E49":"n","\u019E":"n","\u0272":"n","\u0149":"n","\uA791":"n","\uA7A5":"n","\u01CC":"nj","\u24DE":"o","\uFF4F":"o","\u00F2":"o","\u00F3":"o","\u00F4":"o","\u1ED3":"o","\u1ED1":"o","\u1ED7":"o","\u1ED5":"o","\u00F5":"o","\u1E4D":"o","\u022D":"o","\u1E4F":"o","\u014D":"o","\u1E51":"o","\u1E53":"o","\u014F":"o","\u022F":"o","\u0231":"o","\u00F6":"o","\u022B":"o","\u1ECF":"o","\u0151":"o","\u01D2":"o","\u020D":"o","\u020F":"o","\u01A1":"o","\u1EDD":"o","\u1EDB":"o","\u1EE1":"o","\u1EDF":"o","\u1EE3":"o","\u1ECD":"o","\u1ED9":"o","\u01EB":"o","\u01ED":"o","\u00F8":"o","\u01FF":"o","\u0254":"o","\uA74B":"o","\uA74D":"o","\u0275":"o","\u01A3":"oi","\u0223":"ou","\uA74F":"oo","\u24DF":"p","\uFF50":"p","\u1E55":"p","\u1E57":"p","\u01A5":"p","\u1D7D":"p","\uA751":"p","\uA753":"p","\uA755":"p","\u24E0":"q","\uFF51":"q","\u024B":"q","\uA757":"q","\uA759":"q","\u24E1":"r","\uFF52":"r","\u0155":"r","\u1E59":"r","\u0159":"r","\u0211":"r","\u0213":"r","\u1E5B":"r","\u1E5D":"r","\u0157":"r","\u1E5F":"r","\u024D":"r","\u027D":"r","\uA75B":"r","\uA7A7":"r","\uA783":"r","\u24E2":"s","\uFF53":"s","\u00DF":"s","\u015B":"s","\u1E65":"s","\u015D":"s","\u1E61":"s","\u0161":"s","\u1E67":"s","\u1E63":"s","\u1E69":"s","\u0219":"s","\u015F":"s","\u023F":"s","\uA7A9":"s","\uA785":"s","\u1E9B":"s","\u24E3":"t","\uFF54":"t","\u1E6B":"t","\u1E97":"t","\u0165":"t","\u1E6D":"t","\u021B":"t","\u0163":"t","\u1E71":"t","\u1E6F":"t","\u0167":"t","\u01AD":"t","\u0288":"t","\u2C66":"t","\uA787":"t","\uA729":"tz","\u24E4":"u","\uFF55":"u","\u00F9":"u","\u00FA":"u","\u00FB":"u","\u0169":"u","\u1E79":"u","\u016B":"u","\u1E7B":"u","\u016D":"u","\u00FC":"u","\u01DC":"u","\u01D8":"u","\u01D6":"u","\u01DA":"u","\u1EE7":"u","\u016F":"u","\u0171":"u","\u01D4":"u","\u0215":"u","\u0217":"u","\u01B0":"u","\u1EEB":"u","\u1EE9":"u","\u1EEF":"u","\u1EED":"u","\u1EF1":"u","\u1EE5":"u","\u1E73":"u","\u0173":"u","\u1E77":"u","\u1E75":"u","\u0289":"u","\u24E5":"v","\uFF56":"v","\u1E7D":"v","\u1E7F":"v","\u028B":"v","\uA75F":"v","\u028C":"v","\uA761":"vy","\u24E6":"w","\uFF57":"w","\u1E81":"w","\u1E83":"w","\u0175":"w","\u1E87":"w","\u1E85":"w","\u1E98":"w","\u1E89":"w","\u2C73":"w","\u24E7":"x","\uFF58":"x","\u1E8B":"x","\u1E8D":"x","\u24E8":"y","\uFF59":"y","\u1EF3":"y","\u00FD":"y","\u0177":"y","\u1EF9":"y","\u0233":"y","\u1E8F":"y","\u00FF":"y","\u1EF7":"y","\u1E99":"y","\u1EF5":"y","\u01B4":"y","\u024F":"y","\u1EFF":"y","\u24E9":"z","\uFF5A":"z","\u017A":"z","\u1E91":"z","\u017C":"z","\u017E":"z","\u1E93":"z","\u1E95":"z","\u01B6":"z","\u0225":"z","\u0240":"z","\u2C6C":"z","\uA763":"z","\u0386":"\u0391","\u0388":"\u0395","\u0389":"\u0397","\u038A":"\u0399","\u03AA":"\u0399","\u038C":"\u039F","\u038E":"\u03A5","\u03AB":"\u03A5","\u038F":"\u03A9","\u03AC":"\u03B1","\u03AD":"\u03B5","\u03AE":"\u03B7","\u03AF":"\u03B9","\u03CA":"\u03B9","\u0390":"\u03B9","\u03CC":"\u03BF","\u03CD":"\u03C5","\u03CB":"\u03C5","\u03B0":"\u03C5","\u03C9":"\u03C9","\u03C2":"\u03C3"}; - - $document = $(document); - - nextUid=(function() { var counter=1; return function() { return counter++; }; }()); - - - function reinsertElement(element) { - var placeholder = $(document.createTextNode('')); - - element.before(placeholder); - placeholder.before(element); - placeholder.remove(); - } - - function stripDiacritics(str) { - // Used 'uni range + named function' from http://jsperf.com/diacritics/18 - function match(a) { - return DIACRITICS[a] || a; - } - - return str.replace(/[^\u0000-\u007E]/g, match); - } - - function indexOf(value, array) { - var i = 0, l = array.length; - for (; i < l; i = i + 1) { - if (equal(value, array[i])) return i; - } - return -1; - } - - function measureScrollbar () { - var $template = $( MEASURE_SCROLLBAR_TEMPLATE ); - $template.appendTo('body'); - - var dim = { - width: $template.width() - $template[0].clientWidth, - height: $template.height() - $template[0].clientHeight - }; - $template.remove(); - - return dim; - } - - /** - * Compares equality of a and b - * @param a - * @param b - */ - function equal(a, b) { - if (a === b) return true; - if (a === undefined || b === undefined) return false; - if (a === null || b === null) return false; - // Check whether 'a' or 'b' is a string (primitive or object). - // The concatenation of an empty string (+'') converts its argument to a string's primitive. - if (a.constructor === String) return a+'' === b+''; // a+'' - in case 'a' is a String object - if (b.constructor === String) return b+'' === a+''; // b+'' - in case 'b' is a String object - return false; - } - - /** - * Splits the string into an array of values, trimming each value. An empty array is returned for nulls or empty - * strings - * @param string - * @param separator - */ - function splitVal(string, separator) { - var val, i, l; - if (string === null || string.length < 1) return []; - val = string.split(separator); - for (i = 0, l = val.length; i < l; i = i + 1) val[i] = $.trim(val[i]); - return val; - } - - function getSideBorderPadding(element) { - return element.outerWidth(false) - element.width(); - } - - function installKeyUpChangeEvent(element) { - var key="keyup-change-value"; - element.on("keydown", function () { - if ($.data(element, key) === undefined) { - $.data(element, key, element.val()); - } - }); - element.on("keyup", function () { - var val= $.data(element, key); - if (val !== undefined && element.val() !== val) { - $.removeData(element, key); - element.trigger("keyup-change"); - } - }); - } - - - /** - * filters mouse events so an event is fired only if the mouse moved. - * - * filters out mouse events that occur when mouse is stationary but - * the elements under the pointer are scrolled. - */ - function installFilteredMouseMove(element) { - element.on("mousemove", function (e) { - var lastpos = lastMousePosition; - if (lastpos === undefined || lastpos.x !== e.pageX || lastpos.y !== e.pageY) { - $(e.target).trigger("mousemove-filtered", e); - } - }); - } - - /** - * Debounces a function. Returns a function that calls the original fn function only if no invocations have been made - * within the last quietMillis milliseconds. - * - * @param quietMillis number of milliseconds to wait before invoking fn - * @param fn function to be debounced - * @param ctx object to be used as this reference within fn - * @return debounced version of fn - */ - function debounce(quietMillis, fn, ctx) { - ctx = ctx || undefined; - var timeout; - return function () { - var args = arguments; - window.clearTimeout(timeout); - timeout = window.setTimeout(function() { - fn.apply(ctx, args); - }, quietMillis); - }; - } - - function installDebouncedScroll(threshold, element) { - var notify = debounce(threshold, function (e) { element.trigger("scroll-debounced", e);}); - element.on("scroll", function (e) { - if (indexOf(e.target, element.get()) >= 0) notify(e); - }); - } - - function focus($el) { - if ($el[0] === document.activeElement) return; - - /* set the focus in a 0 timeout - that way the focus is set after the processing - of the current event has finished - which seems like the only reliable way - to set focus */ - window.setTimeout(function() { - var el=$el[0], pos=$el.val().length, range; - - $el.focus(); - - /* make sure el received focus so we do not error out when trying to manipulate the caret. - sometimes modals or others listeners may steal it after its set */ - var isVisible = (el.offsetWidth > 0 || el.offsetHeight > 0); - if (isVisible && el === document.activeElement) { - - /* after the focus is set move the caret to the end, necessary when we val() - just before setting focus */ - if(el.setSelectionRange) - { - el.setSelectionRange(pos, pos); - } - else if (el.createTextRange) { - range = el.createTextRange(); - range.collapse(false); - range.select(); - } - } - }, 0); - } - - function getCursorInfo(el) { - el = $(el)[0]; - var offset = 0; - var length = 0; - if ('selectionStart' in el) { - offset = el.selectionStart; - length = el.selectionEnd - offset; - } else if ('selection' in document) { - el.focus(); - var sel = document.selection.createRange(); - length = document.selection.createRange().text.length; - sel.moveStart('character', -el.value.length); - offset = sel.text.length - length; - } - return { offset: offset, length: length }; - } - - function killEvent(event) { - event.preventDefault(); - event.stopPropagation(); - } - function killEventImmediately(event) { - event.preventDefault(); - event.stopImmediatePropagation(); - } - - function measureTextWidth(e) { - if (!sizer){ - var style = e[0].currentStyle || window.getComputedStyle(e[0], null); - sizer = $(document.createElement("div")).css({ - position: "absolute", - left: "-10000px", - top: "-10000px", - display: "none", - fontSize: style.fontSize, - fontFamily: style.fontFamily, - fontStyle: style.fontStyle, - fontWeight: style.fontWeight, - letterSpacing: style.letterSpacing, - textTransform: style.textTransform, - whiteSpace: "nowrap" - }); - sizer.attr("class","select2-sizer"); - $("body").append(sizer); - } - sizer.text(e.val()); - return sizer.width(); - } - - function syncCssClasses(dest, src, adapter) { - var classes, replacements = [], adapted; - - classes = $.trim(dest.attr("class")); - - if (classes) { - classes = '' + classes; // for IE which returns object - - $(classes.split(/\s+/)).each2(function() { - if (this.indexOf("select2-") === 0) { - replacements.push(this); - } - }); - } - - classes = $.trim(src.attr("class")); - - if (classes) { - classes = '' + classes; // for IE which returns object - - $(classes.split(/\s+/)).each2(function() { - if (this.indexOf("select2-") !== 0) { - adapted = adapter(this); - - if (adapted) { - replacements.push(adapted); - } - } - }); - } - - dest.attr("class", replacements.join(" ")); - } - - - function markMatch(text, term, markup, escapeMarkup) { - var match=stripDiacritics(text.toUpperCase()).indexOf(stripDiacritics(term.toUpperCase())), - tl=term.length; - - if (match<0) { - markup.push(escapeMarkup(text)); - return; - } - - markup.push(escapeMarkup(text.substring(0, match))); - markup.push("<span class='select2-match'>"); - markup.push(escapeMarkup(text.substring(match, match + tl))); - markup.push("</span>"); - markup.push(escapeMarkup(text.substring(match + tl, text.length))); - } - - function defaultEscapeMarkup(markup) { - var replace_map = { - '\\': '&#92;', - '&': '&amp;', - '<': '&lt;', - '>': '&gt;', - '"': '&quot;', - "'": '&#39;', - "/": '&#47;' - }; - - return String(markup).replace(/[&<>"'\/\\]/g, function (match) { - return replace_map[match]; - }); - } - - /** - * Produces an ajax-based query function - * - * @param options object containing configuration parameters - * @param options.params parameter map for the transport ajax call, can contain such options as cache, jsonpCallback, etc. see $.ajax - * @param options.transport function that will be used to execute the ajax request. must be compatible with parameters supported by $.ajax - * @param options.url url for the data - * @param options.data a function(searchTerm, pageNumber, context) that should return an object containing query string parameters for the above url. - * @param options.dataType request data type: ajax, jsonp, other datatypes supported by jQuery's $.ajax function or the transport function if specified - * @param options.quietMillis (optional) milliseconds to wait before making the ajaxRequest, helps debounce the ajax function if invoked too often - * @param options.results a function(remoteData, pageNumber, query) that converts data returned form the remote request to the format expected by Select2. - * The expected format is an object containing the following keys: - * results array of objects that will be used as choices - * more (optional) boolean indicating whether there are more results available - * Example: {results:[{id:1, text:'Red'},{id:2, text:'Blue'}], more:true} - */ - function ajax(options) { - var timeout, // current scheduled but not yet executed request - handler = null, - quietMillis = options.quietMillis || 100, - ajaxUrl = options.url, - self = this; - - return function (query) { - window.clearTimeout(timeout); - timeout = window.setTimeout(function () { - var data = options.data, // ajax data function - url = ajaxUrl, // ajax url string or function - transport = options.transport || $.fn.select2.ajaxDefaults.transport, - // deprecated - to be removed in 4.0 - use params instead - deprecated = { - type: options.type || 'GET', // set type of request (GET or POST) - cache: options.cache || false, - jsonpCallback: options.jsonpCallback||undefined, - dataType: options.dataType||"json" - }, - params = $.extend({}, $.fn.select2.ajaxDefaults.params, deprecated); - - data = data ? data.call(self, query.term, query.page, query.context) : null; - url = (typeof url === 'function') ? url.call(self, query.term, query.page, query.context) : url; - - if (handler && typeof handler.abort === "function") { handler.abort(); } - - if (options.params) { - if ($.isFunction(options.params)) { - $.extend(params, options.params.call(self)); - } else { - $.extend(params, options.params); - } - } - - $.extend(params, { - url: url, - dataType: options.dataType, - data: data, - success: function (data) { - // TODO - replace query.page with query so users have access to term, page, etc. - // added query as third paramter to keep backwards compatibility - var results = options.results(data, query.page, query); - query.callback(results); - } - }); - handler = transport.call(self, params); - }, quietMillis); - }; - } - - /** - * Produces a query function that works with a local array - * - * @param options object containing configuration parameters. The options parameter can either be an array or an - * object. - * - * If the array form is used it is assumed that it contains objects with 'id' and 'text' keys. - * - * If the object form is used it is assumed that it contains 'data' and 'text' keys. The 'data' key should contain - * an array of objects that will be used as choices. These objects must contain at least an 'id' key. The 'text' - * key can either be a String in which case it is expected that each element in the 'data' array has a key with the - * value of 'text' which will be used to match choices. Alternatively, text can be a function(item) that can extract - * the text. - */ - function local(options) { - var data = options, // data elements - dataText, - tmp, - text = function (item) { return ""+item.text; }; // function used to retrieve the text portion of a data item that is matched against the search - - if ($.isArray(data)) { - tmp = data; - data = { results: tmp }; - } - - if ($.isFunction(data) === false) { - tmp = data; - data = function() { return tmp; }; - } - - var dataItem = data(); - if (dataItem.text) { - text = dataItem.text; - // if text is not a function we assume it to be a key name - if (!$.isFunction(text)) { - dataText = dataItem.text; // we need to store this in a separate variable because in the next step data gets reset and data.text is no longer available - text = function (item) { return item[dataText]; }; - } - } - - return function (query) { - var t = query.term, filtered = { results: [] }, process; - if (t === "") { - query.callback(data()); - return; - } - - process = function(datum, collection) { - var group, attr; - datum = datum[0]; - if (datum.children) { - group = {}; - for (attr in datum) { - if (datum.hasOwnProperty(attr)) group[attr]=datum[attr]; - } - group.children=[]; - $(datum.children).each2(function(i, childDatum) { process(childDatum, group.children); }); - if (group.children.length || query.matcher(t, text(group), datum)) { - collection.push(group); - } - } else { - if (query.matcher(t, text(datum), datum)) { - collection.push(datum); - } - } - }; - - $(data().results).each2(function(i, datum) { process(datum, filtered.results); }); - query.callback(filtered); - }; - } - - // TODO javadoc - function tags(data) { - var isFunc = $.isFunction(data); - return function (query) { - var t = query.term, filtered = {results: []}; - var result = isFunc ? data(query) : data; - if ($.isArray(result)) { - $(result).each(function () { - var isObject = this.text !== undefined, - text = isObject ? this.text : this; - if (t === "" || query.matcher(t, text)) { - filtered.results.push(isObject ? this : {id: this, text: this}); - } - }); - query.callback(filtered); - } - }; - } - - /** - * Checks if the formatter function should be used. - * - * Throws an error if it is not a function. Returns true if it should be used, - * false if no formatting should be performed. - * - * @param formatter - */ - function checkFormatter(formatter, formatterName) { - if ($.isFunction(formatter)) return true; - if (!formatter) return false; - if (typeof(formatter) === 'string') return true; - throw new Error(formatterName +" must be a string, function, or falsy value"); - } - - /** - * Returns a given value - * If given a function, returns its output - * - * @param val string|function - * @param context value of "this" to be passed to function - * @returns {*} - */ - function evaluate(val, context) { - if ($.isFunction(val)) { - var args = Array.prototype.slice.call(arguments, 2); - return val.apply(context, args); - } - return val; - } - - function countResults(results) { - var count = 0; - $.each(results, function(i, item) { - if (item.children) { - count += countResults(item.children); - } else { - count++; - } - }); - return count; - } - - /** - * Default tokenizer. This function uses breaks the input on substring match of any string from the - * opts.tokenSeparators array and uses opts.createSearchChoice to create the choice object. Both of those - * two options have to be defined in order for the tokenizer to work. - * - * @param input text user has typed so far or pasted into the search field - * @param selection currently selected choices - * @param selectCallback function(choice) callback tho add the choice to selection - * @param opts select2's opts - * @return undefined/null to leave the current input unchanged, or a string to change the input to the returned value - */ - function defaultTokenizer(input, selection, selectCallback, opts) { - var original = input, // store the original so we can compare and know if we need to tell the search to update its text - dupe = false, // check for whether a token we extracted represents a duplicate selected choice - token, // token - index, // position at which the separator was found - i, l, // looping variables - separator; // the matched separator - - if (!opts.createSearchChoice || !opts.tokenSeparators || opts.tokenSeparators.length < 1) return undefined; - - while (true) { - index = -1; - - for (i = 0, l = opts.tokenSeparators.length; i < l; i++) { - separator = opts.tokenSeparators[i]; - index = input.indexOf(separator); - if (index >= 0) break; - } - - if (index < 0) break; // did not find any token separator in the input string, bail - - token = input.substring(0, index); - input = input.substring(index + separator.length); - - if (token.length > 0) { - token = opts.createSearchChoice.call(this, token, selection); - if (token !== undefined && token !== null && opts.id(token) !== undefined && opts.id(token) !== null) { - dupe = false; - for (i = 0, l = selection.length; i < l; i++) { - if (equal(opts.id(token), opts.id(selection[i]))) { - dupe = true; break; - } - } - - if (!dupe) selectCallback(token); - } - } - } - - if (original!==input) return input; - } - - function cleanupJQueryElements() { - var self = this; - - $.each(arguments, function (i, element) { - self[element].remove(); - self[element] = null; - }); - } - - /** - * Creates a new class - * - * @param superClass - * @param methods - */ - function clazz(SuperClass, methods) { - var constructor = function () {}; - constructor.prototype = new SuperClass; - constructor.prototype.constructor = constructor; - constructor.prototype.parent = SuperClass.prototype; - constructor.prototype = $.extend(constructor.prototype, methods); - return constructor; - } - - AbstractSelect2 = clazz(Object, { - - // abstract - bind: function (func) { - var self = this; - return function () { - func.apply(self, arguments); - }; - }, - - // abstract - init: function (opts) { - var results, search, resultsSelector = ".select2-results"; - - // prepare options - this.opts = opts = this.prepareOpts(opts); - - this.id=opts.id; - - // destroy if called on an existing component - if (opts.element.data("select2") !== undefined && - opts.element.data("select2") !== null) { - opts.element.data("select2").destroy(); - } - - this.container = this.createContainer(); - - this.liveRegion = $("<span>", { - role: "status", - "aria-live": "polite" - }) - .addClass("select2-hidden-accessible") - .appendTo(document.body); - - this.containerId="s2id_"+(opts.element.attr("id") || "autogen"+nextUid()); - this.containerEventName= this.containerId - .replace(/([.])/g, '_') - .replace(/([;&,\-\.\+\*\~':"\!\^#$%@\[\]\(\)=>\|])/g, '\\$1'); - this.container.attr("id", this.containerId); - - this.container.attr("title", opts.element.attr("title")); - - this.body = $("body"); - - syncCssClasses(this.container, this.opts.element, this.opts.adaptContainerCssClass); - - this.container.attr("style", opts.element.attr("style")); - this.container.css(evaluate(opts.containerCss, this.opts.element)); - this.container.addClass(evaluate(opts.containerCssClass, this.opts.element)); - - this.elementTabIndex = this.opts.element.attr("tabindex"); - - // swap container for the element - this.opts.element - .data("select2", this) - .attr("tabindex", "-1") - .before(this.container) - .on("click.select2", killEvent); // do not leak click events - - this.container.data("select2", this); - - this.dropdown = this.container.find(".select2-drop"); - - syncCssClasses(this.dropdown, this.opts.element, this.opts.adaptDropdownCssClass); - - this.dropdown.addClass(evaluate(opts.dropdownCssClass, this.opts.element)); - this.dropdown.data("select2", this); - this.dropdown.on("click", killEvent); - - this.results = results = this.container.find(resultsSelector); - this.search = search = this.container.find("input.select2-input"); - - this.queryCount = 0; - this.resultsPage = 0; - this.context = null; - - // initialize the container - this.initContainer(); - - this.container.on("click", killEvent); - - installFilteredMouseMove(this.results); - - this.dropdown.on("mousemove-filtered", resultsSelector, this.bind(this.highlightUnderEvent)); - this.dropdown.on("touchstart touchmove touchend", resultsSelector, this.bind(function (event) { - this._touchEvent = true; - this.highlightUnderEvent(event); - })); - this.dropdown.on("touchmove", resultsSelector, this.bind(this.touchMoved)); - this.dropdown.on("touchstart touchend", resultsSelector, this.bind(this.clearTouchMoved)); - - // Waiting for a click event on touch devices to select option and hide dropdown - // otherwise click will be triggered on an underlying element - this.dropdown.on('click', this.bind(function (event) { - if (this._touchEvent) { - this._touchEvent = false; - this.selectHighlighted(); - } - })); - - installDebouncedScroll(80, this.results); - this.dropdown.on("scroll-debounced", resultsSelector, this.bind(this.loadMoreIfNeeded)); - - // do not propagate change event from the search field out of the component - $(this.container).on("change", ".select2-input", function(e) {e.stopPropagation();}); - $(this.dropdown).on("change", ".select2-input", function(e) {e.stopPropagation();}); - - // if jquery.mousewheel plugin is installed we can prevent out-of-bounds scrolling of results via mousewheel - if ($.fn.mousewheel) { - results.mousewheel(function (e, delta, deltaX, deltaY) { - var top = results.scrollTop(); - if (deltaY > 0 && top - deltaY <= 0) { - results.scrollTop(0); - killEvent(e); - } else if (deltaY < 0 && results.get(0).scrollHeight - results.scrollTop() + deltaY <= results.height()) { - results.scrollTop(results.get(0).scrollHeight - results.height()); - killEvent(e); - } - }); - } - - installKeyUpChangeEvent(search); - search.on("keyup-change input paste", this.bind(this.updateResults)); - search.on("focus", function () { search.addClass("select2-focused"); }); - search.on("blur", function () { search.removeClass("select2-focused");}); - - this.dropdown.on("mouseup", resultsSelector, this.bind(function (e) { - if ($(e.target).closest(".select2-result-selectable").length > 0) { - this.highlightUnderEvent(e); - this.selectHighlighted(e); - } - })); - - // trap all mouse events from leaving the dropdown. sometimes there may be a modal that is listening - // for mouse events outside of itself so it can close itself. since the dropdown is now outside the select2's - // dom it will trigger the popup close, which is not what we want - // focusin can cause focus wars between modals and select2 since the dropdown is outside the modal. - this.dropdown.on("click mouseup mousedown touchstart touchend focusin", function (e) { e.stopPropagation(); }); - - this.nextSearchTerm = undefined; - - if ($.isFunction(this.opts.initSelection)) { - // initialize selection based on the current value of the source element - this.initSelection(); - - // if the user has provided a function that can set selection based on the value of the source element - // we monitor the change event on the element and trigger it, allowing for two way synchronization - this.monitorSource(); - } - - if (opts.maximumInputLength !== null) { - this.search.attr("maxlength", opts.maximumInputLength); - } - - var disabled = opts.element.prop("disabled"); - if (disabled === undefined) disabled = false; - this.enable(!disabled); - - var readonly = opts.element.prop("readonly"); - if (readonly === undefined) readonly = false; - this.readonly(readonly); - - // Calculate size of scrollbar - scrollBarDimensions = scrollBarDimensions || measureScrollbar(); - - this.autofocus = opts.element.prop("autofocus"); - opts.element.prop("autofocus", false); - if (this.autofocus) this.focus(); - - this.search.attr("placeholder", opts.searchInputPlaceholder); - }, - - // abstract - destroy: function () { - var element=this.opts.element, select2 = element.data("select2"); - - this.close(); - - if (element.length && element[0].detachEvent) { - element.each(function () { - this.detachEvent("onpropertychange", this._sync); - }); - } - if (this.propertyObserver) { - this.propertyObserver.disconnect(); - this.propertyObserver = null; - } - this._sync = null; - - if (select2 !== undefined) { - select2.container.remove(); - select2.liveRegion.remove(); - select2.dropdown.remove(); - element - .removeClass("select2-offscreen") - .removeData("select2") - .off(".select2") - .prop("autofocus", this.autofocus || false); - if (this.elementTabIndex) { - element.attr({tabindex: this.elementTabIndex}); - } else { - element.removeAttr("tabindex"); - } - element.show(); - } - - cleanupJQueryElements.call(this, - "container", - "liveRegion", - "dropdown", - "results", - "search" - ); - }, - - // abstract - optionToData: function(element) { - if (element.is("option")) { - return { - id:element.prop("value"), - text:element.text(), - element: element.get(), - css: element.attr("class"), - disabled: element.prop("disabled"), - locked: equal(element.attr("locked"), "locked") || equal(element.data("locked"), true) - }; - } else if (element.is("optgroup")) { - return { - text:element.attr("label"), - children:[], - element: element.get(), - css: element.attr("class") - }; - } - }, - - // abstract - prepareOpts: function (opts) { - var element, select, idKey, ajaxUrl, self = this; - - element = opts.element; - - if (element.get(0).tagName.toLowerCase() === "select") { - this.select = select = opts.element; - } - - if (select) { - // these options are not allowed when attached to a select because they are picked up off the element itself - $.each(["id", "multiple", "ajax", "query", "createSearchChoice", "initSelection", "data", "tags"], function () { - if (this in opts) { - throw new Error("Option '" + this + "' is not allowed for Select2 when attached to a <select> element."); - } - }); - } - - opts = $.extend({}, { - populateResults: function(container, results, query) { - var populate, id=this.opts.id, liveRegion=this.liveRegion; - - populate=function(results, container, depth) { - - var i, l, result, selectable, disabled, compound, node, label, innerContainer, formatted; - - results = opts.sortResults(results, container, query); - - // collect the created nodes for bulk append - var nodes = []; - for (i = 0, l = results.length; i < l; i = i + 1) { - - result=results[i]; - - disabled = (result.disabled === true); - selectable = (!disabled) && (id(result) !== undefined); - - compound=result.children && result.children.length > 0; - - node=$("<li></li>"); - node.addClass("select2-results-dept-"+depth); - node.addClass("select2-result"); - node.addClass(selectable ? "select2-result-selectable" : "select2-result-unselectable"); - if (disabled) { node.addClass("select2-disabled"); } - if (compound) { node.addClass("select2-result-with-children"); } - node.addClass(self.opts.formatResultCssClass(result)); - node.attr("role", "presentation"); - - label=$(document.createElement("div")); - label.addClass("select2-result-label"); - label.attr("id", "select2-result-label-" + nextUid()); - label.attr("role", "option"); - - formatted=opts.formatResult(result, label, query, self.opts.escapeMarkup); - if (formatted!==undefined) { - label.html(formatted); - node.append(label); - } - - - if (compound) { - - innerContainer=$("<ul></ul>"); - innerContainer.addClass("select2-result-sub"); - populate(result.children, innerContainer, depth+1); - node.append(innerContainer); - } - - node.data("select2-data", result); - nodes.push(node[0]); - } - - // bulk append the created nodes - container.append(nodes); - liveRegion.text(opts.formatMatches(results.length)); - }; - - populate(results, container, 0); - } - }, $.fn.select2.defaults, opts); - - if (typeof(opts.id) !== "function") { - idKey = opts.id; - opts.id = function (e) { return e[idKey]; }; - } - - if ($.isArray(opts.element.data("select2Tags"))) { - if ("tags" in opts) { - throw "tags specified as both an attribute 'data-select2-tags' and in options of Select2 " + opts.element.attr("id"); - } - opts.tags=opts.element.data("select2Tags"); - } - - if (select) { - opts.query = this.bind(function (query) { - var data = { results: [], more: false }, - term = query.term, - children, placeholderOption, process; - - process=function(element, collection) { - var group; - if (element.is("option")) { - if (query.matcher(term, element.text(), element)) { - collection.push(self.optionToData(element)); - } - } else if (element.is("optgroup")) { - group=self.optionToData(element); - element.children().each2(function(i, elm) { process(elm, group.children); }); - if (group.children.length>0) { - collection.push(group); - } - } - }; - - children=element.children(); - - // ignore the placeholder option if there is one - if (this.getPlaceholder() !== undefined && children.length > 0) { - placeholderOption = this.getPlaceholderOption(); - if (placeholderOption) { - children=children.not(placeholderOption); - } - } - - children.each2(function(i, elm) { process(elm, data.results); }); - - query.callback(data); - }); - // this is needed because inside val() we construct choices from options and there id is hardcoded - opts.id=function(e) { return e.id; }; - } else { - if (!("query" in opts)) { - - if ("ajax" in opts) { - ajaxUrl = opts.element.data("ajax-url"); - if (ajaxUrl && ajaxUrl.length > 0) { - opts.ajax.url = ajaxUrl; - } - opts.query = ajax.call(opts.element, opts.ajax); - } else if ("data" in opts) { - opts.query = local(opts.data); - } else if ("tags" in opts) { - opts.query = tags(opts.tags); - if (opts.createSearchChoice === undefined) { - opts.createSearchChoice = function (term) { return {id: $.trim(term), text: $.trim(term)}; }; - } - if (opts.initSelection === undefined) { - opts.initSelection = function (element, callback) { - var data = []; - $(splitVal(element.val(), opts.separator)).each(function () { - var obj = { id: this, text: this }, - tags = opts.tags; - if ($.isFunction(tags)) tags=tags(); - $(tags).each(function() { if (equal(this.id, obj.id)) { obj = this; return false; } }); - data.push(obj); - }); - - callback(data); - }; - } - } - } - } - if (typeof(opts.query) !== "function") { - throw "query function not defined for Select2 " + opts.element.attr("id"); - } - - if (opts.createSearchChoicePosition === 'top') { - opts.createSearchChoicePosition = function(list, item) { list.unshift(item); }; - } - else if (opts.createSearchChoicePosition === 'bottom') { - opts.createSearchChoicePosition = function(list, item) { list.push(item); }; - } - else if (typeof(opts.createSearchChoicePosition) !== "function") { - throw "invalid createSearchChoicePosition option must be 'top', 'bottom' or a custom function"; - } - - return opts; - }, - - /** - * Monitor the original element for changes and update select2 accordingly - */ - // abstract - monitorSource: function () { - var el = this.opts.element, observer, self = this; - - el.on("change.select2", this.bind(function (e) { - if (this.opts.element.data("select2-change-triggered") !== true) { - this.initSelection(); - } - })); - - this._sync = this.bind(function () { - - // sync enabled state - var disabled = el.prop("disabled"); - if (disabled === undefined) disabled = false; - this.enable(!disabled); - - var readonly = el.prop("readonly"); - if (readonly === undefined) readonly = false; - this.readonly(readonly); - - syncCssClasses(this.container, this.opts.element, this.opts.adaptContainerCssClass); - this.container.addClass(evaluate(this.opts.containerCssClass, this.opts.element)); - - syncCssClasses(this.dropdown, this.opts.element, this.opts.adaptDropdownCssClass); - this.dropdown.addClass(evaluate(this.opts.dropdownCssClass, this.opts.element)); - - }); - - // IE8-10 (IE9/10 won't fire propertyChange via attachEventListener) - if (el.length && el[0].attachEvent) { - el.each(function() { - this.attachEvent("onpropertychange", self._sync); - }); - } - - // safari, chrome, firefox, IE11 - observer = window.MutationObserver || window.WebKitMutationObserver|| window.MozMutationObserver; - if (observer !== undefined) { - if (this.propertyObserver) { delete this.propertyObserver; this.propertyObserver = null; } - this.propertyObserver = new observer(function (mutations) { - $.each(mutations, self._sync); - }); - this.propertyObserver.observe(el.get(0), { attributes:true, subtree:false }); - } - }, - - // abstract - triggerSelect: function(data) { - var evt = $.Event("select2-selecting", { val: this.id(data), object: data, choice: data }); - this.opts.element.trigger(evt); - return !evt.isDefaultPrevented(); - }, - - /** - * Triggers the change event on the source element - */ - // abstract - triggerChange: function (details) { - - details = details || {}; - details= $.extend({}, details, { type: "change", val: this.val() }); - // prevents recursive triggering - this.opts.element.data("select2-change-triggered", true); - this.opts.element.trigger(details); - this.opts.element.data("select2-change-triggered", false); - - // some validation frameworks ignore the change event and listen instead to keyup, click for selects - // so here we trigger the click event manually - this.opts.element.click(); - - // ValidationEngine ignores the change event and listens instead to blur - // so here we trigger the blur event manually if so desired - if (this.opts.blurOnChange) - this.opts.element.blur(); - }, - - //abstract - isInterfaceEnabled: function() - { - return this.enabledInterface === true; - }, - - // abstract - enableInterface: function() { - var enabled = this._enabled && !this._readonly, - disabled = !enabled; - - if (enabled === this.enabledInterface) return false; - - this.container.toggleClass("select2-container-disabled", disabled); - this.close(); - this.enabledInterface = enabled; - - return true; - }, - - // abstract - enable: function(enabled) { - if (enabled === undefined) enabled = true; - if (this._enabled === enabled) return; - this._enabled = enabled; - - this.opts.element.prop("disabled", !enabled); - this.enableInterface(); - }, - - // abstract - disable: function() { - this.enable(false); - }, - - // abstract - readonly: function(enabled) { - if (enabled === undefined) enabled = false; - if (this._readonly === enabled) return; - this._readonly = enabled; - - this.opts.element.prop("readonly", enabled); - this.enableInterface(); - }, - - // abstract - opened: function () { - return (this.container) ? this.container.hasClass("select2-dropdown-open") : false; - }, - - // abstract - positionDropdown: function() { - var $dropdown = this.dropdown, - offset = this.container.offset(), - height = this.container.outerHeight(false), - width = this.container.outerWidth(false), - dropHeight = $dropdown.outerHeight(false), - $window = $(window), - windowWidth = $window.width(), - windowHeight = $window.height(), - viewPortRight = $window.scrollLeft() + windowWidth, - viewportBottom = $window.scrollTop() + windowHeight, - dropTop = offset.top + height, - dropLeft = offset.left, - enoughRoomBelow = dropTop + dropHeight <= viewportBottom, - enoughRoomAbove = (offset.top - dropHeight) >= $window.scrollTop(), - dropWidth = $dropdown.outerWidth(false), - enoughRoomOnRight = dropLeft + dropWidth <= viewPortRight, - aboveNow = $dropdown.hasClass("select2-drop-above"), - bodyOffset, - above, - changeDirection, - css, - resultsListNode; - - // always prefer the current above/below alignment, unless there is not enough room - if (aboveNow) { - above = true; - if (!enoughRoomAbove && enoughRoomBelow) { - changeDirection = true; - above = false; - } - } else { - above = false; - if (!enoughRoomBelow && enoughRoomAbove) { - changeDirection = true; - above = true; - } - } - - //if we are changing direction we need to get positions when dropdown is hidden; - if (changeDirection) { - $dropdown.hide(); - offset = this.container.offset(); - height = this.container.outerHeight(false); - width = this.container.outerWidth(false); - dropHeight = $dropdown.outerHeight(false); - viewPortRight = $window.scrollLeft() + windowWidth; - viewportBottom = $window.scrollTop() + windowHeight; - dropTop = offset.top + height; - dropLeft = offset.left; - dropWidth = $dropdown.outerWidth(false); - enoughRoomOnRight = dropLeft + dropWidth <= viewPortRight; - $dropdown.show(); - - // fix so the cursor does not move to the left within the search-textbox in IE - this.focusSearch(); - } - - if (this.opts.dropdownAutoWidth) { - resultsListNode = $('.select2-results', $dropdown)[0]; - $dropdown.addClass('select2-drop-auto-width'); - $dropdown.css('width', ''); - // Add scrollbar width to dropdown if vertical scrollbar is present - dropWidth = $dropdown.outerWidth(false) + (resultsListNode.scrollHeight === resultsListNode.clientHeight ? 0 : scrollBarDimensions.width); - dropWidth > width ? width = dropWidth : dropWidth = width; - dropHeight = $dropdown.outerHeight(false); - enoughRoomOnRight = dropLeft + dropWidth <= viewPortRight; - } - else { - this.container.removeClass('select2-drop-auto-width'); - } - - //console.log("below/ droptop:", dropTop, "dropHeight", dropHeight, "sum", (dropTop+dropHeight)+" viewport bottom", viewportBottom, "enough?", enoughRoomBelow); - //console.log("above/ offset.top", offset.top, "dropHeight", dropHeight, "top", (offset.top-dropHeight), "scrollTop", this.body.scrollTop(), "enough?", enoughRoomAbove); - - // fix positioning when body has an offset and is not position: static - if (this.body.css('position') !== 'static') { - bodyOffset = this.body.offset(); - dropTop -= bodyOffset.top; - dropLeft -= bodyOffset.left; - } - - if (!enoughRoomOnRight) { - dropLeft = offset.left + this.container.outerWidth(false) - dropWidth; - } - - css = { - left: dropLeft, - width: width - }; - - if (above) { - css.top = offset.top - dropHeight; - css.bottom = 'auto'; - this.container.addClass("select2-drop-above"); - $dropdown.addClass("select2-drop-above"); - } - else { - css.top = dropTop; - css.bottom = 'auto'; - this.container.removeClass("select2-drop-above"); - $dropdown.removeClass("select2-drop-above"); - } - css = $.extend(css, evaluate(this.opts.dropdownCss, this.opts.element)); - - $dropdown.css(css); - }, - - // abstract - shouldOpen: function() { - var event; - - if (this.opened()) return false; - - if (this._enabled === false || this._readonly === true) return false; - - event = $.Event("select2-opening"); - this.opts.element.trigger(event); - return !event.isDefaultPrevented(); - }, - - // abstract - clearDropdownAlignmentPreference: function() { - // clear the classes used to figure out the preference of where the dropdown should be opened - this.container.removeClass("select2-drop-above"); - this.dropdown.removeClass("select2-drop-above"); - }, - - /** - * Opens the dropdown - * - * @return {Boolean} whether or not dropdown was opened. This method will return false if, for example, - * the dropdown is already open, or if the 'open' event listener on the element called preventDefault(). - */ - // abstract - open: function () { - - if (!this.shouldOpen()) return false; - - this.opening(); - - // Only bind the document mousemove when the dropdown is visible - $document.on("mousemove.select2Event", function (e) { - lastMousePosition.x = e.pageX; - lastMousePosition.y = e.pageY; - }); - - return true; - }, - - /** - * Performs the opening of the dropdown - */ - // abstract - opening: function() { - var cid = this.containerEventName, - scroll = "scroll." + cid, - resize = "resize."+cid, - orient = "orientationchange."+cid, - mask; - - this.container.addClass("select2-dropdown-open").addClass("select2-container-active"); - - this.clearDropdownAlignmentPreference(); - - if(this.dropdown[0] !== this.body.children().last()[0]) { - this.dropdown.detach().appendTo(this.body); - } - - // create the dropdown mask if doesn't already exist - mask = $("#select2-drop-mask"); - if (mask.length == 0) { - mask = $(document.createElement("div")); - mask.attr("id","select2-drop-mask").attr("class","select2-drop-mask"); - mask.hide(); - mask.appendTo(this.body); - mask.on("mousedown touchstart click", function (e) { - // Prevent IE from generating a click event on the body - reinsertElement(mask); - - var dropdown = $("#select2-drop"), self; - if (dropdown.length > 0) { - self=dropdown.data("select2"); - if (self.opts.selectOnBlur) { - self.selectHighlighted({noFocus: true}); - } - self.close(); - e.preventDefault(); - e.stopPropagation(); - } - }); - } - - // ensure the mask is always right before the dropdown - if (this.dropdown.prev()[0] !== mask[0]) { - this.dropdown.before(mask); - } - - // move the global id to the correct dropdown - $("#select2-drop").removeAttr("id"); - this.dropdown.attr("id", "select2-drop"); - - // show the elements - mask.show(); - - this.positionDropdown(); - this.dropdown.show(); - this.positionDropdown(); - - this.dropdown.addClass("select2-drop-active"); - - // attach listeners to events that can change the position of the container and thus require - // the position of the dropdown to be updated as well so it does not come unglued from the container - var that = this; - this.container.parents().add(window).each(function () { - $(this).on(resize+" "+scroll+" "+orient, function (e) { - if (that.opened()) that.positionDropdown(); - }); - }); - - - }, - - // abstract - close: function () { - if (!this.opened()) return; - - var cid = this.containerEventName, - scroll = "scroll." + cid, - resize = "resize."+cid, - orient = "orientationchange."+cid; - - // unbind event listeners - this.container.parents().add(window).each(function () { $(this).off(scroll).off(resize).off(orient); }); - - this.clearDropdownAlignmentPreference(); - - $("#select2-drop-mask").hide(); - this.dropdown.removeAttr("id"); // only the active dropdown has the select2-drop id - this.dropdown.hide(); - this.container.removeClass("select2-dropdown-open").removeClass("select2-container-active"); - this.results.empty(); - - // Now that the dropdown is closed, unbind the global document mousemove event - $document.off("mousemove.select2Event"); - - this.clearSearch(); - this.search.removeClass("select2-active"); - this.opts.element.trigger($.Event("select2-close")); - }, - - /** - * Opens control, sets input value, and updates results. - */ - // abstract - externalSearch: function (term) { - this.open(); - this.search.val(term); - this.updateResults(false); - }, - - // abstract - clearSearch: function () { - - }, - - //abstract - getMaximumSelectionSize: function() { - return evaluate(this.opts.maximumSelectionSize, this.opts.element); - }, - - // abstract - ensureHighlightVisible: function () { - var results = this.results, children, index, child, hb, rb, y, more, topOffset; - - index = this.highlight(); - - if (index < 0) return; - - if (index == 0) { - - // if the first element is highlighted scroll all the way to the top, - // that way any unselectable headers above it will also be scrolled - // into view - - results.scrollTop(0); - return; - } - - children = this.findHighlightableChoices().find('.select2-result-label'); - - child = $(children[index]); - - topOffset = (child.offset() || {}).top || 0; - - hb = topOffset + child.outerHeight(true); - - // if this is the last child lets also make sure select2-more-results is visible - if (index === children.length - 1) { - more = results.find("li.select2-more-results"); - if (more.length > 0) { - hb = more.offset().top + more.outerHeight(true); - } - } - - rb = results.offset().top + results.outerHeight(true); - if (hb > rb) { - results.scrollTop(results.scrollTop() + (hb - rb)); - } - y = topOffset - results.offset().top; - - // make sure the top of the element is visible - if (y < 0 && child.css('display') != 'none' ) { - results.scrollTop(results.scrollTop() + y); // y is negative - } - }, - - // abstract - findHighlightableChoices: function() { - return this.results.find(".select2-result-selectable:not(.select2-disabled):not(.select2-selected)"); - }, - - // abstract - moveHighlight: function (delta) { - var choices = this.findHighlightableChoices(), - index = this.highlight(); - - while (index > -1 && index < choices.length) { - index += delta; - var choice = $(choices[index]); - if (choice.hasClass("select2-result-selectable") && !choice.hasClass("select2-disabled") && !choice.hasClass("select2-selected")) { - this.highlight(index); - break; - } - } - }, - - // abstract - highlight: function (index) { - var choices = this.findHighlightableChoices(), - choice, - data; - - if (arguments.length === 0) { - return indexOf(choices.filter(".select2-highlighted")[0], choices.get()); - } - - if (index >= choices.length) index = choices.length - 1; - if (index < 0) index = 0; - - this.removeHighlight(); - - choice = $(choices[index]); - choice.addClass("select2-highlighted"); - - // ensure assistive technology can determine the active choice - this.search.attr("aria-activedescendant", choice.find(".select2-result-label").attr("id")); - - this.ensureHighlightVisible(); - - this.liveRegion.text(choice.text()); - - data = choice.data("select2-data"); - if (data) { - this.opts.element.trigger({ type: "select2-highlight", val: this.id(data), choice: data }); - } - }, - - removeHighlight: function() { - this.results.find(".select2-highlighted").removeClass("select2-highlighted"); - }, - - touchMoved: function() { - this._touchMoved = true; - }, - - clearTouchMoved: function() { - this._touchMoved = false; - }, - - // abstract - countSelectableResults: function() { - return this.findHighlightableChoices().length; - }, - - // abstract - highlightUnderEvent: function (event) { - var el = $(event.target).closest(".select2-result-selectable"); - if (el.length > 0 && !el.is(".select2-highlighted")) { - var choices = this.findHighlightableChoices(); - this.highlight(choices.index(el)); - } else if (el.length == 0) { - // if we are over an unselectable item remove all highlights - this.removeHighlight(); - } - }, - - // abstract - loadMoreIfNeeded: function () { - var results = this.results, - more = results.find("li.select2-more-results"), - below, // pixels the element is below the scroll fold, below==0 is when the element is starting to be visible - page = this.resultsPage + 1, - self=this, - term=this.search.val(), - context=this.context; - - if (more.length === 0) return; - below = more.offset().top - results.offset().top - results.height(); - - if (below <= this.opts.loadMorePadding) { - more.addClass("select2-active"); - this.opts.query({ - element: this.opts.element, - term: term, - page: page, - context: context, - matcher: this.opts.matcher, - callback: this.bind(function (data) { - - // ignore a response if the select2 has been closed before it was received - if (!self.opened()) return; - - - self.opts.populateResults.call(this, results, data.results, {term: term, page: page, context:context}); - self.postprocessResults(data, false, false); - - if (data.more===true) { - more.detach().appendTo(results).text(evaluate(self.opts.formatLoadMore, self.opts.element, page+1)); - window.setTimeout(function() { self.loadMoreIfNeeded(); }, 10); - } else { - more.remove(); - } - self.positionDropdown(); - self.resultsPage = page; - self.context = data.context; - this.opts.element.trigger({ type: "select2-loaded", items: data }); - })}); - } - }, - - /** - * Default tokenizer function which does nothing - */ - tokenize: function() { - - }, - - /** - * @param initial whether or not this is the call to this method right after the dropdown has been opened - */ - // abstract - updateResults: function (initial) { - var search = this.search, - results = this.results, - opts = this.opts, - data, - self = this, - input, - term = search.val(), - lastTerm = $.data(this.container, "select2-last-term"), - // sequence number used to drop out-of-order responses - queryNumber; - - // prevent duplicate queries against the same term - if (initial !== true && lastTerm && equal(term, lastTerm)) return; - - $.data(this.container, "select2-last-term", term); - - // if the search is currently hidden we do not alter the results - if (initial !== true && (this.showSearchInput === false || !this.opened())) { - return; - } - - function postRender() { - search.removeClass("select2-active"); - self.positionDropdown(); - if (results.find('.select2-no-results,.select2-selection-limit,.select2-searching').length) { - self.liveRegion.text(results.text()); - } - else { - self.liveRegion.text(self.opts.formatMatches(results.find('.select2-result-selectable').length)); - } - } - - function render(html) { - results.html(html); - postRender(); - } - - queryNumber = ++this.queryCount; - - var maxSelSize = this.getMaximumSelectionSize(); - if (maxSelSize >=1) { - data = this.data(); - if ($.isArray(data) && data.length >= maxSelSize && checkFormatter(opts.formatSelectionTooBig, "formatSelectionTooBig")) { - render("<li class='select2-selection-limit'>" + evaluate(opts.formatSelectionTooBig, opts.element, maxSelSize) + "</li>"); - return; - } - } - - if (search.val().length < opts.minimumInputLength) { - if (checkFormatter(opts.formatInputTooShort, "formatInputTooShort")) { - render("<li class='select2-no-results'>" + evaluate(opts.formatInputTooShort, opts.element, search.val(), opts.minimumInputLength) + "</li>"); - } else { - render(""); - } - if (initial && this.showSearch) this.showSearch(true); - return; - } - - if (opts.maximumInputLength && search.val().length > opts.maximumInputLength) { - if (checkFormatter(opts.formatInputTooLong, "formatInputTooLong")) { - render("<li class='select2-no-results'>" + evaluate(opts.formatInputTooLong, opts.element, search.val(), opts.maximumInputLength) + "</li>"); - } else { - render(""); - } - return; - } - - if (opts.formatSearching && this.findHighlightableChoices().length === 0) { - render("<li class='select2-searching'>" + evaluate(opts.formatSearching, opts.element) + "</li>"); - } - - search.addClass("select2-active"); - - this.removeHighlight(); - - // give the tokenizer a chance to pre-process the input - input = this.tokenize(); - if (input != undefined && input != null) { - search.val(input); - } - - this.resultsPage = 1; - - opts.query({ - element: opts.element, - term: search.val(), - page: this.resultsPage, - context: null, - matcher: opts.matcher, - callback: this.bind(function (data) { - var def; // default choice - - // ignore old responses - if (queryNumber != this.queryCount) { - return; - } - - // ignore a response if the select2 has been closed before it was received - if (!this.opened()) { - this.search.removeClass("select2-active"); - return; - } - - // save context, if any - this.context = (data.context===undefined) ? null : data.context; - // create a default choice and prepend it to the list - if (this.opts.createSearchChoice && search.val() !== "") { - def = this.opts.createSearchChoice.call(self, search.val(), data.results); - if (def !== undefined && def !== null && self.id(def) !== undefined && self.id(def) !== null) { - if ($(data.results).filter( - function () { - return equal(self.id(this), self.id(def)); - }).length === 0) { - this.opts.createSearchChoicePosition(data.results, def); - } - } - } - - if (data.results.length === 0 && checkFormatter(opts.formatNoMatches, "formatNoMatches")) { - render("<li class='select2-no-results'>" + evaluate(opts.formatNoMatches, opts.element, search.val()) + "</li>"); - return; - } - - results.empty(); - self.opts.populateResults.call(this, results, data.results, {term: search.val(), page: this.resultsPage, context:null}); - - if (data.more === true && checkFormatter(opts.formatLoadMore, "formatLoadMore")) { - results.append("<li class='select2-more-results'>" + opts.escapeMarkup(evaluate(opts.formatLoadMore, opts.element, this.resultsPage)) + "</li>"); - window.setTimeout(function() { self.loadMoreIfNeeded(); }, 10); - } - - this.postprocessResults(data, initial); - - postRender(); - - this.opts.element.trigger({ type: "select2-loaded", items: data }); - })}); - }, - - // abstract - cancel: function () { - this.close(); - }, - - // abstract - blur: function () { - // if selectOnBlur == true, select the currently highlighted option - if (this.opts.selectOnBlur) - this.selectHighlighted({noFocus: true}); - - this.close(); - this.container.removeClass("select2-container-active"); - // synonymous to .is(':focus'), which is available in jquery >= 1.6 - if (this.search[0] === document.activeElement) { this.search.blur(); } - this.clearSearch(); - this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus"); - }, - - // abstract - focusSearch: function () { - focus(this.search); - }, - - // abstract - selectHighlighted: function (options) { - if (this._touchMoved) { - this.clearTouchMoved(); - return; - } - var index=this.highlight(), - highlighted=this.results.find(".select2-highlighted"), - data = highlighted.closest('.select2-result').data("select2-data"); - - if (data) { - this.highlight(index); - this.onSelect(data, options); - } else if (options && options.noFocus) { - this.close(); - } - }, - - // abstract - getPlaceholder: function () { - var placeholderOption; - return this.opts.element.attr("placeholder") || - this.opts.element.attr("data-placeholder") || // jquery 1.4 compat - this.opts.element.data("placeholder") || - this.opts.placeholder || - ((placeholderOption = this.getPlaceholderOption()) !== undefined ? placeholderOption.text() : undefined); - }, - - // abstract - getPlaceholderOption: function() { - if (this.select) { - var firstOption = this.select.children('option').first(); - if (this.opts.placeholderOption !== undefined ) { - //Determine the placeholder option based on the specified placeholderOption setting - return (this.opts.placeholderOption === "first" && firstOption) || - (typeof this.opts.placeholderOption === "function" && this.opts.placeholderOption(this.select)); - } else if ($.trim(firstOption.text()) === "" && firstOption.val() === "") { - //No explicit placeholder option specified, use the first if it's blank - return firstOption; - } - } - }, - - /** - * Get the desired width for the container element. This is - * derived first from option `width` passed to select2, then - * the inline 'style' on the original element, and finally - * falls back to the jQuery calculated element width. - */ - // abstract - initContainerWidth: function () { - function resolveContainerWidth() { - var style, attrs, matches, i, l, attr; - - if (this.opts.width === "off") { - return null; - } else if (this.opts.width === "element"){ - return this.opts.element.outerWidth(false) === 0 ? 'auto' : this.opts.element.outerWidth(false) + 'px'; - } else if (this.opts.width === "copy" || this.opts.width === "resolve") { - // check if there is inline style on the element that contains width - style = this.opts.element.attr('style'); - if (style !== undefined) { - attrs = style.split(';'); - for (i = 0, l = attrs.length; i < l; i = i + 1) { - attr = attrs[i].replace(/\s/g, ''); - matches = attr.match(/^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i); - if (matches !== null && matches.length >= 1) - return matches[1]; - } - } - - if (this.opts.width === "resolve") { - // next check if css('width') can resolve a width that is percent based, this is sometimes possible - // when attached to input type=hidden or elements hidden via css - style = this.opts.element.css('width'); - if (style.indexOf("%") > 0) return style; - - // finally, fallback on the calculated width of the element - return (this.opts.element.outerWidth(false) === 0 ? 'auto' : this.opts.element.outerWidth(false) + 'px'); - } - - return null; - } else if ($.isFunction(this.opts.width)) { - return this.opts.width(); - } else { - return this.opts.width; - } - }; - - var width = resolveContainerWidth.call(this); - if (width !== null) { - this.container.css("width", width); - } - } - }); - - SingleSelect2 = clazz(AbstractSelect2, { - - // single - - createContainer: function () { - var container = $(document.createElement("div")).attr({ - "class": "select2-container" - }).html([ - "<a href='javascript:void(0)' class='select2-choice' tabindex='-1'>", - " <span class='select2-chosen'>&#160;</span><abbr class='select2-search-choice-close'></abbr>", - " <span class='select2-arrow' role='presentation'><b role='presentation'></b></span>", - "</a>", - "<label for='' class='select2-offscreen'></label>", - "<input class='select2-focusser select2-offscreen' type='text' aria-haspopup='true' role='button' />", - "<div class='select2-drop select2-display-none'>", - " <div class='select2-search'>", - " <label for='' class='select2-offscreen'></label>", - " <input type='text' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' class='select2-input' role='combobox' aria-expanded='true'", - " aria-autocomplete='list' />", - " </div>", - " <ul class='select2-results' role='listbox'>", - " </ul>", - "</div>"].join("")); - return container; - }, - - // single - enableInterface: function() { - if (this.parent.enableInterface.apply(this, arguments)) { - this.focusser.prop("disabled", !this.isInterfaceEnabled()); - } - }, - - // single - opening: function () { - var el, range, len; - - if (this.opts.minimumResultsForSearch >= 0) { - this.showSearch(true); - } - - this.parent.opening.apply(this, arguments); - - if (this.showSearchInput !== false) { - // IE appends focusser.val() at the end of field :/ so we manually insert it at the beginning using a range - // all other browsers handle this just fine - - this.search.val(this.focusser.val()); - } - if (this.opts.shouldFocusInput(this)) { - this.search.focus(); - // move the cursor to the end after focussing, otherwise it will be at the beginning and - // new text will appear *before* focusser.val() - el = this.search.get(0); - if (el.createTextRange) { - range = el.createTextRange(); - range.collapse(false); - range.select(); - } else if (el.setSelectionRange) { - len = this.search.val().length; - el.setSelectionRange(len, len); - } - } - - // initializes search's value with nextSearchTerm (if defined by user) - // ignore nextSearchTerm if the dropdown is opened by the user pressing a letter - if(this.search.val() === "") { - if(this.nextSearchTerm != undefined){ - this.search.val(this.nextSearchTerm); - this.search.select(); - } - } - - this.focusser.prop("disabled", true).val(""); - this.updateResults(true); - this.opts.element.trigger($.Event("select2-open")); - }, - - // single - close: function () { - if (!this.opened()) return; - this.parent.close.apply(this, arguments); - - this.focusser.prop("disabled", false); - - if (this.opts.shouldFocusInput(this)) { - this.focusser.focus(); - } - }, - - // single - focus: function () { - if (this.opened()) { - this.close(); - } else { - this.focusser.prop("disabled", false); - if (this.opts.shouldFocusInput(this)) { - this.focusser.focus(); - } - } - }, - - // single - isFocused: function () { - return this.container.hasClass("select2-container-active"); - }, - - // single - cancel: function () { - this.parent.cancel.apply(this, arguments); - this.focusser.prop("disabled", false); - - if (this.opts.shouldFocusInput(this)) { - this.focusser.focus(); - } - }, - - // single - destroy: function() { - $("label[for='" + this.focusser.attr('id') + "']") - .attr('for', this.opts.element.attr("id")); - this.parent.destroy.apply(this, arguments); - - cleanupJQueryElements.call(this, - "selection", - "focusser" - ); - }, - - // single - initContainer: function () { - - var selection, - container = this.container, - dropdown = this.dropdown, - idSuffix = nextUid(), - elementLabel; - - if (this.opts.minimumResultsForSearch < 0) { - this.showSearch(false); - } else { - this.showSearch(true); - } - - this.selection = selection = container.find(".select2-choice"); - - this.focusser = container.find(".select2-focusser"); - - // add aria associations - selection.find(".select2-chosen").attr("id", "select2-chosen-"+idSuffix); - this.focusser.attr("aria-labelledby", "select2-chosen-"+idSuffix); - this.results.attr("id", "select2-results-"+idSuffix); - this.search.attr("aria-owns", "select2-results-"+idSuffix); - - // rewrite labels from original element to focusser - this.focusser.attr("id", "s2id_autogen"+idSuffix); - - elementLabel = $("label[for='" + this.opts.element.attr("id") + "']"); - - this.focusser.prev() - .text(elementLabel.text()) - .attr('for', this.focusser.attr('id')); - - // Ensure the original element retains an accessible name - var originalTitle = this.opts.element.attr("title"); - this.opts.element.attr("title", (originalTitle || elementLabel.text())); - - this.focusser.attr("tabindex", this.elementTabIndex); - - // write label for search field using the label from the focusser element - this.search.attr("id", this.focusser.attr('id') + '_search'); - - this.search.prev() - .text($("label[for='" + this.focusser.attr('id') + "']").text()) - .attr('for', this.search.attr('id')); - - this.search.on("keydown", this.bind(function (e) { - if (!this.isInterfaceEnabled()) return; - - if (e.which === KEY.PAGE_UP || e.which === KEY.PAGE_DOWN) { - // prevent the page from scrolling - killEvent(e); - return; - } - - switch (e.which) { - case KEY.UP: - case KEY.DOWN: - this.moveHighlight((e.which === KEY.UP) ? -1 : 1); - killEvent(e); - return; - case KEY.ENTER: - this.selectHighlighted(); - killEvent(e); - return; - case KEY.TAB: - this.selectHighlighted({noFocus: true}); - return; - case KEY.ESC: - this.cancel(e); - killEvent(e); - return; - } - })); - - this.search.on("blur", this.bind(function(e) { - // a workaround for chrome to keep the search field focussed when the scroll bar is used to scroll the dropdown. - // without this the search field loses focus which is annoying - if (document.activeElement === this.body.get(0)) { - window.setTimeout(this.bind(function() { - if (this.opened()) { - this.search.focus(); - } - }), 0); - } - })); - - this.focusser.on("keydown", this.bind(function (e) { - if (!this.isInterfaceEnabled()) return; - - if (e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e) || e.which === KEY.ESC) { - return; - } - - if (this.opts.openOnEnter === false && e.which === KEY.ENTER) { - killEvent(e); - return; - } - - if (e.which == KEY.DOWN || e.which == KEY.UP - || (e.which == KEY.ENTER && this.opts.openOnEnter)) { - - if (e.altKey || e.ctrlKey || e.shiftKey || e.metaKey) return; - - this.open(); - killEvent(e); - return; - } - - if (e.which == KEY.DELETE || e.which == KEY.BACKSPACE) { - if (this.opts.allowClear) { - this.clear(); - } - killEvent(e); - return; - } - })); - - - installKeyUpChangeEvent(this.focusser); - this.focusser.on("keyup-change input", this.bind(function(e) { - if (this.opts.minimumResultsForSearch >= 0) { - e.stopPropagation(); - if (this.opened()) return; - this.open(); - } - })); - - selection.on("mousedown touchstart", "abbr", this.bind(function (e) { - if (!this.isInterfaceEnabled()) return; - this.clear(); - killEventImmediately(e); - this.close(); - this.selection.focus(); - })); - - selection.on("mousedown touchstart", this.bind(function (e) { - // Prevent IE from generating a click event on the body - reinsertElement(selection); - - if (!this.container.hasClass("select2-container-active")) { - this.opts.element.trigger($.Event("select2-focus")); - } - - if (this.opened()) { - this.close(); - } else if (this.isInterfaceEnabled()) { - this.open(); - } - - killEvent(e); - })); - - dropdown.on("mousedown touchstart", this.bind(function() { - if (this.opts.shouldFocusInput(this)) { - this.search.focus(); - } - })); - - selection.on("focus", this.bind(function(e) { - killEvent(e); - })); - - this.focusser.on("focus", this.bind(function(){ - if (!this.container.hasClass("select2-container-active")) { - this.opts.element.trigger($.Event("select2-focus")); - } - this.container.addClass("select2-container-active"); - })).on("blur", this.bind(function() { - if (!this.opened()) { - this.container.removeClass("select2-container-active"); - this.opts.element.trigger($.Event("select2-blur")); - } - })); - this.search.on("focus", this.bind(function(){ - if (!this.container.hasClass("select2-container-active")) { - this.opts.element.trigger($.Event("select2-focus")); - } - this.container.addClass("select2-container-active"); - })); - - this.initContainerWidth(); - this.opts.element.addClass("select2-offscreen"); - this.setPlaceholder(); - - }, - - // single - clear: function(triggerChange) { - var data=this.selection.data("select2-data"); - if (data) { // guard against queued quick consecutive clicks - var evt = $.Event("select2-clearing"); - this.opts.element.trigger(evt); - if (evt.isDefaultPrevented()) { - return; - } - var placeholderOption = this.getPlaceholderOption(); - this.opts.element.val(placeholderOption ? placeholderOption.val() : ""); - this.selection.find(".select2-chosen").empty(); - this.selection.removeData("select2-data"); - this.setPlaceholder(); - - if (triggerChange !== false){ - this.opts.element.trigger({ type: "select2-removed", val: this.id(data), choice: data }); - this.triggerChange({removed:data}); - } - } - }, - - /** - * Sets selection based on source element's value - */ - // single - initSelection: function () { - var selected; - if (this.isPlaceholderOptionSelected()) { - this.updateSelection(null); - this.close(); - this.setPlaceholder(); - } else { - var self = this; - this.opts.initSelection.call(null, this.opts.element, function(selected){ - if (selected !== undefined && selected !== null) { - self.updateSelection(selected); - self.close(); - self.setPlaceholder(); - self.nextSearchTerm = self.opts.nextSearchTerm(selected, self.search.val()); - } - }); - } - }, - - isPlaceholderOptionSelected: function() { - var placeholderOption; - if (this.getPlaceholder() === undefined) return false; // no placeholder specified so no option should be considered - return ((placeholderOption = this.getPlaceholderOption()) !== undefined && placeholderOption.prop("selected")) - || (this.opts.element.val() === "") - || (this.opts.element.val() === undefined) - || (this.opts.element.val() === null); - }, - - // single - prepareOpts: function () { - var opts = this.parent.prepareOpts.apply(this, arguments), - self=this; - - if (opts.element.get(0).tagName.toLowerCase() === "select") { - // install the selection initializer - opts.initSelection = function (element, callback) { - var selected = element.find("option").filter(function() { return this.selected && !this.disabled }); - // a single select box always has a value, no need to null check 'selected' - callback(self.optionToData(selected)); - }; - } else if ("data" in opts) { - // install default initSelection when applied to hidden input and data is local - opts.initSelection = opts.initSelection || function (element, callback) { - var id = element.val(); - //search in data by id, storing the actual matching item - var match = null; - opts.query({ - matcher: function(term, text, el){ - var is_match = equal(id, opts.id(el)); - if (is_match) { - match = el; - } - return is_match; - }, - callback: !$.isFunction(callback) ? $.noop : function() { - callback(match); - } - }); - }; - } - - return opts; - }, - - // single - getPlaceholder: function() { - // if a placeholder is specified on a single select without a valid placeholder option ignore it - if (this.select) { - if (this.getPlaceholderOption() === undefined) { - return undefined; - } - } - - return this.parent.getPlaceholder.apply(this, arguments); - }, - - // single - setPlaceholder: function () { - var placeholder = this.getPlaceholder(); - - if (this.isPlaceholderOptionSelected() && placeholder !== undefined) { - - // check for a placeholder option if attached to a select - if (this.select && this.getPlaceholderOption() === undefined) return; - - this.selection.find(".select2-chosen").html(this.opts.escapeMarkup(placeholder)); - - this.selection.addClass("select2-default"); - - this.container.removeClass("select2-allowclear"); - } - }, - - // single - postprocessResults: function (data, initial, noHighlightUpdate) { - var selected = 0, self = this, showSearchInput = true; - - // find the selected element in the result list - - this.findHighlightableChoices().each2(function (i, elm) { - if (equal(self.id(elm.data("select2-data")), self.opts.element.val())) { - selected = i; - return false; - } - }); - - // and highlight it - if (noHighlightUpdate !== false) { - if (initial === true && selected >= 0) { - this.highlight(selected); - } else { - this.highlight(0); - } - } - - // hide the search box if this is the first we got the results and there are enough of them for search - - if (initial === true) { - var min = this.opts.minimumResultsForSearch; - if (min >= 0) { - this.showSearch(countResults(data.results) >= min); - } - } - }, - - // single - showSearch: function(showSearchInput) { - if (this.showSearchInput === showSearchInput) return; - - this.showSearchInput = showSearchInput; - - this.dropdown.find(".select2-search").toggleClass("select2-search-hidden", !showSearchInput); - this.dropdown.find(".select2-search").toggleClass("select2-offscreen", !showSearchInput); - //add "select2-with-searchbox" to the container if search box is shown - $(this.dropdown, this.container).toggleClass("select2-with-searchbox", showSearchInput); - }, - - // single - onSelect: function (data, options) { - - if (!this.triggerSelect(data)) { return; } - - var old = this.opts.element.val(), - oldData = this.data(); - - this.opts.element.val(this.id(data)); - this.updateSelection(data); - - this.opts.element.trigger({ type: "select2-selected", val: this.id(data), choice: data }); - - this.nextSearchTerm = this.opts.nextSearchTerm(data, this.search.val()); - this.close(); - - if ((!options || !options.noFocus) && this.opts.shouldFocusInput(this)) { - this.focusser.focus(); - } - - if (!equal(old, this.id(data))) { - this.triggerChange({ added: data, removed: oldData }); - } - }, - - // single - updateSelection: function (data) { - - var container=this.selection.find(".select2-chosen"), formatted, cssClass; - - this.selection.data("select2-data", data); - - container.empty(); - if (data !== null) { - formatted=this.opts.formatSelection(data, container, this.opts.escapeMarkup); - } - if (formatted !== undefined) { - container.append(formatted); - } - cssClass=this.opts.formatSelectionCssClass(data, container); - if (cssClass !== undefined) { - container.addClass(cssClass); - } - - this.selection.removeClass("select2-default"); - - if (this.opts.allowClear && this.getPlaceholder() !== undefined) { - this.container.addClass("select2-allowclear"); - } - }, - - // single - val: function () { - var val, - triggerChange = false, - data = null, - self = this, - oldData = this.data(); - - if (arguments.length === 0) { - return this.opts.element.val(); - } - - val = arguments[0]; - - if (arguments.length > 1) { - triggerChange = arguments[1]; - } - - if (this.select) { - this.select - .val(val) - .find("option").filter(function() { return this.selected }).each2(function (i, elm) { - data = self.optionToData(elm); - return false; - }); - this.updateSelection(data); - this.setPlaceholder(); - if (triggerChange) { - this.triggerChange({added: data, removed:oldData}); - } - } else { - // val is an id. !val is true for [undefined,null,'',0] - 0 is legal - if (!val && val !== 0) { - this.clear(triggerChange); - return; - } - if (this.opts.initSelection === undefined) { - throw new Error("cannot call val() if initSelection() is not defined"); - } - this.opts.element.val(val); - this.opts.initSelection(this.opts.element, function(data){ - self.opts.element.val(!data ? "" : self.id(data)); - self.updateSelection(data); - self.setPlaceholder(); - if (triggerChange) { - self.triggerChange({added: data, removed:oldData}); - } - }); - } - }, - - // single - clearSearch: function () { - this.search.val(""); - this.focusser.val(""); - }, - - // single - data: function(value) { - var data, - triggerChange = false; - - if (arguments.length === 0) { - data = this.selection.data("select2-data"); - if (data == undefined) data = null; - return data; - } else { - if (arguments.length > 1) { - triggerChange = arguments[1]; - } - if (!value) { - this.clear(triggerChange); - } else { - data = this.data(); - this.opts.element.val(!value ? "" : this.id(value)); - this.updateSelection(value); - if (triggerChange) { - this.triggerChange({added: value, removed:data}); - } - } - } - } - }); - - MultiSelect2 = clazz(AbstractSelect2, { - - // multi - createContainer: function () { - var container = $(document.createElement("div")).attr({ - "class": "select2-container select2-container-multi" - }).html([ - "<ul class='select2-choices'>", - " <li class='select2-search-field'>", - " <label for='' class='select2-offscreen'></label>", - " <input type='text' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' class='select2-input'>", - " </li>", - "</ul>", - "<div class='select2-drop select2-drop-multi select2-display-none'>", - " <ul class='select2-results'>", - " </ul>", - "</div>"].join("")); - return container; - }, - - // multi - prepareOpts: function () { - var opts = this.parent.prepareOpts.apply(this, arguments), - self=this; - - // TODO validate placeholder is a string if specified - - if (opts.element.get(0).tagName.toLowerCase() === "select") { - // install the selection initializer - opts.initSelection = function (element, callback) { - - var data = []; - - element.find("option").filter(function() { return this.selected && !this.disabled }).each2(function (i, elm) { - data.push(self.optionToData(elm)); - }); - callback(data); - }; - } else if ("data" in opts) { - // install default initSelection when applied to hidden input and data is local - opts.initSelection = opts.initSelection || function (element, callback) { - var ids = splitVal(element.val(), opts.separator); - //search in data by array of ids, storing matching items in a list - var matches = []; - opts.query({ - matcher: function(term, text, el){ - var is_match = $.grep(ids, function(id) { - return equal(id, opts.id(el)); - }).length; - if (is_match) { - matches.push(el); - } - return is_match; - }, - callback: !$.isFunction(callback) ? $.noop : function() { - // reorder matches based on the order they appear in the ids array because right now - // they are in the order in which they appear in data array - var ordered = []; - for (var i = 0; i < ids.length; i++) { - var id = ids[i]; - for (var j = 0; j < matches.length; j++) { - var match = matches[j]; - if (equal(id, opts.id(match))) { - ordered.push(match); - matches.splice(j, 1); - break; - } - } - } - callback(ordered); - } - }); - }; - } - - return opts; - }, - - // multi - selectChoice: function (choice) { - - var selected = this.container.find(".select2-search-choice-focus"); - if (selected.length && choice && choice[0] == selected[0]) { - - } else { - if (selected.length) { - this.opts.element.trigger("choice-deselected", selected); - } - selected.removeClass("select2-search-choice-focus"); - if (choice && choice.length) { - this.close(); - choice.addClass("select2-search-choice-focus"); - this.opts.element.trigger("choice-selected", choice); - } - } - }, - - // multi - destroy: function() { - $("label[for='" + this.search.attr('id') + "']") - .attr('for', this.opts.element.attr("id")); - this.parent.destroy.apply(this, arguments); - - cleanupJQueryElements.call(this, - "searchContainer", - "selection" - ); - }, - - // multi - initContainer: function () { - - var selector = ".select2-choices", selection; - - this.searchContainer = this.container.find(".select2-search-field"); - this.selection = selection = this.container.find(selector); - - var _this = this; - this.selection.on("click", ".select2-search-choice:not(.select2-locked)", function (e) { - //killEvent(e); - _this.search[0].focus(); - _this.selectChoice($(this)); - }); - - // rewrite labels from original element to focusser - this.search.attr("id", "s2id_autogen"+nextUid()); - - this.search.prev() - .text($("label[for='" + this.opts.element.attr("id") + "']").text()) - .attr('for', this.search.attr('id')); - - this.search.on("input paste", this.bind(function() { - if (this.search.attr('placeholder') && this.search.val().length == 0) return; - if (!this.isInterfaceEnabled()) return; - if (!this.opened()) { - this.open(); - } - })); - - this.search.attr("tabindex", this.elementTabIndex); - - this.keydowns = 0; - this.search.on("keydown", this.bind(function (e) { - if (!this.isInterfaceEnabled()) return; - - ++this.keydowns; - var selected = selection.find(".select2-search-choice-focus"); - var prev = selected.prev(".select2-search-choice:not(.select2-locked)"); - var next = selected.next(".select2-search-choice:not(.select2-locked)"); - var pos = getCursorInfo(this.search); - - if (selected.length && - (e.which == KEY.LEFT || e.which == KEY.RIGHT || e.which == KEY.BACKSPACE || e.which == KEY.DELETE || e.which == KEY.ENTER)) { - var selectedChoice = selected; - if (e.which == KEY.LEFT && prev.length) { - selectedChoice = prev; - } - else if (e.which == KEY.RIGHT) { - selectedChoice = next.length ? next : null; - } - else if (e.which === KEY.BACKSPACE) { - if (this.unselect(selected.first())) { - this.search.width(10); - selectedChoice = prev.length ? prev : next; - } - } else if (e.which == KEY.DELETE) { - if (this.unselect(selected.first())) { - this.search.width(10); - selectedChoice = next.length ? next : null; - } - } else if (e.which == KEY.ENTER) { - selectedChoice = null; - } - - this.selectChoice(selectedChoice); - killEvent(e); - if (!selectedChoice || !selectedChoice.length) { - this.open(); - } - return; - } else if (((e.which === KEY.BACKSPACE && this.keydowns == 1) - || e.which == KEY.LEFT) && (pos.offset == 0 && !pos.length)) { - - this.selectChoice(selection.find(".select2-search-choice:not(.select2-locked)").last()); - killEvent(e); - return; - } else { - this.selectChoice(null); - } - - if (this.opened()) { - switch (e.which) { - case KEY.UP: - case KEY.DOWN: - this.moveHighlight((e.which === KEY.UP) ? -1 : 1); - killEvent(e); - return; - case KEY.ENTER: - this.selectHighlighted(); - killEvent(e); - return; - case KEY.TAB: - this.selectHighlighted({noFocus:true}); - this.close(); - return; - case KEY.ESC: - this.cancel(e); - killEvent(e); - return; - } - } - - if (e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e) - || e.which === KEY.BACKSPACE || e.which === KEY.ESC) { - return; - } - - if (e.which === KEY.ENTER) { - if (this.opts.openOnEnter === false) { - return; - } else if (e.altKey || e.ctrlKey || e.shiftKey || e.metaKey) { - return; - } - } - - this.open(); - - if (e.which === KEY.PAGE_UP || e.which === KEY.PAGE_DOWN) { - // prevent the page from scrolling - killEvent(e); - } - - if (e.which === KEY.ENTER) { - // prevent form from being submitted - killEvent(e); - } - - })); - - this.search.on("keyup", this.bind(function (e) { - this.keydowns = 0; - this.resizeSearch(); - }) - ); - - this.search.on("blur", this.bind(function(e) { - this.container.removeClass("select2-container-active"); - this.search.removeClass("select2-focused"); - this.selectChoice(null); - if (!this.opened()) this.clearSearch(); - e.stopImmediatePropagation(); - this.opts.element.trigger($.Event("select2-blur")); - })); - - this.container.on("click", selector, this.bind(function (e) { - if (!this.isInterfaceEnabled()) return; - if ($(e.target).closest(".select2-search-choice").length > 0) { - // clicked inside a select2 search choice, do not open - return; - } - this.selectChoice(null); - this.clearPlaceholder(); - if (!this.container.hasClass("select2-container-active")) { - this.opts.element.trigger($.Event("select2-focus")); - } - this.open(); - this.focusSearch(); - e.preventDefault(); - })); - - this.container.on("focus", selector, this.bind(function () { - if (!this.isInterfaceEnabled()) return; - if (!this.container.hasClass("select2-container-active")) { - this.opts.element.trigger($.Event("select2-focus")); - } - this.container.addClass("select2-container-active"); - this.dropdown.addClass("select2-drop-active"); - this.clearPlaceholder(); - })); - - this.initContainerWidth(); - this.opts.element.addClass("select2-offscreen"); - - // set the placeholder if necessary - this.clearSearch(); - }, - - // multi - enableInterface: function() { - if (this.parent.enableInterface.apply(this, arguments)) { - this.search.prop("disabled", !this.isInterfaceEnabled()); - } - }, - - // multi - initSelection: function () { - var data; - if (this.opts.element.val() === "" && this.opts.element.text() === "") { - this.updateSelection([]); - this.close(); - // set the placeholder if necessary - this.clearSearch(); - } - if (this.select || this.opts.element.val() !== "") { - var self = this; - this.opts.initSelection.call(null, this.opts.element, function(data){ - if (data !== undefined && data !== null) { - self.updateSelection(data); - self.close(); - // set the placeholder if necessary - self.clearSearch(); - } - }); - } - }, - - // multi - clearSearch: function () { - var placeholder = this.getPlaceholder(), - maxWidth = this.getMaxSearchWidth(); - - if (placeholder !== undefined && this.getVal().length === 0 && this.search.hasClass("select2-focused") === false) { - this.search.val(placeholder).addClass("select2-default"); - // stretch the search box to full width of the container so as much of the placeholder is visible as possible - // we could call this.resizeSearch(), but we do not because that requires a sizer and we do not want to create one so early because of a firefox bug, see #944 - this.search.width(maxWidth > 0 ? maxWidth : this.container.css("width")); - } else { - this.search.val("").width(10); - } - }, - - // multi - clearPlaceholder: function () { - if (this.search.hasClass("select2-default")) { - this.search.val("").removeClass("select2-default"); - } - }, - - // multi - opening: function () { - this.clearPlaceholder(); // should be done before super so placeholder is not used to search - this.resizeSearch(); - - this.parent.opening.apply(this, arguments); - - this.focusSearch(); - - // initializes search's value with nextSearchTerm (if defined by user) - // ignore nextSearchTerm if the dropdown is opened by the user pressing a letter - if(this.search.val() === "") { - if(this.nextSearchTerm != undefined){ - this.search.val(this.nextSearchTerm); - this.search.select(); - } - } - - this.updateResults(true); - if (this.opts.shouldFocusInput(this)) { - this.search.focus(); - } - this.opts.element.trigger($.Event("select2-open")); - }, - - // multi - close: function () { - if (!this.opened()) return; - this.parent.close.apply(this, arguments); - }, - - // multi - focus: function () { - this.close(); - this.search.focus(); - }, - - // multi - isFocused: function () { - return this.search.hasClass("select2-focused"); - }, - - // multi - updateSelection: function (data) { - var ids = [], filtered = [], self = this; - - // filter out duplicates - $(data).each(function () { - if (indexOf(self.id(this), ids) < 0) { - ids.push(self.id(this)); - filtered.push(this); - } - }); - data = filtered; - - this.selection.find(".select2-search-choice").remove(); - $(data).each(function () { - self.addSelectedChoice(this); - }); - self.postprocessResults(); - }, - - // multi - tokenize: function() { - var input = this.search.val(); - input = this.opts.tokenizer.call(this, input, this.data(), this.bind(this.onSelect), this.opts); - if (input != null && input != undefined) { - this.search.val(input); - if (input.length > 0) { - this.open(); - } - } - - }, - - // multi - onSelect: function (data, options) { - - if (!this.triggerSelect(data)) { return; } - - this.addSelectedChoice(data); - - this.opts.element.trigger({ type: "selected", val: this.id(data), choice: data }); - - // keep track of the search's value before it gets cleared - this.nextSearchTerm = this.opts.nextSearchTerm(data, this.search.val()); - - this.clearSearch(); - this.updateResults(); - - if (this.select || !this.opts.closeOnSelect) this.postprocessResults(data, false, this.opts.closeOnSelect===true); - - if (this.opts.closeOnSelect) { - this.close(); - this.search.width(10); - } else { - if (this.countSelectableResults()>0) { - this.search.width(10); - this.resizeSearch(); - if (this.getMaximumSelectionSize() > 0 && this.val().length >= this.getMaximumSelectionSize()) { - // if we reached max selection size repaint the results so choices - // are replaced with the max selection reached message - this.updateResults(true); - } else { - // initializes search's value with nextSearchTerm and update search result - if(this.nextSearchTerm != undefined){ - this.search.val(this.nextSearchTerm); - this.updateResults(); - this.search.select(); - } - } - this.positionDropdown(); - } else { - // if nothing left to select close - this.close(); - this.search.width(10); - } - } - - // since its not possible to select an element that has already been - // added we do not need to check if this is a new element before firing change - this.triggerChange({ added: data }); - - if (!options || !options.noFocus) - this.focusSearch(); - }, - - // multi - cancel: function () { - this.close(); - this.focusSearch(); - }, - - addSelectedChoice: function (data) { - var enableChoice = !data.locked, - enabledItem = $( - "<li class='select2-search-choice'>" + - " <div></div>" + - " <a href='#' class='select2-search-choice-close' tabindex='-1'></a>" + - "</li>"), - disabledItem = $( - "<li class='select2-search-choice select2-locked'>" + - "<div></div>" + - "</li>"); - var choice = enableChoice ? enabledItem : disabledItem, - id = this.id(data), - val = this.getVal(), - formatted, - cssClass; - - formatted=this.opts.formatSelection(data, choice.find("div"), this.opts.escapeMarkup); - if (formatted != undefined) { - choice.find("div").replaceWith("<div>"+formatted+"</div>"); - } - cssClass=this.opts.formatSelectionCssClass(data, choice.find("div")); - if (cssClass != undefined) { - choice.addClass(cssClass); - } - - if(enableChoice){ - choice.find(".select2-search-choice-close") - .on("mousedown", killEvent) - .on("click dblclick", this.bind(function (e) { - if (!this.isInterfaceEnabled()) return; - - this.unselect($(e.target)); - this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus"); - killEvent(e); - this.close(); - this.focusSearch(); - })).on("focus", this.bind(function () { - if (!this.isInterfaceEnabled()) return; - this.container.addClass("select2-container-active"); - this.dropdown.addClass("select2-drop-active"); - })); - } - - choice.data("select2-data", data); - choice.insertBefore(this.searchContainer); - - val.push(id); - this.setVal(val); - }, - - // multi - unselect: function (selected) { - var val = this.getVal(), - data, - index; - selected = selected.closest(".select2-search-choice"); - - if (selected.length === 0) { - throw "Invalid argument: " + selected + ". Must be .select2-search-choice"; - } - - data = selected.data("select2-data"); - - if (!data) { - // prevent a race condition when the 'x' is clicked really fast repeatedly the event can be queued - // and invoked on an element already removed - return; - } - - var evt = $.Event("select2-removing"); - evt.val = this.id(data); - evt.choice = data; - this.opts.element.trigger(evt); - - if (evt.isDefaultPrevented()) { - return false; - } - - while((index = indexOf(this.id(data), val)) >= 0) { - val.splice(index, 1); - this.setVal(val); - if (this.select) this.postprocessResults(); - } - - selected.remove(); - - this.opts.element.trigger({ type: "select2-removed", val: this.id(data), choice: data }); - this.triggerChange({ removed: data }); - - return true; - }, - - // multi - postprocessResults: function (data, initial, noHighlightUpdate) { - var val = this.getVal(), - choices = this.results.find(".select2-result"), - compound = this.results.find(".select2-result-with-children"), - self = this; - - choices.each2(function (i, choice) { - var id = self.id(choice.data("select2-data")); - if (indexOf(id, val) >= 0) { - choice.addClass("select2-selected"); - // mark all children of the selected parent as selected - choice.find(".select2-result-selectable").addClass("select2-selected"); - } - }); - - compound.each2(function(i, choice) { - // hide an optgroup if it doesn't have any selectable children - if (!choice.is('.select2-result-selectable') - && choice.find(".select2-result-selectable:not(.select2-selected)").length === 0) { - choice.addClass("select2-selected"); - } - }); - - if (this.highlight() == -1 && noHighlightUpdate !== false){ - self.highlight(0); - } - - //If all results are chosen render formatNoMatches - if(!this.opts.createSearchChoice && !choices.filter('.select2-result:not(.select2-selected)').length > 0){ - if(!data || data && !data.more && this.results.find(".select2-no-results").length === 0) { - if (checkFormatter(self.opts.formatNoMatches, "formatNoMatches")) { - this.results.append("<li class='select2-no-results'>" + evaluate(self.opts.formatNoMatches, self.opts.element, self.search.val()) + "</li>"); - } - } - } - - }, - - // multi - getMaxSearchWidth: function() { - return this.selection.width() - getSideBorderPadding(this.search); - }, - - // multi - resizeSearch: function () { - var minimumWidth, left, maxWidth, containerLeft, searchWidth, - sideBorderPadding = getSideBorderPadding(this.search); - - minimumWidth = measureTextWidth(this.search) + 10; - - left = this.search.offset().left; - - maxWidth = this.selection.width(); - containerLeft = this.selection.offset().left; - - searchWidth = maxWidth - (left - containerLeft) - sideBorderPadding; - - if (searchWidth < minimumWidth) { - searchWidth = maxWidth - sideBorderPadding; - } - - if (searchWidth < 40) { - searchWidth = maxWidth - sideBorderPadding; - } - - if (searchWidth <= 0) { - searchWidth = minimumWidth; - } - - this.search.width(Math.floor(searchWidth)); - }, - - // multi - getVal: function () { - var val; - if (this.select) { - val = this.select.val(); - return val === null ? [] : val; - } else { - val = this.opts.element.val(); - return splitVal(val, this.opts.separator); - } - }, - - // multi - setVal: function (val) { - var unique; - if (this.select) { - this.select.val(val); - } else { - unique = []; - // filter out duplicates - $(val).each(function () { - if (indexOf(this, unique) < 0) unique.push(this); - }); - this.opts.element.val(unique.length === 0 ? "" : unique.join(this.opts.separator)); - } - }, - - // multi - buildChangeDetails: function (old, current) { - var current = current.slice(0), - old = old.slice(0); - - // remove intersection from each array - for (var i = 0; i < current.length; i++) { - for (var j = 0; j < old.length; j++) { - if (equal(this.opts.id(current[i]), this.opts.id(old[j]))) { - current.splice(i, 1); - if(i>0){ - i--; - } - old.splice(j, 1); - j--; - } - } - } - - return {added: current, removed: old}; - }, - - - // multi - val: function (val, triggerChange) { - var oldData, self=this; - - if (arguments.length === 0) { - return this.getVal(); - } - - oldData=this.data(); - if (!oldData.length) oldData=[]; - - // val is an id. !val is true for [undefined,null,'',0] - 0 is legal - if (!val && val !== 0) { - this.opts.element.val(""); - this.updateSelection([]); - this.clearSearch(); - if (triggerChange) { - this.triggerChange({added: this.data(), removed: oldData}); - } - return; - } - - // val is a list of ids - this.setVal(val); - - if (this.select) { - this.opts.initSelection(this.select, this.bind(this.updateSelection)); - if (triggerChange) { - this.triggerChange(this.buildChangeDetails(oldData, this.data())); - } - } else { - if (this.opts.initSelection === undefined) { - throw new Error("val() cannot be called if initSelection() is not defined"); - } - - this.opts.initSelection(this.opts.element, function(data){ - var ids=$.map(data, self.id); - self.setVal(ids); - self.updateSelection(data); - self.clearSearch(); - if (triggerChange) { - self.triggerChange(self.buildChangeDetails(oldData, self.data())); - } - }); - } - this.clearSearch(); - }, - - // multi - onSortStart: function() { - if (this.select) { - throw new Error("Sorting of elements is not supported when attached to <select>. Attach to <input type='hidden'/> instead."); - } - - // collapse search field into 0 width so its container can be collapsed as well - this.search.width(0); - // hide the container - this.searchContainer.hide(); - }, - - // multi - onSortEnd:function() { - - var val=[], self=this; - - // show search and move it to the end of the list - this.searchContainer.show(); - // make sure the search container is the last item in the list - this.searchContainer.appendTo(this.searchContainer.parent()); - // since we collapsed the width in dragStarted, we resize it here - this.resizeSearch(); - - // update selection - this.selection.find(".select2-search-choice").each(function() { - val.push(self.opts.id($(this).data("select2-data"))); - }); - this.setVal(val); - this.triggerChange(); - }, - - // multi - data: function(values, triggerChange) { - var self=this, ids, old; - if (arguments.length === 0) { - return this.selection - .children(".select2-search-choice") - .map(function() { return $(this).data("select2-data"); }) - .get(); - } else { - old = this.data(); - if (!values) { values = []; } - ids = $.map(values, function(e) { return self.opts.id(e); }); - this.setVal(ids); - this.updateSelection(values); - this.clearSearch(); - if (triggerChange) { - this.triggerChange(this.buildChangeDetails(old, this.data())); - } - } - } - }); - - $.fn.select2 = function () { - - var args = Array.prototype.slice.call(arguments, 0), - opts, - select2, - method, value, multiple, - allowedMethods = ["val", "destroy", "opened", "open", "close", "focus", "isFocused", "container", "dropdown", "onSortStart", "onSortEnd", "enable", "disable", "readonly", "positionDropdown", "data", "search"], - valueMethods = ["opened", "isFocused", "container", "dropdown"], - propertyMethods = ["val", "data"], - methodsMap = { search: "externalSearch" }; - - this.each(function () { - if (args.length === 0 || typeof(args[0]) === "object") { - opts = args.length === 0 ? {} : $.extend({}, args[0]); - opts.element = $(this); - - if (opts.element.get(0).tagName.toLowerCase() === "select") { - multiple = opts.element.prop("multiple"); - } else { - multiple = opts.multiple || false; - if ("tags" in opts) {opts.multiple = multiple = true;} - } - - select2 = multiple ? new window.Select2["class"].multi() : new window.Select2["class"].single(); - select2.init(opts); - } else if (typeof(args[0]) === "string") { - - if (indexOf(args[0], allowedMethods) < 0) { - throw "Unknown method: " + args[0]; - } - - value = undefined; - select2 = $(this).data("select2"); - if (select2 === undefined) return; - - method=args[0]; - - if (method === "container") { - value = select2.container; - } else if (method === "dropdown") { - value = select2.dropdown; - } else { - if (methodsMap[method]) method = methodsMap[method]; - - value = select2[method].apply(select2, args.slice(1)); - } - if (indexOf(args[0], valueMethods) >= 0 - || (indexOf(args[0], propertyMethods) >= 0 && args.length == 1)) { - return false; // abort the iteration, ready to return first matched value - } - } else { - throw "Invalid arguments to select2 plugin: " + args; - } - }); - return (value === undefined) ? this : value; - }; - - // plugin defaults, accessible to users - $.fn.select2.defaults = { - width: "copy", - loadMorePadding: 0, - closeOnSelect: true, - openOnEnter: true, - containerCss: {}, - dropdownCss: {}, - containerCssClass: "", - dropdownCssClass: "", - formatResult: function(result, container, query, escapeMarkup) { - var markup=[]; - markMatch(result.text, query.term, markup, escapeMarkup); - return markup.join(""); - }, - formatSelection: function (data, container, escapeMarkup) { - return data ? escapeMarkup(data.text) : undefined; - }, - sortResults: function (results, container, query) { - return results; - }, - formatResultCssClass: function(data) {return data.css;}, - formatSelectionCssClass: function(data, container) {return undefined;}, - formatMatches: function (matches) { if (matches === 1) { return "One result is available, press enter to select it."; } return matches + " results are available, use up and down arrow keys to navigate."; }, - formatNoMatches: function () { return "No matches found"; }, - formatInputTooShort: function (input, min) { var n = min - input.length; return "Please enter " + n + " or more character" + (n == 1? "" : "s"); }, - formatInputTooLong: function (input, max) { var n = input.length - max; return "Please delete " + n + " character" + (n == 1? "" : "s"); }, - formatSelectionTooBig: function (limit) { return "You can only select " + limit + " item" + (limit == 1 ? "" : "s"); }, - formatLoadMore: function (pageNumber) { return "Loading more results…"; }, - formatSearching: function () { return "Searching…"; }, - minimumResultsForSearch: 0, - minimumInputLength: 0, - maximumInputLength: null, - maximumSelectionSize: 0, - id: function (e) { return e == undefined ? null : e.id; }, - matcher: function(term, text) { - return stripDiacritics(''+text).toUpperCase().indexOf(stripDiacritics(''+term).toUpperCase()) >= 0; - }, - separator: ",", - tokenSeparators: [], - tokenizer: defaultTokenizer, - escapeMarkup: defaultEscapeMarkup, - blurOnChange: false, - selectOnBlur: false, - adaptContainerCssClass: function(c) { return c; }, - adaptDropdownCssClass: function(c) { return null; }, - nextSearchTerm: function(selectedObject, currentSearchTerm) { return undefined; }, - searchInputPlaceholder: '', - createSearchChoicePosition: 'top', - shouldFocusInput: function (instance) { - // Attempt to detect touch devices - var supportsTouchEvents = (('ontouchstart' in window) || - (navigator.msMaxTouchPoints > 0)); - - // Only devices which support touch events should be special cased - if (!supportsTouchEvents) { - return true; - } - - // Never focus the input if search is disabled - if (instance.opts.minimumResultsForSearch < 0) { - return false; - } - - return true; - } - }; - - $.fn.select2.ajaxDefaults = { - transport: $.ajax, - params: { - type: "GET", - cache: false, - dataType: "json" - } - }; - - // exports - window.Select2 = { - query: { - ajax: ajax, - local: local, - tags: tags - }, util: { - debounce: debounce, - markMatch: markMatch, - escapeMarkup: defaultEscapeMarkup, - stripDiacritics: stripDiacritics - }, "class": { - "abstract": AbstractSelect2, - "single": SingleSelect2, - "multi": MultiSelect2 - } - }; - -}(jQuery)); -(function() { - this.ScrivitoHandlebarsTemplates || (this.ScrivitoHandlebarsTemplates = {}); - this.ScrivitoHandlebarsTemplates["alert_dialog"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) { - this.compilerInfo = [3,'>= 1.0.0-rc.4']; -helpers = helpers || Handlebars.helpers; data = data || {}; - var buffer = "", stack1, options, functionType="function", escapeExpression=this.escapeExpression, helperMissing=helpers.helperMissing; - - - buffer += "<div class=\"scrivito_alert_dialog scrivito_modal_prompt scrivito_center_dialog scrivito_red\">\n <div class=\"scrivito_modal_header\">\n <i class=\"scrivito_icon\">&#xf01d;</i><h3 class=\"scrivito_title\">"; - if (stack1 = helpers.message) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.message; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + "</h3>\n </div>\n <div class=\"scrivito_modal_footer\">\n <a href=\"#\" class=\"scrivito_button scrivito_close\">"; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.translate),stack1 ? stack1.call(depth0, "ok", options) : helperMissing.call(depth0, "translate", "ok", options))) - + "</a>\n </div>\n</div>\n"; - return buffer; - }); - return this.ScrivitoHandlebarsTemplates["alert_dialog"]; -}).call(this); -(function() { - this.ScrivitoHandlebarsTemplates || (this.ScrivitoHandlebarsTemplates = {}); - this.ScrivitoHandlebarsTemplates["changes_list_dialog"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) { - this.compilerInfo = [3,'>= 1.0.0-rc.4']; -helpers = helpers || Handlebars.helpers; data = data || {}; - var buffer = "", stack1, options, helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; - - - buffer += "<div class=\"scrivito_changes_overview scrivito_modal_large scrivito_adjust_dialog\" >\n\n <div class=\"scrivito_modal_header\">\n <h3>\n <i class=\"scrivito_icon\">&#xf080;</i>\n "; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.translate),stack1 ? stack1.call(depth0, "changes_list.title", depth0.selected_workspace_title, options) : helperMissing.call(depth0, "translate", "changes_list.title", depth0.selected_workspace_title, options))) - + "\n <span id=\"scrivito_obj_count\" style=\"display:none;\">\n (<span id=\"scrivito_loaded_obj_count\"></span> / <span id=\"scrivito_total_obj_count\"></span>)\n </span>\n </h3>\n </div>\n <div class=\"scrivito_modal_body scrivito_auto_height\">\n\n <table class=\"scrivito_changes_table\">\n <thead>\n <tr>\n <th><span class=\"scrivito_sortable\" data-scrivito-private-sort-by=\"modification\">"; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.translate),stack1 ? stack1.call(depth0, "changes_list.row.change", options) : helperMissing.call(depth0, "translate", "changes_list.row.change", options))) - + "</span></th>\n <th><span class=\"scrivito_sortable\" data-scrivito-private-sort-by=\"rights\">"; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.translate),stack1 ? stack1.call(depth0, "changes_list.row.rights", options) : helperMissing.call(depth0, "translate", "changes_list.row.rights", options))) - + "</span></th>\n <th><span>"; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.translate),stack1 ? stack1.call(depth0, "changes_list.row.description_for_editor", options) : helperMissing.call(depth0, "translate", "changes_list.row.description_for_editor", options))) - + "</span></th>\n <th><span class=\"scrivito_sortable\" data-scrivito-private-sort-by=\"obj_class_name\">"; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.translate),stack1 ? stack1.call(depth0, "changes_list.row.type", options) : helperMissing.call(depth0, "translate", "changes_list.row.type", options))) - + "</span></th>\n <th><span class=\"scrivito_sortable sort_down\" data-scrivito-private-sort-by=\"last_changed\">"; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.translate),stack1 ? stack1.call(depth0, "changes_list.row.last_changed", options) : helperMissing.call(depth0, "translate", "changes_list.row.last_changed", options))) - + "</span></th>\n </tr>\n </thead>\n <tbody id=\"scrivito_changes_table_loaded\">\n </tbody>\n <tbody id=\"scrivito_changes_table_empty_result\" style=\"display:none;\">\n <tr>\n <td colspan=\"5\">\n "; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.translate),stack1 ? stack1.call(depth0, "changes_list.empty_result", options) : helperMissing.call(depth0, "translate", "changes_list.empty_result", options))) - + "\n </td>\n </tr>\n </tbody>\n <tbody id=\"scrivito_changes_table_loading\">\n <tr>\n <td colspan=\"5\">\n <i class=\"scrivito_icon scrivito_spinning\">&#xf023;</i>\n </td>\n </tr>\n </tbody>\n\n </table>\n\n <span class=\"scrivito_load_more\" style=\"display: none;\">"; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.translate),stack1 ? stack1.call(depth0, "changes_list.more", options) : helperMissing.call(depth0, "translate", "changes_list.more", options))) - + "</span>\n\n </div>\n <div class=\"scrivito_modal_footer\">\n <a class=\"scrivito_button scrivito_cancel scrivito_green\" href=\"#\">"; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.translate),stack1 ? stack1.call(depth0, "done", options) : helperMissing.call(depth0, "translate", "done", options))) - + "</a>\n </div>\n\n</div>\n"; - return buffer; - }); - return this.ScrivitoHandlebarsTemplates["changes_list_dialog"]; -}).call(this); -(function() { - this.ScrivitoHandlebarsTemplates || (this.ScrivitoHandlebarsTemplates = {}); - this.ScrivitoHandlebarsTemplates["changes_list_row"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) { - this.compilerInfo = [3,'>= 1.0.0-rc.4']; -helpers = helpers || Handlebars.helpers; data = data || {}; - var buffer = "", stack1, helperMissing=helpers.helperMissing, functionType="function", escapeExpression=this.escapeExpression, self=this; - -function program1(depth0,data) { - - - return "conflict"; - } - -function program3(depth0,data) { - - var buffer = "", stack1, stack2, options; - buffer += "\n <span class=\"scrivito_restriction\" title=\""; - options = {hash:{},data:data}; - stack2 = ((stack1 = helpers.array_to_title),stack1 ? stack1.call(depth0, depth0.restriction_messages, options) : helperMissing.call(depth0, "array_to_title", depth0.restriction_messages, options)); - if(stack2 || stack2 === 0) { buffer += stack2; } - buffer += "\"></span>\n "; - return buffer; - } - -function program5(depth0,data) { - - - return "\n <span></span>\n "; - } - -function program7(depth0,data) { - - var buffer = "", stack1, options; - buffer += "\n <span><time datetime=\""; - if (stack1 = helpers.last_changed) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.last_changed; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + "\" title=\""; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.localize_date),stack1 ? stack1.call(depth0, depth0.last_changed, options) : helperMissing.call(depth0, "localize_date", depth0.last_changed, options))) - + "\">\n "; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.localize_date_relative),stack1 ? stack1.call(depth0, depth0.last_changed, options) : helperMissing.call(depth0, "localize_date_relative", depth0.last_changed, options))) - + "\n </time></span>\n "; - return buffer; - } - - buffer += "<tr class=\"scrivito_link_to_obj\" title=\""; - if (stack1 = helpers.tooltip) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.tooltip; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + "\"\n data-scrivito-private-changes-list-obj-id=\""; - if (stack1 = helpers.id) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.id; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + "\"\n data-scrivito-private-changes-list-obj-modification=\""; - if (stack1 = helpers.modification) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.modification; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + "\"\n data-scrivito-private-changes-list-obj-is-binary=\""; - if (stack1 = helpers.is_binary) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.is_binary; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + "\">\n <td><span class=\"scrivito_changes_state "; - if (stack1 = helpers.modification) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.modification; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + " "; - stack1 = helpers['if'].call(depth0, depth0.has_conflict, {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data}); - if(stack1 || stack1 === 0) { buffer += stack1; } - buffer += "\"></span></td>\n <td>\n "; - stack1 = helpers['if'].call(depth0, depth0.has_restriction, {hash:{},inverse:self.program(5, program5, data),fn:self.program(3, program3, data),data:data}); - if(stack1 || stack1 === 0) { buffer += stack1; } - buffer += "\n </td>\n <td><span class=\"scrivito_title\">"; - if (stack1 = helpers.description_for_editor) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.description_for_editor; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + "</span>\n <td><span class=\"scrivito_obj_class\">"; - if (stack1 = helpers.obj_class_name) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.obj_class_name; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + "</span></td>\n <td>\n "; - stack1 = helpers.unless.call(depth0, depth0.is_deleted, {hash:{},inverse:self.noop,fn:self.program(7, program7, data),data:data}); - if(stack1 || stack1 === 0) { buffer += stack1; } - buffer += "\n </td>\n</tr>\n"; - return buffer; - }); - return this.ScrivitoHandlebarsTemplates["changes_list_row"]; -}).call(this); -(function() { - this.ScrivitoHandlebarsTemplates || (this.ScrivitoHandlebarsTemplates = {}); - this.ScrivitoHandlebarsTemplates["choose_obj_class_dialog"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) { - this.compilerInfo = [3,'>= 1.0.0-rc.4']; -helpers = helpers || Handlebars.helpers; data = data || {}; - var buffer = "", stack1, options, functionType="function", escapeExpression=this.escapeExpression, helperMissing=helpers.helperMissing; - - - buffer += "<div class=\"scrivito_choose_obj_class_dialog scrivito_modal_large scrivito_adjust_dialog\">\n\n <div class=\"scrivito_modal_header\">\n <h3><i class=\"scrivito_icon\">&#61498;</i>"; - if (stack1 = helpers.title) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.title; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + "</h3>\n </div>\n\n <div class=\"scrivito_modal_body scrivito_auto_height\">\n <div id=\"scrivito_replace_with_real_obj_classes\">\n <i class=\"scrivito_icon scrivito_spinning\" title=\""; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.translate),stack1 ? stack1.call(depth0, "loading", options) : helperMissing.call(depth0, "translate", "loading", options))) - + "\">&#61475;</i>\n "; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.translate),stack1 ? stack1.call(depth0, "loading", options) : helperMissing.call(depth0, "translate", "loading", options))) - + "\n </div>\n </div>\n\n <div class=\"scrivito_modal_footer\">\n <a href=\"#\" class=\"scrivito_button scrivito_cancel\">"; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.translate),stack1 ? stack1.call(depth0, "cancel", options) : helperMissing.call(depth0, "translate", "cancel", options))) - + "</a>\n </div>\n\n</div>\n"; - return buffer; - }); - return this.ScrivitoHandlebarsTemplates["choose_obj_class_dialog"]; -}).call(this); -(function() { - this.ScrivitoHandlebarsTemplates || (this.ScrivitoHandlebarsTemplates = {}); - this.ScrivitoHandlebarsTemplates["choose_obj_class_list"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) { - this.compilerInfo = [3,'>= 1.0.0-rc.4']; -helpers = helpers || Handlebars.helpers; data = data || {}; - var buffer = "", stack1, functionType="function", escapeExpression=this.escapeExpression, self=this; - -function program1(depth0,data) { - - var buffer = "", stack1; - buffer += "\n "; - stack1 = helpers['with'].call(depth0, depth0, {hash:{},inverse:self.noop,fn:self.program(2, program2, data),data:data}); - if(stack1 || stack1 === 0) { buffer += stack1; } - buffer += "\n"; - return buffer; - } -function program2(depth0,data) { - - var buffer = "", stack1; - buffer += "\n <div class=\"scrivito_obj_class_thumbnail scrivito_editing_widget_preview\" data-scrivito-private-obj-class-name=\""; - if (stack1 = helpers.name) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.name; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + "\">\n "; - if (stack1 = helpers.markup) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.markup; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - if(stack1 || stack1 === 0) { buffer += stack1; } - buffer += "\n </div>\n "; - return buffer; - } - - stack1 = helpers.each.call(depth0, depth0.obj_classes, {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data}); - if(stack1 || stack1 === 0) { buffer += stack1; } - buffer += "\n"; - return buffer; - }); - return this.ScrivitoHandlebarsTemplates["choose_obj_class_list"]; -}).call(this); -(function() { - this.ScrivitoHandlebarsTemplates || (this.ScrivitoHandlebarsTemplates = {}); - this.ScrivitoHandlebarsTemplates["confirmation_dialog"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) { - this.compilerInfo = [3,'>= 1.0.0-rc.4']; -helpers = helpers || Handlebars.helpers; data = data || {}; - var buffer = "", stack1, functionType="function", escapeExpression=this.escapeExpression, self=this; - -function program1(depth0,data) { - - var buffer = "", stack1; - buffer += "scrivito_"; - if (stack1 = helpers.color) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.color; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1); - return buffer; - } - -function program3(depth0,data) { - - var buffer = "", stack1; - buffer += "\n <p class=\"scrivito_description\">"; - if (stack1 = helpers.description) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.description; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + "</p>\n "; - return buffer; - } - - buffer += "<div class=\"scrivito_confirmation_dialog scrivito_modal_prompt scrivito_center_dialog\n "; - stack1 = helpers['if'].call(depth0, depth0.color, {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data}); - if(stack1 || stack1 === 0) { buffer += stack1; } - buffer += "\">\n <div class=\"scrivito_modal_header\">\n <i class=\"scrivito_icon\">"; - if (stack1 = helpers.icon) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.icon; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - if(stack1 || stack1 === 0) { buffer += stack1; } - buffer += "</i>\n <h3 class=\"scrivito_title\">"; - if (stack1 = helpers.title) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.title; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + "</h3>\n "; - stack1 = helpers['if'].call(depth0, depth0.description, {hash:{},inverse:self.noop,fn:self.program(3, program3, data),data:data}); - if(stack1 || stack1 === 0) { buffer += stack1; } - buffer += "\n </div>\n <div class=\"scrivito_modal_footer\">\n <a href=\"#\" class=\"scrivito_button scrivito_"; - if (stack1 = helpers.cancel_button_color) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.cancel_button_color; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + " scrivito_cancel\">\n "; - if (stack1 = helpers.cancel_button_text) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.cancel_button_text; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + "\n </a>\n <a href=\"#\" class=\"scrivito_button scrivito_"; - if (stack1 = helpers.confirm_button_color) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.confirm_button_color; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + " scrivito_confirm\">\n "; - if (stack1 = helpers.confirm_button_text) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.confirm_button_text; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + "\n </a>\n </div>\n</div>\n"; - return buffer; - }); - return this.ScrivitoHandlebarsTemplates["confirmation_dialog"]; -}).call(this); -(function() { - this.ScrivitoHandlebarsTemplates || (this.ScrivitoHandlebarsTemplates = {}); - this.ScrivitoHandlebarsTemplates["current_page_restriction"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) { - this.compilerInfo = [3,'>= 1.0.0-rc.4']; -helpers = helpers || Handlebars.helpers; data = data || {}; - var buffer = "", stack1, options, helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; - - - buffer += "<div class=\"scrivito_button_bar scrivito_right\" title=\""; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.array_to_title),stack1 ? stack1.call(depth0, depth0.restriction_messages, options) : helperMissing.call(depth0, "array_to_title", depth0.restriction_messages, options))) - + "\">\n <i class=\"scrivito_icon\">&#xf065;</i>\n</div>\n"; - return buffer; - }); - return this.ScrivitoHandlebarsTemplates["current_page_restriction"]; -}).call(this); -(function() { - this.ScrivitoHandlebarsTemplates || (this.ScrivitoHandlebarsTemplates = {}); - this.ScrivitoHandlebarsTemplates["details_dialog"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) { - this.compilerInfo = [3,'>= 1.0.0-rc.4']; -helpers = helpers || Handlebars.helpers; data = data || {}; - var buffer = "", stack1, options, functionType="function", escapeExpression=this.escapeExpression, self=this, helperMissing=helpers.helperMissing; - -function program1(depth0,data) { - - - return "\n <div class=\"scrivito_button_bar scrivito_obj_menu\"></div>\n "; - } - - buffer += "<div class=\"scrivito_details_dialog scrivito_modal_medium scrivito_adjust_dialog\">\n\n <div class=\"scrivito_modal_header\">\n <h3><i class=\"scrivito_icon\">"; - if (stack1 = helpers.icon) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.icon; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - if(stack1 || stack1 === 0) { buffer += stack1; } - buffer += "</i>"; - if (stack1 = helpers.title) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.title; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + "</h3>\n <div class=\"scrivito_details_dialog_saving_indicator\"></div>\n "; - stack1 = helpers['if'].call(depth0, depth0.obj, {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data}); - if(stack1 || stack1 === 0) { buffer += stack1; } - buffer += "\n </div>\n\n <div class=\"scrivito_modal_body scrivito_auto_height\">\n <i class=\"scrivito_icon scrivito_spinning\">&#xf023;</i>\n <div class=\"scrivito_details_dialog_markup\"></div>\n </div>\n\n <div class=\"scrivito_modal_footer\">\n <a href=\"#\" class=\"scrivito_button scrivito_cancel scrivito_green\">"; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.translate),stack1 ? stack1.call(depth0, "done", options) : helperMissing.call(depth0, "translate", "done", options))) - + "</a>\n </div>\n\n</div>\n"; - return buffer; - }); - return this.ScrivitoHandlebarsTemplates["details_dialog"]; -}).call(this); -(function() { - this.ScrivitoHandlebarsTemplates || (this.ScrivitoHandlebarsTemplates = {}); - this.ScrivitoHandlebarsTemplates["editable_workspace_dialog"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) { - this.compilerInfo = [3,'>= 1.0.0-rc.4']; -helpers = helpers || Handlebars.helpers; data = data || {}; - var buffer = "", stack1, stack2, options, helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, functionType="function", self=this; - -function program1(depth0,data) { - - var buffer = "", stack1, options; - buffer += "\n "; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.translate),stack1 ? stack1.call(depth0, "editable_ws_dialog.select_or_create", options) : helperMissing.call(depth0, "translate", "editable_ws_dialog.select_or_create", options))) - + "\n "; - return buffer; - } - -function program3(depth0,data) { - - var buffer = "", stack1, options; - buffer += "\n "; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.translate),stack1 ? stack1.call(depth0, "editable_ws_dialog.create", options) : helperMissing.call(depth0, "translate", "editable_ws_dialog.create", options))) - + "\n "; - return buffer; - } - -function program5(depth0,data) { - - var buffer = "", stack1, stack2, options; - buffer += "\n <div class=\"scrivito_input_list_of_ws\">\n <label for=\"scrivito_list_of_ws\">"; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.translate),stack1 ? stack1.call(depth0, "editable_ws_dialog.choose_existing", options) : helperMissing.call(depth0, "translate", "editable_ws_dialog.choose_existing", options))) - + "</label>\n <select id=\"scrivito_list_of_ws\">\n "; - stack2 = helpers.each.call(depth0, depth0.workspaces, {hash:{},inverse:self.noop,fn:self.program(6, program6, data),data:data}); - if(stack2 || stack2 === 0) { buffer += stack2; } - buffer += "\n </select>\n </div>\n "; - return buffer; - } -function program6(depth0,data) { - - var buffer = "", stack1, stack2; - buffer += "\n <option value=\"" - + escapeExpression(((stack1 = depth0.id),typeof stack1 === functionType ? stack1.apply(depth0) : stack1)) - + "\">\n "; - stack2 = helpers['if'].call(depth0, depth0.title, {hash:{},inverse:self.program(9, program9, data),fn:self.program(7, program7, data),data:data}); - if(stack2 || stack2 === 0) { buffer += stack2; } - buffer += "\n </option>\n "; - return buffer; - } -function program7(depth0,data) { - - var buffer = "", stack1; - buffer += "\n " - + escapeExpression(((stack1 = depth0.title),typeof stack1 === functionType ? stack1.apply(depth0) : stack1)) - + "\n "; - return buffer; - } - -function program9(depth0,data) { - - var buffer = "", stack1, options; - buffer += "\n "; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.translate),stack1 ? stack1.call(depth0, "menu_bar.empty_workspace_title", options) : helperMissing.call(depth0, "translate", "menu_bar.empty_workspace_title", options))) - + "\n "; - return buffer; - } - -function program11(depth0,data) { - - var buffer = "", stack1, options; - buffer += "\n "; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.translate),stack1 ? stack1.call(depth0, "editable_ws_dialog.or_create_new", options) : helperMissing.call(depth0, "translate", "editable_ws_dialog.or_create_new", options))) - + "\n "; - return buffer; - } - -function program13(depth0,data) { - - var buffer = "", stack1, options; - buffer += "\n "; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.translate),stack1 ? stack1.call(depth0, "editable_ws_dialog.create_new", options) : helperMissing.call(depth0, "translate", "editable_ws_dialog.create_new", options))) - + "\n "; - return buffer; - } - - buffer += "<div class=\"scrivito_editable_workspace_dialog scrivito_modal_prompt scrivito_center_dialog scrivito_green\">\n <div class=\"scrivito_modal_header\">\n <i class=\"scrivito_icon\">&#xf011;</i>\n <h3 class=\"scrivito_title\">\n "; - stack1 = helpers['if'].call(depth0, depth0.workspaces, {hash:{},inverse:self.program(3, program3, data),fn:self.program(1, program1, data),data:data}); - if(stack1 || stack1 === 0) { buffer += stack1; } - buffer += "\n </h3>\n </div>\n <div class=\"scrivito_modal_body\">\n <div>\n "; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.translate),stack1 ? stack1.call(depth0, "editable_ws_dialog.description", options) : helperMissing.call(depth0, "translate", "editable_ws_dialog.description", options))) - + "\n </div>\n <div>\n &nbsp;\n </div>\n "; - stack2 = helpers['if'].call(depth0, depth0.workspaces, {hash:{},inverse:self.noop,fn:self.program(5, program5, data),data:data}); - if(stack2 || stack2 === 0) { buffer += stack2; } - buffer += "\n <div class=\"scrivito_input_new_ws_name\">\n <label for=\"scrivito_new_ws_name\">\n "; - stack2 = helpers['if'].call(depth0, depth0.workspaces, {hash:{},inverse:self.program(13, program13, data),fn:self.program(11, program11, data),data:data}); - if(stack2 || stack2 === 0) { buffer += stack2; } - buffer += "\n </label>\n <input type=\"text\" id=\"scrivito_new_ws_name\" value=\"\"\n placeholder=\""; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.translate),stack1 ? stack1.call(depth0, "editable_ws_dialog.create_new_playholder", options) : helperMissing.call(depth0, "translate", "editable_ws_dialog.create_new_playholder", options))) - + "\">\n </div>\n </div>\n <div class=\"scrivito_modal_footer\">\n <a href=\"#\" class=\"scrivito_button scrivito_cancel\">"; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.translate),stack1 ? stack1.call(depth0, "cancel", options) : helperMissing.call(depth0, "translate", "cancel", options))) - + "</a>\n <a href=\"#\" class=\"scrivito_button scrivito_green scrivito_confirm\">"; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.translate),stack1 ? stack1.call(depth0, "confirm", options) : helperMissing.call(depth0, "translate", "confirm", options))) - + "</a>\n </div>\n</div>\n"; - return buffer; - }); - return this.ScrivitoHandlebarsTemplates["editable_workspace_dialog"]; -}).call(this); -(function() { - this.ScrivitoHandlebarsTemplates || (this.ScrivitoHandlebarsTemplates = {}); - this.ScrivitoHandlebarsTemplates["element_overlay"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) { - this.compilerInfo = [3,'>= 1.0.0-rc.4']; -helpers = helpers || Handlebars.helpers; data = data || {}; - - - - return "<div class=\"scrivito_element_overlay\"></div>\n"; - }); - return this.ScrivitoHandlebarsTemplates["element_overlay"]; -}).call(this); -(function() { - this.ScrivitoHandlebarsTemplates || (this.ScrivitoHandlebarsTemplates = {}); - this.ScrivitoHandlebarsTemplates["inplace_marker"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) { - this.compilerInfo = [3,'>= 1.0.0-rc.4']; -helpers = helpers || Handlebars.helpers; data = data || {}; - var buffer = "", stack1, functionType="function", escapeExpression=this.escapeExpression, self=this; - -function program1(depth0,data) { - - var buffer = "", stack1; - buffer += "\n <span class=\"scrivito_editing_marker_title\">"; - if (stack1 = helpers.description) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.description; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + "</span>\n "; - return buffer; - } - - buffer += "<span class=\"scrivito_editing_marker "; - if (stack1 = helpers.css_classes) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.css_classes; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + "\" title=\""; - if (stack1 = helpers.tooltip) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.tooltip; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + "\">\n <i class=\"scrivito_icon\">"; - if (stack1 = helpers.icon) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.icon; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + "</i>\n "; - stack1 = helpers['if'].call(depth0, depth0.description, {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data}); - if(stack1 || stack1 === 0) { buffer += stack1; } - buffer += "\n</span>\n"; - return buffer; - }); - return this.ScrivitoHandlebarsTemplates["inplace_marker"]; -}).call(this); -(function() { - this.ScrivitoHandlebarsTemplates || (this.ScrivitoHandlebarsTemplates = {}); - this.ScrivitoHandlebarsTemplates["menu"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) { - this.compilerInfo = [3,'>= 1.0.0-rc.4']; -helpers = helpers || Handlebars.helpers; data = data || {}; - var buffer = "", stack1, functionType="function", escapeExpression=this.escapeExpression, self=this; - -function program1(depth0,data) { - - var buffer = "", stack1; - buffer += "scrivito_"; - if (stack1 = helpers.align) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.align; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1); - return buffer; - } - -function program3(depth0,data) { - - - return "scrivito_right"; - } - -function program5(depth0,data) { - - var buffer = "", stack1, stack2; - buffer += "\n "; - stack2 = ((stack1 = depth0.render),typeof stack1 === functionType ? stack1.apply(depth0) : stack1); - if(stack2 || stack2 === 0) { buffer += stack2; } - buffer += "\n "; - return buffer; - } - - buffer += "<div class=\"scrivito_editing_marker_menu\">\n <ul class=\"scrivito_menu_box "; - stack1 = helpers['if'].call(depth0, depth0.align, {hash:{},inverse:self.program(3, program3, data),fn:self.program(1, program1, data),data:data}); - if(stack1 || stack1 === 0) { buffer += stack1; } - buffer += "\">\n "; - stack1 = helpers.each.call(depth0, depth0.menu_items, {hash:{},inverse:self.noop,fn:self.program(5, program5, data),data:data}); - if(stack1 || stack1 === 0) { buffer += stack1; } - buffer += "\n </ul>\n</div>\n"; - return buffer; - }); - return this.ScrivitoHandlebarsTemplates["menu"]; -}).call(this); -(function() { - this.ScrivitoHandlebarsTemplates || (this.ScrivitoHandlebarsTemplates = {}); - this.ScrivitoHandlebarsTemplates["menu_bar"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) { - this.compilerInfo = [3,'>= 1.0.0-rc.4']; -helpers = helpers || Handlebars.helpers; data = data || {}; - - - - return "<div class=\"scrivito_topbar\">\n <div class=\"scrivito_first_level\">\n <div id=\"scrivito_menu_bar_toggle\" class=\"scrivito_viewmodes_wrapper\"></div>\n <div class=\"scrivito_button_bar scrivito_app scrivito_no_hover\"><span class=\"scrivito_logo\"></span></div>\n <div id=\"scrivito_workspace_select\" class=\"scrivito_button_bar\"></div>\n <div id=\"scrivito_current_page_menu\" class=\"scrivito_button_bar scrivito_right\"></div>\n <div id=\"scrivito_current_page_restriction\"></div>\n <div id=\"scrivito_menu_bar_saving_indicator\"></div>\n </div>\n</div>\n"; - }); - return this.ScrivitoHandlebarsTemplates["menu_bar"]; -}).call(this); -(function() { - this.ScrivitoHandlebarsTemplates || (this.ScrivitoHandlebarsTemplates = {}); - this.ScrivitoHandlebarsTemplates["menu_bar_toggle"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) { - this.compilerInfo = [3,'>= 1.0.0-rc.4']; -helpers = helpers || Handlebars.helpers; data = data || {}; - var buffer = "", stack1, stack2, functionType="function", escapeExpression=this.escapeExpression; - - - buffer += "<div class=\"scrivito_viewmodes scrivito_viewmode_"; - if (stack1 = helpers.mode) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.mode; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + "_active\">\n <span class=\"scrivito_viewmode_pill\"></span>\n\n <div class=\"scrivito_viewmode_view\">\n <span class=\"scrivito_viewmode_icon " - + escapeExpression(((stack1 = ((stack1 = depth0.switch_to_view_mode_command),stack1 == null || stack1 === false ? stack1 : stack1.id)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1)) - + "\"></span>\n <span class=\"scrivito_viewmode_label\">" - + escapeExpression(((stack1 = ((stack1 = depth0.switch_to_view_mode_command),stack1 == null || stack1 === false ? stack1 : stack1.title)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1)) - + "</span>\n </div>\n\n <div class=\"scrivito_viewmode_editing\">\n <span class=\"scrivito_viewmode_icon " - + escapeExpression(((stack1 = ((stack1 = depth0.switch_to_editing_mode_command),stack1 == null || stack1 === false ? stack1 : stack1.id)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1)) - + "\"></span>\n <span class=\"scrivito_viewmode_label\">" - + escapeExpression(((stack1 = ((stack1 = depth0.switch_to_editing_mode_command),stack1 == null || stack1 === false ? stack1 : stack1.title)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1)) - + "</span>\n </div>\n\n <div class=\"scrivito_viewmode_"; - if (stack2 = helpers.comparing_mode) { stack2 = stack2.call(depth0, {hash:{},data:data}); } - else { stack2 = depth0.comparing_mode; stack2 = typeof stack2 === functionType ? stack2.apply(depth0) : stack2; } - buffer += escapeExpression(stack2) - + "\">\n <span class=\"scrivito_viewmode_icon " - + escapeExpression(((stack1 = ((stack1 = depth0.switch_to_comparing_mode_command),stack1 == null || stack1 === false ? stack1 : stack1.id)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1)) - + "\"></span>\n <span class=\"scrivito_viewmode_label scrivito_comparing_mode_toggle\">\n " - + escapeExpression(((stack1 = ((stack1 = depth0.switch_to_comparing_mode_command),stack1 == null || stack1 === false ? stack1 : stack1.title)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1)) - + " <i class=\"scrivito_icon\">&#xf025;</i>\n </span>\n </div>\n</div>\n"; - return buffer; - }); - return this.ScrivitoHandlebarsTemplates["menu_bar_toggle"]; -}).call(this); -(function() { - this.ScrivitoHandlebarsTemplates || (this.ScrivitoHandlebarsTemplates = {}); - this.ScrivitoHandlebarsTemplates["menu_item"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) { - this.compilerInfo = [3,'>= 1.0.0-rc.4']; -helpers = helpers || Handlebars.helpers; data = data || {}; - var buffer = "", stack1, functionType="function", escapeExpression=this.escapeExpression, self=this; - -function program1(depth0,data) { - - - return "scrivito_disabled"; - } - -function program3(depth0,data) { - - var stack1; - if (stack1 = helpers.tooltip) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.tooltip; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - return escapeExpression(stack1); - } - -function program5(depth0,data) { - - var stack1; - if (stack1 = helpers.reason_for_being_disabled) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.reason_for_being_disabled; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - return escapeExpression(stack1); - } - - buffer += "<li class=\"scrivito_menu_item scrivito_"; - if (stack1 = helpers.id) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.id; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + " "; - stack1 = helpers['if'].call(depth0, depth0.is_disabled, {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data}); - if(stack1 || stack1 === 0) { buffer += stack1; } - buffer += "\">\n <span title=\""; - stack1 = helpers['if'].call(depth0, depth0.is_enabled, {hash:{},inverse:self.program(5, program5, data),fn:self.program(3, program3, data),data:data}); - if(stack1 || stack1 === 0) { buffer += stack1; } - buffer += "\">\n <i class=\"scrivito_icon\">"; - if (stack1 = helpers.icon) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.icon; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - if(stack1 || stack1 === 0) { buffer += stack1; } - buffer += "</i>"; - if (stack1 = helpers.title) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.title; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + "\n </span>\n</li>\n"; - return buffer; - }); - return this.ScrivitoHandlebarsTemplates["menu_item"]; -}).call(this); -(function() { - this.ScrivitoHandlebarsTemplates || (this.ScrivitoHandlebarsTemplates = {}); - this.ScrivitoHandlebarsTemplates["menu_item/spinner"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) { - this.compilerInfo = [3,'>= 1.0.0-rc.4']; -helpers = helpers || Handlebars.helpers; data = data || {}; - var buffer = "", stack1, options, functionType="function", escapeExpression=this.escapeExpression, helperMissing=helpers.helperMissing; - - - buffer += "<li id=\""; - if (stack1 = helpers.id) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.id; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + "\" class=\"scrivito_menu_item\">\n <span>\n <i class=\"scrivito_icon scrivito_spinning\">&#xf023;</i>\n "; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.translate),stack1 ? stack1.call(depth0, "menu_item.spinner.loading", options) : helperMissing.call(depth0, "translate", "menu_item.spinner.loading", options))) - + "\n </span>\n</li>\n"; - return buffer; - }); - return this.ScrivitoHandlebarsTemplates["menu_item/spinner"]; -}).call(this); -(function() { - this.ScrivitoHandlebarsTemplates || (this.ScrivitoHandlebarsTemplates = {}); - this.ScrivitoHandlebarsTemplates["obj_menu"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) { - this.compilerInfo = [3,'>= 1.0.0-rc.4']; -helpers = helpers || Handlebars.helpers; data = data || {}; - var buffer = "", stack1, stack2, functionType="function", escapeExpression=this.escapeExpression, self=this; - -function program1(depth0,data) { - - - return "\n scrivito_new\n "; - } - -function program3(depth0,data) { - - - return "\n scrivito_changed\n "; - } - -function program5(depth0,data) { - - - return "\n scrivito_deleted\n "; - } - -function program7(depth0,data) { - - - return "\n scrivito_conflict\n "; - } - - buffer += "<i title=\"" - + escapeExpression(((stack1 = ((stack1 = depth0.obj),stack1 == null || stack1 === false ? stack1 : stack1.tooltip)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1)) - + "\" class=\"scrivito_icon\n "; - stack2 = helpers['if'].call(depth0, ((stack1 = depth0.obj),stack1 == null || stack1 === false ? stack1 : stack1.is_new), {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data}); - if(stack2 || stack2 === 0) { buffer += stack2; } - buffer += "\n\n "; - stack2 = helpers['if'].call(depth0, ((stack1 = depth0.obj),stack1 == null || stack1 === false ? stack1 : stack1.is_edited), {hash:{},inverse:self.noop,fn:self.program(3, program3, data),data:data}); - if(stack2 || stack2 === 0) { buffer += stack2; } - buffer += "\n\n "; - stack2 = helpers['if'].call(depth0, ((stack1 = depth0.obj),stack1 == null || stack1 === false ? stack1 : stack1.is_deleted), {hash:{},inverse:self.noop,fn:self.program(5, program5, data),data:data}); - if(stack2 || stack2 === 0) { buffer += stack2; } - buffer += "\n\n "; - stack2 = helpers['if'].call(depth0, ((stack1 = depth0.obj),stack1 == null || stack1 === false ? stack1 : stack1.has_conflict), {hash:{},inverse:self.noop,fn:self.program(7, program7, data),data:data}); - if(stack2 || stack2 === 0) { buffer += stack2; } - buffer += "\n\">&#xf087;</i>\n"; - return buffer; - }); - return this.ScrivitoHandlebarsTemplates["obj_menu"]; -}).call(this); -(function() { - this.ScrivitoHandlebarsTemplates || (this.ScrivitoHandlebarsTemplates = {}); - this.ScrivitoHandlebarsTemplates["obj_sorting_dialog"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) { - this.compilerInfo = [3,'>= 1.0.0-rc.4']; -helpers = helpers || Handlebars.helpers; data = data || {}; - var buffer = "", stack1, stack2, options, functionType="function", escapeExpression=this.escapeExpression, helperMissing=helpers.helperMissing, self=this; - -function program1(depth0,data) { - - var buffer = "", stack1; - buffer += "\n <li data-scrivito-private-obj-id="; - if (stack1 = helpers.id) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.id; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + ">"; - if (stack1 = helpers.description_for_editor) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.description_for_editor; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + "</li>\n "; - return buffer; - } - - buffer += "<div class=\"scrivito_obj_sorting_dialog scrivito_modal_large scrivito_adjust_dialog\">\n\n <div class=\"scrivito_modal_header\">\n <h3><i class=\"scrivito_icon\">"; - if (stack1 = helpers.icon) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.icon; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - if(stack1 || stack1 === 0) { buffer += stack1; } - buffer += "</i>"; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.translate),stack1 ? stack1.call(depth0, "obj_sorting_dialog.title", options) : helperMissing.call(depth0, "translate", "obj_sorting_dialog.title", options))) - + "</h3>\n </div>\n\n <div class=\"scrivito_modal_body scrivito_auto_height\">\n <ul id=\"scrivito_obj_sorting_sortable\">\n "; - stack2 = helpers.each.call(depth0, depth0.child_list, {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data}); - if(stack2 || stack2 === 0) { buffer += stack2; } - buffer += "\n </ul>\n </div>\n\n <div class=\"scrivito_modal_footer\">\n <a href=\"#\" class=\"scrivito_button scrivito_cancel\">"; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.translate),stack1 ? stack1.call(depth0, "cancel", options) : helperMissing.call(depth0, "translate", "cancel", options))) - + "</a>\n <a href=\"#\" class=\"scrivito_button scrivito_green scrivito_confirm\">"; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.translate),stack1 ? stack1.call(depth0, "confirm", options) : helperMissing.call(depth0, "translate", "confirm", options))) - + "</a>\n </div>\n\n</div>\n"; - return buffer; - }); - return this.ScrivitoHandlebarsTemplates["obj_sorting_dialog"]; -}).call(this); -(function() { - this.ScrivitoHandlebarsTemplates || (this.ScrivitoHandlebarsTemplates = {}); - this.ScrivitoHandlebarsTemplates["overlay"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) { - this.compilerInfo = [3,'>= 1.0.0-rc.4']; -helpers = helpers || Handlebars.helpers; data = data || {}; - - - - return "<div class=\"scrivito_overlay\"></div>\n"; - }); - return this.ScrivitoHandlebarsTemplates["overlay"]; -}).call(this); -(function() { - this.ScrivitoHandlebarsTemplates || (this.ScrivitoHandlebarsTemplates = {}); - this.ScrivitoHandlebarsTemplates["prompt_dialog"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) { - this.compilerInfo = [3,'>= 1.0.0-rc.4']; -helpers = helpers || Handlebars.helpers; data = data || {}; - var buffer = "", stack1, functionType="function", escapeExpression=this.escapeExpression, self=this; - -function program1(depth0,data) { - - var buffer = "", stack1; - buffer += "scrivito_"; - if (stack1 = helpers.color) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.color; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1); - return buffer; - } - -function program3(depth0,data) { - - var buffer = "", stack1; - buffer += "\n <p class=\"scrivito_description\">"; - if (stack1 = helpers.description) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.description; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + "</p>\n "; - return buffer; - } - - buffer += "<div class=\"scrivito_prompt_dialog scrivito_center_dialog scrivito_modal_prompt\n "; - stack1 = helpers['if'].call(depth0, depth0.color, {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data}); - if(stack1 || stack1 === 0) { buffer += stack1; } - buffer += "\">\n <div class=\"scrivito_modal_header\">\n <i class=\"scrivito_icon\">"; - if (stack1 = helpers.icon) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.icon; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - if(stack1 || stack1 === 0) { buffer += stack1; } - buffer += "</i>\n <h3 class=\"scrivito_title\">"; - if (stack1 = helpers.title) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.title; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + "</h3>\n "; - stack1 = helpers['if'].call(depth0, depth0.description, {hash:{},inverse:self.noop,fn:self.program(3, program3, data),data:data}); - if(stack1 || stack1 === 0) { buffer += stack1; } - buffer += "\n </div>\n <div class=\"scrivito_modal_body\">\n <input type=\"text\" value=\""; - if (stack1 = helpers.value) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.value; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + "\" placeholder=\""; - if (stack1 = helpers.placeholder) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.placeholder; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + "\"></input>\n </div>\n <div class=\"scrivito_modal_footer\">\n <a href=\"#\" class=\"scrivito_button scrivito_"; - if (stack1 = helpers.cancel_button_color) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.cancel_button_color; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + " scrivito_cancel\">\n "; - if (stack1 = helpers.cancel_button_text) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.cancel_button_text; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + "\n </a>\n <a href=\"#\" class=\"scrivito_button scrivito_"; - if (stack1 = helpers.accept_button_color) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.accept_button_color; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + " scrivito_accept\">\n "; - if (stack1 = helpers.accept_button_text) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.accept_button_text; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + "\n </a>\n </div>\n</div>\n"; - return buffer; - }); - return this.ScrivitoHandlebarsTemplates["prompt_dialog"]; -}).call(this); -(function() { - this.ScrivitoHandlebarsTemplates || (this.ScrivitoHandlebarsTemplates = {}); - this.ScrivitoHandlebarsTemplates["saving_indicator"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) { - this.compilerInfo = [3,'>= 1.0.0-rc.4']; -helpers = helpers || Handlebars.helpers; data = data || {}; - var buffer = "", stack1, options, helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; - - - buffer += "<span class=\"scrivito_saving_indicator scrivito_saving_state_bar\">\n <span class=\"scrivito_saving_in_progress\" style=\"display:none;\">\n <i class=\"scrivito_icon scrivito_spinning\">&#xf023;</i>\n <span class=\"scrivito_button_label\"><span>"; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.translate),stack1 ? stack1.call(depth0, "saving_indicator_item.saving", options) : helperMissing.call(depth0, "translate", "saving_indicator_item.saving", options))) - + "</span></span>\n </span>\n\n <span class=\"scrivito_saving_done\" style=\"display:none;\">\n <i class=\"scrivito_icon\">&#xf03F;</i>\n <span class=\"scrivito_button_label\"><span>"; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.translate),stack1 ? stack1.call(depth0, "saving_indicator_item.saved", options) : helperMissing.call(depth0, "translate", "saving_indicator_item.saved", options))) - + "</span></span>\n </span>\n</div>\n"; - return buffer; - }); - return this.ScrivitoHandlebarsTemplates["saving_indicator"]; -}).call(this); -(function() { - this.ScrivitoHandlebarsTemplates || (this.ScrivitoHandlebarsTemplates = {}); - this.ScrivitoHandlebarsTemplates["saving_overlay"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) { - this.compilerInfo = [3,'>= 1.0.0-rc.4']; -helpers = helpers || Handlebars.helpers; data = data || {}; - - - - return "<div class=\"scrivito_saving_overlay scrivito_overlay\">\n <i class=\"scrivito_icon scrivito_processing\">&#61475;</i>\n</div>\n"; - }); - return this.ScrivitoHandlebarsTemplates["saving_overlay"]; -}).call(this); -(function() { - this.ScrivitoHandlebarsTemplates || (this.ScrivitoHandlebarsTemplates = {}); - this.ScrivitoHandlebarsTemplates["title"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) { - this.compilerInfo = [3,'>= 1.0.0-rc.4']; -helpers = helpers || Handlebars.helpers; data = data || {}; - var buffer = "", stack1, functionType="function", escapeExpression=this.escapeExpression; - - - buffer += "<h1>"; - if (stack1 = helpers.title) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.title; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + "</h1>\n"; - return buffer; - }); - return this.ScrivitoHandlebarsTemplates["title"]; -}).call(this); -(function() { - this.ScrivitoHandlebarsTemplates || (this.ScrivitoHandlebarsTemplates = {}); - this.ScrivitoHandlebarsTemplates["workspace_select"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) { - this.compilerInfo = [3,'>= 1.0.0-rc.4']; -helpers = helpers || Handlebars.helpers; data = data || {}; - var buffer = "", stack1, stack2, options, helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, functionType="function", self=this; - -function program1(depth0,data) { - - var buffer = "", stack1; - buffer += "\n <i class=\"scrivito_icon\">"; - if (stack1 = helpers.icon) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.icon; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - if(stack1 || stack1 === 0) { buffer += stack1; } - buffer += "</i>\n <span class=\"scrivito_button_label\">"; - if (stack1 = helpers.title) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.title; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + "</span>\n "; - stack1 = helpers['if'].call(depth0, depth0.is_outdated, {hash:{},inverse:self.noop,fn:self.program(2, program2, data),data:data}); - if(stack1 || stack1 === 0) { buffer += stack1; } - buffer += "\n"; - return buffer; - } -function program2(depth0,data) { - - var buffer = "", stack1, options; - buffer += "\n <span class=\"scrivito_button_notice\">\n <i class=\"scrivito_icon\">&#xf021;</i>\n "; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.translate),stack1 ? stack1.call(depth0, "workspace_select.outdated", options) : helperMissing.call(depth0, "translate", "workspace_select.outdated", options))) - + "\n </span>\n "; - return buffer; - } - -function program4(depth0,data) { - - var buffer = "", stack1, stack2, options; - buffer += "\n <li class=\"scrivito_menu_separator\">\n <span>"; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.translate),stack1 ? stack1.call(depth0, "workspace_select.this_workspace", options) : helperMissing.call(depth0, "translate", "workspace_select.this_workspace", options))) - + "</span>\n </li>\n "; - stack2 = helpers.each.call(depth0, ((stack1 = depth0.commands),stack1 == null || stack1 === false ? stack1 : stack1.for_editable), {hash:{},inverse:self.noop,fn:self.program(5, program5, data),data:data}); - if(stack2 || stack2 === 0) { buffer += stack2; } - buffer += "\n <li class=\"scrivito_menu_separator\"></li>\n "; - return buffer; - } -function program5(depth0,data) { - - var buffer = "", stack1, stack2, options; - buffer += "\n "; - options = {hash:{},data:data}; - stack2 = ((stack1 = helpers.render),stack1 ? stack1.call(depth0, "workspace_select/menu_item", depth0, options) : helperMissing.call(depth0, "render", "workspace_select/menu_item", depth0, options)); - if(stack2 || stack2 === 0) { buffer += stack2; } - buffer += "\n "; - return buffer; - } - -function program7(depth0,data) { - - var buffer = "", stack1, stack2, options; - buffer += "\n <li class=\"scrivito_menu_separator\"></li>\n "; - options = {hash:{},data:data}; - stack2 = ((stack1 = helpers.render),stack1 ? stack1.call(depth0, "workspace_select/menu_item", ((stack1 = depth0.commands),stack1 == null || stack1 === false ? stack1 : stack1.select_published), options) : helperMissing.call(depth0, "render", "workspace_select/menu_item", ((stack1 = depth0.commands),stack1 == null || stack1 === false ? stack1 : stack1.select_published), options)); - if(stack2 || stack2 === 0) { buffer += stack2; } - buffer += "\n "; - return buffer; - } - - stack1 = helpers['with'].call(depth0, depth0.selected_workspace, {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data}); - if(stack1 || stack1 === 0) { buffer += stack1; } - buffer += "\n\n<ul class=\"scrivito_menu_box\" style=\"display:none\">\n "; - stack2 = helpers['if'].call(depth0, ((stack1 = depth0.selected_workspace),stack1 == null || stack1 === false ? stack1 : stack1.is_editable), {hash:{},inverse:self.noop,fn:self.program(4, program4, data),data:data}); - if(stack2 || stack2 === 0) { buffer += stack2; } - buffer += "\n\n <li class=\"scrivito_menu_separator\">\n <span>"; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.translate),stack1 ? stack1.call(depth0, "workspace_select.other_workspaces", options) : helperMissing.call(depth0, "translate", "workspace_select.other_workspaces", options))) - + "</span>\n </li>\n\n "; - options = {hash:{},data:data}; - stack2 = ((stack1 = helpers.render),stack1 ? stack1.call(depth0, "workspace_select/menu_item", ((stack1 = depth0.commands),stack1 == null || stack1 === false ? stack1 : stack1.create_workspace), options) : helperMissing.call(depth0, "render", "workspace_select/menu_item", ((stack1 = depth0.commands),stack1 == null || stack1 === false ? stack1 : stack1.create_workspace), options)); - if(stack2 || stack2 === 0) { buffer += stack2; } - buffer += "\n\n <li class=\"scrivito_menu_item scrivito_workspace_list\">\n <span>\n <i class=\"scrivito_icon scrivito_spinning\">&#xf023;</i>\n "; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.translate),stack1 ? stack1.call(depth0, "menu_bar.loading_workspaces", options) : helperMissing.call(depth0, "translate", "menu_bar.loading_workspaces", options))) - + "\n </span>\n </li>\n\n "; - stack2 = helpers.unless.call(depth0, ((stack1 = depth0.selected_workspace),stack1 == null || stack1 === false ? stack1 : stack1.is_published), {hash:{},inverse:self.noop,fn:self.program(7, program7, data),data:data}); - if(stack2 || stack2 === 0) { buffer += stack2; } - buffer += "\n</ul>\n"; - return buffer; - }); - return this.ScrivitoHandlebarsTemplates["workspace_select"]; -}).call(this); -(function() { - this.ScrivitoHandlebarsTemplates || (this.ScrivitoHandlebarsTemplates = {}); - this.ScrivitoHandlebarsTemplates["workspace_select/menu_item"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) { - this.compilerInfo = [3,'>= 1.0.0-rc.4']; -helpers = helpers || Handlebars.helpers; data = data || {}; - var buffer = "", stack1, functionType="function", escapeExpression=this.escapeExpression, self=this; - -function program1(depth0,data) { - - - return "scrivito_highlight"; - } - -function program3(depth0,data) { - - - return "scrivito_disabled"; - } - -function program5(depth0,data) { - - var stack1; - if (stack1 = helpers.tooltip) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.tooltip; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - return escapeExpression(stack1); - } - -function program7(depth0,data) { - - var stack1; - if (stack1 = helpers.reason_for_being_disabled) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.reason_for_being_disabled; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - return escapeExpression(stack1); - } - - buffer += "<li id=\"scrivito_"; - if (stack1 = helpers.id) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.id; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + "\" class=\"scrivito_menu_item\n "; - stack1 = helpers['if'].call(depth0, depth0.is_action_required, {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data}); - if(stack1 || stack1 === 0) { buffer += stack1; } - buffer += "\n "; - stack1 = helpers['if'].call(depth0, depth0.is_disabled, {hash:{},inverse:self.noop,fn:self.program(3, program3, data),data:data}); - if(stack1 || stack1 === 0) { buffer += stack1; } - buffer += "\">\n <span title=\""; - stack1 = helpers['if'].call(depth0, depth0.is_enabled, {hash:{},inverse:self.program(7, program7, data),fn:self.program(5, program5, data),data:data}); - if(stack1 || stack1 === 0) { buffer += stack1; } - buffer += "\">\n <i class=\"scrivito_icon\">"; - if (stack1 = helpers.icon) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.icon; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - if(stack1 || stack1 === 0) { buffer += stack1; } - buffer += "</i> "; - if (stack1 = helpers.title) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.title; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + "\n </span>\n</li>\n"; - return buffer; - }); - return this.ScrivitoHandlebarsTemplates["workspace_select/menu_item"]; -}).call(this); -(function() { - this.ScrivitoHandlebarsTemplates || (this.ScrivitoHandlebarsTemplates = {}); - this.ScrivitoHandlebarsTemplates["workspace_select/other_workspaces"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) { - this.compilerInfo = [3,'>= 1.0.0-rc.4']; -helpers = helpers || Handlebars.helpers; data = data || {}; - var buffer = "", stack1, stack2, helperMissing=helpers.helperMissing, self=this; - -function program1(depth0,data) { - - - return "\n <li class=\"scrivito_menu_separator\"></li>\n"; - } - -function program3(depth0,data) { - - var buffer = "", stack1, stack2, options; - buffer += "\n "; - options = {hash:{},data:data}; - stack2 = ((stack1 = helpers.render),stack1 ? stack1.call(depth0, "workspace_select/menu_item", depth0, options) : helperMissing.call(depth0, "render", "workspace_select/menu_item", depth0, options)); - if(stack2 || stack2 === 0) { buffer += stack2; } - buffer += "\n"; - return buffer; - } - - stack2 = helpers['if'].call(depth0, ((stack1 = depth0.commands),stack1 == null || stack1 === false ? stack1 : stack1.length), {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data}); - if(stack2 || stack2 === 0) { buffer += stack2; } - buffer += "\n"; - stack2 = helpers.each.call(depth0, depth0.commands, {hash:{},inverse:self.noop,fn:self.program(3, program3, data),data:data}); - if(stack2 || stack2 === 0) { buffer += stack2; } - buffer += "\n"; - return buffer; - }); - return this.ScrivitoHandlebarsTemplates["workspace_select/other_workspaces"]; -}).call(this); -(function() { - this.ScrivitoHandlebarsTemplates || (this.ScrivitoHandlebarsTemplates = {}); - this.ScrivitoHandlebarsTemplates["workspace_settings_dialog"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) { - this.compilerInfo = [3,'>= 1.0.0-rc.4']; -helpers = helpers || Handlebars.helpers; data = data || {}; - var buffer = "", stack1, stack2, options, functionType="function", escapeExpression=this.escapeExpression, helperMissing=helpers.helperMissing; - - - buffer += "<div class=\"scrivito_workspace_settings_dialog scrivito_modal_large scrivito_adjust_dialog\">\n <div class=\"scrivito_modal_header\">\n <h3><i class=\"scrivito_icon\">&#xf030;</i>"; - if (stack1 = helpers.title) { stack1 = stack1.call(depth0, {hash:{},data:data}); } - else { stack1 = depth0.title; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; } - buffer += escapeExpression(stack1) - + "</h3>\n </div>\n\n <div class=\"scrivito_modal_body scrivito_auto_height\">\n <h4><i class=\"scrivito_icon\">&#xf00a;</i>"; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.translate),stack1 ? stack1.call(depth0, "workspace_settings_dialog.owners", options) : helperMissing.call(depth0, "translate", "workspace_settings_dialog.owners", options))) - + "</h4>\n <input type=\"hidden\" class=\"scrivito_select_owners\" value=\""; - if (stack2 = helpers.owners) { stack2 = stack2.call(depth0, {hash:{},data:data}); } - else { stack2 = depth0.owners; stack2 = typeof stack2 === functionType ? stack2.apply(depth0) : stack2; } - buffer += escapeExpression(stack2) - + "\" />\n </div>\n\n <div class=\"scrivito_modal_footer\">\n <a href=\"#\" class=\"scrivito_button scrivito_cancel\">"; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.translate),stack1 ? stack1.call(depth0, "cancel", options) : helperMissing.call(depth0, "translate", "cancel", options))) - + "</a>\n <a href=\"#\" class=\"scrivito_button scrivito_green scrivito_confirm\">"; - options = {hash:{},data:data}; - buffer += escapeExpression(((stack1 = helpers.translate),stack1 ? stack1.call(depth0, "confirm", options) : helperMissing.call(depth0, "translate", "confirm", options))) - + "</a>\n </div>\n</div>\n"; - return buffer; - }); - return this.ScrivitoHandlebarsTemplates["workspace_settings_dialog"]; -}).call(this); -$.i18n().load({ - 'confirm': 'Bestätigen', - 'cancel': 'Abbrechen', - 'save': 'Speichern', - 'welcome': 'Willkommen', - 'welcome_x': 'Willkommen $1', - 'accept': 'Übernehmen', - 'close': 'Schließen', - 'done': 'Fertig', - 'loading': 'Lade...', - 'current_page': 'Aktuelle Seite', - 'ok': 'Ok', - - 'obj.tooltip.is_new': 'Diese Seite ist neu.', - 'obj.tooltip.is_edited': 'Diese Seite wurde geändert.', - 'obj.tooltip.has_conflict': 'Auf dieser Seite gab es parallele Änderungen, die mit den Änderungen in dieser Arbeitskopie zusammengeführt werden sollten.', - 'obj.tooltip.is_deleted': 'Diese Seite wurde gelöscht.', - - 'workspace.title_published': 'Veröffentlichte Inhalte', - 'workspace.empty_title': '<leerer Titel>', - - 'workspace_settings_dialog.owners': 'Besitzer', - 'workspace_settings_dialog.nothing_found': 'Nichts gefunden', - 'workspace_settings_dialog.searching': 'Suche...', - 'workspace_settings_dialog.too_short': 'Benutzer suchen...', - - 'workspace_select.outdated': 'veraltet', - 'workspace_select.this_workspace': 'Diese Arbeitskopie', - 'workspace_select.other_workspaces': 'Andere Arbeitskopien', - - 'menu_item.spinner.loading': 'Laden...', - - 'choose_obj_class_dialog.add_child_page.title': 'Seitenvorlage auswählen', - 'choose_obj_class_dialog.add_widget.title': 'Widget auswählen', - - 'editable_ws_dialog.create': 'Arbeitskopie anlegen', - 'editable_ws_dialog.select_or_create': 'Arbeitskopie auswählen oder anlegen', - 'editable_ws_dialog.description': 'Veröffentlichte Inhalte können nicht direkt bearbeitet werden. Verwenden Sie eine Arbeitskopie, um Inhalte zu ändern.', - 'editable_ws_dialog.choose_existing': 'Wählen Sie eine bestehende Arbeitskopie aus:', - 'editable_ws_dialog.create_new': 'Legen Sie eine neue Arbeitskopie an:', - 'editable_ws_dialog.or_create_new': 'Oder legen Sie eine neue an:', - 'editable_ws_dialog.create_new_playholder': 'Titel der neuen Arbeitskopie', - 'editable_ws_dialog.select': 'Auswählen', - - 'resource_dialog.title': 'Eigenschaften der Ressource "$1"', - - 'resource_dialog.commands.revert_obj.title': 'Änderungen an Ressource verwerfen', - 'resource_dialog.commands.revert_obj.rtc_workspace': 'Diese Ressource ist Teil der "rtc"-Arbeitskopie, bei der Änderungen nicht verworfen werden können.', - 'resource_dialog.commands.revert_obj.new_obj': 'Dies ist eine neue Ressource. Um die Erstellung dieser Ressource rückgängig zu machen, löschen Sie sie bitte.', - 'resource_dialog.commands.revert_obj.not_modified_obj': 'Diese Ressource wurde nicht geändert. Daher gibt es nichts zu verwerfen.', - 'resource_dialog.commands.revert_obj.dialog.title': 'Wirklich Änderungen an dieser Ressource verwerfen?', - - 'resource_dialog.commands.restore_obj.title': 'Ressource wiederherstellen', - 'resource_dialog.commands.restore_obj.rtc_workspace': 'Diese Ressource ist Teil der "rtc"-Arbeitskopie, bei der gelöschte Seiten nicht wiederhergestellt werden können.', - - 'resource_dialog.commands.mark_resolved_obj.title': 'Parallele Änderungen an der Ressource überschreiben', - 'resource_dialog.commands.mark_resolved_obj.dialog.description': 'Diese Ressource wurde in einer anderen, inzwischen veröffentlichten Arbeitskopie geändert. Bitte bestätigen Sie, dass Ihre Änderungen erhalten und die parallel durchgeführten Änderungen verworfen werden.', - - 'resource_dialog.commands.delete_obj.title': 'Ressource löschen', - 'resource_dialog.commands.delete_obj.dialog.title': 'Wirklich diese Ressource löschen?', - 'resource_dialog.commands.delete_obj.dialog.description': 'Änderungen an einer gelöschten Ressource können nicht wiederhergestellt werden.', - - 'menu_bar.loading_workspaces': 'Lade Arbeitskopien', - 'menu_bar.move': 'Verschieben', - 'menu_bar.copy': 'Kopieren', - 'menu_bar.create': 'Anlegen', - - 'saving_indicator_item.saving': 'Wird gespeichert...', - 'saving_indicator_item.saved': 'Änderungen gespeichert', - - 'widget_marker.widget_is_new': 'Widget ist neu', - 'widget_marker.widget_is_edited': 'Widget wurde geändert', - 'widget_marker.widget_is_edited_and_dragged_here': 'Widget wurde geändert und hierher gezogen', - 'widget_marker.widget_is_edited_and_dragged_away': 'Widget wurde geändert und von hier weggezogen', - 'widget_marker.widget_is_deleted': 'Widget wurde gelöscht', - 'widget_marker.widget_is_dragged_here': 'Widget wurde hierher gezogen', - 'widget_marker.widget_is_dragged_away': 'Widget wurde von hier weggezogen', - - 'child_list_menu.description': 'Elemente von $1', - - 'changes_list.title': 'Änderungen von "$1"', - 'changes_list.empty_result': 'In dieser Arbeitskopie wurde nichts geändert.', - 'changes_list.more': 'Mehr...', - 'changes_list.row.change': 'Änderung', - 'changes_list.row.rights': 'Veröffentlichen erlaubt', - 'changes_list.row.description_for_editor': 'Titel', - 'changes_list.row.type': 'Typ', - 'changes_list.row.last_changed': 'Letzte Änderung', - - 'commands.create_workspace.title': 'Arbeitskopie anlegen', - 'commands.create_workspace.dialog.title': 'Arbeitskopie anlegen', - 'commands.create_workspace.dialog.description': 'Bitte geben Sie den Titel der neuen Arbeitskopie ein.', - 'commands.create_workspace.dialog.placeholder': 'Neuer Titel', - 'commands.create_workspace.dialog.accept': 'Anlegen', - - 'commands.rename_workspace.title': 'Umbenennen', - 'commands.rename_workspace.dialog.title': '"$1" umbenennen', - 'commands.rename_workspace.dialog.description': 'Bitte geben Sie den neuen Titel der Arbeitskopie ein.', - 'commands.rename_workspace.dialog.accept': 'Umbenennen', - - 'commands.rebase_workspace.title': 'Aktualisieren', - 'commands.rebase_workspace.tooltip': 'Arbeitskopie "$1" is veraltet. Bitte aktualisieren Sie sie.', - 'commands.rebase_workspace.uptodate': 'Arbeitskopie "$1" muss nicht aktualisiert werden.', - - 'commands.delete_workspace.title': 'Löschen', - 'commands.delete_workspace.dialog.title': 'Wirklich "$1" löschen?', - 'commands.delete_workspace.dialog.description': 'Eine gelöschte Arbeitskopie kann nicht wiederhergestellt werden.', - 'commands.delete_workspace.dialog.confirm': 'Löschen', - - 'commands.workspace_settings.title': 'Einstellungen bearbeiten', - 'commands.workspace_settings.dialog.title': 'Einstellungen von "$1"', - - 'commands.workspace_changes.title': 'Änderungen anzeigen', - - 'commands.obj_details.title': 'Seiteneigenschaften', - 'commands.obj_details.dialog.title': 'Eigenschaften von "$1"', - - 'commands.save_obj_to_clipboard.title': 'Seite zum Kopieren oder Verschieben markieren', - 'commands.save_obj_to_clipboard.has_children': 'Seiten mit Unterseiten können noch nicht verschoben oder kopiert werden.', - - 'commands.delete_obj.title': 'Seite löschen', - 'commands.delete_obj.published_workspace': 'Die veröffentlichten Inhalte können nicht direkt geändert werden.', - 'commands.delete_obj.has_children': 'Seiten mit Unterseiten können noch nicht gelöscht werden.', - 'commands.delete_obj.dialog.title': 'Wirklich diese Seite löschen?', - 'commands.delete_obj.dialog.description': 'Änderungen an einer gelöschten Seite können nicht wiederhergestellt werden.', - 'commands.delete_obj.dialog.confirm': 'Löschen', - - 'commands.revert_obj.title': 'Änderungen an Seite verwerfen', - 'commands.revert_obj.published_workspace': 'Die veröffentlichten Inhalte können nicht direkt geändert werden. Daher gibt es nichts zu verwerfen.', - 'commands.revert_obj.rtc_workspace': 'Diese Seite ist Teil der "rtc"-Arbeitskopie, bei der Änderungen nicht verworfen werden können.', - 'commands.revert_obj.new_obj': 'Dies ist eine neue Seite. Um die Erstellung dieser Seite rückgängig zu machen, löschen Sie sie bitte.', - 'commands.revert_obj.not_modified_obj': 'Diese Seite wurde nicht geändert. Daher gibt es nichts zu verwerfen.', - 'commands.revert_obj.is_binary': 'Verwerfen von Änderungen ist nicht verfügbar für binäre Daten.', - 'commands.revert_obj.dialog.title': 'Wirklich Änderungen an dieser Seite verwerfen?', - 'commands.revert_obj.dialog.description': 'Verworfene Änderungen können nicht wiederhergestellt werden.', - 'commands.revert_obj.dialog.confirm': 'Verwerfen', - - 'commands.revert_widget.title': 'Änderungen am Widget verwerfen', - 'commands.revert_widget.is_new': 'Dies ist ein neues Widget. Um die Erstellung dieses Widgets rückgängig zu machen, löschen Sie es bitte.', - 'commands.revert_widget.is_not_modified': 'Dieses Widget wurde nicht geändert. Daher gibt es nichts zu verwerfen.', - 'commands.revert_widget.dialog.title': 'Wirklich Änderungen an diesem Widget verwerfen?', - 'commands.revert_widget.dialog.description': 'Verworfene Änderungen können nicht wiederhergestellt werden.', - 'commands.revert_widget.dialog.confirm': 'Verwerfen', - - 'commands.restore_obj.title': 'Seite wiederherstellen', - 'commands.restore_obj.rtc_workspace': 'Diese Seite ist Teil der "rtc"-Arbeitskopie, bei der gelöschte Seiten nicht wiederhergestellt werden können.', - - 'commands.mark_resolved_obj.title': 'Parallele Änderungen an der Seite überschreiben', - 'commands.mark_resolved_obj.dialog.title': 'Wirklich parallele Änderungen an der Seite überschreiben?', - 'commands.mark_resolved_obj.dialog.description': 'Diese Seite wurde in einer anderen, inzwischen veröffentlichten Arbeitskopie geändert. Bitte bestätigen Sie, dass Ihre Änderungen erhalten und die parallel durchgeführten Änderungen verworfen werden.', - 'commands.mark_resolved_obj.dialog.confirm': 'Änderungen überschreiben', - - 'commands.duplicate_obj.title': 'Seite duplizieren', - 'commands.duplicate_obj.published_workspace': 'Die veröffentlichten Inhalte können nicht direkt geändert werden.', - 'commands.duplicate_obj.has_children': 'Seiten mit Unterseiten können noch nicht dupliziert werden.', - - 'commands.add_subpage.title': 'Neue Seite anlegen', - 'commands.add_subpage.tooltip': 'Seite unterhalb $1 anlegen', - - 'commands.copy_page_from_clipboard.title': 'Markierte Seite hierher kopieren', - 'commands.copy_page_from_clipboard.paste_forbidden': 'Aufgrund ihres Typs kann die Seite hier nicht eingefügt werden. Nur Seiten der folgenden Typen können hierher verschoben oder kopiert werden: $1', - - 'commands.move_page_from_clipboard.title': 'Markierte Seite hierher verschieben', - 'commands.move_page_from_clipboard.paste_forbidden': 'Aufgrund ihres Typs kann die Seite hier nicht eingefügt werden. Nur Seiten der folgenden Typen können hierher verschoben oder kopiert werden: $1', - - 'commands.sort_items.title': 'Elemente sortieren', - 'commands.sort_items.tooltip': 'Reihenfolge der Elemente unterhalb $1 bearbeiten', - 'commands.sort_items.auto_sort': 'Diese Navigation wird automatisch sortiert.', - 'commands.sort_items.too_less_children': 'Die Navigation kann nicht sortiert werden, weil sie weniger als zwei Elemente enthält.', - - 'commands.add_widget.title': 'Widget einfügen', - - 'obj_sorting_dialog.title': 'Elemente sortieren', - - 'commands.widget_details.title': 'Widget-Eigenschaften', - 'commands.widget_details.no_details_view': 'Dieses Widget hat keine Eigenschaften', - 'commands.widget_details.dialog.title': 'Eigenschaften von "$1"', - - 'commands.save_widget_to_clipboard.title': 'Widget zum Kopieren markieren', - - 'commands.copy_widget_from_clipboard.title': 'Kopie des markierten Widgets anhängen', - 'commands.copy_widget_from_clipboard.paste_forbidden': 'Aufgrund ihres Typs kann das Widget hier nicht eingefügt werden. Nur Widgets der folgenden Typen können hierher verschoben oder kopiert werden: $1', - - 'commands.delete_widget.title': 'Widget löschen', - 'commands.delete_widget.dialog.title': 'Wirklich dieses Widget löschen?', - 'commands.delete_widget.dialog.description': 'Ein gelöschtes Widget kann nicht wiederhergestellt werden.', - 'commands.delete_widget.dialog.confirm': 'Löschen', - - 'commands.switch_mode.view': 'Vorschau', - 'commands.switch_mode.editing': 'Bearbeiten', - 'commands.switch_mode.diff': 'Vergleichen', - 'commands.switch_mode.added': 'Hinzugefügt', - 'commands.switch_mode.deleted': 'Gelöscht', - 'commands.switch_mode.disabled': 'Aktuell ausgewählter Anzeigemodus', - - 'commands.publish_workspace.title': 'Veröffentlichen', - 'commands.publish_workspace.permission_denied': 'Die Arbeitskopie kann aufgrund fehlender Benutzerrechte nicht veröffentlicht werden.', - 'commands.publish_workspace.dialog.confirm': 'Veröffentlichen', - 'commands.publish_workspace.dialog.title': '"$1" veröffentlichen?', - 'commands.publish_workspace.dialog.description': 'Eine Arbeitskopie zu veröffentlichen ist endgültig. Dieser Vorgang kann nicht rückgängig gemacht werden.', - 'commands.publish_workspace.error_dialog.title': 'Fehler beim Publizieren', - 'commands.publish_workspace.error_dialog.description': 'Ihre Arbeitskopie konnte nicht veröffentlicht werden. Bitte entnehmen Sie die Details der Liste der Änderungen.', - 'commands.publish_workspace.error_dialog.confirm': 'Liste der Änderungen', - 'commands.publish_workspace.alert.invalid_certificates': 'Die Arbeitskopie konnte nicht veröffentlicht werden, weil mindestens ein Benutzer gerade Inhalte darin ändert.', - - 'ajax.error': 'Die Kommunikation mit dem CMS ist aufgrund eines Fehlers fehlgeschlagen: $1', - 'ajax.error.communication': 'Die Kommunikation mit dem CMS ist fehlgeschlagen. Bitte überprüfen Sie Ihre Netzwerkverbindung.', - 'ajax.error.unknown': 'Die Kommunikation mit dem CMS ist aufgrund eines unbekannten Fehlers fehlgeschlagen.', - - 'warn_before_unloading': 'Sie haben nicht gespeicherte Änderungen! Sind Sie sicher, dass sie schließen wollen?' -}, 'de'); -$.i18n().load({ - 'confirm': 'Confirm', - 'cancel': 'Cancel', - 'save': 'Save', - 'welcome': 'Welcome', - 'welcome_x': 'Welcome $1', - 'accept': 'Accept', - 'close': 'Close', - 'done': 'Done', - 'loading': 'Loading...', - 'current_page': 'current page', - 'ok': 'Ok', - - 'obj.tooltip.is_new': 'This page is new.', - 'obj.tooltip.is_edited': 'This page has been modified.', - 'obj.tooltip.has_conflict': 'To this page concurrent changes were made that should be merged with the changes in this working copy.', - 'obj.tooltip.is_deleted': 'This page has been deleted.', - - 'workspace.title_published': 'Published content', - 'workspace.empty_title': '<empty title>', - - 'workspace_settings_dialog.owners': 'Owners', - 'workspace_settings_dialog.nothing_found': 'Nothing found', - 'workspace_settings_dialog.searching': 'Searching...', - 'workspace_settings_dialog.too_short': 'Find user...', - - 'workspace_select.outdated': 'outdated', - 'workspace_select.this_workspace': 'This working copy', - 'workspace_select.other_workspaces': 'Other working copies', - - 'menu_item.spinner.loading': 'Loading...', - - 'choose_obj_class_dialog.add_child_page.title': 'Select Page Type', - 'choose_obj_class_dialog.add_widget.title': 'Select Widget', - - 'editable_ws_dialog.create': 'Create a working copy', - 'editable_ws_dialog.select_or_create': 'Select or create a working copy', - 'editable_ws_dialog.description': 'The published content cannot be edited directly. Use a working copy to change content.', - 'editable_ws_dialog.choose_existing': 'Select an existing working copy:', - 'editable_ws_dialog.create_new': 'Create a new working copy:', - 'editable_ws_dialog.or_create_new': 'Or, create a new one:', - 'editable_ws_dialog.create_new_playholder': 'new working copy title', - 'editable_ws_dialog.select': 'Select', - - 'resource_dialog.title': 'Properties of resource "$1"', - - 'resource_dialog.commands.revert_obj.title': 'Discard changes to resource', - 'resource_dialog.commands.revert_obj.rtc_workspace': 'This resource is part of the "rtc" working copy, for which discarding changes is not supported.', - 'resource_dialog.commands.revert_obj.new_obj': 'This is a new resource. To discard the creation of this resource, please delete it.', - 'resource_dialog.commands.revert_obj.not_modified_obj': 'This resource has not been modified. Therefore, nothing can be discarded.', - 'resource_dialog.commands.revert_obj.dialog.title': 'Really discard changes to this resource?', - - 'resource_dialog.commands.restore_obj.title': 'Restore resource', - 'resource_dialog.commands.restore_obj.rtc_workspace': 'This resource is part of the "rtc" working copy, for which restoring resources is not supported.', - - 'resource_dialog.commands.mark_resolved_obj.title': 'Override concurrent changes to resource', - 'resource_dialog.commands.mark_resolved_obj.dialog.description': 'This resource was altered in a different working copy that has been published. Please confirm that you want to keep your changes and discard the ones concurrently made by others.', - - 'resource_dialog.commands.delete_obj.title': 'Delete resource', - 'resource_dialog.commands.delete_obj.dialog.title': 'Really delete this resource?', - 'resource_dialog.commands.delete_obj.dialog.description': 'Changes to a deleted resource cannot be restored.', - - 'menu_bar.loading_workspaces': 'Loading working copies', - 'menu_bar.create': 'Create', - 'menu_bar.move': 'Move', - 'menu_bar.copy': 'Copy', - - 'saving_indicator_item.saving': 'Saving...', - 'saving_indicator_item.saved': 'Changes saved', - - 'widget_marker.widget_is_new': 'Widget is new', - 'widget_marker.widget_is_edited': 'Widget has been modified', - 'widget_marker.widget_is_edited_and_dragged_here': 'Widget has been modified and dragged here', - 'widget_marker.widget_is_edited_and_dragged_away': 'Widget has been modified and dragged away from here', - 'widget_marker.widget_is_deleted': 'Widget has been deleted', - 'widget_marker.widget_is_dragged_here': 'Widget has been dragged here', - 'widget_marker.widget_is_dragged_away': 'Widget has been dragged away from here', - - 'child_list_menu.description': 'Items of $1', - - 'changes_list.title': 'Changes to "$1"', - 'changes_list.empty_result': 'Nothing was changed in this working copy.', - 'changes_list.more': 'More...', - 'changes_list.row.change': 'Change', - 'changes_list.row.rights': 'Publishing permitted', - 'changes_list.row.description_for_editor': 'Title', - 'changes_list.row.type': 'Type', - 'changes_list.row.last_changed': 'Last change', - - 'commands.create_workspace.title': 'Create working copy', - 'commands.create_workspace.dialog.title': 'Create working copy', - 'commands.create_workspace.dialog.description': 'Please enter the title of the new working copy.', - 'commands.create_workspace.dialog.placeholder': 'new title', - 'commands.create_workspace.dialog.accept': 'Create', - - 'commands.rename_workspace.title': 'Rename', - 'commands.rename_workspace.dialog.title': 'Rename "$1"', - 'commands.rename_workspace.dialog.description': 'Please enter the new title of the working copy.', - 'commands.rename_workspace.dialog.accept': 'Rename', - - 'commands.rebase_workspace.title': 'Update', - 'commands.rebase_workspace.tooltip': 'Working copy "$1" is outdated. Please update it.', - 'commands.rebase_workspace.uptodate': 'Working copy "$1" is up to date.', - - 'commands.delete_workspace.title': 'Delete', - 'commands.delete_workspace.dialog.title': 'Really delete "$1"?', - 'commands.delete_workspace.dialog.description': 'A deleted working copy cannot be restored.', - 'commands.delete_workspace.dialog.confirm': 'Delete', - - 'commands.workspace_settings.title': 'Edit settings', - 'commands.workspace_settings.dialog.title': 'Settings for "$1"', - - 'commands.workspace_changes.title': 'Show changes', - - 'commands.obj_details.title': 'Page properties', - 'commands.obj_details.dialog.title': 'Properties of "$1"', - - 'commands.save_obj_to_clipboard.title': 'Mark page for copying or moving', - 'commands.save_obj_to_clipboard.has_children': 'Pages with subpages cannot be copied or moved yet.', - - 'commands.delete_obj.title': 'Delete page', - 'commands.delete_obj.published_workspace': 'Since this is the published content, nothing can be modified.', - 'commands.delete_obj.has_children': 'Pages with subpages cannot be deleted yet.', - 'commands.delete_obj.dialog.title': 'Really delete this page?', - 'commands.delete_obj.dialog.description': 'Changes to a deleted page cannot be restored.', - 'commands.delete_obj.dialog.confirm': 'Delete', - - 'commands.revert_obj.title': 'Discard changes to page', - 'commands.revert_obj.published_workspace': 'Since this is the published content, nothing has been modified. Therefore, nothing can be discarded.', - 'commands.revert_obj.rtc_workspace': 'This page is part of the "rtc" working copy, for which discarding changes is not supported.', - 'commands.revert_obj.new_obj': 'This is a new page. To discard the creation of this page, please delete it.', - 'commands.revert_obj.is_binary': 'Discarding changes is not available for binary content.', - 'commands.revert_obj.not_modified_obj': 'This page has not been modified. Therefore, nothing can be discarded.', - 'commands.revert_obj.dialog.title': 'Really discard changes to this page?', - 'commands.revert_obj.dialog.description': 'Discarded changes cannot be restored.', - 'commands.revert_obj.dialog.confirm': 'Discard', - - 'commands.revert_widget.title': 'Discard changes to widget', - 'commands.revert_widget.is_new': 'This is a new widget. To discard the creation of this widget, please delete it.', - 'commands.revert_widget.is_not_modified': 'This widget has not been modified. Therefore, nothing can be discarded.', - 'commands.revert_widget.dialog.title': 'Really discard changes to this widget?', - 'commands.revert_widget.dialog.description': 'Discarded changes cannot be restored.', - 'commands.revert_widget.dialog.confirm': 'Discard', - - 'commands.restore_obj.title': 'Restore page', - 'commands.restore_obj.rtc_workspace': 'This page is part of the "rtc" working copy, for which restoring pages is not supported.', - - 'commands.mark_resolved_obj.title': 'Override concurrent changes to page', - 'commands.mark_resolved_obj.dialog.confirm': 'Override changes', - 'commands.mark_resolved_obj.dialog.title': 'Really override changes made by others in the meantime?', - 'commands.mark_resolved_obj.dialog.description': 'This page was altered in a different working copy that has been published. Please confirm that you want to keep your changes and discard the ones concurrently made by others.', - - 'commands.duplicate_obj.title': 'Duplicate page', - 'commands.duplicate_obj.published_workspace': 'Since this is the published content, nothing can be modified.', - 'commands.duplicate_obj.has_children': 'Pages with subpages cannot be duplicated yet.', - - 'commands.add_subpage.title': 'Create new page', - 'commands.add_subpage.tooltip': 'Create page underneath $1', - - 'commands.copy_page_from_clipboard.title': 'Copy marked page here', - 'commands.copy_page_from_clipboard.paste_forbidden': 'Due to its type, the page cannot be moved or copied here. Only pages of the following types can be inserted here: $1', - - 'commands.move_page_from_clipboard.title': 'Move marked page here', - 'commands.move_page_from_clipboard.paste_forbidden': 'Due to its type, the page cannot be moved or copied here. Only pages of the following types can be inserted here: $1', - - 'commands.sort_items.title': 'Sort items', - 'commands.sort_items.tooltip': 'Edit order of items underneath $1', - 'commands.sort_items.auto_sort': 'This navigation is sorted automatically.', - 'commands.sort_items.too_less_children': 'This navigation cannot be sorted because it consists of less than two items.', - - 'obj_sorting_dialog.title': 'Sort items', - - 'commands.add_widget.title': 'Insert widget', - - 'commands.widget_details.title': 'Widget properties', - 'commands.widget_details.no_details_view': 'This widget has no properties', - 'commands.widget_details.dialog.title': 'Properties of "$1"', - - 'commands.save_widget_to_clipboard.title': 'Mark widget for copying', - - 'commands.copy_widget_from_clipboard.title': 'Append copy of marked widget', - 'commands.copy_widget_from_clipboard.paste_forbidden': 'Due to its type, the widget cannot be moved or copied here. Only widgets of the following types can be inserted here: $1', - - 'commands.delete_widget.title': 'Delete widget', - 'commands.delete_widget.dialog.title': 'Really delete this widget?', - 'commands.delete_widget.dialog.description': 'A deleted widget cannot be restored.', - 'commands.delete_widget.dialog.confirm': 'Delete', - - 'commands.switch_mode.view': 'Preview', - 'commands.switch_mode.editing': 'Edit', - 'commands.switch_mode.diff': 'All changes', - 'commands.switch_mode.added': 'Additions', - 'commands.switch_mode.deleted': 'Deletions', - 'commands.switch_mode.disabled': 'Currently selected display mode', - - 'commands.publish_workspace.title': 'Publish', - 'commands.publish_workspace.permission_denied': 'The working copy can not be published due to missing user permissions.', - 'commands.publish_workspace.dialog.confirm': 'Publish', - 'commands.publish_workspace.dialog.title': 'Publish "$1"?', - 'commands.publish_workspace.dialog.description': 'Publishing a working copy is final. This action cannot be undone.', - 'commands.publish_workspace.error_dialog.title': 'Error while publishing', - 'commands.publish_workspace.error_dialog.description': 'Your working copy could not be published. Please check the changes list for details.', - 'commands.publish_workspace.error_dialog.confirm': 'Open Changes List', - 'commands.publish_workspace.alert.invalid_certificates': 'The working copy could not be published because at least one user is currently modifying content in it.', - - 'ajax.error': 'Communication with the CMS failed with error: $1', - 'ajax.error.communication': 'Communication with the CMS failed. Please check your network connectivity.', - 'ajax.error.unknown': 'Communication with the CMS failed for unknown reasons.', - - 'warn_before_unloading': 'You have unsaved changes. Are you sure you want to quit?', - - 'test.two_arguments': '$1, $2', - 'test.four_arguments': '$1, $2, $3, $4' -}, 'en'); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// - -// - - - -// - - - -// - - - - - - - - - - -// - - -/*global alert:false */ - - -var scrivito = {}; - -(function() { - var wait_until_write_ends = function() { - var deferred = $.Deferred(); - if (scrivito.write_monitor.is_writing()) { - scrivito.write_monitor.on('end_write', function() { - wait_until_write_ends().done(function() { - deferred.resolve(); - }); - }); - } else { - deferred.resolve(); - } - return deferred; - }; - - var convert_internal_error = function(error) { - // message is the only field of an error that is public API - return {message: error.message}; - }; - - $.extend(scrivito, { - suppress_alerts: false, - - alert: function(message) { - if (!scrivito.suppress_alerts) { - window.alert(message); - } - }, - - log_error: function(message, exception) { - if (window.console) { - window.console.error(message, exception); - } - }, - - change_location: function(location) { - // this is a proxy method, so we can stub it easier. - window.location = location; - }, - - redirect_to: function(location) { - wait_until_write_ends().done(function() { - scrivito.change_location(location); - }); - - // it returns an never resolved or rejected deferred. - return $.Deferred(); - }, - - wait: function(seconds) { - // this is a proxy method, so we can stub it easier. - return $.Deferred(function(dfd) { - setTimeout(dfd.resolve, seconds * 1000); - }); - }, - - run_new_event: function(method) { - scrivito.wait(0).done(method); - }, - - // For testing purpose only. - reload_location: function() { - window.location.reload(); - }, - - reload: function() { - wait_until_write_ends().done(function() { - scrivito.reload_location(); - }); - - return $.Deferred(); - }, - - center: function(elem) { - if (elem.length === 1) { - elem.css({ - marginLeft: -elem.innerWidth() / 2, - marginTop: -elem.innerHeight() / 2, - left: '50%' - }); - } - }, - - ensure_fully_visible_within: function(dom_element, viewport_container, viewport_height) { - var viewport_offset = viewport_container.scrollTop(); - var dom_element_offset = dom_element.offset().top; - var dom_element_height = dom_element.height(); - - var scroll_top; - if (viewport_offset > dom_element_offset) { - scroll_top = dom_element_offset - 50; - } else if (dom_element_offset + dom_element_height > viewport_offset + viewport_height) { - scroll_top = dom_element_height + dom_element_offset + 50 - viewport_height; - } - - if (scroll_top) { - viewport_container.animate({scrollTop: scroll_top}); - } - }, - - ensure_fully_visible_within_window: function(dom_element) { - scrivito.ensure_fully_visible_within(dom_element, $('body'), $(window).height()); - }, - - describe_element: function(elem) { - var description = elem.get(0).nodeName; - if (elem.attr("id")) { description += "#"+elem.attr("id"); } - var css_class = elem.attr('class'); - if (css_class) { - _(css_class.split(" ")).each(function(class_name) { - description += "."+class_name; - }); - } - return "["+description+"]"; - }, - - remove_enter_and_escape_action: function() { - $(document).off('keyup.scrivito_enter_escape_action'); - }, - - random_hex: function() { - var hex = Math.floor(Math.random() * Math.pow(16, 8)).toString(16); - while (hex.length < 8) { - hex = '0' + hex; - } - return hex; - }, - - // 16 chars hex string - random_id: function() { - return scrivito.random_hex() + scrivito.random_hex(); - }, - - deprecation_warning: function(subject, alternative) { - var message = 'DEPRECATION WARNING: "' + subject + '" is deprecated.'; - - if (alternative) { - message += ' Please use "' + alternative + '" instead.'; - } - - if (window.console) { - window.console.warn(message); - } - }, - - // @api public - on: function(event, callback) { - if (event === 'load') { - scrivito.gui.on('open', function() { - callback(); - }); - - if (scrivito.gui.is_started()) { - scrivito.run_new_event(function() { - callback(); - }); - } - } else if (event === 'content') { - scrivito.on('load', function() { - callback(window.document); - }); - - scrivito.gui.on('content', function(dom_element) { - callback(dom_element); - }); - } else { - $.error('Unknown event "' + event + '"'); - } - }, - - // @api public - create_obj: function(attributes) { - return scrivito.obj.create(attributes).then(function(obj) { - return {id: obj.id()}; - }, convert_internal_error); - }, - - // @api public - delete_obj: function(id) { - if (id) { - return scrivito.obj.create_instance({id: id}).destroy() - .then(null, convert_internal_error); - } else { - $.error("Can't delete without ID"); - } - }, - - // @api public - is_current_page_restricted: function() { - return !!scrivito.obj.current_page && scrivito.obj.current_page.has_restriction(); - }, - - never_resolve: function() { - return $.Deferred(); - }, - - // @api public - trigger: function(event_name, dom_element) { - if (event_name === 'content') { - _.each($(dom_element), function(e) { - scrivito.gui.new_content(e); - }); - } else if (event_name === 'new_content') { - scrivito.deprecation_warning( - 'scrivito.trigger("new_content")', 'scrivito.trigger("content")'); - scrivito.trigger('content', dom_element); - } else { - $.error('Unknown event "' + event_name + '"'); - } - }, - - // @api public - in_editable_view: function() { - return scrivito.editing_context.display_mode === 'editing' && - scrivito.editing_context.visible_workspace.is_editable(); - }, - - open_resource_dialog: function(obj_id) { - return scrivito.resource_dialog.open(obj_id); - }, - - // See http://underscorejs.org/#throttle - throttle: function(fn, ms) { - return scrivito.bypass_throttle ? fn : _.throttle(fn, ms); - }, - - json_parse_base64: function(base64_string) { - // See http://mzl.la/1p1zI9k. - var dom_string = decodeURIComponent(window.escape(atob(base64_string))); - return JSON.parse(dom_string); - }, - - json_stringify_base64: function(object) { - var dom_string = JSON.stringify(object); - // See http://mzl.la/1p1zI9k. - return btoa(window.unescape(encodeURIComponent(dom_string))); - }, - - t: function() { - return scrivito.i18n.translate.apply(null, arguments); - }, - - init: function(config) { - scrivito.config = config; - - scrivito.editing_context.init(config.editing_context); - scrivito.i18n.init(config.i18n); - scrivito.obj.init(config.obj); - scrivito.resource_dialog.init(config.resource_dialog); - scrivito.user.init(config.user); - scrivito.user_permissions.init(config.user_permissions); - - scrivito.inplace_marker.init(); - scrivito.menu_bar_saving_indicator.init(); - scrivito.menu_bar_toggle.init(); - scrivito.current_page_menu.init(); - scrivito.current_page_restriction.init(); - scrivito.workspace_select.init(); - scrivito.menu_bar.init(); - - scrivito.child_list_commands.init(); - scrivito.widget_commands.init(); - scrivito.widget_field_commands.init(); - - scrivito.child_list_marker.init(); - scrivito.widget_field_marker.init(); - scrivito.widget_marker.init(); - - scrivito.widget_reloading.init(); - scrivito.widget_sorting.init(); - scrivito.reloading.init(); - - window.onbeforeunload = scrivito.warn_before_unloading; - } - }); -}()); -(function() { - var valid_locale = ['en', 'de']; - var language; - - $.extend(scrivito, { - i18n: { - init: function(config) { - scrivito.i18n.set_locale(config.locale); - }, - - locale: function() { - return language; - }, - - set_locale: function(locale) { - if($.inArray(locale, valid_locale) !== -1) { - language = locale; - } else { - language = 'en'; - } - moment.lang(language); - }, - - // In addition to the key you can pass multiple parameters that will be interpolated into - // the translated string. - translate: function(key) { - if (!scrivito.i18n.locale()) { - $.error('scrivito.i18n locale not yet set!'); - } - - $.i18n().locale = scrivito.i18n.locale(); - - return $.i18n.apply(0, arguments); - }, - - // localize_date localizes an ISO6801 date string according to the current locale. - localize_date: function(date_string) { - return moment(date_string).format('LLLL'); - }, - - // localize_date_relative converts an ISO6801 date string to a relative time and localizes it - // according to the current locale. - localize_date_relative: function(date_string) { - return moment(date_string).fromNow(); - }, - - // Test purpose only. - reset_locale: function() { - language = undefined; - } - } - }); -}()); -(function() { - var assert_valid_dom_element = function(dom_element) { - if (dom_element.length < 1) { - $.error('Can not call "scrivito" method on an empty element'); - } - if (dom_element.length > 1) { - $.error('Can not call "scrivito" method on more than one tag'); - } - }; - - var build_cms_element = function(dom_element) { - return scrivito.cms_element.from_dom_element(dom_element); - }; - - var save_content = function(dom_element, content) { - if (dom_element.length > 0) { - if (dom_element.length === 1) { - if (content === undefined) { - $.error('Can not call "save" with no content'); - } else { - var cms_element = build_cms_element(dom_element); - return cms_element.save(content).then(function() { - cms_element.set_original_content(content); - }, function(error) { - return { message: error.message }; - }); - } - } else { - $.error('Can not call "scrivito" method on more than one tag'); - } - } - }; - - var get_original_content = function(dom_element) { - assert_valid_dom_element(dom_element); - return build_cms_element(dom_element).original_content(); - }; - - var get_menu = function(dom_element) { - assert_valid_dom_element(dom_element); - var cms_element = build_cms_element(dom_element); - return { - add: function(command_options) { - var menu = cms_element.menu(); - menu.push(scrivito.command.create_instance(command_options)); - cms_element.set_menu(menu); - } - }; - }; - - $.extend(scrivito, { - // @api public - jquery_plugin: function(method, content) { - switch (method) { - case 'save': - return save_content($(this), content); - case 'content': - return get_original_content($(this)); - case 'menu': - return get_menu($(this)); - default: - $.error('Unknown method "' + method + '"'); - } - } - }); - - $.fn.scrivito = scrivito.jquery_plugin; - -}()); -(function() { - var callbacks = {}; - - // The callback has to be function that takes no arguments - var log_exception_in_callback = function(event_name, callback) { - if (scrivito.gui.sandbox_callbacks) { - try { - callback(); - } catch(exception) { - var text = "'"+event_name+"' callback threw exception: "; - scrivito.log_error(text, exception); - } - } else { - callback(); - } - }; - - var run_open_callbacks = function() { - if (callbacks.open) { - _.each(callbacks.open, function(callback) { - log_exception_in_callback('open', callback); - }); - } - - if (scrivito.editing_context.is_editing_mode() && callbacks.editing) { - _.each(callbacks.editing, function(callback) { - log_exception_in_callback('editing', callback); - }); - } - }; - - var run_new_content_callbacks = function(dom_element) { - if (scrivito.editing_context.is_editing_mode() && callbacks.new_content) { - _.each(callbacks.new_content, function(callback) { - if (dom_element) { - log_exception_in_callback('new_content', function() { - callback(dom_element); - }); - } - }); - } - - if (callbacks.content) { - _.each(callbacks.content, function(callback) { - if (dom_element) { - log_exception_in_callback('content', function() { - callback(dom_element); - }); - } - }); - } - }; - - var assert_no_turbolinks = function() { - if (window.Turbolinks) { - scrivito.alert_dialog( - 'You have Turbolinks enabled. ' + - 'Scrivito does not yet support Turbolink. ' + - 'Please remove it from your assets.' - ); - } - }; - - $.extend(scrivito, { - gui: { - start: function() { - $('body').attr('data-scrivito-display-mode', scrivito.editing_context.display_mode); - $('body').append('<div id="scrivito_editing"></div>'); - run_open_callbacks(); - assert_no_turbolinks(); - }, - - new_content: function(dom_element) { - run_new_content_callbacks(dom_element); - }, - + if (!window.scrivito) { + window.scrivito = { on: function(event_name, callback) { - if (callbacks[event_name] === undefined) { - callbacks[event_name] = []; - } - - callbacks[event_name].push(callback); - }, - - // For testing purpose only. - reset_callbacks: function() { - callbacks = {}; - }, - - // For testing purpose only. - sandbox_callbacks: true, - - is_started: function() { - return !!$('body').attr('data-scrivito-display-mode'); - } - } - }); -}()); -(function() { - $.extend(scrivito, { - editing_context: { - display_mode: null, - selected_workspace: null, - visible_workspace: null, - - init: function(config) { - scrivito.editing_context.display_mode = config.display_mode; - - var visible_workspace = scrivito.workspace.from_data(config.visible_workspace); - var selected_workspace = scrivito.workspace.from_data(config.selected_workspace); - scrivito.editing_context.visible_workspace = visible_workspace; - scrivito.editing_context.selected_workspace = selected_workspace; - - $.ajaxPrefilter(scrivito.editing_context.ajax_prefilter); - - if (scrivito.mock_always_focus_during_integration_test || document.hasFocus()) { - scrivito.editing_context.write_cookie(); - } - - // This can not be unit tested, since it is not possible to trigger a 'focus' - // event on a 'window' object with JavaScript. - $(window).focus(function() { - scrivito.editing_context.write_cookie(); - }); - }, - - is_view_mode: function() { - return scrivito.editing_context.display_mode === 'view'; - }, - - is_editing_mode: function() { - return scrivito.editing_context.display_mode === 'editing'; - }, - - is_added_mode: function() { - return scrivito.editing_context.display_mode === 'added'; - }, - - is_deleted_mode: function() { - return scrivito.editing_context.display_mode === 'deleted'; - }, - - is_diff_mode: function() { - return scrivito.editing_context.display_mode === 'diff'; - }, - - is_comparing_mode: function() { - return scrivito.editing_context.is_added_mode() || - scrivito.editing_context.is_deleted_mode() || scrivito.editing_context.is_diff_mode(); - }, - - ajax_prefilter: function(options, originalOptions, xhr) { - if (!options.crossDomain) { - xhr.setRequestHeader('Scrivito-Editing-Context', serialize()); - } - }, - - write_cookie: function() { - $.cookie('scrivito_editing_context', serialize(), {path: '/'}); - }, - - comparing_mode: function() { - var storage_key = 'editing_context.comparing_mode'; - if (scrivito.editing_context.is_comparing_mode()) { - var mode = scrivito.editing_context.display_mode; - scrivito.storage.set(storage_key, mode); - return mode; - } else { - if (scrivito.storage.has_key(storage_key)) { - return scrivito.storage.get(storage_key); - } else { - return 'diff'; - } - } - } - } - }); - - var serialize = function() { - return JSON.stringify({ - display_mode: scrivito.editing_context.display_mode, - workspace_id: scrivito.editing_context.selected_workspace.id() - }); - }; -}()); -(function() { - $.extend(scrivito, { - user_permissions: { - permissions_hash: {}, - - init: function(permissions_hash) { - scrivito.user_permissions.permissions_hash = permissions_hash; - }, - - can: function(permission_key) { - return !!scrivito.user_permissions.permissions_hash[permission_key]; - } - } - }); -}()); -(function() { - var handle_task = function(task) { - switch (task.status) { - case 'success': - return $.Deferred().resolve(task.result); - case 'error': - return $.Deferred().reject({ - message: task.message, - code: task.code - }); - case 'open': - return scrivito.wait(2).then(function() { - return single_ajax('GET', 'tasks/' + task.id).then(function(data) { - return handle_task(data); + if (event_name === 'content') { + $(function() { + callback(window.document); }); - }); - default: - throw { message: "Invalid task (unknown status)", task: task }; - } - }; - - var single_ajax = function(type, path, options) { - var base_url = window.location.protocol + '//' + window.location.host + '/__scrivito/'; - if (options && options.data) { - options.data = JSON.stringify(options.data); - } - return $.ajax(base_url + path, $.extend({ - type: type, - dataType: 'json', - contentType: 'application/json; charset=utf-8', - cache: false // Don't cache GET requests. - }, options || {})).then( - function(result, text_status, xhr) { - return $.Deferred().resolve(result); - }, function(xhr, text_status, error) { - var error_message; - var error_code; - try { - var error_json = JSON.parse(xhr.responseText); - error_message = error_json.error; - error_code = error_json.code; - } catch (SyntaxError) {} - - if (!error_message) { - error_message = error; } - return $.Deferred().reject({ - status: xhr.status, - message: error_message, - code: error_code - }); - } - ); - }; - - $.extend(scrivito, { - silent_ajax: function(type, path, options) { - var is_write_request = type === 'PUT' || type === 'POST' || type === 'DELETE'; - if (is_write_request) { - options = options || {}; - options.timeout = 15000; // miliseconds - scrivito.write_monitor.start_write(); - } - - var ajax_promise = single_ajax(type, path, options).then(function(result) { - if (result && result.task && _.size(result) === 1) { - return handle_task(result.task); - } else { - return $.Deferred().resolve(result); - } - }); - - if (is_write_request) { - ajax_promise.always(function() { - scrivito.write_monitor.end_write(); - }); - } - - return ajax_promise; - }, - - ajax: function(type, path, options) { - return scrivito.silent_ajax(type, path, options).fail(function(error) { - scrivito.display_ajax_error(error); - }); - }, - - display_ajax_error: function(error) { - var error_message = error.message; - if (_.contains(['abort', 'parsererror', 'timeout'], error_message)) { - scrivito.alert_dialog(scrivito.t('ajax.error.communication')); - } else if (error_message === 'error') { - scrivito.alert_dialog(scrivito.t('ajax.error.unknown')); - } else if (error_message) { - scrivito.alert_dialog(scrivito.t('ajax.error', error_message)); - } else { - scrivito.alert_dialog(scrivito.t('ajax.error.unknown')); - } - } - }); -}()); -(function() { - $.extend(scrivito, { - command: { - create_instance: function(params) { - var that = { - id: function() { - return params.id; - }, - - title: function() { - return params.title; - }, - - icon: function() { - return params.icon; - }, - - tooltip: function() { - return params.tooltip; - }, - - is_present: function() { - var is_present = params.present; - switch (typeof is_present) { - case 'undefined': - return true; - case 'function': - return !!is_present(); - default: - return !!is_present; - } - }, - - is_enabled: function() { - return !that.is_disabled(); - }, - - is_disabled: function() { - return !!that.reason_for_being_disabled(); - }, - - is_action_required: function() { - var is_action_required = params.action_required; - return typeof is_action_required === 'function' && is_action_required(); - }, - - reason_for_being_disabled: function() { - var reason_for_being_disabled = params.disabled; - if (typeof reason_for_being_disabled === 'function') { - return reason_for_being_disabled(); - } - }, - - update: function() { - if (that.needs_update()) { - return params.update(); - } - }, - - needs_update: function() { - return !!params.update; - }, - - execute: function() { - if (that.is_present() && that.is_enabled()) { - params.execute(); - return true; - } - return false; - } - }; - - return that; - } - } - }); -}()); -(function() { - $.extend(scrivito, { - menu_item: { - create_instance: function(command) { - var render_menu_item = function() { - return scrivito.template.render('menu_item', command); - }; - - return { - render: function() { - if (command.is_present()) { - var view; - if (command.needs_update()) { - var id = _.uniqueId('scrivito_' + command.id()); - view = scrivito.template.render('menu_item/spinner', {id: id}); - command.update().then(function() { - $('#' + id).replaceWith(render_menu_item()); - }); - } else { - view = render_menu_item(); - } - return view; - } - } - }; - } - } - }); -}()); -(function() { - var callbacks = {}; - var current_token = 0; - var counter = 0; - - var run_callbacks = function(event_name) { - _.each(callbacks[event_name], function(callback) { - callback(); - }); - }; - - $.extend(scrivito, { - write_monitor: { - on: function(event_name, callback) { - if (callbacks[event_name] === undefined) { - callbacks[event_name] = {}; - } - current_token += 1; - callbacks[event_name][current_token] = callback; - return current_token; }, - off: function(token) { - _.each(callbacks, function(event_callbacks) { - delete event_callbacks[token]; - }); - }, - - is_writing: function() { - return counter > 0; - }, - - start_write: function() { - if (!scrivito.write_monitor.is_writing()) { - run_callbacks('start_write'); - } - counter += 1; - }, - - end_write: function() { - counter -= 1; - if (!scrivito.write_monitor.is_writing()) { - scrivito.run_new_event(function() { - if (!scrivito.write_monitor.is_writing()) { - run_callbacks('end_write'); - } - }); - } - }, - - track_changes: function(fn, on_change_callback) { - var has_changes = false; - var changes_finished = false; - - var start_token = scrivito.write_monitor.on('start_write', function() { - has_changes = true; - changes_finished = false; - }); - var end_token = scrivito.write_monitor.on('end_write', function() { - changes_finished = true; - }); - - return fn().done(function() { - scrivito.write_monitor.off(start_token); - scrivito.write_monitor.off(end_token); - if (has_changes) { - if (changes_finished) { - on_change_callback(); - } else { - var saving_promise = $.Deferred(); - var final_end_token = scrivito.write_monitor.on('end_write', function() { - scrivito.write_monitor.off(final_end_token); - saving_promise.resolve(); - on_change_callback(); - }); - scrivito.with_saving_overlay(saving_promise); - } - } - }); - }, - - // For test purpose only. - reset_callbacks: function() { - callbacks = {}; - current_token = 0; - }, - - // For test purpose only. - reset_counter: function() { - counter = 0; - } - } - }); -}()); -(function() { - var menu_bar_items_renderer = []; - - var add_menu_bar = function() { - var body = $('body'); - body.addClass('scrivito_editing_active'); - - var view = $(scrivito.template.render('menu_bar')); - - _.each(menu_bar_items_renderer, function(item_renderer) { - item_renderer(view); - }); - - body.append(view); - }; - - $.extend(scrivito, { - menu_bar: { - register_item_renderer: function(item_renderer) { - menu_bar_items_renderer.push(item_renderer); - }, - - init: function() { - scrivito.gui.on('open', function() { - add_menu_bar(); - }); - }, - - // For test purpose only. - remove: function() { - $('.scrivito_topbar').remove(); - $('body').removeClass('scrivito_editing_active'); - }, - - // For test purpose only. - reset_items_renderer: function() { - menu_bar_items_renderer = []; - } - } - }); -}()); -(function() { - $.extend(scrivito, { - menu_bar_saving_indicator: { - init: function() { - scrivito.menu_bar.register_item_renderer(function(parent_view) { - scrivito.saving_indicator.create(parent_view.find('#scrivito_menu_bar_saving_indicator')); - }); - } - } - }); -}()); -(function() { - $.extend(scrivito, { - menu_bar_toggle: { - init: function() { - scrivito.menu_bar.register_item_renderer(function(menu_bar) { - var comparing_mode = scrivito.editing_context.comparing_mode(); - var switch_to_view_mode_command = scrivito.switch_mode_command('view'); - var switch_to_editing_mode_command = scrivito.switch_mode_command('editing'); - var switch_to_comparing_mode_command = scrivito.switch_mode_command(comparing_mode); - - var template = scrivito.template.render('menu_bar_toggle', { - mode: scrivito.editing_context.display_mode, - comparing_mode: comparing_mode, - switch_to_view_mode_command: switch_to_view_mode_command, - switch_to_editing_mode_command: switch_to_editing_mode_command, - switch_to_comparing_mode_command: switch_to_comparing_mode_command - }); - - var menu_bar_toggle = menu_bar.find('#scrivito_menu_bar_toggle').html(template); - - _.each([ - switch_to_view_mode_command, - switch_to_editing_mode_command, - switch_to_comparing_mode_command - ], function(command) { - menu_bar_toggle.find('.' + command.id()).on('click', function() { - command.execute(); - return false; - }); - }); - - menu_bar_toggle.find('.scrivito_comparing_mode_toggle').on('click', function() { - scrivito.inline_menus.toggle($(this), [ - scrivito.switch_mode_command('diff'), - scrivito.switch_mode_command('added'), - scrivito.switch_mode_command('deleted') - ], 'left'); - return false; - }); - }); - } - } - }); -}()); -(function() { - $.extend(scrivito, { - obj_menu: { - create: function(dom_element, obj, commands, options) { - dom_element.append(scrivito.template.render('obj_menu', {obj: obj})); - dom_element.on('click', function() { - scrivito.inline_menus.toggle(dom_element, commands, options); - return false; - }); - } - } - }); -}()); -(function() { - $.extend(scrivito, { - current_page_menu: { - init: function() { - if (scrivito.obj.current_page) { - scrivito.menu_bar.register_item_renderer(function(menu_bar) { - var current_page = scrivito.obj.current_page; - scrivito.obj_menu.create(menu_bar.find('#scrivito_current_page_menu'), current_page, [ - scrivito.obj_details_command(current_page), - scrivito.save_obj_to_clipboard_command(current_page), - scrivito.delete_obj_command(current_page), - scrivito.revert_obj_command(current_page), - scrivito.restore_obj_command(current_page), - scrivito.mark_resolved_obj_command(current_page), - scrivito.duplicate_obj_command(current_page) - ]); - }); - } - } - } - }); -}()); -(function() { - $.extend(scrivito, { - current_page_restriction: { - init: function() { - var current_page = scrivito.obj.current_page; - if (current_page && current_page.has_restriction()) { - scrivito.menu_bar.register_item_renderer(function(menu_bar) { - $(scrivito.template.render('current_page_restriction', { - restriction_messages: current_page.restriction_messages - })).appendTo(menu_bar.find('#scrivito_current_page_restriction')); - }); - } - } - } - }); -}()); -(function() { - $.extend(scrivito, { - workspace_select: { - init: function() { - var selected_workspace = scrivito.editing_context.selected_workspace; - var commands = { - create_workspace: scrivito.create_workspace_command(), - select_published: scrivito.select_workspace_command(scrivito.workspace.published()), - for_editable: [ - scrivito.workspace_settings_command(selected_workspace), - scrivito.workspace_changes_command(), - scrivito.rename_workspace_command(selected_workspace), - scrivito.rebase_workspace_command(selected_workspace), - scrivito.delete_workspace_command(selected_workspace), - scrivito.publish_workspace_command(selected_workspace) - ] - }; - - scrivito.menu_bar.register_item_renderer(function(menu_bar) { - var workspace_select = menu_bar.find('#scrivito_workspace_select'); - workspace_select.append(scrivito.template.render('workspace_select', { - selected_workspace: selected_workspace, - commands: commands - })); - - var bind_command = function(command) { - workspace_select.on('click', '#scrivito_' + command.id(), function() { - return command.execute(); - }); - }; - - bind_command(commands.create_workspace); - bind_command(commands.select_published); - _.each(commands.for_editable, function(command) { - bind_command(command); - }); - - workspace_select.on('click', function() { - var menu_box = workspace_select.find('.scrivito_menu_box'); - menu_box.fadeToggle('50'); - - var workspace_list = menu_box.find('.scrivito_workspace_list'); - if (workspace_list.find('.scrivito_spinning').length) { - scrivito.workspace.all_editable().then(function(workspaces) { - var commands = _(workspaces).reject(function(workspace) { - return workspace.id() === selected_workspace.id(); - }).map(function(workspace) { - return scrivito.select_workspace_command(workspace); - }); - - workspace_list.replaceWith(scrivito.template.render( - 'workspace_select/other_workspaces', {commands: commands} - )); - - _.each(commands, function(command) { - bind_command(command); - }); - }); - } - - return false; - }); - }); - } - } - }); -}()); -(function() { - $.extend(scrivito, { - changes_dialog: { - open: function() { - loaded_objs = []; - total_obj_count = 0; - batch = basic_batch(); - - view = $(scrivito.template.render('changes_list_dialog', { - selected_workspace_title: scrivito.editing_context.selected_workspace.title() - })); - - $('#scrivito_editing').append(view); - var next_loader = view.find('.scrivito_load_more'); - - target = view.find('#scrivito_changes_table_loaded'); - var spinner = view.find('#scrivito_changes_table_loading'); - var empty_result = view.find('#scrivito_changes_table_empty_result'); - - var obj_count = view.find('#scrivito_obj_count'); - - loaded_obj_count_ref = view.find('#scrivito_loaded_obj_count'); - total_obj_count_ref = view.find('#scrivito_total_obj_count'); - - load_markup = function() { - loading_in_progress = true; - spinner.show(); - - batch.load_batch().then(function(data, next) { - loading_in_progress = false; - - batch = next; - if (!batch) { - next_loader.hide(); - } else { - next_loader.show(); - } - - if (data.total > 0) { - loaded_objs = loaded_objs.concat(data.hits); - total_obj_count = data.total; - - render_objs(loaded_objs); - } else { - empty_result.show(); - } - - spinner.hide(); - - loaded_obj_count_ref.text(loaded_objs.length); - total_obj_count_ref.text(total_obj_count); - obj_count.show(); - - view.on('click.scrivito_link_to_obj', '.scrivito_link_to_obj', function(e) { - var element = $(e.currentTarget); - var obj_id = element.attr('data-scrivito-private-changes-list-obj-id'); - var obj_modification = element.attr( - 'data-scrivito-private-changes-list-obj-modification'); - var obj_is_binary = element.attr('data-scrivito-private-changes-list-obj-is-binary'); - - if (can_use_resource_dialog_directly(obj_modification, obj_is_binary)) { - var loaded_obj = _.find(loaded_objs, function(obj) { - return obj.id === obj_id; - }); - - scrivito.resource_dialog.open(scrivito.obj.create_instance(loaded_obj)); - } else { - scrivito.changes_dialog.redirect_to_obj(obj_id, obj_modification, obj_is_binary); - } - - return false; - }); - }); - }; - - next_loader.on('click', load_markup); - load_markup(); - activate_sorting(); - - var deferred = $.Deferred(); - - var cancel = function() { - scrivito.dialog.close(view); - deferred.resolve(); - return false; - }; - - view.find('.scrivito_cancel').on('click', cancel); - - scrivito.dialog.open_and_adjust(view); - return scrivito.with_dialog_behaviour(view, deferred, {escape: cancel}); - }, - - redirect_to_obj: function(obj_id, modification, is_binary) { - var base_url = '/'; - var query_params = {}; - - if (!!is_binary) { - base_url = '/__scrivito/details_page/'; - query_params.return_to = document.URL; - } - - if (modification === 'deleted' && !scrivito.editing_context.is_deleted_mode()) { - query_params._scrivito_display_mode = 'deleted'; - } - - if (modification === 'new' && scrivito.editing_context.is_deleted_mode()) { - query_params._scrivito_display_mode = 'added'; - } - - scrivito.change_location(base_url + obj_id + '?' + $.param( query_params )); - } - } - }); - - var batch; - var view; - var loaded_obj_count_ref; - var total_obj_count_ref; - var loaded_objs; - var total_obj_count; - var target; - var load_markup; - var loading_in_progress; - - var can_use_resource_dialog_directly = function(modification, is_binary) { - return is_binary && ( - modification === 'edited' || - modification === 'deleted' && scrivito.editing_context.is_deleted_mode() || - modification === 'new' && !scrivito.editing_context.is_deleted_mode()); - }; - - var basic_batch = function() { - return scrivito. - obj_where('_modification', 'equals', ['new', 'edited', 'deleted']). - batch_size(100). - order('_last_changed'). - reverse_order(). - format('_default'). - include_deleted(); - }; - - var render_objs = function(obj_specs) { - target.html(_.map(obj_specs, function(obj_spec) { - return scrivito.template.render('changes_list_row', - scrivito.obj.create_instance(obj_spec)); - })); - }; - - var activate_sorting = function() { - var sortables = view.find('.scrivito_sortable'); - - view.on('click.scrivito_sortable', '.scrivito_sortable', function() { - if (loading_in_progress) { - return; - } - - var sortable = $(this); - var sorting_by = {}; - sorting_by.attribute = sortable.attr('data-scrivito-private-sort-by'); - - var order_was_asc = sortable.hasClass('sort_up'); - if (order_was_asc) { - sorting_by.order = 'desc'; - } else { - sorting_by.order = 'asc'; - } - sortables.removeClass('sort_up').removeClass('sort_down'); - - var local_sort = function() { - var sort_function_or_attribute = sorting_by.attribute; - - if (sort_function_or_attribute === 'rights') { - sort_function_or_attribute = function(obj) { - return -obj.restriction_messages.length; - }; - } - - var objs = _.sortBy(loaded_objs, sort_function_or_attribute); - - if (sorting_by.order === 'desc') { - objs = objs.reverse(); - } - - render_objs(objs); - }; - - var backend_sort = function() { - batch = basic_batch(); - batch.order('_' + sorting_by.attribute); - - if (sorting_by.order === 'asc') { - batch.reverse_order(); - } - - loaded_objs = []; - render_objs(loaded_objs); - load_markup(); - }; - - if (loaded_objs.length === total_obj_count || sorting_by.attribute === 'rights') { - local_sort(); - } else { - backend_sort(); - } - - if (sorting_by.order === 'asc') { - sortable.addClass('sort_up'); - } else { - sortable.addClass('sort_down'); - } - }); - - }; - -}()); -(function() { - - $.extend(scrivito, { - blob: { - create: function(file) { - return get_upload_permission().then(function(permission) { - scrivito.write_monitor.start_write(); - return upload_to_s3(file, permission).always(function() { - scrivito.write_monitor.end_write(); - }); - }); - }, - - // For testing purpose only. - get_form_data: function() { - return new FormData(); - } - } - }); - - var get_upload_permission = function() { - return scrivito.ajax('GET', 'blobs/upload_permission'); - }; - - var upload_to_s3 = function(file, permission) { - var form_data = scrivito.blob.get_form_data(); - _.each(permission.fields, function(value, name) { - form_data.append(name, value); - }); - form_data.append('file', file); // File must be appended last, otherwise S3 will complain. - - permission.blob.filename = file.name; - - return $.ajax({type: 'POST', url: permission.url, data: form_data, - // These are needed in order for jQuery to work properly with a FormData. - contentType: false, - processData: false - }).then(function() { return permission.blob; }); - }; - -}()); -(function() { - $.extend(scrivito, { - child_list_element: { - create_instance: function(cms_element) { - if (cms_element.dom_element().attr('data-scrivito-private-child-list-path')) { - var that = cms_element; - - $.extend(that, { - path: function() { - return that.dom_element().attr('data-scrivito-private-child-list-path'); - }, - - obj: function() { - return scrivito.obj.create_instance({ - id: that.dom_element().attr('data-scrivito-private-child-list-order-obj-id'), - description_for_editor: that.dom_element() - .attr('data-scrivito-private-obj-description-for-editor') - }); - }, - - fetch_page_class_selection: function() { - return scrivito.ajax('GET', 'objs/page_class_selection?' + - $.param({parent_path: that.path()})); - }, - - allowed_classes: function() { - return JSON.parse( - that.dom_element().attr('data-scrivito-private-child-list-allowed-classes')); - }, - - create_child: function(obj_class) { - var id = scrivito.random_id(); - return scrivito.obj.create({ - _id: id, - _path: that.path() + '/' + id, - _obj_class: obj_class - }); - }, - - add_child: function(child) { - return child.save({ - _path: that.path() + '/' + child.id() - }); - }, - - children: function() { - return _.map(that.dom_element().find('>[data-scrivito-private-obj-id]'), - function(dom_element) { - return scrivito.cms_element.from_dom_element($(dom_element)); - }); - }, - - has_child_order: function() { - return !!that.dom_element().attr('data-scrivito-private-child-list-order-obj-id'); - }, - - save_order: function() { - if (that.has_child_order()) { - var new_child_order = _.map(that.children(), function(child) { - return child.obj().id(); - }); - return that.obj().save({child_order: new_child_order}); - } else { - $.error("Can't save order, when child order is not allowed!"); - } - }, - - is_valid_child_class: function(obj_class_name) { - var allowed_classes = that.allowed_classes(); - - if (allowed_classes) { - return _.contains(allowed_classes, obj_class_name); - } else { - return true; - } - } - }); - - return that; - } - }, - - all: function(root_element) { - return scrivito.cms_element.all('[data-scrivito-private-child-list-path]', root_element); - } - } - }); -}()); - -$(function() { - scrivito.cms_element.definitions.push(scrivito.child_list_element); -}); -(function() { - var expando = "scrivito_cms_element"; - - $.extend(scrivito, { - cms_element: { - create_instance: function(dom_element) { - var that = { - dom_element: function() { - return dom_element; - }, - - equals: function(cms_element) { - return cms_element.dom_element().get(0) === that.dom_element().get(0); - }, - - menu: function() { - var menu = dom_element.data('scrivito-menu'); - if (!menu) { - menu = []; - that.set_menu(menu); - } - return menu; - }, - - set_menu: function(menu) { - dom_element.data('scrivito-menu', menu); - } - }; - - return that; - }, - - from_dom_element: function(dom_element) { - if (!dom_element || !dom_element.jquery || dom_element.length === 0) { - $.error("Expected a jquery instance with exactly one element, " + - "instead got " + dom_element); - } - - var instance = dom_element[0][expando]; - - if (!instance) { - var cms_element = scrivito.cms_element.create_instance(dom_element); - - _.find(scrivito.cms_element.definitions, function(definition) { - instance = definition.create_instance(cms_element); - return instance; - }); - - if (!instance) { - $.error("This dom element is not a scrivito tag."); - } - - dom_element[0][expando] = instance; - } - - return instance; - }, - - definitions: [], - - all: function(selector, root_element) { - var dom_elements = (root_element || $('body')).find(selector).addBack(selector); - return _.map(dom_elements, function(dom_element) { - return scrivito.cms_element.from_dom_element($(dom_element)); - }); - } - } - }); -}()); -(function() { - var has_original_content = function(field_type) { - return _.contains([ - 'enum', - 'html', - 'multienum', - 'reference', - 'referencelist', - 'string', - 'text' - ], field_type); - }; - - $.extend(scrivito, { - cms_field_element: { - create_instance: function(cms_element) { - var that = cms_element; - - $.extend(that, { - field_name: function() { - return that.dom_element().attr('data-scrivito-field-name'); - }, - field_type: function() { - return that.dom_element().attr('data-scrivito-field-type'); - }, - obj: function() { - return scrivito.obj.create_instance({ - id: that.dom_element().attr('data-scrivito-private-field-obj-id'), - obj_class_name: that.dom_element().attr('data-scrivito-field-obj-class') - }); - }, - - workspace_id: function() { - return that.dom_element().attr('data-scrivito-private-field-workspace-id'); - }, - - widget: function() { - var widget_id = that.dom_element().attr('data-scrivito-private-field-widget-id'); - - if (widget_id) { - return scrivito.widget.create_instance(that.obj(), widget_id, - that.dom_element().attr('data-scrivito-widget-obj-class')); - } - }, - - save: function(content) { - assert_valid_workspace_id(); - - if (content === undefined) { - if (that.content) { - content = that.content(); - } else { - $.error("Can't save without content"); - } - } - - var request_promise = $.Deferred(); - - var to_be_saved = to_be_saved_data() || {}; - to_be_saved.value = content; - to_be_saved.promises = to_be_saved.promises || []; - to_be_saved.promises.push(request_promise); - to_be_saved_data(to_be_saved); - - if (!currently_saving()) { - next_save_request(); - } - - return request_promise.then(function(model_data) { - return model_data[that.field_name()]; - }); - }, - - original_content: function() { - assert_valid_workspace_id(); - - if (has_original_content(that.field_type())) { - return scrivito.json_parse_base64( - that.dom_element().attr('data-scrivito-private-field-original-content')); - } else { - $.error('Fields of type ' + that.field_type() + ' do not support original content'); - } - }, - - set_original_content: function(content) { - if (has_original_content(that.field_type())) { - that.dom_element().attr('data-scrivito-private-field-original-content', - scrivito.json_stringify_base64(content)); - } - } - }); - - var assert_valid_workspace_id = function() { - if (that.workspace_id() !== scrivito.editing_context.selected_workspace.id()) { - $.error('Tried to edit cms data from wrong workspace!'); - } - }; - - var next_save_request = function() { - currently_saving(true); - var to_be_saved = to_be_saved_data(); - remove_to_be_saved(); - - var changes = {}; - changes[that.field_name()] = to_be_saved.value; - - var widget = that.widget(); - var save_promise = widget ? widget.save(changes) : that.obj().save(changes); - - save_promise.done(function(result) { - _.each(to_be_saved.promises, function(succeeding_promise) { - succeeding_promise.resolve(result); - }); - - if (to_be_saved_data()) { - next_save_request(); - } else { - remove_currently_saving(); - } - }).fail(function(error) { - var new_promises = (to_be_saved_data() || {}).promises; - var failing_promises = to_be_saved.promises.concat(new_promises || []); - _.each(failing_promises, function(failing_promise) { - failing_promise.reject(error); - }); - - remove_to_be_saved(); - remove_currently_saving(); - }); - }; - - var to_be_saved_data = function(new_to_be_saved) { - if (new_to_be_saved) { - return that.dom_element().data('scrivito-to-be-saved', new_to_be_saved); - } else { - return that.dom_element().data('scrivito-to-be-saved'); - } - }; - - var remove_to_be_saved = function() { - that.dom_element().removeData('scrivito-to-be-saved'); - }; - - var currently_saving = function(new_currently_saving) { - if (new_currently_saving) { - return that.dom_element().data('scrivito-currently-saving', new_currently_saving); - } else { - return that.dom_element().data('scrivito-currently-saving'); - } - }; - - var remove_currently_saving = function() { - that.dom_element().removeData('scrivito-currently-saving'); - }; - - return that; - } - } - }); -}()); -(function() { - $.extend(scrivito, { - date_field_element: { - create_instance: function(cms_element) { - if (cms_element.dom_element().attr('data-scrivito-field-type') === 'date') { - return scrivito.cms_field_element.create_instance(cms_element); - } - }, - - all: function() { - return _.map($('[data-scrivito-field-type="date"]'), function(dom_element) { - return scrivito.cms_element.from_dom_element($(dom_element)); - }); - } - } - }); - - scrivito.cms_element.definitions.push(scrivito.date_field_element); -}()); -(function() { - $.extend(scrivito, { - html_field_element: { - create_instance: function(cms_element) { - if (cms_element.dom_element().attr('data-scrivito-field-type') === 'html') { - var that = scrivito.cms_field_element.create_instance(cms_element); - - $.extend(that, { - content: function() { - var content = that.dom_element().html(); - return $.trim(content); - } - }); - - return that; - } - }, - all: function() { - return _.map($('[data-scrivito-field-type="html"]'), function(dom_element) { - return scrivito.cms_element.from_dom_element($(dom_element)); - }); - } - } - }); - - scrivito.cms_element.definitions.push(scrivito.html_field_element); -}()); -(function() { - var format_date = function(date) { - return date.getUTCFullYear().toString() + - format_date_number(date.getUTCMonth() + 1) + // Month numbers are starting at 0. - format_date_number(date.getUTCDate()) + - format_date_number(date.getUTCHours()) + - format_date_number(date.getUTCMinutes()) + - format_date_number(date.getUTCSeconds()); - }; - - var format_date_number = function(number) { - var string = number.toString(); - return string.length === 1 ? '0' + string : string; - }; - - var convert_attributes = function(data) { - var collected_promises = _.map(data, function(value, field_name) { - if (value instanceof Date) { - return $.Deferred().resolve([field_name, format_date(value)]); - } else if (value instanceof window.File) { - return scrivito.blob.create(value).then(function(value) { - return [field_name, value]; - }); - } else { - return $.Deferred().resolve([field_name, value]); - } - }); - - return $.when.apply(this, collected_promises).then(function() { - return _.object(arguments); - }); - }; - - var convert_widget_pool = function(widget_pool) { - if(widget_pool) { - var conversion_promises = _.map(widget_pool, function(attributes, widget_id) { - return convert_attributes(attributes).then(function(attributes) { - return [widget_id, attributes]; - }); - }); - - return $.when.apply(this, conversion_promises).then(function() { - return _.object(arguments); - }); - } else { - return $.Deferred().resolve(widget_pool); - } - }; - - var prepare_attributes = function(data) { - return convert_widget_pool(data._widget_pool).then(function(widget_pool) { - return convert_attributes(data).then(function(attributes) { - attributes._widget_pool = widget_pool; - return attributes; - }); - }); - }; - - $.extend(scrivito, { - obj: { - init: function(config) { - if (config.current_page) { - scrivito.obj.current_page = scrivito.obj.create_instance(config.current_page); - } - }, - - create_instance: function(params) { - var that = { - id: function() { - return params.id; - }, - - obj_class_name: function() { - return params.obj_class_name; - }, - - description_for_editor: function() { - return params.description_for_editor; - }, - - modification: function() { - return params.modification; - }, - - is_new: function() { - return that.modification() === 'new'; - }, - - is_edited: function() { - return that.modification() === 'edited'; - }, - - is_deleted: function() { - return that.modification() === 'deleted'; - }, - - has_children: function() { - return !!params.has_children; - }, - - has_conflict: function() { - return !!params.has_conflict; - }, - - has_restriction : function() { - return that.restriction_messages().length > 0; - }, - - restriction_messages: function() { - return params.restriction_messages || []; - }, - - is_binary: function() { - return !!params.is_binary; - }, - - has_details_view: function() { - return !!params.has_details_view; - }, - - tooltip: function() { - if (editing_state()) { - return scrivito.t('obj.tooltip.' + editing_state()); - } - }, - - last_changed: function() { - return params.last_changed; - }, - - save: function(data) { - return prepare_attributes(data).then(function(attributes) { - return scrivito.ajax('PUT', 'objs/' + that.id(), {data: {obj: attributes}}); - }); - }, - - destroy: function() { - return scrivito.ajax('DELETE', 'objs/' + that.id()); - }, - - destroy_widget: function(widget_id) { - return scrivito.ajax('PUT', - 'objs/' + that.id() + '/destroy_widget?widget_id=' + widget_id); - }, - - revert: function() { - return scrivito.ajax('PUT', 'objs/' + that.id() + '/revert'); - }, - - revert_widget: function(widget_id) { - return scrivito.ajax('PUT', - 'objs/' + that.id() + '/revert_widget?widget_id=' + widget_id); - }, - - update_widget_modification: function(widget_id) { - return scrivito.ajax('GET', 'objs/' + that.id() + '/widget_modification?widget_id=' + widget_id); - }, - - restore: function() { - return scrivito.ajax('PUT', 'objs/' + that.id() + '/restore'); - }, - - fetch_details_markup: function() { - return scrivito.ajax('GET', 'objs/' + that.id() + '/details').then(function(data) { - return data.markup; - }); - }, - - mark_resolved: function() { - return scrivito.ajax('PUT', 'objs/' + that.id() + '/mark_resolved'); - }, - - copy_to: function(path) { - var post_attr = {data: {parent_path: path}}; - var url = 'objs/'+that.id()+'/copy'; - - return scrivito.ajax('POST', url, post_attr).then(function(new_data) { - return scrivito.obj.create_instance_from_server_data(new_data); - }); - }, - - duplicate: function() { - return scrivito.ajax('POST', 'objs/'+that.id()+'/duplicate').then(function(new_data) { - return scrivito.obj.create_instance_from_server_data(new_data); - }); - }, - - update_modification: function() { - return scrivito.ajax('GET', 'objs/' + that.id() + '/modification').then(function(data) { - params.modification = data.modification; - }); - } - }; - - var editing_state = function() { - if (that.is_new()) { - return 'is_new'; - } - - if (that.is_edited()) { - if (that.has_conflict()) { - return 'has_conflict'; - } else { - return 'is_edited'; - } - } - - if (that.is_deleted()) { - return 'is_deleted'; - } - }; - - return that; - }, - - create_instance_from_server_data: function(params) { - return scrivito.obj.create_instance({ - id: (params.id || params._id), - obj_class_name: params._obj_class - }); - }, - - create: function(data) { - return prepare_attributes(data).then(function(attributes) { - return scrivito.ajax('POST', 'objs', {data: {obj: attributes}}).then(function(new_data) { - return scrivito.obj.create_instance_from_server_data(new_data); - }); - }); - } - } - }); -}()); -(function() { - $.extend(scrivito, { - obj_element: { - create_instance: function(cms_element) { - if (cms_element.dom_element().attr('data-scrivito-private-obj-id')) { - var that = cms_element; - - $.extend(that, { - obj: function() { - return scrivito.obj.create_instance({ - id: that.dom_element().attr('data-scrivito-private-obj-id'), - description_for_editor: that.dom_element() - .attr('data-scrivito-private-obj-description-for-editor') - }); - } - }); - - return that; - } - }, - - // for testing purposes only - all: function() { - return _.map($('[data-scrivito-private-obj-id]'), function(dom_element) { - return scrivito.cms_element.from_dom_element($(dom_element)); - }); - } - } - }); -}()); - -$(function() { - scrivito.cms_element.definitions.push(scrivito.obj_element); -}); -(function() { - $.extend(scrivito, { - chainable_search: { - create_instance: function(build_query) { - var query = build_query || { predicates: [] }; - - var add_predicate = function(field, operator, value, boost, negate) { - var new_query = { - field: field, - operator: operator, - value: value - }; - - if (negate) { - new_query.negate = true; - } - - if (boost) { - new_query.boost = boost; - } - - query.predicates.push(new_query); - return that; - }; - - var execute_search = function(query, action) { - return scrivito.ajax('GET', 'objs/search?' + - $.param({query: JSON.stringify(query), query_action: action})); - }; - - var that = { - // @api public - query: function() { - return query; - }, - - // @api public - and: function(field, operator, value, boost) { - add_predicate(field, operator, value, boost); - return that; - }, - - // @api public - and_not: function(field, operator, value) { - add_predicate(field, operator, value, undefined, true); - return that; - }, - - // @api public - offset: function(offset) { - query.offset = offset; - return that; - }, - - // @api public - order: function(order) { - query.order = order; - return that; - }, - - // @api public - reverse_order: function() { - if (query.reverse_order) { - delete query.reverse_order; - } else { - query.reverse_order = true; - } - return that; - }, - - // @api public - batch_size: function(batch_size) { - query.batch_size = batch_size; - return that; - }, - - // @api public - format: function(name) { - query.format = name; - return that; - }, - - // @api public - include_deleted: function() { - query.include_deleted = true; - return that; - }, - - // @api public - load_batch: function() { - var offset = query.offset || 0; - var next; - - return execute_search(query).then(function(result) { - var batch_size = result.hits.length; - var total_matches = result.total; - - if (total_matches > (batch_size + offset)) { - var next_offset = offset + batch_size; - var next_query = $.extend({}, query, {offset: next_offset}); - next = scrivito.chainable_search.create_instance(next_query); - } else { - next = undefined; - } - - return $.Deferred().resolve(result, next); - }); - }, - - // @api public - size: function() { - return execute_search(query, 'size').then(function(result) { - return $.Deferred().resolve(result.total); - }); - }, - - // @api public - clone: function() { - var cloned_query = $.extend(true, {}, query); - return scrivito.chainable_search.create_instance(cloned_query); - } - - }; - - return that; - } - } - - }); - -}()); - -(function() { - $.extend(scrivito, { - // @api public - obj_where: function(field, operator, value, boost) { - return scrivito.chainable_search.create_instance().and(field, operator, value, boost); - } - }); -}()); - -(function() { - var field_types = [ - 'binary', - 'enum', - 'link', - 'linklist', - 'multienum', - 'reference', - 'referencelist', - 'text' - ]; - - $.extend(scrivito, { - standard_field_element: { - create_instance: function(cms_element) { - if (_.include(field_types, cms_element.dom_element().attr('data-scrivito-field-type'))) { - return scrivito.cms_field_element.create_instance(cms_element); - } - } - } - }); - - scrivito.cms_element.definitions.push(scrivito.standard_field_element); -}()); -(function() { - $.extend(scrivito, { - string_field_element: { - create_instance: function(cms_element) { - if (cms_element.dom_element().attr('data-scrivito-field-type') === 'string') { - var that = scrivito.cms_field_element.create_instance(cms_element); - - $.extend(that, { - content: function() { - var content = that.dom_element().text(); - return $.trim(content); - } - }); - - return that; - } - }, - all: function() { - return _.map($('[data-scrivito-field-type="string"]'), function(dom_element) { - return scrivito.cms_element.from_dom_element($(dom_element)); - }); - } - } - }); - - scrivito.cms_element.definitions.push(scrivito.string_field_element); -}()); -(function() { - $.extend(scrivito, { - user: { - init: function(config) { - scrivito.user.current = scrivito.user.create_instance(config.current); - }, - - create_instance: function(params) { - var that = { - id: function() { - return params.id; - } - }; - - return that; - }, - - suggest: function(input) { - return scrivito.ajax('GET', 'users/suggest?input=' + input); - } - } - }); -}()); -(function() { - $.extend(scrivito, { - widget: { - create_instance: function(obj, id, widget_class_name, options) { - options = options || {}; - - var that = { - id: function() { - return id; - }, - - obj: function() { - return obj; - }, - - widget_class_name: function() { - return widget_class_name; - }, - - modification: function() { - return options.modification; - }, - - placement_modification: function() { - return options.placement_modification; - }, - - description_for_editor: function() { - return options.description_for_editor; - }, - - is_modified: function() { - return !!that.modification(); - }, - - is_new: function() { - return that.modification() === 'new'; - }, - - is_edited: function() { - return that.modification() === 'edited'; - }, - - is_deleted: function() { - return that.modification() === 'deleted'; - }, - - is_placement_modified: function() { - return !!that.placement_modification(); - }, - - save: function(widget_attributes) { - var obj_attributes = build_obj_attributes(widget_attributes); - return that.obj().save(obj_attributes).then(function(obj_data) { - return obj_data._widget_pool[that.id()]; - }); - }, - - destroy: function() { - return that.obj().destroy_widget(that.id()); - }, - - fetch_details_markup: function() { - return that.fetch_markup('widget_details'); - }, - - fetch_show_markup: function() { - return that.fetch_markup('show_widget'); - }, - - revert: function() { - return that.obj().revert_widget(that.id()).then(function() { - options.modification = null; - }); - }, - - fetch_markup: function(action_name) { - var obj_id = that.obj().id(); - var widget_id = that.id(); - var url = 'render_widget/' + obj_id + '/' + action_name + '/' + widget_id; - return scrivito.ajax('GET', url, {dataType: 'html'}); - }, - - update_modification: function() { - return that.obj().update_widget_modification(that.id()).then(function(data) { - options.modification = data.modification; - }); - } - }; - - var build_obj_attributes = function(widget_attributes) { - var obj_attributes = {_widget_pool: {}}; - obj_attributes._widget_pool[that.id()] = widget_attributes; - return obj_attributes; - }; - - return that; - } - } - }); -}()); -(function() { - $.extend(scrivito, { - widget_element: { - create_instance: function(cms_element) { - if (cms_element.dom_element().attr('data-scrivito-private-widget-id')) { - var that = cms_element; - - $.extend(that, { - widget: function() { - var dom_element = that.dom_element(); - return scrivito.widget.create_instance(that.widget_field().obj(), - dom_element.attr('data-scrivito-private-widget-id'), - dom_element.attr('data-scrivito-widget-obj-class'), - { - modification: dom_element.attr('data-scrivito-private-widget-modification'), - placement_modification: dom_element.attr( - 'data-scrivito-private-widget-placement-modification'), - description_for_editor: dom_element.attr( - 'data-scrivito-private-widget-description-for-editor') - } - ); - }, - - widget_field: function() { - return scrivito.cms_element.from_dom_element(that.dom_element().parent()); - }, - - has_details_view: function() { - return that.dom_element().attr('data-scrivito-private-widget-has-details-view') ? true : false; - }, - - fetch_details_markup: function() { - return that.widget().fetch_details_markup(); - }, - - fetch_show_markup: function() { - return that.widget().fetch_show_markup(); - }, - - field_name: function() { - return that.widget_field().field_name(); - } - }); - - return that; - } - }, - - all: function(root_element) { - return scrivito.cms_element.all('[data-scrivito-private-widget-id]', root_element); - } - } - }); - - scrivito.cms_element.definitions.push(scrivito.widget_element); -}()); -(function() { - $.extend(scrivito, { - widget_field_element: { - create_instance: function(cms_element) { - if (cms_element.dom_element().attr('data-scrivito-field-type') === 'widget') { - var that = scrivito.cms_field_element.create_instance(cms_element); - - $.extend(that, { - content: function() { - return _.map(that.widget_elements(), function(widget_element) { - return widget_element.widget().id(); - }); - }, - - widget_elements: function() { - var widget_elements_dom = that.dom_element() - .children('[data-scrivito-private-widget-id]'); - var widget_elements = _.map(widget_elements_dom, function(widget_element_dom) { - return scrivito.cms_element.from_dom_element($(widget_element_dom)); - }); - return widget_elements; - }, - - is_empty: function() { - return that.widget_elements().length === 0; - }, - - parent_widget: function() { - var widgets = that.dom_element().parents('[data-scrivito-private-widget-id]'); - if (widgets.length) { - return scrivito.cms_element.from_dom_element(widgets.eq(0)).widget(); - } - }, - - create_widget: function(widget_class, widget_element) { - var widget_spec = {create: {_obj_class: widget_class}}; - return add_widget(widget_spec, widget_element); - }, - - copy_widget: function(src_obj_id, src_widget_id, widget_element) { - var widget_spec = {copy: {src_obj_id: src_obj_id, src_widget_id: src_widget_id}}; - return add_widget(widget_spec, widget_element); - }, - - fetch_widget_class_selection: function() { - var params = {field_name: that.field_name()}; - var parent_widget = that.parent_widget(); - if (parent_widget) { - params.widget_id = parent_widget.id(); - } - return scrivito.ajax('GET', 'objs/' + that.obj().id() + '/widget_class_selection?' + - $.param(params)); - }, - - allowed_classes: function() { - var allowed_classes = that.dom_element().attr('data-scrivito-private-field-widget-allowed-classes'); - - if (allowed_classes) { - return JSON.parse(allowed_classes); - } else { - return null; - } - }, - - is_valid_child_class: function(widget_class_name) { - var allowed_classes = that.allowed_classes(); - - if (allowed_classes) { - return _.contains(allowed_classes, widget_class_name); - } else { - return true; - } - }, - - append_widget_markup: function(widget_markup, widget_element) { - var dom_element = $($.trim(widget_markup)); - if (widget_element) { - widget_element.dom_element().after(dom_element); - } else { - that.dom_element().append(dom_element); - } - scrivito.gui.new_content(dom_element.get(0)); - return dom_element; - } - }); - - var add_widget = function(widget_spec, widget_element) { - var position; - if (widget_element) { - position = widget_element.dom_element() - .prevAll('[data-scrivito-private-widget-id]').length + 1; - } else { - position = that.widget_elements().length; - } - - var content = that.content(); - content.splice(position, 0, widget_spec); - - return that.save(content).then(function(field_data) { - var new_widget_id = field_data.list[position].widget; - return scrivito.widget.create_instance(that.obj(), new_widget_id); - }); - }; - - return that; - } - }, - - all: function(root_element) { - return scrivito.cms_element.all('[data-scrivito-field-type="widget"]', root_element); - } - } - }); - - scrivito.cms_element.definitions.push(scrivito.widget_field_element); -}()); -(function() { - $.extend(scrivito, { - workspace: { - from_data: function(data) { - var that = { - id: function() { - return data.id; - }, - - title: function() { - return that.original_title() || default_title(); - }, - - original_title: function() { - return data.title; - }, - - icon: function() { - return that.is_published() ? '&#xf064;' : '&#xf011;'; - }, - - is_published: function() { - return that.id() === 'published'; - }, - - is_outdated: function() { - return !!data.outdated; - }, - - mark_as_outdated: function() { - data.outdated = true; - }, - - is_editable: function() { - return !that.is_published(); - }, - - is_rtc: function() { - return that.id() === 'rtc'; - }, - - check: function() { - return check(0).then(function(result) { - return handle_check_result(result, []); - }); - }, - - check_and_publish: function() { - return check_and_publish(0); - }, - - publish: function(certificates) { - return scrivito.silent_ajax('PUT', 'workspaces/' + that.id() + '/publish', - {data: { certificates: certificates }}); - }, - - rebase: function() { - return scrivito.ajax('PUT', 'workspaces/' + that.id() + '/rebase').done(function() { - data.outdated = false; - }); - }, - - update: function(attributes) { - return scrivito.ajax('PUT', 'workspaces/' + that.id(), {data: {workspace: attributes}}); - }, - - rename: function(new_title) { - return that.update({title: new_title}); - }, - - destroy: function() { - return scrivito.ajax('DELETE', 'workspaces/' + that.id()); - }, - - fetch_memberships: function() { - return scrivito.ajax('GET', 'workspaces/' + that.id()).then(function(details) { - return details.memberships; - }); - } - }; - - var check_and_publish = function(number_of_retries) { - return rebase_outdated().then(function() { - return that.check().then(function(certificates) { - if (certificates) { - return that.publish(certificates).then(null, function(error) { - return handle_check_and_publish_error(error, number_of_retries); - }); - } else { - return $.Deferred().reject({type: 'check_failed'}); - } - }, function(error) { - return handle_check_and_publish_error(error, number_of_retries); - }); - }); - }; - - var rebase_outdated = function() { - return that.is_outdated() ? that.rebase() : $.Deferred().resolve(); - }; - - var check = function(offset) { - return scrivito.silent_ajax('GET', 'workspaces/' + that.id() + '/check?from=' + offset); - }; - - var handle_check_result = function(result, certificates) { - if (result.result === 'fail') { - return $.Deferred().resolve(false); - } - - certificates.push(result.certificate); - - if (result.pass.until === 'END') { - return $.Deferred().resolve(certificates); - } else { - var offset = parseInt(result.pass.until, 10) + 1; - return check(offset).then(function(result) { - return handle_check_result(result, certificates); - }); - } - }; - - var handle_check_and_publish_error = function(error, number_of_retries) { - if (error.code === 'precondition_not_verifiable.workspace.publish.content_state_id') { - // Another workspace has been published since last check. - that.mark_as_outdated(); - return check_and_publish(number_of_retries); - } else if (error.code === 'precondition_not_met.workspace.publish.content_state_id') { - // The workspace has been changed since last check. - if (number_of_retries === 2) { - return $.Deferred().reject({type: 'outdated_certificates'}); - } else { - return check_and_publish(number_of_retries + 1); - } - } else { - scrivito.display_ajax_error(error); - return error; - } - }; - - var default_title = function() { - if (that.is_published()) { - return scrivito.t('workspace.title_published'); - } else { - return scrivito.t('workspace.empty_title'); - } - }; - - return that; - }, - - all: function() { - return scrivito.ajax('GET', 'workspaces').then(function(workspace_datas) { - return _.sortBy(_.map(workspace_datas, function(workspace_data) { - return scrivito.workspace.from_data(workspace_data); - }, function(workspace) { - return workspace.is_published() ? '' : workspace.title().toUpperCase(); - })); - }); - }, - - all_editable: function() { - return scrivito.workspace.all().then(function(workspaces) { - return _.select(workspaces, function(workspace) { - return workspace.is_editable(); - }); - }); - }, - - published: function() { - return scrivito.workspace.from_data({id: 'published'}); - }, - - create: function(title) { - return scrivito.ajax('POST', 'workspaces', {data: {workspace: {title: title}}}). - then(function(ws_data) { - return scrivito.workspace.from_data(ws_data); - }); - } - } - }); -}()); -(function() { - scrivito.storage = { - set: function(key, object) { - localStorage.setItem(full_key(key), JSON.stringify(object)); - }, - - get: function(key) { - return JSON.parse(localStorage.getItem(full_key(key))); - }, - - has_key: function(key) { - return !!scrivito.storage.get(key); - }, - - remove: function(key) { - localStorage.removeItem(full_key(key)); - }, - - clear: function() { - for (var i=0; i < localStorage.length; i++) { - var key = localStorage.key(i); - - if (key.indexOf(storage_key_prefix) === 0) { - localStorage.removeItem(key); - } - } - } - }; - - var storage_key_prefix = '_scrivito_'; - - var full_key = function(key_suffix) { - return storage_key_prefix + key_suffix; - }; -})(); -(function() { - $.extend(scrivito, { - /* - * This component has two main purposes: - * - * 1. It wraps a function triggering a CSS transition - * in an additional javascript event, so that that - * transition will be executed even if associated target - * has just been added to the DOM. - * - * 2. It skips any transitions and immediately executes - * all functions in correct order if configured to do so, - * e.g. in specs. - */ - transition: function(target, trigger_fn) { - var deferred = $.Deferred(); - if (!scrivito.transition.immediate_mode) { - target.on('webkitTransitionEnd oTransitionEnd otransitionend transitionend msTransitionEnd', - function() { deferred.resolve(); }); - setTimeout(trigger_fn, 0); - } else { - trigger_fn(); - deferred.resolve(); - } - return deferred; - } - }); - - $.extend(scrivito.transition, {immediate_mode: false}); -}()); -(function() { - - var auto_height_dirty = false; - - var relevant_siblings_for = function(elem) { - return elem.siblings().filter(":not(.hover):visible"); - }; - - var target_height_for = function(elem, dont_store_height) { - var parent = elem.parent(); - var heightOfParent = parent.innerHeight(); - if (!dont_store_height) { parent.data("scrivito_last_inner_height", heightOfParent); } - var heightOfAllSiblings = _(relevant_siblings_for(elem)) - .chain() - .map($) - .reduce(function(sum, sibling) { - var height = sibling.outerHeight(true); - if (!dont_store_height) { sibling.data("scrivito_last_outer_height", height); } - return sum + height; - }, 0).value() - ; - return Math.max(0, heightOfParent - heightOfAllSiblings); - }; - - var set_auto_height_for = function(elem) { - elem.css('height', target_height_for(elem)); - elem.addClass("scrivito_height_done"); - }; - - var sibling_height_changes = function(elem) { - return _(relevant_siblings_for(elem)).map(function(sibling) { - sibling = $(sibling); - var last = sibling.data("scrivito_last_outer_height"); - var actual = sibling.outerHeight(true); - if (last !== actual) { - return scrivito.describe_element(sibling) + - " unexpectantly changed it's height from " + (last === undefined ? "<invisible>" : last) + " to " + actual - ; - } - }); - }; - - var parent_height_changes = function(elem) { - var parent = elem.parent(); - var last = parent.data("scrivito_last_inner_height"); - var actual = parent.innerHeight(); - if (last !== actual) { - return scrivito.describe_element(parent) + - " unexpectantly changed it's height from " + (last || "<invisible>") + " to " + actual - ; - } - }; - - $.extend(scrivito, { - update_auto_height_for: function(root_element) { - var elements = root_element.find('.scrivito_auto_height:visible'); - if (root_element.hasClass("scrivito_auto_height")) { - elements = elements.add(root_element); - } - elements.not(".scrivito_height_done").each(function (i, elem) { - set_auto_height_for($(elem)); - }); - }, - - invalidate_auto_height: function() { - $(".scrivito_height_done").removeClass("scrivito_height_done"); - auto_height_dirty = true; - }, - - invalidate_auto_height_for: function(elem) { - elem.find(".scrivito_height_done").removeClass("scrivito_height_done"); - }, - - process_auto_height: function() { - if (auto_height_dirty) { - scrivito.update_auto_height_for($("body")); - auto_height_dirty = false; - } - }, - - auto_height_errors: function() { - return _($(".scrivito_auto_height:visible")).chain().map($).map(function(elem) { - var expected = target_height_for(elem, true); - var actual = parseInt(elem.css('height'), 10); - if (actual !== expected) { - if (!elem.hasClass("scrivito_height_done")) { - return [scrivito.describe_element(elem) + " was never updated"]; - } - else { - var errors = sibling_height_changes(elem); - errors.push(parent_height_changes(elem)); - return _(errors).compact(); - } - } - }).compact().flatten().value(); - } - }); -}()); -/*global ScrivitoHandlebarsTemplates:false */ -/*global Handlebars:false */ - - -(function() { - Handlebars.registerHelper('translate', scrivito.i18n.translate); - - Handlebars.registerHelper('localize_date', function(date_value_function) { - return scrivito.i18n.localize_date(date_value_function()); - }); - - Handlebars.registerHelper('localize_date_relative', function(date_value_function) { - return scrivito.i18n.localize_date_relative(date_value_function()); - }); - - Handlebars.registerHelper('array_to_title', function(array_fn) { - var escaped_array = array_fn().map(function(text) { - return Handlebars.Utils.escapeExpression(text); - }); - - return new Handlebars.SafeString(escaped_array.join('&#13;')); - }); - - Handlebars.registerHelper('render', function(template_path, object) { - return new Handlebars.SafeString(scrivito.template.render(template_path, object)); - }); - - $.extend(scrivito, { - template: { - load_templates_from_server: false, - - render: function(template_path, data) { - var template; - if(typeof ScrivitoHandlebarsTemplates !== 'undefined') { - template = ScrivitoHandlebarsTemplates[template_path]; - } - if(template === undefined) { - if(scrivito.template.load_templates_from_server) { - var url = "/app/assets/javascripts/templates/" + template_path + ".hbs?" + Math.random(); - var source = jQuery.ajax(url, { async: false }).responseText; - template = Handlebars.compile(source); - } else { - throw('could not load template' + template_path); - } - } - return template(data); - } - } - }); -}()); -(function() { - $.extend(scrivito, { - with_dialog_overlay: function(dom_element, promise) { - var overlay = scrivito.dialog_overlay.create(dom_element); - return promise.always(function() { - scrivito.dialog_overlay.destroy(overlay); - }); - }, - - dialog_overlay: { - create: function(dom_element) { - $('.scrivito_overlay').removeClass('scrivito_show'); - - var overlay = $(scrivito.template.render('overlay')); - dom_element.before(overlay); - - scrivito.transition(overlay, function() { - overlay.addClass('scrivito_show'); - }); - - return overlay; - }, - - destroy: function(overlay) { - scrivito.transition(overlay, function() { - overlay.removeClass('scrivito_show'); - }).then(function() { - overlay.remove(); - var last_overlay = $('.scrivito_overlay').last(); - if (last_overlay.length) { - last_overlay.addClass('scrivito_show'); - } - }); - }, - - // Test purpose only. - remove_all: function() { - $('.scrivito_overlay').remove(); - } - } - }); -}()); -(function() { - var view; - - $.extend(scrivito, { - with_saving_overlay: function(promise) { - scrivito.saving_overlay.show(); - return promise.always(function() { - scrivito.saving_overlay.hide(); - }); - }, - - saving_overlay: { - show: function() { - if (!view) { - view = $(scrivito.template.render('saving_overlay')); - $('#scrivito_editing').append(view); - } - - scrivito.transition(view, function() { - view.addClass('scrivito_show'); - }); - }, - - hide: function() { - if (view) { - scrivito.transition(view, function() { - view.removeClass('scrivito_show'); - }).then(function(e) { - // Remove the view only if event is triggered by a "fade-out" transition. - if (e && $(e.target).hasClass('scrivito_show')) { return; } - view.remove(); - view = null; - }); - } - }, - - // Test purpose only. - remove_all: function() { - $('.scrivito_saving_overlay').remove(); - view = null; - } - } - }); - - return scrivito; -}()); -(function() { - $.extend(scrivito, { - saving_indicator: { - create: function(parent_view) { - var target_selector = '.scrivito_saving_indicator'; - var saving_in_progress_selector = target_selector + ' .scrivito_saving_in_progress'; - var saving_done_selector = target_selector + ' .scrivito_saving_done'; - - parent_view.append(scrivito.template.render('saving_indicator')); - - var start_write_token = scrivito.write_monitor.on('start_write', function() { - parent_view.find(saving_in_progress_selector).show(); - parent_view.find(saving_done_selector).hide(); - }); - - var end_write_token = scrivito.write_monitor.on('end_write', function() { - if (!scrivito.write_monitor.is_writing()) { - parent_view.find(saving_in_progress_selector).hide(); - - var saving_done_element = parent_view.find(saving_done_selector); - saving_done_element.show(); - - if (!scrivito.transition.immediate_mode) { - setTimeout(function() { - saving_done_element.fadeOut(1000); - }, 3000); - } - } - }); - - return { - destroy: function() { - scrivito.write_monitor.off(start_write_token); - scrivito.write_monitor.off(end_write_token); - parent_view.find(target_selector).remove(); - }, - - // Test purpose only. - start_write_token: start_write_token, - end_write_token: end_write_token - }; - } - } - }); -}()); -(function() { - $.extend(scrivito, { - with_element_overlay: function(dom_element, promise) { - var element_overlay = scrivito.element_overlay.create(dom_element); - return promise.always(function() { - element_overlay.remove(); - }); - }, - - element_overlay: { - create: function(dom_element) { - var dom_element_position = dom_element.position(); - var view = $(scrivito.template.render('element_overlay')).css({ - position: 'absolute', // Required for unit tests to pass without an extra CSS file. - top: 0, - left: dom_element_position.left, - width: dom_element.width(), - height: dom_element.height() - }); - dom_element.append(view); - return view; - } - } - }); -}()); -(function() { - $.extend(scrivito, { - alert_dialog: function(message) { - return scrivito.alert_dialog.open(message); - } - }); - - $.extend(scrivito.alert_dialog, { - open: function(message) { - var view = $(scrivito.template.render('alert_dialog', {message: message})); - view.appendTo($('#scrivito_editing')); - - var promise = $.Deferred(); - - var close = function() { - scrivito.dialog.close(view); - promise.resolve(); - return false; - }; - - view.find('.scrivito_close').on('click', close); - - scrivito.dialog.open_and_center(view); - - return scrivito.with_dialog_behaviour(view, promise, {enter: close, escape: close}); - } - }); -}()); -(function() { - $.extend(scrivito, { - confirmation_dialog: function(options) { - return scrivito.confirmation_dialog.open(options); - } - }); - - $.extend(scrivito.confirmation_dialog, { - open: function(options) { - var view = $(scrivito.template.render('confirmation_dialog', $.extend({ - icon: '&#xf01d;', - cancel_button_text: scrivito.t('cancel'), - confirm_button_text: scrivito.t('confirm') - }, options || {}))); - - $('#scrivito_editing').append(view); - - var deferred = $.Deferred(); - - var accept = function() { - scrivito.dialog.close(view); - deferred.resolve(); - return false; - }; - - var cancel = function() { - scrivito.dialog.close(view); - deferred.reject(); - return false; - }; - - view.find('.scrivito_confirm').on('click', accept); - view.find('.scrivito_cancel').on('click', cancel); - - scrivito.dialog.open_and_center(view); - return scrivito.with_dialog_behaviour(view, deferred, {enter: accept, escape: cancel}); - }, - - // Test purpose only. - remove_all: function() { - $('.scrivito_confirmation_dialog').remove(); - } - }); -}()); -(function() { - $.extend(scrivito, { - prompt_dialog: function(options) { - return scrivito.prompt_dialog.open(options); - } - }); - - $.extend(scrivito.prompt_dialog, { - open: function(options) { - var view = $(scrivito.template.render('prompt_dialog', $.extend({ - icon: '&#61468;', - accept_button_text: scrivito.t('accept'), - cancel_button_text: scrivito.t('cancel') - }, options || {}))); - - $('#scrivito_editing').append(view); - - var deferred = $.Deferred(); - - var accept = function() { - var val = view.find('input').val(); - if (val) { - scrivito.dialog.close(view); - deferred.resolve(val); - } - return false; - }; - - var cancel = function() { - scrivito.dialog.close(view); - deferred.reject(); - return false; - }; - - view.find('.scrivito_accept').on('click', accept); - view.find('.scrivito_cancel').on('click', cancel); - - scrivito.dialog.open_and_center(view).then(function() { - view.find('input').focus(); - }); - - return scrivito.with_dialog_behaviour(view, deferred, {enter: accept, escape: cancel}); - } - }); -}()); -(function() { - $.extend(scrivito, { - dialog: { - open: function(view) { - return scrivito.transition(view, function() { - view.addClass('scrivito_show'); - }); - }, - - open_and_adjust: function(view) { - return scrivito.dialog.open(view).then(function() { - scrivito.dialog.adjust(view); - }); - }, - - open_and_center: function(view) { - return scrivito.dialog.open(view).then(function() { - scrivito.center(view); - }); - }, - - close: function(view) { - scrivito.transition(view, function() { - view.removeClass('scrivito_show'); - }).then(function() { - view.remove(); - view = null; - }); - }, - - adjust: function(view) { - scrivito.invalidate_auto_height_for(view); - scrivito.update_auto_height_for(view); - } - } - }); - - $(window).on('resize', function() { - _.each($('.scrivito_adjust_dialog'), function(elem) { - scrivito.dialog.adjust($(elem)); - }); - - _.each($('.scrivito_center_dialog'), function(elem) { - scrivito.center($(elem)); - }); - }); -}()); -(function() { - $.extend(scrivito, { - reloading: { - init: function() { - $('body').on('scrivito_reload', function() { - scrivito.with_saving_overlay(scrivito.reload()); - }); - } - } - }); -}()); -(function() { - $.extend(scrivito, { - choose_obj_class_dialog: function(obj_classes_deferred, locale_path) { - return scrivito.choose_obj_class_dialog.open(obj_classes_deferred, locale_path); - } - }); - - $.extend(scrivito.choose_obj_class_dialog, { - open: function(obj_classes_deferred, locale_path) { - var deferred = $.Deferred(); - - var view = $(scrivito.template.render('choose_obj_class_dialog', { - title: scrivito.t('choose_obj_class_dialog.' + locale_path + '.title'), - description: scrivito.t('choose_obj_class_dialog.' + locale_path + '.description') - })); - - obj_classes_deferred.done(function(obj_class_selection) { - var selection_view = scrivito.template.render('choose_obj_class_list', - {obj_classes: obj_class_selection}); - - selection_view = $($.trim(selection_view)); - - view.find('#scrivito_replace_with_real_obj_classes').replaceWith(selection_view); - - view.on('click', '.scrivito_obj_class_thumbnail', function(e) { - e.preventDefault(); - scrivito.dialog.close(view); - deferred.resolve($(this).attr('data-scrivito-private-obj-class-name')); - }); - }); - - $('#scrivito_editing').append(view); - - var cancel = function() { - scrivito.dialog.close(view); - deferred.reject(); - return false; - }; - - view.find('.scrivito_cancel').on('click', cancel); - - scrivito.dialog.open_and_adjust(view); - return scrivito.with_dialog_behaviour(view, deferred, {escape: cancel}); - } - }); -}()); -(function() { - $.extend(scrivito, { - details_dialog: { - open: function(options) { - var deferred = $.Deferred(); - - var view = $(scrivito.template.render('details_dialog', - $.extend({icon: '&#xf030;'}, options || {}))); - - if (options.obj) { - scrivito.obj_menu.create(view.find('.scrivito_obj_menu'), options.obj, options.commands); - } - - $('#scrivito_editing').append(view); - - var saving_indicator = scrivito.saving_indicator.create( - view.find('.scrivito_details_dialog_saving_indicator')); - - var load_markup = function() { - var target = view.find('.scrivito_details_dialog_markup'); - var spinner = view.find('.scrivito_modal_body .scrivito_spinning'); - - target.hide(); - spinner.show(); - - options.fetch_markup().then(function(markup) { - target.html(markup); - - var size_attr = 'data-scrivito-modal-size'; - var modal_size = $(markup).attr(size_attr) || - $(markup).find('[' + size_attr + ']').attr(size_attr); - if (_.contains(['small', 'medium', 'large'], modal_size)) { - view.removeClass('scrivito_modal_medium'); - scrivito.transition(view, function() { - view.addClass('scrivito_modal_' + modal_size); - }).then(function() { - scrivito.dialog.adjust(view); - }); - } - - spinner.hide(); - target.show(); - - scrivito.gui.new_content(target.get(0)); - }, function() { - close(); - }); - }; - - view.on('scrivito_reload', function() { - load_markup(); - return false; - }); - - load_markup(); - - var close = function() { - scrivito.dialog.close(view); - deferred.resolve(); - }; - - var cancel = function(e) { - saving_indicator.destroy(); - close(); - return false; - }; - - view.find('.scrivito_cancel').on('click', cancel); - scrivito.dialog.open_and_adjust(view); - return scrivito.with_dialog_behaviour(view, deferred, {escape: cancel}); - } - } - }); -}()); -(function() { - $.extend(scrivito, { - menus: { - open: function(dom_element, commands) { - scrivito.close_all_menus(); - - var menu = $(scrivito.template.render('menu', { - menu_items: _.map(commands, function(command) { - return scrivito.menu_item.create_instance(command); - }) - })); - - dom_element.data('scrivito-private-menu', menu); - - menu.data('scrivito-menu-close', function() { - dom_element.removeData('scrivito-private-menu'); - menu.fadeOut(500, function() { - menu.remove(); - }); - }); - - menu.data('scrivito-menu-update-position', function() { - menu.offset(dom_element.offset()); - }); - - _.each(commands, function(command) { - menu.on('click', '.scrivito_' + command.id(), function() { - if (command.is_enabled()) { - menu.data('scrivito-menu-close')(); - } - command.execute(); - return false; - }); - }); - - menu.appendTo($('body')); - menu.data('scrivito-menu-update-position')(); // Bugfix IE: can't set offset before append. - menu.find('.scrivito_menu_box').fadeIn(500); - }, - - toggle: function(dom_element, commands) { - var menu = dom_element.data('scrivito-private-menu'); - if (menu) { - menu.data('scrivito-menu-close')(); - } else { - scrivito.menus.open(dom_element, commands); - } - }, - - update_positions: function() { - _.each($('.scrivito_editing_marker_menu'), function(menu) { - var update_position = $(menu).data('scrivito-menu-update-position'); - if (update_position) { - update_position(); - } - }); - } - } - }); -}()); - -$(window).on('resize', function() { - scrivito.menus.update_positions(); -}); - -$(window).on('load', function() { - scrivito.menus.update_positions(); -}); -(function() { - $.extend(scrivito, { - inline_menus: { - toggle: function(dom_element, commands, align) { - var menu = dom_element.find('.scrivito_editing_marker_menu'); - if (menu.length) { - menu.data('scrivito-menu-close')(); - } else { - open(dom_element, commands, align); - } - } - } - }); - - var open = function(dom_element, commands, align) { - scrivito.close_all_menus(); - - var menu = $(scrivito.template.render('menu', {align: align, - menu_items: _.map(commands, function(command) { - return scrivito.menu_item.create_instance(command); - }) - })); - - menu.data('scrivito-menu-close', function() { - menu.find('.scrivito_menu_box').fadeOut(500, function() { - menu.remove(); - }); - }); - - _.each(commands, function(command) { - menu.on('click', '.scrivito_' + command.id(), function() { - if (command.is_enabled()) { - menu.data('scrivito-menu-close')(); - } - command.execute(); - return false; - }); - }); - - menu.appendTo(dom_element); - menu.find('.scrivito_menu_box').fadeIn(500); - }; -}()); -(function() { - $.extend(scrivito, { - close_all_menus: function() { - _.each($('.scrivito_editing_marker_menu'), function(menu) { - $(menu).data('scrivito-menu-close')(); - }); - } - }); -}()); -(function() { - var callbacks = []; - - $.extend(scrivito, { - inplace_marker: { - init: function() { - scrivito.on('load', function() { - scrivito.inplace_marker.refresh(); - }); - scrivito.on('content', function() { - scrivito.inplace_marker.refresh(); - }); - }, - - define: function(callback) { - callbacks.push(callback); - }, - - refresh: function() { - if (!scrivito.editing_context.is_view_mode()) { - $('.scrivito_editing_marker').remove(); - - _.each(callbacks, function(callback) { - callback(builder); - }); - - scrivito.menus.update_positions(); - } - }, - - // For test purpose only. - reset_callbacks: function() { - callbacks = []; - } - } - }); - - var builder = { - activate_for: function(cms_element, options) { - var marker = $(scrivito.template.render('inplace_marker', - $.extend({icon: '\uf000'}, options || {}))); - - marker.on('click', function() { - scrivito.menus.toggle(marker, cms_element.menu()); - return false; - }); - - var marker_container = cms_element.dom_element(); - marker.prependTo(marker_container); - - var timer; - marker_container.on('mouseenter', function() { - marker_container.addClass('scrivito_entered'); - timer = setTimeout(function() { - marker_container.removeClass('scrivito_entered'); - }, 2000); - }); - marker_container.on('mouseleave', function() { - clearTimeout(timer); - }); - } - }; -}()); -(function() { - $.extend(scrivito, { - resource_dialog: { - init: function(config) { - if (config.obj) { - var obj = scrivito.obj.create_instance(config.obj); - scrivito.gui.on('open', function() { - scrivito.resource_dialog.open(obj).done(function() { - return scrivito.redirect_to(config.return_to); - }); - }); - } - }, - - open: function(obj) { - return scrivito.details_dialog.open({ - title: scrivito.t('resource_dialog.title', obj.obj_class_name()), - fetch_markup: function() { - return obj.fetch_details_markup(); - }, - obj: obj, - commands: [ - scrivito.revert_obj_command(obj, 'resource_dialog.commands.revert_obj'), - scrivito.restore_obj_command(obj, 'resource_dialog.commands.restore_obj'), - scrivito.mark_resolved_obj_command(obj, 'resource_dialog.commands.mark_resolved_obj'), - scrivito.delete_obj_command(obj, 'resource_dialog.commands.delete_obj') - ] - }); - } - } - }); -}()); -(function() { - $.extend(scrivito, { - add_subpage_command: function(child_list_element) { - return scrivito.command.create_instance({ - id: 'add_subpage', - title: scrivito.t('commands.add_subpage.title'), - icon: '&#xf022;', - tooltip: scrivito.t('commands.add_subpage.tooltip', - child_list_element.obj().description_for_editor()), - - execute: function() { - var class_selection = child_list_element.fetch_page_class_selection(); - var choose_obj_class = scrivito.choose_obj_class_dialog(class_selection, 'add_child_page'); - - return choose_obj_class.then(function(obj_class) { - return scrivito.with_saving_overlay( - child_list_element.create_child(obj_class).then(function(new_obj) { - return scrivito.redirect_to('/' + new_obj.id()); - }) - ); - }); - } - }); - } - }); -}()); -(function() { - $.extend(scrivito, { - add_widget_command: function(widget_field_element, widget_element) { - return scrivito.command.create_instance({ - id: 'add_widget', - title: scrivito.t('commands.add_widget.title'), - icon: '&#xf022;', - - present: function() { - if (widget_element) { - return scrivito.editing_context.is_editing_mode(); - } else { - return scrivito.editing_context.is_editing_mode() && - widget_field_element.widget_elements().length === 0; - } - }, - - execute: function() { - var selection = widget_field_element.fetch_widget_class_selection(); - var choose_widget_obj_class = scrivito.choose_obj_class_dialog(selection, 'add_widget'); - return choose_widget_obj_class.then(function(obj_class) { - return scrivito.with_saving_overlay( - widget_field_element.create_widget(obj_class, widget_element).then(function(widget) { - return widget.fetch_show_markup().then(function(widget_markup) { - var dom_element = widget_field_element - .append_widget_markup(widget_markup, widget_element); - scrivito.ensure_fully_visible_within_window(dom_element); - scrivito.widget_sorting.update_placeholder(widget_field_element); - }); - }) - ); - }); - } - }); - } - }); -}()); -(function() { - $.extend(scrivito, { - copy_page_from_clipboard_command: function(child_list_element) { - return scrivito.command.create_instance({ - id: 'copy_page_from_clipboard', - title: scrivito.t('commands.copy_page_from_clipboard.title'), - icon: '&#xf015;', - - present: function() { - return scrivito.obj_clipboard.is_present(); - }, - - disabled: function() { - var obj_class_name = scrivito.obj_clipboard.obj().obj_class_name(); - if (!child_list_element.is_valid_child_class(obj_class_name)) { - return scrivito.t('commands.copy_page_from_clipboard.paste_forbidden', - child_list_element.allowed_classes().join(', ')); - } - }, - - execute: function() { - return scrivito.with_saving_overlay( - scrivito.obj_clipboard.obj().copy_to(child_list_element.path()).then(function() { - return scrivito.reload(); - }) - ); - } - }); - } - }); -}()); -(function() { - $.extend(scrivito, { - copy_widget_from_clipboard_command: function(widget_field_element, widget_element) { - return scrivito.command.create_instance({ - id: 'copy_widget_from_clipboard', - title: scrivito.t('commands.copy_widget_from_clipboard.title'), - icon: '&#xf015;', - - present: function() { - var is_editing_mode = scrivito.editing_context.is_editing_mode(); - var is_clipboard_present = scrivito.widget_clipboard.is_present(); - if (widget_element) { - return is_editing_mode && is_clipboard_present; - } else { - var is_empty_widget_field = widget_field_element.widget_elements().length === 0; - return is_editing_mode && is_clipboard_present && is_empty_widget_field; - } - }, - - disabled: function() { - var widget_class_name = scrivito.widget_clipboard.widget().widget_class_name(); - if (!widget_field_element.is_valid_child_class(widget_class_name)) { - return scrivito.t('commands.copy_widget_from_clipboard.paste_forbidden', - widget_field_element.allowed_classes().join(', ')); - } - }, - - execute: function() { - var widget = scrivito.widget_clipboard.widget(); - var widget_id = widget.id(); - var obj_id = widget.obj().id(); - - var copy_widget = widget_field_element.copy_widget(obj_id, widget_id, widget_element); - return scrivito.with_saving_overlay(copy_widget.then(function(widget) { - return widget.fetch_show_markup().then(function(widget_markup) { - var dom_element = widget_field_element - .append_widget_markup(widget_markup, widget_element); - scrivito.ensure_fully_visible_within_window(dom_element); - scrivito.widget_sorting.update_placeholder(widget_field_element); - scrivito.inplace_marker.refresh(); - }); - })); - } - }); - } - }); -}()); -(function() { - $.extend(scrivito, { - create_workspace_command: function() { - return scrivito.command.create_instance({ - id: 'create_workspace', - title: scrivito.t('commands.create_workspace.title'), - icon: '&#xf022;', - - execute: function() { - scrivito.prompt_dialog({ - title: scrivito.t('commands.create_workspace.dialog.title'), - description: scrivito.t('commands.create_workspace.dialog.description'), - placeholder: scrivito.t('commands.create_workspace.dialog.placeholder'), - icon: '&#xf022;', - color: 'green', - accept_button_text: scrivito.t('commands.create_workspace.dialog.accept'), - accept_button_color: 'green' - }).then(function(title) { - scrivito.with_saving_overlay(scrivito.workspace.create(title).then(function(workspace) { - var path = '?_scrivito_workspace_id=' + workspace.id(); - if (!scrivito.editing_context.selected_workspace.is_editable()) { - path += '&_scrivito_display_mode=editing'; - } - return scrivito.redirect_to(path); - })); - }); - } - }); - } - }); -}()); -(function() { - $.extend(scrivito, { - delete_obj_command: function(obj, translations_namespace) { - if (!translations_namespace) { - translations_namespace = 'commands.delete_obj'; - } - - return scrivito.command.create_instance({ - id: 'delete_obj', - title: scrivito.t(translations_namespace + '.title'), - icon: '&#xf018;', - - present: function() { - return obj && !scrivito.editing_context.is_deleted_mode(); - }, - - disabled: function() { - if (!scrivito.editing_context.selected_workspace.is_editable()) { - return scrivito.t('commands.delete_obj.published_workspace'); - } - if (obj.has_children()) { - return scrivito.t('commands.delete_obj.has_children'); - } - }, - - execute: function() { - return scrivito.confirmation_dialog({ - title: scrivito.t(translations_namespace + '.dialog.title'), - description: scrivito.t(translations_namespace + '.dialog.description'), - icon: '&#xf018;', - color: 'red', - confirm_button_text: scrivito.t('commands.delete_obj.dialog.confirm'), - confirm_button_color: 'red' - }).then(function() { - return scrivito.with_saving_overlay(obj.destroy().then(function() { - if (scrivito.obj_clipboard.is_present() && - scrivito.obj_clipboard.obj().id() === obj.id()) { - scrivito.obj_clipboard.clear(); - } - return scrivito.redirect_to('/'); - })); - }); - } - }); - } - }); -}()); -(function() { - $.extend(scrivito, { - delete_widget_command: function(widget_field_element, widget_element) { - return scrivito.command.create_instance({ - id: 'delete_widget', - title: scrivito.t('commands.delete_widget.title'), - icon: '&#xf018;', - - present: function() { - return scrivito.editing_context.is_editing_mode(); - }, - - execute: function() { - return scrivito.confirmation_dialog({ - title: scrivito.t('commands.delete_widget.dialog.title'), - description: scrivito.t('commands.delete_widget.dialog.description'), - icon: '&#xf018;', - color: 'red', - confirm_button_text: scrivito.t('commands.delete_widget.dialog.confirm'), - confirm_button_color: 'red' - }).then(function() { - var widget = widget_element.widget(); - widget_element.dom_element().remove(); - - if (widget_field_element.widget_elements().length === 0) { - scrivito.inplace_marker.refresh(); - } - - scrivito.widget_sorting.update_placeholder(widget_field_element); - - return widget.destroy().then(function() { - if (scrivito.widget_clipboard.is_present() && - scrivito.widget_clipboard.widget().id() === widget.id()) { - scrivito.widget_clipboard.clear(); - } - }); - }); - } - }); - } - }); -}()); -(function() { - $.extend(scrivito, { - delete_workspace_command: function(workspace) { - return scrivito.command.create_instance({ - id: 'delete_workspace', - title: scrivito.t('commands.delete_workspace.title'), - icon: '&#xf018;', - - execute: function() { - scrivito.confirmation_dialog({ - title: scrivito.t('commands.delete_workspace.dialog.title', workspace.title()), - description: scrivito.t('commands.delete_workspace.dialog.description'), - icon: '&#xf018;', - color: 'red', - confirm_button_text: scrivito.t('commands.delete_workspace.dialog.confirm'), - confirm_button_color: 'red' - }).done(function() { - scrivito.with_saving_overlay(workspace.destroy().then(function() { - return scrivito.redirect_to('?_scrivito_workspace_id=published'); - })); - }); - } - }); - } - }); -}()); -(function() { - $.extend(scrivito, { - duplicate_obj_command: function(obj) { - return scrivito.command.create_instance({ - id: 'duplicate_obj', - title: scrivito.t('commands.duplicate_obj.title'), - icon: '&#xf015;', - - present: function() { - return obj && !scrivito.editing_context.is_deleted_mode(); - }, - - disabled: function() { - if (!scrivito.editing_context.selected_workspace.is_editable()) { - return scrivito.t('commands.duplicate_obj.published_workspace'); - } - if (obj.has_children()) { - return scrivito.t('commands.duplicate_obj.has_children'); - } - }, - - execute: function() { - return scrivito.with_saving_overlay(obj.duplicate().then(function(new_obj) { - return scrivito.redirect_to('/' + new_obj.id()); - })); - } - }); - } - }); -}()); -(function() { - $.extend(scrivito, { - mark_resolved_obj_command: function(obj, translations_namespace) { - if (!translations_namespace) { - translations_namespace = 'commands.mark_resolved_obj'; - } - - return scrivito.command.create_instance({ - id: 'mark_resolved_obj', - title: scrivito.t(translations_namespace + '.title'), - icon: '&#xf124;', - - present: function() { - return obj && obj.has_conflict(); - }, - - execute: function() { - return scrivito.confirmation_dialog({ - title: scrivito.t('commands.mark_resolved_obj.dialog.title'), - description: scrivito.t(translations_namespace + '.dialog.description'), - icon: '&#xf124;', - color: 'red', - confirm_button_text: scrivito.t('commands.mark_resolved_obj.dialog.confirm'), - confirm_button_color: 'red' - }).then(function() { - return scrivito.with_saving_overlay(obj.mark_resolved().then(function() { - scrivito.reload(); - })); - }); - } - }); - } - }); -}()); -(function() { - $.extend(scrivito, { - move_page_from_clipboard_command: function(child_list_element) { - return scrivito.command.create_instance({ - id: 'move_page_from_clipboard', - title: scrivito.t('commands.move_page_from_clipboard.title'), - icon: '&#xf016;', - - present: function() { - return scrivito.obj_clipboard.is_present(); - }, - - disabled: function() { - var obj_class_name = scrivito.obj_clipboard.obj().obj_class_name(); - if (!child_list_element.is_valid_child_class(obj_class_name)) { - return scrivito.t('commands.move_page_from_clipboard.paste_forbidden', - child_list_element.allowed_classes().join(', ')); - } - }, - - execute: function() { - var obj = scrivito.obj_clipboard.obj(); - return scrivito.with_saving_overlay(child_list_element.add_child(obj).then(function() { - scrivito.obj_clipboard.clear(); - return scrivito.reload(); - })); - } - }); - } - }); -}()); -(function() { - $.extend(scrivito, { - obj_details_command: function(obj) { - return scrivito.command.create_instance({ - id: 'obj_details', - title: scrivito.t('commands.obj_details.title'), - icon: '&#xf030;', - - present: function() { - return obj.has_details_view(); - }, - - execute: function() { - return scrivito.write_monitor.track_changes(function() { - return scrivito.details_dialog.open({ - title: scrivito.t('commands.obj_details.dialog.title', obj.obj_class_name()), - fetch_markup: function() { - return obj.fetch_details_markup(); - } - }); - }, function() { - return scrivito.with_saving_overlay(scrivito.reload()); - }); - } - }); - } - }); -}()); -(function() { - $.extend(scrivito, { - publish_workspace_command: function(workspace) { - var open_confirmation_dialog = function() { - return scrivito.confirmation_dialog({ - title: scrivito.t('commands.publish_workspace.dialog.title', workspace.title()), - description: scrivito.t('commands.publish_workspace.dialog.description'), - icon: '&#xf064;', - color: 'green', - confirm_button_text: scrivito.t('commands.publish_workspace.dialog.confirm'), - confirm_button_color: 'green' - }); - }; - - var open_check_failed_dialog = function() { - scrivito.confirmation_dialog({ - title: scrivito.t('commands.publish_workspace.error_dialog.title'), - description: scrivito.t('commands.publish_workspace.error_dialog.description'), - color: 'red', - icon: '&#xf064;', - confirm_button_text: scrivito.t('commands.publish_workspace.error_dialog.confirm') - }).then(function() { - scrivito.changes_dialog.open(); - }); - }; - - return scrivito.command.create_instance({ - id: 'publish_workspace', - title: scrivito.t('commands.publish_workspace.title'), - icon: '&#xf064;', - tooltip: scrivito.t('commands.publish_workspace.title', workspace.title()), - - disabled: function() { - if (!scrivito.user_permissions.can('publish_workspace')) { - return scrivito.t('commands.publish_workspace.permission_denied'); - } - }, - - execute: function() { - if (scrivito.user_permissions.can('publish_workspace')) { - open_confirmation_dialog().done(function() { - scrivito.with_saving_overlay(workspace.check_and_publish().done(function() { - return scrivito.redirect_to('?_scrivito_workspace_id=published'); - }).fail(function(error) { - if (error.type === 'check_failed') { - open_check_failed_dialog(); - } else if (error.type === 'outdated_certificates') { - scrivito.alert_dialog( - scrivito.t('commands.publish_workspace.alert.invalid_certificates')); - } - })); - }); - } - } - }); - } - }); -}()); -(function() { - $.extend(scrivito, { - rebase_workspace_command: function(workspace) { - return scrivito.command.create_instance({ - id: 'rebase_workspace', - title: scrivito.t('commands.rebase_workspace.title'), - icon: '&#xf023;', - tooltip: scrivito.t('commands.rebase_workspace.tooltip', workspace.title()), - - disabled: function() { - if (!workspace.is_outdated()) { - return scrivito.t('commands.rebase_workspace.uptodate', workspace.title()); - } - }, - - action_required: function() { - return workspace.is_outdated(); - }, - - execute: function() { - scrivito.with_saving_overlay(workspace.rebase().then(function() { - return scrivito.reload(); - })); - } - }); - } - }); -}()); -(function() { - $.extend(scrivito, { - rename_workspace_command: function(workspace) { - return scrivito.command.create_instance({ - id: 'rename_workspace', - title: scrivito.t('commands.rename_workspace.title'), - icon: '&#xf04f;', - - execute: function() { - scrivito.prompt_dialog({ - title: scrivito.t('commands.rename_workspace.dialog.title', workspace.title()), - description: scrivito.t('commands.rename_workspace.dialog.description'), - value: workspace.original_title(), - icon: '&#xf04f;', - color: 'green', - accept_button_text: scrivito.t('commands.rename_workspace.dialog.accept'), - accept_button_color: 'green' - }).done(function(new_title) { - scrivito.with_saving_overlay(workspace.rename(new_title).then(function() { - return scrivito.reload(); - })); - }); - } - }); - } - }); -}()); -(function() { - $.extend(scrivito, { - restore_obj_command: function(obj, translations_namespace) { - if (!translations_namespace) { - translations_namespace = 'commands.restore_obj'; - } - - return scrivito.command.create_instance({ - id: 'restore_obj', - title: scrivito.t(translations_namespace + '.title'), - icon: '&#xf032;', - - present: function() { - return obj && obj.is_deleted(); - }, - - disabled: function() { - if (scrivito.editing_context.selected_workspace.is_rtc()) { - return scrivito.t(translations_namespace + '.rtc_workspace'); - } - }, - - execute: function() { - return scrivito.with_saving_overlay(obj.restore().then(function() { - scrivito.reload(); - })); - } - }); - } - }); -}()); -(function() { - $.extend(scrivito, { - revert_obj_command: function(obj, translations_namespace) { - if (!translations_namespace) { - translations_namespace = 'commands.revert_obj'; - } - - return scrivito.command.create_instance({ - id: 'revert_obj', - title: scrivito.t(translations_namespace + '.title'), - icon: '&#xf032;', - - present: function() { - return scrivito.editing_context.selected_workspace.is_editable() && - obj && !obj.is_deleted(); - }, - - disabled: function() { - if (scrivito.editing_context.selected_workspace.is_rtc()) { - return scrivito.t(translations_namespace + '.rtc_workspace'); - } - if (!obj.modification()) { - return scrivito.t(translations_namespace + '.not_modified_obj'); - } - if (obj.is_new()) { - return scrivito.t(translations_namespace + '.new_obj'); - } - }, - - update: function() { - return obj.update_modification(); - }, - - execute: function() { - return scrivito.confirmation_dialog({ - title: scrivito.t(translations_namespace + '.dialog.title'), - description: scrivito.t('commands.revert_obj.dialog.description'), - icon: '&#xf032;', - color: 'red', - confirm_button_text: scrivito.t('commands.revert_obj.dialog.confirm'), - confirm_button_color: 'red' - }).then(function() { - return scrivito.with_saving_overlay(obj.revert().then(function() { - scrivito.reload(); - })); - }); - } - }); - } - }); -}()); -(function() { - $.extend(scrivito, { - revert_widget_command: function(widget_element) { - var widget = widget_element.widget(); - return scrivito.command.create_instance({ - id: 'revert_widget', - title: scrivito.i18n.translate('commands.revert_widget.title'), - icon: '&#xf032;', - - present: function() { - return scrivito.editing_context.selected_workspace.is_editable() && !widget.is_deleted(); - }, - - disabled: function() { - if (widget.is_new()) { - return scrivito.i18n.translate('commands.revert_widget.is_new'); - } - if (!widget.is_modified()) { - return scrivito.i18n.translate('commands.revert_widget.is_not_modified'); - } - }, - - update: function() { - return widget.update_modification(); - }, - - execute: function() { - return scrivito.confirmation_dialog({ - title: scrivito.i18n.translate('commands.revert_widget.dialog.title'), - description: scrivito.i18n.translate('commands.revert_widget.dialog.description'), - icon: '&#xf032;', - color: 'red', - confirm_button_text: scrivito.i18n.translate('commands.revert_obj.dialog.confirm'), - confirm_button_color: 'red' - }).then(function() { - var dom_element = widget_element.dom_element(); - scrivito.with_element_overlay(dom_element, widget.revert().then(function() { - dom_element.trigger('scrivito_reload'); - })); - }); - } - }); - } - }); -}()); -(function() { - $.extend(scrivito, { - save_obj_to_clipboard_command: function(obj) { - return scrivito.command.create_instance({ - id: 'save_obj_to_clipboard', - title: scrivito.t('commands.save_obj_to_clipboard.title'), - icon: '&#xf017;', - - present: function() { - return !scrivito.editing_context.is_deleted_mode(); - }, - - disabled: function() { - if (obj.has_children()) { - return scrivito.t('commands.save_obj_to_clipboard.has_children'); - } - }, - - execute: function() { - scrivito.obj_clipboard.save_obj(obj); - } - }); - } - }); -}()); -(function() { - $.extend(scrivito, { - save_widget_to_clipboard_command: function(widget_element) { - return scrivito.command.create_instance({ - id: 'save_widget_to_clipboard', - title: scrivito.t('commands.save_widget_to_clipboard.title'), - icon: '&#xf017;', - - present: function() { - return scrivito.editing_context.is_editing_mode(); - }, - - execute: function() { - scrivito.widget_clipboard.save_widget(widget_element.widget()); - } - }); - } - }); -}()); -(function() { - $.extend(scrivito, { - select_workspace_command: function(workspace) { - return scrivito.command.create_instance({ - id: 'select_workspace_' + workspace.id(), - title: workspace.title(), - icon: workspace.icon(), - - execute: function() { - scrivito.with_saving_overlay( - scrivito.redirect_to('?_scrivito_workspace_id=' + workspace.id())); - } - }); - } - }); -}()); -(function() { - $.extend(scrivito, { - sort_items_command: function(child_list_element) { - return scrivito.command.create_instance({ - id: 'sort_items', - title: scrivito.t('commands.sort_items.title'), - icon: '&#xf03c;', - tooltip: scrivito.t('commands.sort_items.tooltip', - child_list_element.obj().description_for_editor()), - - disabled: function() { - if (!child_list_element.has_child_order()) { - return scrivito.t('commands.sort_items.auto_sort'); - } - if (child_list_element.children().length < 2) { - return scrivito.t('commands.sort_items.too_less_children'); - } - }, - - execute: function() { - var children = child_list_element.children(); - return scrivito.obj_sorting_dialog.open(children).then(function(sorted_children) { - var dom_element = child_list_element.dom_element(); - _.each(sorted_children, function(sorted_child) { - dom_element.append(sorted_child.dom_element()); - }); - return child_list_element.save_order(); - }); - } - }); - } - }); -}()); -(function() { - $.extend(scrivito, { - switch_mode_command: function(mode) { - var icon; - switch (mode) { - case 'diff': - icon = '&#xf035;'; - break; - case 'added': - icon = '&#xf022;'; - break; - case 'deleted': - icon = '&#xf038;'; - break; - } - - return scrivito.command.create_instance({ - id: 'switch_to_' + mode + '_mode', - title: scrivito.t('commands.switch_mode.' + mode), - icon: icon, - - disabled: function() { - if (scrivito.editing_context.display_mode === mode) { - return scrivito.t('commands.switch_mode.disabled'); - } - }, - - execute: function() { - if (mode !== 'view' && !scrivito.editing_context.selected_workspace.is_editable()) { - var fetch_workspaces = scrivito.with_saving_overlay(scrivito.workspace.all_editable()); - fetch_workspaces.then(function(workspaces) { - scrivito.editable_workspace_dialog.open(workspaces).done(function(workspace_id) { - redirect_to(mode, workspace_id); - }); - }); - } else { - redirect_to(mode); - } - } - }); - } - }); - - var redirect_to = function(mode, workspace_id) { - var path = '?_scrivito_display_mode=' + mode; - if (workspace_id) { - path += '&_scrivito_workspace_id=' + workspace_id; - } - scrivito.with_saving_overlay(scrivito.redirect_to(path)); - }; -}()); -(function() { - $.extend(scrivito, { - widget_details_command: function(widget_element) { - var widget = function() { - return widget_element.widget(); - }; - - return scrivito.command.create_instance({ - id: 'widget_details', - title: scrivito.t('commands.widget_details.title'), - icon: '&#xf030;', - - present: function() { - return scrivito.editing_context.is_editing_mode() || - widget().is_modified() || - widget().is_placement_modified(); - }, - - disabled: function() { - if (!widget_element.has_details_view()) { - return scrivito.t('commands.widget_details.no_details_view'); - } - }, - - execute: function() { - return scrivito.write_monitor.track_changes(function() { - return scrivito.details_dialog.open({ - title: scrivito.t('commands.widget_details.dialog.title', widget().widget_class_name()), - fetch_markup: function() { - return widget_element.fetch_details_markup(); - } - }); - }, function() { - widget_element.dom_element().trigger('scrivito_reload'); - }); - } - }); - } - }); -}()); -(function() { - $.extend(scrivito, { - workspace_changes_command: function() { - return scrivito.command.create_instance({ - id: 'workspace_changes', - title: scrivito.t('commands.workspace_changes.title'), - icon: '&#xf080;', - - execute: function() { - scrivito.changes_dialog.open(); - } - }); - } - }); -}()); -(function() { - $.extend(scrivito, { - workspace_settings_command: function(workspace) { - return scrivito.command.create_instance({ - id: 'workspace_settings', - title: scrivito.t('commands.workspace_settings.title'), - icon: '&#xf030;', - - execute: function() { - workspace.fetch_memberships().then(function(memberships) { - var title = scrivito.t('commands.workspace_settings.dialog.title', workspace.title()); - scrivito.workspace_settings_dialog.open(title, memberships).then(function(memberships) { - scrivito.with_saving_overlay( - workspace.update({memberships: memberships}).then(function() { - return scrivito.reload(); - }) - ); - }); - }); - } - }); - } - }); -}()); -(function() { - $.extend(scrivito, { - child_list_commands: { - init: function() { - if (scrivito.editing_context.is_editing_mode()) { - scrivito.on('content', function(content) { - _.each(scrivito.child_list_element.all($(content)), function(child_list_element) { - child_list_element.set_menu([ - scrivito.add_subpage_command(child_list_element), - scrivito.copy_page_from_clipboard_command(child_list_element), - scrivito.move_page_from_clipboard_command(child_list_element), - scrivito.sort_items_command(child_list_element) - ].concat(child_list_element.menu())); - }); - }); - } - } - } - }); -}()); -(function() { - $.extend(scrivito, { - widget_commands: { - init: function() { - if (!scrivito.editing_context.is_view_mode()) { - scrivito.on('content', function(content) { - _.each(scrivito.widget_element.all($(content)), function(widget_element) { - var widget_field_element = widget_element.widget_field(); - widget_element.set_menu([ - scrivito.add_widget_command(widget_field_element, widget_element), - scrivito.widget_details_command(widget_element), - scrivito.save_widget_to_clipboard_command(widget_element), - scrivito.copy_widget_from_clipboard_command(widget_field_element, widget_element), - scrivito.revert_widget_command(widget_element), - scrivito.delete_widget_command(widget_field_element, widget_element) - ].concat(widget_element.menu())); - }); - }); - } - } - } - }); -}()); -(function() { - $.extend(scrivito, { - widget_field_commands: { - init: function() { - if (scrivito.editing_context.is_editing_mode()) { - scrivito.on('content', function(content) { - _.each(scrivito.widget_field_element.all($(content)), function(widget_field_element) { - widget_field_element.set_menu([ - scrivito.add_widget_command(widget_field_element), - scrivito.copy_widget_from_clipboard_command(widget_field_element) - ].concat(widget_field_element.menu())); - }); - }); - } - } - } - }); -}()); -(function() { - $.extend(scrivito, { - child_list_marker: { - init: function() { - scrivito.inplace_marker.define(function(inplace_marker) { - if (scrivito.editing_context.is_editing_mode()) { - _.each(scrivito.child_list_element.all(), function(child_list_element) { - var description = scrivito.t('child_list_menu.description', - child_list_element.obj().description_for_editor()); - inplace_marker.activate_for(child_list_element, {description: description}); - }); - } - }); - } - } - }); -}()); -(function() { - $.extend(scrivito, { - widget_field_marker: { - init: function() { - scrivito.inplace_marker.define(function(inplace_marker) { - if (scrivito.editing_context.is_editing_mode()) { - _.each(scrivito.widget_field_element.all(), function(widget_field_element) { - if (widget_field_element.is_empty()) { - inplace_marker.activate_for(widget_field_element); - } - }); - } - }); - } - } - }); -}()); -(function() { - $.extend(scrivito, { - widget_marker: { - init: function() { - scrivito.inplace_marker.define(function(inplace_marker) { - if (scrivito.editing_context.selected_workspace.is_editable()) { - _.each(scrivito.widget_field_element.all(), function(widget_field_element) { - _.each(widget_field_element.widget_elements(), function(widget_element) { - var show_as_modified = widget_element.widget().is_modified() || - widget_element.widget().is_placement_modified(); - if (scrivito.editing_context.is_editing_mode() || - scrivito.editing_context.is_comparing_mode() && show_as_modified) { - inplace_marker.activate_for(widget_element, - inplace_marker_options(widget_element)); - } - }); - }); - } - }); - } - } - }); - - var inplace_marker_options = function(widget_element) { - var options = {}; - - if (scrivito.editing_context.is_comparing_mode()) { - var tooltip_translation_key; - var modification = widget_element.widget().modification(); - var placement_modification = widget_element.widget().placement_modification(); - - switch (modification) { - case 'new': - tooltip_translation_key = 'widget_is_new'; - options.icon = '\uf022'; - break; - case 'deleted': - tooltip_translation_key = 'widget_is_deleted'; - options.icon = '\uf018'; - break; - case 'edited': - options.icon = '\uf035'; - switch (placement_modification) { - case 'new': - tooltip_translation_key = 'widget_is_edited_and_dragged_here'; - options.css_classes = 'scrivito_widget_moved_icon'; - break; - case 'deleted': - tooltip_translation_key = 'widget_is_edited_and_dragged_away'; - options.css_classes = 'scrivito_widget_moved_icon'; - break; - default: - tooltip_translation_key = 'widget_is_edited'; - } - break; - default: - options.icon = '\uf03c'; - switch (placement_modification) { - case 'new': - tooltip_translation_key = 'widget_is_dragged_here'; - break; - case 'deleted': - tooltip_translation_key = 'widget_is_dragged_away'; - break; - } - } - - if (tooltip_translation_key) { - options.tooltip = scrivito.t('widget_marker.' + tooltip_translation_key); - } - } - - options.description = widget_element.widget().description_for_editor(); - - return options; - }; -}()); -(function() { - $.extend(scrivito, { - widget_reloading: { - init: function() { - scrivito.on('content', function(dom_element) { - if (scrivito.in_editable_view()) { - var jquery_object = $(dom_element); - - if (jquery_object.attr('data-scrivito-private-widget-id')) { - activate_for(jquery_object); - } - - _.each(jquery_object.find('[data-scrivito-private-widget-id]'), function(dom_element) { - activate_for($(dom_element)); - }); - } - }); - } - } - }); - - var activate_for = function(jquery_object) { - jquery_object.on('scrivito_reload', function() { - var widget_element = scrivito.cms_element.from_dom_element(jquery_object); - - scrivito.with_element_overlay(jquery_object, - widget_element.fetch_show_markup().then(function(show_markup) { - var new_jquery_object = $(show_markup); - jquery_object.replaceWith(new_jquery_object); - scrivito.gui.new_content(new_jquery_object.get(0)); - }) - ); - - return false; - }); - }; -}()); -(function() { - $.extend(scrivito, { - widget_sorting: { - init: function() { - scrivito.on('load', function() { - if (scrivito.in_editable_view()) { - create(); - } - }); - scrivito.on('content', function() { - if (scrivito.in_editable_view()) { - create(); - } - }); - }, - - start: function(event, ui) { - $('body').addClass('scrivito_widget_dragging_active'); - - scrivito.close_all_menus(); - - var widget_element = scrivito.cms_element.from_dom_element(ui.item); - var widget_class_name = widget_element.widget().widget_class_name(); - _.each(widget_field_elements, function(widget_field_element) { - var dom_element = widget_field_element.dom_element(); - if (dom_element.data('ui-sortable')) { - if (widget_field_element.is_valid_child_class(widget_class_name)) { - dom_element.addClass('scrivito_widget_drop_allowed'); - } else { - dom_element.sortable('disable'); - } - } - }); - $(event.target).sortable('refresh'); - }, - - stop: function(event, ui) { - $('body').removeClass('scrivito_widget_dragging_active'); - - // Dragged the last widget of the widget field and dropped it back to same widget field. - if (ui.item.parent()[0] === ui.sender) { - var widget_field_element = scrivito.cms_element.from_dom_element(ui.item).widget_field(); - scrivito.widget_sorting.update_placeholder(widget_field_element); - } - - scrivito.inplace_marker.refresh(); - - _.each(widget_field_dom_elements, function(dom_element) { - dom_element.removeClass('scrivito_widget_drop_allowed'); - if (dom_element.data('ui-sortable')) { - $(dom_element).sortable('enable'); - } - }); - }, - - update: function(event, ui) { - if (event.target === ui.item.parent()[0]) { - var widget_field_element = scrivito.cms_element.from_dom_element(ui.item).widget_field(); - scrivito.widget_sorting.update_placeholder(widget_field_element); - - if (ui.sender) { - var sender_widget_field_element = scrivito.cms_element.from_dom_element(ui.sender); - scrivito.widget_sorting.update_placeholder(sender_widget_field_element); - sender_widget_field_element.save().then(function() { - widget_field_element.save(); - }); - } else { - widget_field_element.save(); - } - } - }, - - // We can not listen to "out", because of the a bug in jQuery-Sortable. - // The bug in http://bugs.jqueryui.com/ticket/5671 is still present. - over: function(event, ui) { - if (ui.sender) { - var widget_field_element = scrivito.cms_element.from_dom_element(ui.sender); - // If "over" is triggered, then exactly one item has been removed from the sender field. - var number_of_widget_elements = widget_field_element.widget_elements().length - 1; - scrivito.widget_sorting.update_placeholder(widget_field_element, - number_of_widget_elements); - } - }, - - update_placeholder: function(widget_field_element, number_of_widget_elements) { - var dom_element = widget_field_element.dom_element(); - - if (number_of_widget_elements === undefined) { - number_of_widget_elements = widget_field_element.widget_elements().length; - } - - if (number_of_widget_elements === 0) { - dom_element.addClass('scrivito_empty_widget_field'); - } else { - dom_element.removeClass('scrivito_empty_widget_field'); - } - } - } - }); - - var widget_field_elements = []; - var widget_field_dom_elements = []; - - var create = function() { - if (scrivito.editing_context.visible_workspace.is_editable()) { - _.each(scrivito.widget_field_element.all(), function(widget_field_element) { - var dom_element = widget_field_element.dom_element(); - if (!dom_element.data('ui-sortable')) { - dom_element.sortable({ - items: '> [data-scrivito-private-widget-id]', - handle: '> .scrivito_editing_marker', - placeholder: 'scrivito_widget_drop_placeholder', - connectWith: '*[data-scrivito-field-type="widget"]', - - start: scrivito.widget_sorting.start, - stop: scrivito.widget_sorting.stop, - update: scrivito.widget_sorting.update, - over: scrivito.widget_sorting.over, - - cursor: 'move', - forcePlaceholderSize: true, // Force placeholders to be always visible. - tolerance: 'pointer' // jQuery fails to correctly determine the intersection. - }); - - scrivito.widget_sorting.update_placeholder(widget_field_element); - - widget_field_elements.push(widget_field_element); - widget_field_dom_elements.push(dom_element); - } - }); - } - }; -}()); -(function() { - $.extend(scrivito, { - hotkeys: { - add_actions_while: function(promise, key_map) { - var key_actions = { - 13: key_map.enter, // enter key - 27: key_map.escape // escape key - }; - - $(document).on('keyup.scrivito_hotkeys_add_actions_while', function(e) { - if (key_actions[e.keyCode]) { - e.preventDefault(); - key_actions[e.keyCode](e); - } - }); - - return promise.always(function() { - $(document).off('keyup.scrivito_hotkeys_add_actions_while'); - }); - } - } - }); -}()); -(function() { - $.extend(scrivito, { - with_dialog_behaviour: function(dom_element, promise, key_map) { - return scrivito.with_dialog_overlay(dom_element, - scrivito.hotkeys.add_actions_while(promise, key_map)); - } - }); -}()); -(function() { - $.extend(scrivito, { - editable_workspace_dialog: function(workspaces) { - return scrivito.editable_workspace_dialog.open(workspaces); - } - }); - - $.extend(scrivito.editable_workspace_dialog, { - open: function(workspaces) { - var view = $(scrivito.template.render('editable_workspace_dialog', { - workspaces: workspaces - })); - - $('#scrivito_editing').append(view); - - var create_new_ws = false; - - view.on('focus click', '.scrivito_input_list_of_ws', function(e) { - create_new_ws = false; - view.find(".scrivito_confirm").html(scrivito.t('editable_ws_dialog.select')); - view.find(".scrivito_disabled").removeClass("scrivito_disabled"); - view.find(".scrivito_input_new_ws_name label, .scrivito_input_new_ws_name input").addClass("scrivito_disabled"); - }); - - view.on('focus click drop', '.scrivito_input_new_ws_name', function(e) { - create_new_ws = true; - view.find(".scrivito_confirm").html(scrivito.t('menu_bar.create')); - view.find(".scrivito_disabled").removeClass("scrivito_disabled"); - view.find(".scrivito_input_list_of_ws label, .scrivito_input_list_of_ws select").addClass("scrivito_disabled"); - }); - - var deferred = $.Deferred(); - - var confirm_action = function(e) { - e.preventDefault(); - if (create_new_ws) { - var title = $('#scrivito_new_ws_name').val(); - scrivito.with_saving_overlay( - scrivito.workspace.create(title).then(function(new_workspace) { - return deferred.resolve(new_workspace.id()); - }) - ); - } else { - var ws_id = $('select#scrivito_list_of_ws').val(); - deferred.resolve(ws_id); - } - scrivito.dialog.close(view); - }; - - var cancel_action = function(e) { - e.preventDefault(); - scrivito.dialog.close(view); - deferred.reject(); - }; - - view.find('.scrivito_confirm').on('click', confirm_action); - view.find('.scrivito_cancel').on('click', cancel_action); - - scrivito.dialog.open_and_center(view); - - if (workspaces.length === 0) { - view.find('.scrivito_input_new_ws_name').click(); - view.find('#scrivito_new_ws_name').focus(); - } else { - view.find('.scrivito_input_list_of_ws').click(); - view.find('#scrivito_list_of_ws').focus(); - } - - return scrivito.with_dialog_behaviour(view, deferred, { - enter: confirm_action, - escape: cancel_action - }); - } - }); -}()); -(function() { - $.extend(scrivito, { - obj_sorting_dialog: { - open: function(children) { - var child_list = _.map(children, function(child) { return child.obj(); }); - - var view = $(scrivito.template.render('obj_sorting_dialog', { - icon: '\uF03C', - child_list: child_list - })); - - $('#scrivito_editing').append(view); - $('#scrivito_obj_sorting_sortable').sortable({ - placeholder: 'scrivito_obj_sorting_placeholder' - }); - - var deferred = $.Deferred(); - - var confirm_action = function(e) { - var new_id_order = _.map($('#scrivito_obj_sorting_sortable li'), function(child) { - return $(child).attr('data-scrivito-private-obj-id'); - }); - var sorted_children = _.sortBy(children, function(child) { - return _.indexOf(new_id_order, child.obj().id()); - }); - deferred.resolve(sorted_children); - - scrivito.dialog.close(view); - - return false; - }; - - var cancel_action = function(e) { - deferred.reject(); - scrivito.dialog.close(view); - - return false; - }; - - view.find('.scrivito_confirm').on('click', confirm_action); - view.find('.scrivito_cancel').on('click', cancel_action); - - scrivito.dialog.open_and_adjust(view); - - return scrivito.with_dialog_behaviour(view, deferred, { - enter: confirm_action, - escape: cancel_action - }); - } - } - }); -}()); -(function() { - $.extend(scrivito, { - workspace_settings_dialog: { - open: function(title, memberships) { - var promise = $.Deferred(); - - var view = $(scrivito.template.render('workspace_settings_dialog', { - title: title, - owners: _.pluck(_.where(memberships, {role: 'owner'}), 'user_id').join() - })); - view.appendTo($('#scrivito_editing')); - - var select_owners = view.find('.scrivito_select_owners'); - - var confirm = function() { - var new_memberships = {}; - _.each(select_owners.select2('val'), function(user_id) { - new_memberships[user_id] = {role: 'owner'}; - }); - promise.resolve(new_memberships); - scrivito.dialog.close(view); - return false; - }; - - var cancel = function() { - promise.reject(); - scrivito.dialog.close(view); - return false; - }; - - select_owners.select2({ - multiple: true, - minimumInputLength: 1, - query: scrivito.throttle(function(query) { - scrivito.user.suggest(query.term).then(function(users) { - query.callback({results: _.map(users, function(user) { - return {id: user.id, text: user.description}; - })}); - }); - }, 500), - initSelection: function(element, callback) { - var value = $(element).val(); - if (value) { - callback(_.map(value.split(','), function(user_id) { - return { - id: user_id, - text: _.findWhere(memberships, {user_id: user_id}).description, - locked: user_id === scrivito.user.current.id() - }; - })); - } - }, - formatNoMatches: scrivito.t('workspace_settings_dialog.nothing_found'), - formatSearching: scrivito.t('workspace_settings_dialog.searching'), - formatInputTooShort: scrivito.t('workspace_settings_dialog.too_short') - }); - - view.find('.scrivito_confirm').on('click', confirm); - view.find('.scrivito_cancel').on('click', cancel); - - scrivito.dialog.open_and_adjust(view); - - view.on('keyup', function(e) { - if ((e.keyCode === 13 || e.keyCode === 27) && - $(e.target).attr('class').indexOf('select2') > -1) { - return false; - } - }); - - return scrivito.with_dialog_behaviour(view, promise, {enter: confirm, escape: cancel}); - } - } - }); -}()); -(function() { - $.extend(scrivito, { - warn_before_unloading: function() { - if (scrivito.write_monitor.is_writing()) { - return scrivito.t('warn_before_unloading'); - } - } - }); -}()); -(function(){ - scrivito.obj_clipboard = { - save_obj: function(obj) { - store_obj(obj); - }, - - is_present: function() { - return !!scrivito.storage.has_key(storage_key); - }, - - obj: function() { - var data = stored_data(); - return scrivito.obj.create_instance({id: data.id, obj_class_name: data.obj_class_name}); - }, - - clear: function() { - scrivito.storage.remove(storage_key); - } - }; - - var storage_key = 'obj_clipboard'; - - var store_obj = function(obj) { - var data = {id: obj.id(), obj_class_name: obj.obj_class_name()}; - scrivito.storage.set(storage_key, data); - }; - - var stored_data = function() { - var data = scrivito.storage.get(storage_key); - - return data || {}; - }; -})(); -(function(){ - scrivito.widget_clipboard = { - save_widget: function(widget) { - store_widget(widget); - }, - - is_present: function() { - return !!scrivito.storage.has_key(storage_key); - }, - - widget: function() { - var data = stored_data(); - var obj = scrivito.obj.create_instance({ - id: data.obj_id, - obj_class_name: data.obj_class_name - }); - return scrivito.widget.create_instance(obj, data.id, data.widget_class_name); - }, - - clear: function() { - scrivito.storage.remove(storage_key); - } - }; - - var storage_key = 'widget_clipboard'; - - var store_widget = function(widget) { - var data = { - id: widget.id(), - widget_class_name: widget.widget_class_name(), - obj_id: widget.obj().id(), - obj_class_name: widget.obj().obj_class_name() + in_editable_view: function() { return false; } }; - scrivito.storage.set(storage_key, data); - }; - - var stored_data = function() { - var data = scrivito.storage.get(storage_key); - - return data || {}; - }; -})(); -(function() { - $(function() { - var config = $('[data-scrivito-private-config]').data('scrivito-private-config'); - if (config) { - scrivito.init(config); - scrivito.gui.start(); - } - }); + } }());