You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

448 lines
11 KiB

1 year ago
  1. /*!
  2. * jQuery UI Button 1.13.2
  3. * http://jqueryui.com
  4. *
  5. * Copyright jQuery Foundation and other contributors
  6. * Released under the MIT license.
  7. * http://jquery.org/license
  8. */
  9. //>>label: Button
  10. //>>group: Widgets
  11. //>>description: Enhances a form with themeable buttons.
  12. //>>docs: http://api.jqueryui.com/button/
  13. //>>demos: http://jqueryui.com/button/
  14. //>>css.structure: ../../themes/base/core.css
  15. //>>css.structure: ../../themes/base/button.css
  16. //>>css.theme: ../../themes/base/theme.css
  17. ( function( factory ) {
  18. "use strict";
  19. if ( typeof define === "function" && define.amd ) {
  20. // AMD. Register as an anonymous module.
  21. define( [
  22. "jquery",
  23. // These are only for backcompat
  24. // TODO: Remove after 1.12
  25. "./controlgroup",
  26. "./checkboxradio",
  27. "./core"
  28. ], factory );
  29. } else {
  30. // Browser globals
  31. factory( jQuery );
  32. }
  33. } )( function( $ ) {
  34. "use strict";
  35. $.widget( "ui.button", {
  36. version: "1.13.2",
  37. defaultElement: "<button>",
  38. options: {
  39. classes: {
  40. "ui-button": "ui-corner-all"
  41. },
  42. disabled: null,
  43. icon: null,
  44. iconPosition: "beginning",
  45. label: null,
  46. showLabel: true
  47. },
  48. _getCreateOptions: function() {
  49. var disabled,
  50. // This is to support cases like in jQuery Mobile where the base widget does have
  51. // an implementation of _getCreateOptions
  52. options = this._super() || {};
  53. this.isInput = this.element.is( "input" );
  54. disabled = this.element[ 0 ].disabled;
  55. if ( disabled != null ) {
  56. options.disabled = disabled;
  57. }
  58. this.originalLabel = this.isInput ? this.element.val() : this.element.html();
  59. if ( this.originalLabel ) {
  60. options.label = this.originalLabel;
  61. }
  62. return options;
  63. },
  64. _create: function() {
  65. if ( !this.option.showLabel & !this.options.icon ) {
  66. this.options.showLabel = true;
  67. }
  68. // We have to check the option again here even though we did in _getCreateOptions,
  69. // because null may have been passed on init which would override what was set in
  70. // _getCreateOptions
  71. if ( this.options.disabled == null ) {
  72. this.options.disabled = this.element[ 0 ].disabled || false;
  73. }
  74. this.hasTitle = !!this.element.attr( "title" );
  75. // Check to see if the label needs to be set or if its already correct
  76. if ( this.options.label && this.options.label !== this.originalLabel ) {
  77. if ( this.isInput ) {
  78. this.element.val( this.options.label );
  79. } else {
  80. this.element.html( this.options.label );
  81. }
  82. }
  83. this._addClass( "ui-button", "ui-widget" );
  84. this._setOption( "disabled", this.options.disabled );
  85. this._enhance();
  86. if ( this.element.is( "a" ) ) {
  87. this._on( {
  88. "keyup": function( event ) {
  89. if ( event.keyCode === $.ui.keyCode.SPACE ) {
  90. event.preventDefault();
  91. // Support: PhantomJS <= 1.9, IE 8 Only
  92. // If a native click is available use it so we actually cause navigation
  93. // otherwise just trigger a click event
  94. if ( this.element[ 0 ].click ) {
  95. this.element[ 0 ].click();
  96. } else {
  97. this.element.trigger( "click" );
  98. }
  99. }
  100. }
  101. } );
  102. }
  103. },
  104. _enhance: function() {
  105. if ( !this.element.is( "button" ) ) {
  106. this.element.attr( "role", "button" );
  107. }
  108. if ( this.options.icon ) {
  109. this._updateIcon( "icon", this.options.icon );
  110. this._updateTooltip();
  111. }
  112. },
  113. _updateTooltip: function() {
  114. this.title = this.element.attr( "title" );
  115. if ( !this.options.showLabel && !this.title ) {
  116. this.element.attr( "title", this.options.label );
  117. }
  118. },
  119. _updateIcon: function( option, value ) {
  120. var icon = option !== "iconPosition",
  121. position = icon ? this.options.iconPosition : value,
  122. displayBlock = position === "top" || position === "bottom";
  123. // Create icon
  124. if ( !this.icon ) {
  125. this.icon = $( "<span>" );
  126. this._addClass( this.icon, "ui-button-icon", "ui-icon" );
  127. if ( !this.options.showLabel ) {
  128. this._addClass( "ui-button-icon-only" );
  129. }
  130. } else if ( icon ) {
  131. // If we are updating the icon remove the old icon class
  132. this._removeClass( this.icon, null, this.options.icon );
  133. }
  134. // If we are updating the icon add the new icon class
  135. if ( icon ) {
  136. this._addClass( this.icon, null, value );
  137. }
  138. this._attachIcon( position );
  139. // If the icon is on top or bottom we need to add the ui-widget-icon-block class and remove
  140. // the iconSpace if there is one.
  141. if ( displayBlock ) {
  142. this._addClass( this.icon, null, "ui-widget-icon-block" );
  143. if ( this.iconSpace ) {
  144. this.iconSpace.remove();
  145. }
  146. } else {
  147. // Position is beginning or end so remove the ui-widget-icon-block class and add the
  148. // space if it does not exist
  149. if ( !this.iconSpace ) {
  150. this.iconSpace = $( "<span> </span>" );
  151. this._addClass( this.iconSpace, "ui-button-icon-space" );
  152. }
  153. this._removeClass( this.icon, null, "ui-wiget-icon-block" );
  154. this._attachIconSpace( position );
  155. }
  156. },
  157. _destroy: function() {
  158. this.element.removeAttr( "role" );
  159. if ( this.icon ) {
  160. this.icon.remove();
  161. }
  162. if ( this.iconSpace ) {
  163. this.iconSpace.remove();
  164. }
  165. if ( !this.hasTitle ) {
  166. this.element.removeAttr( "title" );
  167. }
  168. },
  169. _attachIconSpace: function( iconPosition ) {
  170. this.icon[ /^(?:end|bottom)/.test( iconPosition ) ? "before" : "after" ]( this.iconSpace );
  171. },
  172. _attachIcon: function( iconPosition ) {
  173. this.element[ /^(?:end|bottom)/.test( iconPosition ) ? "append" : "prepend" ]( this.icon );
  174. },
  175. _setOptions: function( options ) {
  176. var newShowLabel = options.showLabel === undefined ?
  177. this.options.showLabel :
  178. options.showLabel,
  179. newIcon = options.icon === undefined ? this.options.icon : options.icon;
  180. if ( !newShowLabel && !newIcon ) {
  181. options.showLabel = true;
  182. }
  183. this._super( options );
  184. },
  185. _setOption: function( key, value ) {
  186. if ( key === "icon" ) {
  187. if ( value ) {
  188. this._updateIcon( key, value );
  189. } else if ( this.icon ) {
  190. this.icon.remove();
  191. if ( this.iconSpace ) {
  192. this.iconSpace.remove();
  193. }
  194. }
  195. }
  196. if ( key === "iconPosition" ) {
  197. this._updateIcon( key, value );
  198. }
  199. // Make sure we can't end up with a button that has neither text nor icon
  200. if ( key === "showLabel" ) {
  201. this._toggleClass( "ui-button-icon-only", null, !value );
  202. this._updateTooltip();
  203. }
  204. if ( key === "label" ) {
  205. if ( this.isInput ) {
  206. this.element.val( value );
  207. } else {
  208. // If there is an icon, append it, else nothing then append the value
  209. // this avoids removal of the icon when setting label text
  210. this.element.html( value );
  211. if ( this.icon ) {
  212. this._attachIcon( this.options.iconPosition );
  213. this._attachIconSpace( this.options.iconPosition );
  214. }
  215. }
  216. }
  217. this._super( key, value );
  218. if ( key === "disabled" ) {
  219. this._toggleClass( null, "ui-state-disabled", value );
  220. this.element[ 0 ].disabled = value;
  221. if ( value ) {
  222. this.element.trigger( "blur" );
  223. }
  224. }
  225. },
  226. refresh: function() {
  227. // Make sure to only check disabled if its an element that supports this otherwise
  228. // check for the disabled class to determine state
  229. var isDisabled = this.element.is( "input, button" ) ?
  230. this.element[ 0 ].disabled : this.element.hasClass( "ui-button-disabled" );
  231. if ( isDisabled !== this.options.disabled ) {
  232. this._setOptions( { disabled: isDisabled } );
  233. }
  234. this._updateTooltip();
  235. }
  236. } );
  237. // DEPRECATED
  238. if ( $.uiBackCompat !== false ) {
  239. // Text and Icons options
  240. $.widget( "ui.button", $.ui.button, {
  241. options: {
  242. text: true,
  243. icons: {
  244. primary: null,
  245. secondary: null
  246. }
  247. },
  248. _create: function() {
  249. if ( this.options.showLabel && !this.options.text ) {
  250. this.options.showLabel = this.options.text;
  251. }
  252. if ( !this.options.showLabel && this.options.text ) {
  253. this.options.text = this.options.showLabel;
  254. }
  255. if ( !this.options.icon && ( this.options.icons.primary ||
  256. this.options.icons.secondary ) ) {
  257. if ( this.options.icons.primary ) {
  258. this.options.icon = this.options.icons.primary;
  259. } else {
  260. this.options.icon = this.options.icons.secondary;
  261. this.options.iconPosition = "end";
  262. }
  263. } else if ( this.options.icon ) {
  264. this.options.icons.primary = this.options.icon;
  265. }
  266. this._super();
  267. },
  268. _setOption: function( key, value ) {
  269. if ( key === "text" ) {
  270. this._super( "showLabel", value );
  271. return;
  272. }
  273. if ( key === "showLabel" ) {
  274. this.options.text = value;
  275. }
  276. if ( key === "icon" ) {
  277. this.options.icons.primary = value;
  278. }
  279. if ( key === "icons" ) {
  280. if ( value.primary ) {
  281. this._super( "icon", value.primary );
  282. this._super( "iconPosition", "beginning" );
  283. } else if ( value.secondary ) {
  284. this._super( "icon", value.secondary );
  285. this._super( "iconPosition", "end" );
  286. }
  287. }
  288. this._superApply( arguments );
  289. }
  290. } );
  291. $.fn.button = ( function( orig ) {
  292. return function( options ) {
  293. var isMethodCall = typeof options === "string";
  294. var args = Array.prototype.slice.call( arguments, 1 );
  295. var returnValue = this;
  296. if ( isMethodCall ) {
  297. // If this is an empty collection, we need to have the instance method
  298. // return undefined instead of the jQuery instance
  299. if ( !this.length && options === "instance" ) {
  300. returnValue = undefined;
  301. } else {
  302. this.each( function() {
  303. var methodValue;
  304. var type = $( this ).attr( "type" );
  305. var name = type !== "checkbox" && type !== "radio" ?
  306. "button" :
  307. "checkboxradio";
  308. var instance = $.data( this, "ui-" + name );
  309. if ( options === "instance" ) {
  310. returnValue = instance;
  311. return false;
  312. }
  313. if ( !instance ) {
  314. return $.error( "cannot call methods on button" +
  315. " prior to initialization; " +
  316. "attempted to call method '" + options + "'" );
  317. }
  318. if ( typeof instance[ options ] !== "function" ||
  319. options.charAt( 0 ) === "_" ) {
  320. return $.error( "no such method '" + options + "' for button" +
  321. " widget instance" );
  322. }
  323. methodValue = instance[ options ].apply( instance, args );
  324. if ( methodValue !== instance && methodValue !== undefined ) {
  325. returnValue = methodValue && methodValue.jquery ?
  326. returnValue.pushStack( methodValue.get() ) :
  327. methodValue;
  328. return false;
  329. }
  330. } );
  331. }
  332. } else {
  333. // Allow multiple hashes to be passed on init
  334. if ( args.length ) {
  335. options = $.widget.extend.apply( null, [ options ].concat( args ) );
  336. }
  337. this.each( function() {
  338. var type = $( this ).attr( "type" );
  339. var name = type !== "checkbox" && type !== "radio" ? "button" : "checkboxradio";
  340. var instance = $.data( this, "ui-" + name );
  341. if ( instance ) {
  342. instance.option( options || {} );
  343. if ( instance._init ) {
  344. instance._init();
  345. }
  346. } else {
  347. if ( name === "button" ) {
  348. orig.call( $( this ), options );
  349. return;
  350. }
  351. $( this ).checkboxradio( $.extend( { icon: false }, options ) );
  352. }
  353. } );
  354. }
  355. return returnValue;
  356. };
  357. } )( $.fn.button );
  358. $.fn.buttonset = function() {
  359. if ( !$.ui.controlgroup ) {
  360. $.error( "Controlgroup widget missing" );
  361. }
  362. if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" && arguments[ 2 ] ) {
  363. return this.controlgroup.apply( this,
  364. [ arguments[ 0 ], "items.button", arguments[ 2 ] ] );
  365. }
  366. if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" ) {
  367. return this.controlgroup.apply( this, [ arguments[ 0 ], "items.button" ] );
  368. }
  369. if ( typeof arguments[ 0 ] === "object" && arguments[ 0 ].items ) {
  370. arguments[ 0 ].items = {
  371. button: arguments[ 0 ].items
  372. };
  373. }
  374. return this.controlgroup.apply( this, arguments );
  375. };
  376. }
  377. return $.ui.button;
  378. } );