web/static/js/ui/jquery.ui.button.js
changeset 30 81d408373dde
equal deleted inserted replaced
29:1f2c13ece5e9 30:81d408373dde
       
     1 /*
       
     2  * jQuery UI Button 1.8.1
       
     3  *
       
     4  * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
       
     5  * Dual licensed under the MIT (MIT-LICENSE.txt)
       
     6  * and GPL (GPL-LICENSE.txt) licenses.
       
     7  *
       
     8  * http://docs.jquery.com/UI/Button
       
     9  *
       
    10  * Depends:
       
    11  *	jquery.ui.core.js
       
    12  *	jquery.ui.widget.js
       
    13  */
       
    14 (function( $ ) {
       
    15 
       
    16 var lastActive,
       
    17 	baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
       
    18 	otherClasses = "ui-state-hover ui-state-active " +
       
    19 		"ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon ui-button-text-only",
       
    20 	formResetHandler = function( event ) {
       
    21 		$( ":ui-button", event.target.form ).each(function() {
       
    22 			var inst = $( this ).data( "button" );
       
    23 			setTimeout(function() {
       
    24 				inst.refresh();
       
    25 			}, 1 );
       
    26 		});
       
    27 	},
       
    28 	radioGroup = function( radio ) {
       
    29 		var name = radio.name,
       
    30 			form = radio.form,
       
    31 			radios = $( [] );
       
    32 		if ( name ) {
       
    33 			if ( form ) {
       
    34 				radios = $( form ).find( "[name='" + name + "']" );
       
    35 			} else {
       
    36 				radios = $( "[name='" + name + "']", radio.ownerDocument )
       
    37 					.filter(function() {
       
    38 						return !this.form;
       
    39 					});
       
    40 			}
       
    41 		}
       
    42 		return radios;
       
    43 	};
       
    44 
       
    45 $.widget( "ui.button", {
       
    46 	options: {
       
    47 		text: true,
       
    48 		label: null,
       
    49 		icons: {
       
    50 			primary: null,
       
    51 			secondary: null
       
    52 		}
       
    53 	},
       
    54 	_create: function() {
       
    55 		this.element.closest( "form" )
       
    56 			.unbind( "reset.button" )
       
    57 			.bind( "reset.button", formResetHandler );
       
    58 
       
    59 		this._determineButtonType();
       
    60 		this.hasTitle = !!this.buttonElement.attr( "title" );
       
    61 
       
    62 		var self = this,
       
    63 			options = this.options,
       
    64 			toggleButton = this.type === "checkbox" || this.type === "radio",
       
    65 			hoverClass = "ui-state-hover" + ( !toggleButton ? " ui-state-active" : "" ),
       
    66 			focusClass = "ui-state-focus";
       
    67 
       
    68 		if ( options.label === null ) {
       
    69 			options.label = this.buttonElement.html();
       
    70 		}
       
    71 
       
    72 		if ( this.element.is( ":disabled" ) ) {
       
    73 			options.disabled = true;
       
    74 		}
       
    75 
       
    76 		this.buttonElement
       
    77 			.addClass( baseClasses )
       
    78 			.attr( "role", "button" )
       
    79 			.bind( "mouseenter.button", function() {
       
    80 				if ( options.disabled ) {
       
    81 					return;
       
    82 				}
       
    83 				$( this ).addClass( "ui-state-hover" );
       
    84 				if ( this === lastActive ) {
       
    85 					$( this ).addClass( "ui-state-active" );
       
    86 				}
       
    87 			})
       
    88 			.bind( "mouseleave.button", function() {
       
    89 				if ( options.disabled ) {
       
    90 					return;
       
    91 				}
       
    92 				$( this ).removeClass( hoverClass );
       
    93 			})
       
    94 			.bind( "focus.button", function() {
       
    95 				// no need to check disabled, focus won't be triggered anyway
       
    96 				$( this ).addClass( focusClass );
       
    97 			})
       
    98 			.bind( "blur.button", function() {
       
    99 				$( this ).removeClass( focusClass );
       
   100 			});
       
   101 
       
   102 		if ( toggleButton ) {
       
   103 			this.element.bind( "change.button", function() {
       
   104 				self.refresh();
       
   105 			});
       
   106 		}
       
   107 
       
   108 		if ( this.type === "checkbox" ) {
       
   109 			this.buttonElement.bind( "click.button", function() {
       
   110 				if ( options.disabled ) {
       
   111 					return false;
       
   112 				}
       
   113 				$( this ).toggleClass( "ui-state-active" );
       
   114 				self.buttonElement.attr( "aria-pressed", self.element[0].checked );
       
   115 			});
       
   116 		} else if ( this.type === "radio" ) {
       
   117 			this.buttonElement.bind( "click.button", function() {
       
   118 				if ( options.disabled ) {
       
   119 					return false;
       
   120 				}
       
   121 				$( this ).addClass( "ui-state-active" );
       
   122 				self.buttonElement.attr( "aria-pressed", true );
       
   123 
       
   124 				var radio = self.element[ 0 ];
       
   125 				radioGroup( radio )
       
   126 					.not( radio )
       
   127 					.map(function() {
       
   128 						return $( this ).button( "widget" )[ 0 ];
       
   129 					})
       
   130 					.removeClass( "ui-state-active" )
       
   131 					.attr( "aria-pressed", false );
       
   132 			});
       
   133 		} else {
       
   134 			this.buttonElement
       
   135 				.bind( "mousedown.button", function() {
       
   136 					if ( options.disabled ) {
       
   137 						return false;
       
   138 					}
       
   139 					$( this ).addClass( "ui-state-active" );
       
   140 					lastActive = this;
       
   141 					$( document ).one( "mouseup", function() {
       
   142 						lastActive = null;
       
   143 					});
       
   144 				})
       
   145 				.bind( "mouseup.button", function() {
       
   146 					if ( options.disabled ) {
       
   147 						return false;
       
   148 					}
       
   149 					$( this ).removeClass( "ui-state-active" );
       
   150 				})
       
   151 				.bind( "keydown.button", function(event) {
       
   152 					if ( options.disabled ) {
       
   153 						return false;
       
   154 					}
       
   155 					if ( event.keyCode == $.ui.keyCode.SPACE || event.keyCode == $.ui.keyCode.ENTER ) {
       
   156 						$( this ).addClass( "ui-state-active" );
       
   157 					}
       
   158 				})
       
   159 				.bind( "keyup.button", function() {
       
   160 					$( this ).removeClass( "ui-state-active" );
       
   161 				});
       
   162 
       
   163 			if ( this.buttonElement.is("a") ) {
       
   164 				this.buttonElement.keyup(function(event) {
       
   165 					if ( event.keyCode === $.ui.keyCode.SPACE ) {
       
   166 						// TODO pass through original event correctly (just as 2nd argument doesn't work)
       
   167 						$( this ).click();
       
   168 					}
       
   169 				});
       
   170 			}
       
   171 		}
       
   172 
       
   173 		// TODO: pull out $.Widget's handling for the disabled option into
       
   174 		// $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
       
   175 		// be overridden by individual plugins
       
   176 		this._setOption( "disabled", options.disabled );
       
   177 	},
       
   178 
       
   179 	_determineButtonType: function() {
       
   180 		
       
   181 		if ( this.element.is(":checkbox") ) {
       
   182 			this.type = "checkbox";
       
   183 		} else {
       
   184 			if ( this.element.is(":radio") ) {
       
   185 				this.type = "radio";
       
   186 			} else {
       
   187 				if ( this.element.is("input") ) {
       
   188 					this.type = "input";
       
   189 				} else {
       
   190 					this.type = "button";
       
   191 				}
       
   192 			}
       
   193 		}
       
   194 		
       
   195 		if ( this.type === "checkbox" || this.type === "radio" ) {
       
   196 			// we don't search against the document in case the element
       
   197 			// is disconnected from the DOM
       
   198 			this.buttonElement = this.element.parents().last()
       
   199 				.find( "[for=" + this.element.attr("id") + "]" );
       
   200 			this.element.addClass( "ui-helper-hidden-accessible" );
       
   201 
       
   202 			var checked = this.element.is( ":checked" );
       
   203 			if ( checked ) {
       
   204 				this.buttonElement.addClass( "ui-state-active" );
       
   205 			}
       
   206 			this.buttonElement.attr( "aria-pressed", checked );
       
   207 		} else {
       
   208 			this.buttonElement = this.element;
       
   209 		}
       
   210 	},
       
   211 
       
   212 	widget: function() {
       
   213 		return this.buttonElement;
       
   214 	},
       
   215 
       
   216 	destroy: function() {
       
   217 		this.element
       
   218 			.removeClass( "ui-helper-hidden-accessible" );
       
   219 		this.buttonElement
       
   220 			.removeClass( baseClasses + " " + otherClasses )
       
   221 			.removeAttr( "role" )
       
   222 			.removeAttr( "aria-pressed" )
       
   223 			.html( this.buttonElement.find(".ui-button-text").html() );
       
   224 
       
   225 		if ( !this.hasTitle ) {
       
   226 			this.buttonElement.removeAttr( "title" );
       
   227 		}
       
   228 
       
   229 		$.Widget.prototype.destroy.call( this );
       
   230 	},
       
   231 
       
   232 	_setOption: function( key, value ) {
       
   233 		$.Widget.prototype._setOption.apply( this, arguments );
       
   234 		if ( key === "disabled" ) {
       
   235 			if ( value ) {
       
   236 				this.element.attr( "disabled", true );
       
   237 			} else {
       
   238 				this.element.removeAttr( "disabled" );
       
   239 			}
       
   240 		}
       
   241 		this._resetButton();
       
   242 	},
       
   243 
       
   244 	refresh: function() {
       
   245 		var isDisabled = this.element.is( ":disabled" );
       
   246 		if ( isDisabled !== this.options.disabled ) {
       
   247 			this._setOption( "disabled", isDisabled );
       
   248 		}
       
   249 		if ( this.type === "radio" ) {
       
   250 			radioGroup( this.element[0] ).each(function() {
       
   251 				if ( $( this ).is( ":checked" ) ) {
       
   252 					$( this ).button( "widget" )
       
   253 						.addClass( "ui-state-active" )
       
   254 						.attr( "aria-pressed", true );
       
   255 				} else {
       
   256 					$( this ).button( "widget" )
       
   257 						.removeClass( "ui-state-active" )
       
   258 						.attr( "aria-pressed", false );
       
   259 				}
       
   260 			});
       
   261 		} else if ( this.type === "checkbox" ) {
       
   262 			if ( this.element.is( ":checked" ) ) {
       
   263 				this.buttonElement
       
   264 					.addClass( "ui-state-active" )
       
   265 					.attr( "aria-pressed", true );
       
   266 			} else {
       
   267 				this.buttonElement
       
   268 					.removeClass( "ui-state-active" )
       
   269 					.attr( "aria-pressed", false );
       
   270 			}
       
   271 		}
       
   272 	},
       
   273 
       
   274 	_resetButton: function() {
       
   275 		if ( this.type === "input" ) {
       
   276 			if ( this.options.label ) {
       
   277 				this.element.val( this.options.label );
       
   278 			}
       
   279 			return;
       
   280 		}
       
   281 		var buttonElement = this.buttonElement,
       
   282 			buttonText = $( "<span></span>" )
       
   283 				.addClass( "ui-button-text" )
       
   284 				.html( this.options.label )
       
   285 				.appendTo( buttonElement.empty() )
       
   286 				.text(),
       
   287 			icons = this.options.icons,
       
   288 			multipleIcons = icons.primary && icons.secondary;
       
   289 		if ( icons.primary || icons.secondary ) {
       
   290 			buttonElement.addClass( "ui-button-text-icon" +
       
   291 				( multipleIcons ? "s" : "" ) );
       
   292 			if ( icons.primary ) {
       
   293 				buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
       
   294 			}
       
   295 			if ( icons.secondary ) {
       
   296 				buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
       
   297 			}
       
   298 			if ( !this.options.text ) {
       
   299 				buttonElement
       
   300 					.addClass( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" )
       
   301 					.removeClass( "ui-button-text-icons ui-button-text-icon" );
       
   302 				if ( !this.hasTitle ) {
       
   303 					buttonElement.attr( "title", buttonText );
       
   304 				}
       
   305 			}
       
   306 		} else {
       
   307 			buttonElement.addClass( "ui-button-text-only" );
       
   308 		}
       
   309 	}
       
   310 });
       
   311 
       
   312 $.widget( "ui.buttonset", {
       
   313 	_create: function() {
       
   314 		this.element.addClass( "ui-buttonset" );
       
   315 		this._init();
       
   316 	},
       
   317 	
       
   318 	_init: function() {
       
   319 		this.refresh();
       
   320 	},
       
   321 
       
   322 	_setOption: function( key, value ) {
       
   323 		if ( key === "disabled" ) {
       
   324 			this.buttons.button( "option", key, value );
       
   325 		}
       
   326 
       
   327 		$.Widget.prototype._setOption.apply( this, arguments );
       
   328 	},
       
   329 	
       
   330 	refresh: function() {
       
   331 		this.buttons = this.element.find( ":button, :submit, :reset, :checkbox, :radio, a, :data(button)" )
       
   332 			.filter( ":ui-button" )
       
   333 				.button( "refresh" )
       
   334 			.end()
       
   335 			.not( ":ui-button" )
       
   336 				.button()
       
   337 			.end()
       
   338 			.map(function() {
       
   339 				return $( this ).button( "widget" )[ 0 ];
       
   340 			})
       
   341 				.removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
       
   342 				.filter( ":first" )
       
   343 					.addClass( "ui-corner-left" )
       
   344 				.end()
       
   345 				.filter( ":last" )
       
   346 					.addClass( "ui-corner-right" )
       
   347 				.end()
       
   348 			.end();
       
   349 	},
       
   350 
       
   351 	destroy: function() {
       
   352 		this.element.removeClass( "ui-buttonset" );
       
   353 		this.buttons
       
   354 			.map(function() {
       
   355 				return $( this ).button( "widget" )[ 0 ];
       
   356 			})
       
   357 				.removeClass( "ui-corner-left ui-corner-right" )
       
   358 			.end()
       
   359 			.button( "destroy" )
       
   360 
       
   361 		$.Widget.prototype.destroy.call( this );
       
   362 	}
       
   363 });
       
   364 
       
   365 }( jQuery ) );