Repository: jquery/jquery-ui Branch: main Commit: 839ff8fae666 Files: 654 Total size: 8.6 MB Directory structure: gitextract_52g99wg1/ ├── .csslintrc ├── .editorconfig ├── .gitattributes ├── .github/ │ ├── dependabot.yml │ └── workflows/ │ ├── browser-tests.yml │ ├── codeql-analysis.yml │ ├── filestash.yml │ └── node.js.yml ├── .gitignore ├── .mailmap ├── .npmignore ├── .npmrc ├── AUTHORS.txt ├── CONTRIBUTING.md ├── Gruntfile.js ├── LICENSE.txt ├── README.md ├── SECURITY.md ├── bower.json ├── build/ │ ├── release-test.js │ ├── release.js │ └── tasks/ │ ├── build.js │ └── minify.js ├── demos/ │ ├── accordion/ │ │ ├── collapsible.html │ │ ├── custom-icons.html │ │ ├── default.html │ │ ├── fillspace.html │ │ ├── index.html │ │ ├── no-auto-height.html │ │ └── sortable.html │ ├── autocomplete/ │ │ ├── categories.html │ │ ├── combobox.html │ │ ├── custom-data.html │ │ ├── default.html │ │ ├── folding.html │ │ ├── index.html │ │ ├── london.xml │ │ ├── maxheight.html │ │ ├── multiple-remote.html │ │ ├── multiple.html │ │ ├── remote-jsonp.html │ │ ├── remote-with-cache.html │ │ ├── remote.html │ │ └── xml.html │ ├── bootstrap.js │ ├── button/ │ │ ├── default.html │ │ ├── icons.html │ │ └── index.html │ ├── checkboxradio/ │ │ ├── default.html │ │ ├── index.html │ │ ├── no-icons.html │ │ ├── product-selector.html │ │ └── radiogroup.html │ ├── controlgroup/ │ │ ├── default.html │ │ ├── index.html │ │ ├── splitbutton.html │ │ └── toolbar.html │ ├── datepicker/ │ │ ├── alt-field.html │ │ ├── animation.html │ │ ├── buttonbar.html │ │ ├── date-formats.html │ │ ├── date-range.html │ │ ├── default.html │ │ ├── dropdown-month-year.html │ │ ├── icon-trigger.html │ │ ├── index.html │ │ ├── inline.html │ │ ├── localization.html │ │ ├── min-max.html │ │ ├── multiple-calendars.html │ │ ├── other-months.html │ │ └── show-week.html │ ├── demos.css │ ├── dialog/ │ │ ├── animated.html │ │ ├── default.html │ │ ├── index.html │ │ ├── modal-confirmation.html │ │ ├── modal-form.html │ │ └── modal-message.html │ ├── draggable/ │ │ ├── constrain-movement.html │ │ ├── cursor-style.html │ │ ├── default.html │ │ ├── events.html │ │ ├── handle.html │ │ ├── index.html │ │ ├── revert.html │ │ ├── scroll.html │ │ ├── snap-to.html │ │ ├── sortable.html │ │ └── visual-feedback.html │ ├── droppable/ │ │ ├── accepted-elements.html │ │ ├── default.html │ │ ├── index.html │ │ ├── photo-manager.html │ │ ├── propagation.html │ │ ├── revert.html │ │ └── visual-feedback.html │ ├── effect/ │ │ ├── addClass.html │ │ ├── animate.html │ │ ├── default.html │ │ ├── easing.html │ │ ├── hide.html │ │ ├── index.html │ │ ├── removeClass.html │ │ ├── show.html │ │ ├── switchClass.html │ │ ├── toggle.html │ │ └── toggleClass.html │ ├── index.html │ ├── menu/ │ │ ├── categories.html │ │ ├── default.html │ │ ├── icons.html │ │ └── index.html │ ├── position/ │ │ ├── cycler.html │ │ ├── default.html │ │ └── index.html │ ├── progressbar/ │ │ ├── default.html │ │ ├── download.html │ │ ├── indeterminate.html │ │ ├── index.html │ │ └── label.html │ ├── resizable/ │ │ ├── animate.html │ │ ├── aspect-ratio.html │ │ ├── constrain-area.html │ │ ├── default.html │ │ ├── helper.html │ │ ├── index.html │ │ ├── max-min.html │ │ ├── snap-to-grid.html │ │ ├── synchronous-resize.html │ │ ├── textarea.html │ │ └── visual-feedback.html │ ├── search.js │ ├── selectable/ │ │ ├── default.html │ │ ├── display-grid.html │ │ ├── index.html │ │ └── serialize.html │ ├── selectmenu/ │ │ ├── custom_render.html │ │ ├── default.html │ │ ├── index.html │ │ └── product-selection.html │ ├── slider/ │ │ ├── colorpicker.html │ │ ├── custom-handle.html │ │ ├── default.html │ │ ├── hotelrooms.html │ │ ├── index.html │ │ ├── multiple-vertical.html │ │ ├── range-vertical.html │ │ ├── range.html │ │ ├── rangemax.html │ │ ├── rangemin.html │ │ ├── slider-vertical.html │ │ └── steps.html │ ├── sortable/ │ │ ├── connect-lists.html │ │ ├── default.html │ │ ├── display-grid.html │ │ ├── empty-lists.html │ │ ├── index.html │ │ ├── items.html │ │ ├── placeholder.html │ │ └── portlets.html │ ├── spinner/ │ │ ├── currency.html │ │ ├── decimal.html │ │ ├── default.html │ │ ├── index.html │ │ ├── latlong.html │ │ ├── overflow.html │ │ └── time.html │ ├── tabs/ │ │ ├── ajax/ │ │ │ ├── content1.html │ │ │ ├── content2.html │ │ │ └── content3-slow.html │ │ ├── ajax.html │ │ ├── collapsible.html │ │ ├── default.html │ │ ├── index.html │ │ ├── manipulation.html │ │ ├── mouseover.html │ │ ├── sortable.html │ │ └── vertical.html │ ├── tooltip/ │ │ ├── ajax/ │ │ │ ├── content1.html │ │ │ └── content2.html │ │ ├── custom-animation.html │ │ ├── custom-content.html │ │ ├── custom-style.html │ │ ├── default.html │ │ ├── forms.html │ │ ├── index.html │ │ ├── tracking.html │ │ └── video-player.html │ └── widget/ │ ├── default.html │ └── index.html ├── eslint.config.mjs ├── external/ │ ├── globalize/ │ │ ├── LICENSE │ │ ├── globalize.culture.de-DE.js │ │ ├── globalize.culture.ja-JP.js │ │ └── globalize.js │ ├── jquery/ │ │ ├── LICENSE.txt │ │ ├── MIT-LICENSE.txt │ │ └── jquery.js │ ├── jquery-1.12.4/ │ │ ├── LICENSE.txt │ │ └── jquery.js │ ├── jquery-2.2.4/ │ │ ├── LICENSE.txt │ │ └── jquery.js │ ├── jquery-3.0.0/ │ │ ├── LICENSE.txt │ │ └── jquery.js │ ├── jquery-3.1.0/ │ │ ├── LICENSE.txt │ │ └── jquery.js │ ├── jquery-3.1.1/ │ │ ├── LICENSE.txt │ │ └── jquery.js │ ├── jquery-3.2.0/ │ │ ├── LICENSE.txt │ │ └── jquery.js │ ├── jquery-3.2.1/ │ │ ├── LICENSE.txt │ │ └── jquery.js │ ├── jquery-3.3.0/ │ │ ├── LICENSE.txt │ │ └── jquery.js │ ├── jquery-3.3.1/ │ │ ├── LICENSE.txt │ │ └── jquery.js │ ├── jquery-3.4.0/ │ │ ├── LICENSE.txt │ │ └── jquery.js │ ├── jquery-3.4.1/ │ │ ├── LICENSE.txt │ │ └── jquery.js │ ├── jquery-3.5.0/ │ │ ├── LICENSE.txt │ │ └── jquery.js │ ├── jquery-3.5.1/ │ │ ├── LICENSE.txt │ │ └── jquery.js │ ├── jquery-3.6.0/ │ │ ├── LICENSE.txt │ │ └── jquery.js │ ├── jquery-3.6.1/ │ │ ├── LICENSE.txt │ │ └── jquery.js │ ├── jquery-3.6.2/ │ │ ├── LICENSE.txt │ │ └── jquery.js │ ├── jquery-3.6.3/ │ │ ├── LICENSE.txt │ │ └── jquery.js │ ├── jquery-3.6.4/ │ │ ├── LICENSE.txt │ │ └── jquery.js │ ├── jquery-3.7.0/ │ │ ├── LICENSE.txt │ │ └── jquery.js │ ├── jquery-3.7.1/ │ │ ├── LICENSE.txt │ │ └── jquery.js │ ├── jquery-4.0.0/ │ │ ├── LICENSE.txt │ │ └── jquery.js │ ├── jquery-custom/ │ │ ├── MIT-LICENSE.txt │ │ └── jquery.js │ ├── jquery-migrate-1.x/ │ │ ├── LICENSE.txt │ │ └── jquery-migrate.js │ ├── jquery-migrate-3.x/ │ │ ├── LICENSE.txt │ │ └── jquery-migrate.js │ ├── jquery-migrate-4.x/ │ │ ├── LICENSE.txt │ │ └── jquery-migrate.js │ ├── jquery-mousewheel/ │ │ ├── LICENSE.txt │ │ └── jquery.mousewheel.js │ ├── jquery-simulate/ │ │ ├── LICENSE.txt │ │ └── jquery.simulate.js │ ├── qunit/ │ │ ├── LICENSE.txt │ │ ├── MIT-LICENSE.txt │ │ ├── qunit.css │ │ └── qunit.js │ └── requirejs/ │ └── require.js ├── jtr-git.yml ├── jtr-stable.yml ├── jtr.yml ├── package.json ├── tests/ │ ├── index.css │ ├── index.html │ ├── index.js │ ├── lib/ │ │ ├── bootstrap.js │ │ ├── common.js │ │ ├── css.js │ │ ├── grunt-contrib-qunit-bridges/ │ │ │ ├── bridge-wrapper.js.intro │ │ │ └── bridge-wrapper.js.outro │ │ ├── helper.js │ │ ├── qunit-assert-domequal.js │ │ ├── qunit.js │ │ ├── testIframe.js │ │ └── vendor/ │ │ ├── qunit-assert-classes/ │ │ │ ├── LICENSE.txt │ │ │ └── qunit-assert-classes.js │ │ ├── qunit-assert-close/ │ │ │ ├── MIT-LICENSE.txt │ │ │ └── qunit-assert-close.js │ │ └── qunit-composite/ │ │ ├── LICENSE.txt │ │ ├── qunit-composite.css │ │ └── qunit-composite.js │ ├── unit/ │ │ ├── accordion/ │ │ │ ├── accordion.html │ │ │ ├── all.html │ │ │ ├── common.js │ │ │ ├── core.js │ │ │ ├── events.js │ │ │ ├── helper.js │ │ │ ├── methods.js │ │ │ └── options.js │ │ ├── all.html │ │ ├── autocomplete/ │ │ │ ├── all.html │ │ │ ├── autocomplete.html │ │ │ ├── common.js │ │ │ ├── core.js │ │ │ ├── events.js │ │ │ ├── methods.js │ │ │ ├── options.js │ │ │ ├── remote_object_array_labels.txt │ │ │ ├── remote_object_array_values.txt │ │ │ └── remote_string_array.txt │ │ ├── button/ │ │ │ ├── all.html │ │ │ ├── button.html │ │ │ ├── common-deprecated.js │ │ │ ├── common.js │ │ │ ├── core.js │ │ │ ├── deprecated.html │ │ │ ├── deprecated.js │ │ │ ├── events.js │ │ │ ├── methods.js │ │ │ └── options.js │ │ ├── checkboxradio/ │ │ │ ├── all.html │ │ │ ├── checkboxradio.html │ │ │ ├── common.js │ │ │ ├── core.js │ │ │ ├── events.js │ │ │ ├── methods.js │ │ │ └── options.js │ │ ├── controlgroup/ │ │ │ ├── all.html │ │ │ ├── common.js │ │ │ ├── controlgroup.html │ │ │ ├── core.js │ │ │ ├── methods.js │ │ │ └── options.js │ │ ├── core/ │ │ │ ├── all.html │ │ │ ├── core.html │ │ │ ├── core.js │ │ │ └── selector.js │ │ ├── datepicker/ │ │ │ ├── all.html │ │ │ ├── common.js │ │ │ ├── core.js │ │ │ ├── datepicker.html │ │ │ ├── events.js │ │ │ ├── helper.js │ │ │ ├── methods.js │ │ │ └── options.js │ │ ├── dialog/ │ │ │ ├── all.html │ │ │ ├── common-deprecated.js │ │ │ ├── common.js │ │ │ ├── core.js │ │ │ ├── deprecated.html │ │ │ ├── deprecated.js │ │ │ ├── dialog.html │ │ │ ├── events.js │ │ │ ├── helper.js │ │ │ ├── methods.js │ │ │ └── options.js │ │ ├── draggable/ │ │ │ ├── all.html │ │ │ ├── common.js │ │ │ ├── core.js │ │ │ ├── draggable.html │ │ │ ├── events.js │ │ │ ├── helper.js │ │ │ ├── methods.js │ │ │ └── options.js │ │ ├── droppable/ │ │ │ ├── all.html │ │ │ ├── common-deprecated.js │ │ │ ├── common.js │ │ │ ├── core.js │ │ │ ├── deprecated.html │ │ │ ├── deprecated.js │ │ │ ├── droppable.html │ │ │ ├── events.js │ │ │ ├── helper.js │ │ │ ├── methods.js │ │ │ └── options.js │ │ ├── effects/ │ │ │ ├── all.html │ │ │ ├── core.js │ │ │ ├── effects.html │ │ │ └── scale.js │ │ ├── form-reset-mixin/ │ │ │ ├── all.html │ │ │ ├── core.js │ │ │ └── form-reset-mixin.html │ │ ├── index.html │ │ ├── jquery-patch/ │ │ │ ├── all.html │ │ │ ├── core.js │ │ │ └── jquery-patch.html │ │ ├── menu/ │ │ │ ├── all.html │ │ │ ├── common.js │ │ │ ├── core.js │ │ │ ├── events.js │ │ │ ├── helper.js │ │ │ ├── menu.html │ │ │ ├── methods.js │ │ │ └── options.js │ │ ├── position/ │ │ │ ├── all.html │ │ │ ├── core.js │ │ │ └── position.html │ │ ├── progressbar/ │ │ │ ├── all.html │ │ │ ├── common.js │ │ │ ├── core.js │ │ │ ├── events.js │ │ │ ├── methods.js │ │ │ ├── options.js │ │ │ └── progressbar.html │ │ ├── resizable/ │ │ │ ├── all.html │ │ │ ├── common.js │ │ │ ├── core.js │ │ │ ├── events.js │ │ │ ├── helper.js │ │ │ ├── methods.js │ │ │ ├── options.js │ │ │ └── resizable.html │ │ ├── selectable/ │ │ │ ├── all.html │ │ │ ├── common.js │ │ │ ├── core.js │ │ │ ├── events.js │ │ │ ├── methods.js │ │ │ ├── options.js │ │ │ └── selectable.html │ │ ├── selectmenu/ │ │ │ ├── all.html │ │ │ ├── common.js │ │ │ ├── core.js │ │ │ ├── events.js │ │ │ ├── methods.js │ │ │ ├── options.js │ │ │ └── selectmenu.html │ │ ├── slider/ │ │ │ ├── all.html │ │ │ ├── common.js │ │ │ ├── core.js │ │ │ ├── events.js │ │ │ ├── methods.js │ │ │ ├── options.js │ │ │ └── slider.html │ │ ├── sortable/ │ │ │ ├── all.html │ │ │ ├── common.js │ │ │ ├── core.js │ │ │ ├── events.js │ │ │ ├── helper.js │ │ │ ├── methods.js │ │ │ ├── options.js │ │ │ └── sortable.html │ │ ├── spinner/ │ │ │ ├── all.html │ │ │ ├── common-deprecated.js │ │ │ ├── common.js │ │ │ ├── core.js │ │ │ ├── deprecated.html │ │ │ ├── deprecated.js │ │ │ ├── events.js │ │ │ ├── helper.js │ │ │ ├── methods.js │ │ │ ├── mousewheel-wheel.html │ │ │ ├── options.js │ │ │ └── spinner.html │ │ ├── subsuite.js │ │ ├── tabs/ │ │ │ ├── all.html │ │ │ ├── common.js │ │ │ ├── core.js │ │ │ ├── data/ │ │ │ │ └── test.html │ │ │ ├── events.js │ │ │ ├── helper.js │ │ │ ├── methods.js │ │ │ ├── options.js │ │ │ └── tabs.html │ │ ├── tooltip/ │ │ │ ├── all.html │ │ │ ├── common-deprecated.js │ │ │ ├── common.js │ │ │ ├── core.js │ │ │ ├── deprecated.html │ │ │ ├── deprecated.js │ │ │ ├── events.js │ │ │ ├── helper.js │ │ │ ├── methods.js │ │ │ ├── options.js │ │ │ └── tooltip.html │ │ └── widget/ │ │ ├── all.html │ │ ├── animation.js │ │ ├── classes.js │ │ ├── core.js │ │ ├── extend.js │ │ └── widget.html │ └── visual/ │ ├── accordion/ │ │ └── icons.html │ ├── addClass/ │ │ └── queue.html │ ├── checkboxradio/ │ │ └── checkboxradio.html │ ├── compound/ │ │ ├── accordion_tabs.html │ │ ├── datepicker_dialog.html │ │ ├── dialog_widgets.html │ │ ├── draggable_accordion.html │ │ ├── draggable_accordion_accordion_tabs_draggable.html │ │ ├── draggable_resizable.html │ │ ├── sortable_accordion_sortable_tabs.html │ │ ├── tabs_selectmenu.html │ │ ├── tabs_tabs.html │ │ └── tabs_tooltips.html │ ├── dialog/ │ │ ├── animated.html │ │ ├── complex-dialogs.html │ │ ├── form.html │ │ ├── performance.html │ │ └── stacking.html │ ├── draggable/ │ │ └── replaced.html │ ├── effects/ │ │ ├── all.html │ │ ├── clip.html │ │ ├── effects.css │ │ ├── effects.js │ │ ├── scale.html │ │ └── shake.html │ ├── index.html │ ├── menu/ │ │ └── menu.html │ ├── position/ │ │ ├── position.html │ │ └── position_feedback.html │ ├── selectmenu/ │ │ └── selectmenu.html │ ├── slider/ │ │ └── range_slider.html │ ├── tooltip/ │ │ ├── animations.html │ │ └── tooltip.html │ └── visual.css ├── themes/ │ └── base/ │ ├── accordion.css │ ├── all.css │ ├── autocomplete.css │ ├── base.css │ ├── button.css │ ├── checkboxradio.css │ ├── controlgroup.css │ ├── core.css │ ├── datepicker.css │ ├── dialog.css │ ├── draggable.css │ ├── menu.css │ ├── progressbar.css │ ├── resizable.css │ ├── selectable.css │ ├── selectmenu.css │ ├── slider.css │ ├── sortable.css │ ├── spinner.css │ ├── tabs.css │ ├── theme.css │ └── tooltip.css └── ui/ ├── data.js ├── disable-selection.js ├── effect.js ├── effects/ │ ├── effect-blind.js │ ├── effect-bounce.js │ ├── effect-clip.js │ ├── effect-drop.js │ ├── effect-explode.js │ ├── effect-fade.js │ ├── effect-fold.js │ ├── effect-highlight.js │ ├── effect-puff.js │ ├── effect-pulsate.js │ ├── effect-scale.js │ ├── effect-shake.js │ ├── effect-size.js │ ├── effect-slide.js │ └── effect-transfer.js ├── focusable.js ├── form-reset-mixin.js ├── i18n/ │ ├── datepicker-af.js │ ├── datepicker-ar-DZ.js │ ├── datepicker-ar.js │ ├── datepicker-az.js │ ├── datepicker-be.js │ ├── datepicker-bg.js │ ├── datepicker-bs.js │ ├── datepicker-ca.js │ ├── datepicker-cs.js │ ├── datepicker-cy-GB.js │ ├── datepicker-da.js │ ├── datepicker-de-AT.js │ ├── datepicker-de.js │ ├── datepicker-el.js │ ├── datepicker-en-AU.js │ ├── datepicker-en-GB.js │ ├── datepicker-en-NZ.js │ ├── datepicker-eo.js │ ├── datepicker-es.js │ ├── datepicker-et.js │ ├── datepicker-eu.js │ ├── datepicker-fa.js │ ├── datepicker-fi.js │ ├── datepicker-fo.js │ ├── datepicker-fr-CA.js │ ├── datepicker-fr-CH.js │ ├── datepicker-fr.js │ ├── datepicker-gl.js │ ├── datepicker-he.js │ ├── datepicker-hi.js │ ├── datepicker-hr.js │ ├── datepicker-hu.js │ ├── datepicker-hy.js │ ├── datepicker-id.js │ ├── datepicker-is.js │ ├── datepicker-it-CH.js │ ├── datepicker-it.js │ ├── datepicker-ja.js │ ├── datepicker-ka.js │ ├── datepicker-kk.js │ ├── datepicker-km.js │ ├── datepicker-ko.js │ ├── datepicker-ky.js │ ├── datepicker-lb.js │ ├── datepicker-lt.js │ ├── datepicker-lv.js │ ├── datepicker-mk.js │ ├── datepicker-ml.js │ ├── datepicker-ms.js │ ├── datepicker-nb.js │ ├── datepicker-nl-BE.js │ ├── datepicker-nl.js │ ├── datepicker-nn.js │ ├── datepicker-no.js │ ├── datepicker-pl.js │ ├── datepicker-pt-BR.js │ ├── datepicker-pt.js │ ├── datepicker-rm.js │ ├── datepicker-ro.js │ ├── datepicker-ru.js │ ├── datepicker-sk.js │ ├── datepicker-sl.js │ ├── datepicker-sq.js │ ├── datepicker-sr-SR.js │ ├── datepicker-sr.js │ ├── datepicker-sv.js │ ├── datepicker-ta.js │ ├── datepicker-th.js │ ├── datepicker-tj.js │ ├── datepicker-tr.js │ ├── datepicker-uk.js │ ├── datepicker-vi.js │ ├── datepicker-zh-CN.js │ ├── datepicker-zh-HK.js │ └── datepicker-zh-TW.js ├── jquery-patch.js ├── jquery-var-for-color.js ├── keycode.js ├── labels.js ├── plugin.js ├── position.js ├── scroll-parent.js ├── tabbable.js ├── unique-id.js ├── vendor/ │ └── jquery-color/ │ ├── LICENSE.txt │ └── jquery.color.js ├── version.js ├── widget.js └── widgets/ ├── accordion.js ├── autocomplete.js ├── button.js ├── checkboxradio.js ├── controlgroup.js ├── datepicker.js ├── dialog.js ├── draggable.js ├── droppable.js ├── menu.js ├── mouse.js ├── progressbar.js ├── resizable.js ├── selectable.js ├── selectmenu.js ├── slider.js ├── sortable.js ├── spinner.js ├── tabs.js └── tooltip.js ================================================ FILE CONTENTS ================================================ ================================================ FILE: .csslintrc ================================================ { "adjoining-classes": false, "box-model": false, "box-sizing": false, "compatible-vendor-prefixes": false, "duplicate-background-images": false, "import": false, "important": false, "outline-none": false, "order-alphabetical": false, "overqualified-elements": false, "text-indent": false } ================================================ FILE: .editorconfig ================================================ # This file is for unifying the coding style for different editors and IDEs # editorconfig.org root = true [*] indent_style = tab end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true [*.yml] indent_style = space indent_size = 2 [external/**] trim_trailing_whitespace = false insert_final_newline = varies end_of_line = varies ================================================ FILE: .gitattributes ================================================ # Auto detect text files and perform LF normalization * text=auto # JS files must always use LF for tools to work *.js eol=lf ================================================ FILE: .github/dependabot.yml ================================================ version: 2 updates: - package-ecosystem: github-actions directory: "/" schedule: interval: monthly # Group all dependabot version update PRs into one groups: github-actions: applies-to: version-updates patterns: - "*" ================================================ FILE: .github/workflows/browser-tests.yml ================================================ name: Browser Tests on: pull_request: push: branches-ignore: "dependabot/**" # Once a week every Monday schedule: - cron: "42 1 * * 1" permissions: contents: read env: NODE_VERSION: 22.x jobs: build-and-test: runs-on: ubuntu-latest name: | ${{ matrix.BROWSER }} | ${{ matrix.CONFIGS.name }} strategy: fail-fast: false matrix: BROWSER: [chrome, firefox] CONFIGS: - config: jtr-git.yml name: jQuery git - config: jtr-stable.yml name: jQuery stable steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Use Node.js ${{ env.NODE_VERSION }} uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: node-version: ${{ env.NODE_VERSION }} cache: npm cache-dependency-path: '**/package-lock.json' - name: Install npm dependencies run: npm ci - name: Build run: npm run build - name: Test run: | npm run test:unit -- \ --headless -b ${{ matrix.BROWSER }} \ -c ${{ matrix.CONFIGS.config }} edge: runs-on: windows-latest name: | edge | ${{ matrix.CONFIGS.name }} strategy: fail-fast: false matrix: CONFIGS: - config: jtr-git.yml name: jQuery git - config: jtr-stable.yml name: jQuery stable steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Use Node.js ${{ env.NODE_VERSION }} uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: node-version: ${{ env.NODE_VERSION }} cache: npm cache-dependency-path: '**/package-lock.json' - name: Install dependencies run: npm ci - name: Build run: npm run build - name: Test run: npm run test:unit -- --headless -b edge -c ${{ matrix.CONFIGS.config }} safari: runs-on: macos-latest name: | safari | ${{ matrix.CONFIGS.name }} strategy: fail-fast: false matrix: CONFIGS: - config: jtr-git.yml name: jQuery git - config: jtr-stable.yml name: jQuery stable steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Use Node.js ${{ env.NODE_VERSION }} uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: node-version: ${{ env.NODE_VERSION }} cache: npm cache-dependency-path: '**/package-lock.json' - name: Install dependencies run: npm ci - name: Build run: npm run build - name: Test run: npm run test:unit -- -b safari -c ${{ matrix.CONFIGS.config }} ================================================ FILE: .github/workflows/codeql-analysis.yml ================================================ name: "Code scanning - action" on: pull_request: push: branches-ignore: "dependabot/**" schedule: - cron: "0 4 * * 6" permissions: contents: read # to fetch code (actions/checkout) jobs: CodeQL-Build: permissions: contents: read # to fetch code (actions/checkout) security-events: write # (github/codeql-action/autobuild) runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: # We must fetch at least the immediate parents so that if this is # a pull request then we can checkout the head. fetch-depth: 2 # If this run was triggered by a pull request event, then checkout # the head of the pull request instead of the merge commit. - run: git checkout HEAD^2 if: ${{ github.event_name == 'pull_request' }} # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL uses: github/codeql-action/init@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4 # Override language selection by uncommenting this and choosing your languages # with: # languages: go, javascript, csharp, python, cpp, java # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild uses: github/codeql-action/autobuild@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines # and modify them (or add more) to build your code if your project # uses a compiled language #- run: | # make bootstrap # make release - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4 ================================================ FILE: .github/workflows/filestash.yml ================================================ name: Filestash on: push: branches: - main permissions: contents: read # to fetch code (actions/checkout) jobs: update: runs-on: ubuntu-latest environment: filestash env: NODE_VERSION: 22.x name: Update Filestash steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Use Node.js ${{ env.NODE_VERSION }} uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: node-version: ${{ env.NODE_VERSION }} cache: npm cache-dependency-path: '**/package-lock.json' - name: Install dependencies run: npm ci - name: Build run: npm run build - name: Set up SSH run: | install --directory ~/.ssh --mode 700 base64 --decode <<< "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_ed25519 chmod 600 ~/.ssh/id_ed25519 ssh-keyscan -t ed25519 -H "${{ secrets.FILESTASH_SERVER }}" >> ~/.ssh/known_hosts - name: Upload to Filestash run: | rsync dist/jquery-ui.js filestash@"${{ secrets.FILESTASH_SERVER }}":ui/jquery-ui-git.js rsync dist/jquery-ui.css filestash@"${{ secrets.FILESTASH_SERVER }}":ui/jquery-ui-git.css ================================================ FILE: .github/workflows/node.js.yml ================================================ name: Node on: pull_request: push: branches-ignore: "dependabot/**" permissions: contents: read env: NODE_VERSION: 22.x jobs: build-and-test: runs-on: ubuntu-latest name: Build & lint steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Use Node.js ${{ env.NODE_VERSION }} uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: node-version: ${{ env.NODE_VERSION }} cache: npm cache-dependency-path: '**/package-lock.json' - name: Install npm dependencies run: npm ci - name: Build run: npm run build # Lint must happen after build as we lint generated files. - name: Lint run: npm run lint ================================================ FILE: .gitignore ================================================ dist bower_components node_modules .sizecache.json local.log ================================================ FILE: .mailmap ================================================ Aaron Peterson Adam Baratz Adam Sontag Alexander Polomoshnov Aliaksandr Rahalevich Andrew Couch Andrew Newcomb Andrew Powell Andrew Powell Andrey Kapitcyn Ben Hollis Benjamin Scott Boyle Bert ter Heide Bjørn Johansen Chairat Sunthornwiphat Christoph Rönsch Corey Frang Courtland Allen Dan Streetman Dan Strohl Danny Trunk David De Sloovere David Murdoch Diego Tres Dominique Vincent Doug Blood Douglas Cerna Douglas Neiner Douglas Neiner Dylan Just Eddie Monge Edward A Faulkner Eric Hynds Ethan Romba EungJun Yi Eyal Kobrigo Felix Nagel Filippo Cavallarin Florian Gutmann Genie <386@mail.com> Guntupalli Karunakar Harri Kilpiö Heiko Henning Hiroshi Tomita Ian Simpson Igor Milla Israel Tsadok Jacek Jędrzejewski Jamie Gegerson Jason Oster Jay Merrifield Jean-Francois Remy Jyoti Deka John Enters Jonathan Vingiano Josh Varner Justin Domnitz Justin MacCarthy Jörn Zaefferer Karl Kirch Keith Wood Kevin Dalman Klaus Hartl Klaus Hartl Kris Borchers Kris Borchers Krzysztof Rosiński Lev Kitsis Maciej Mroziński Maggie Wachs Maggie Wachs Marc Neuwirth Marcos Sousa Martin Frost Mathias Stenbom Matt Hoskins Matthew Edward Hutton Max Schnur Michael Hollis Michael Stay Michael Wu Michał Gołębiowski-Owczarek Mike Alsup Milan Broum Mohamed Cherif Bouchelaghem Monika Piotrowicz Nick Pierpoint Ondrej Novy Paul Bakaus Paul Irish Pavol Hluchý Peter Heiberg Petr Hromadko Phillip Barnes Pierre-Henri Ausseil Raymond Schwartz Richard Worth Rick Waldron Ryan Neufeld Ryan Olton Saji Nediyanchath Saji Scott Jehl Sebastian Sauer Sergey Kartashov Shahyar Ghobadpour Shane Whittet Shannon Pekary Siebrand Mazeland Simon Sattes Stojce Slavkovski Tarafder Ashek-E-Elahi Thibault Duplessis Thomas Jaggi Ting Kuei Todd Parker Wesley Walser Xavi Ramirez Yermo Lamers Yuriy Khabarov <13real008@gmail.com> Ziling Zhao ================================================ FILE: .npmignore ================================================ /.github /build /demos /dist/cdn /external /tests /Gruntfile.js .csslintrc .editorconfig .eslintrc.json .eslintignore .gitattributes .mailmap ================================================ FILE: .npmrc ================================================ save-exact=true ================================================ FILE: AUTHORS.txt ================================================ Authors ordered by first contribution A list of current team members is available at https://jqueryui.com/about Paul Bakaus Richard Worth Yehuda Katz Sean Catchpole John Resig Tane Piper Dmitri Gaskin Klaus Hartl Stefan Petre Gilles van den Hoven Micheil Bryan Smith Jörn Zaefferer Marc Grabanski Keith Wood Brandon Aaron Scott González Eduardo Lundgren Aaron Eisenberger Joan Piedra Bruno Basto Remy Sharp Bohdan Ganicky David Bolter Chi Cheng Ca-Phun Ung Ariel Flesler Maggie Wachs Scott Jehl Todd Parker Andrew Powell Brant Burnett Douglas Neiner Paul Irish Ralph Whitbeck Thibault Duplessis Dominique Vincent Jack Hsu Adam Sontag Carl Fürstenberg Kevin Dalman Alberto Fernández Capel Jacek Jędrzejewski (https://jacek.jedrzejewski.name) Ting Kuei Samuel Cormier-Iijima Jon Palmer Ben Hollis Justin MacCarthy Eyal Kobrigo Tiago Freire Diego Tres Holger Rüprich Ziling Zhao Mike Alsup Robson Braga Araujo Pierre-Henri Ausseil Christopher McCulloh Andrew Newcomb Lim Chee Aun Jorge Barreiro Daniel Steigerwald John Firebaugh John Enters Andrey Kapitcyn Dmitry Petrov Eric Hynds Chairat Sunthornwiphat Josh Varner Stéphane Raimbault Jay Merrifield J. Ryan Stinnett Peter Heiberg Alex Dovenmuehle Jamie Gegerson Raymond Schwartz Phillip Barnes Kyle Wilkinson Khaled AlHourani Marian Rudzynski Jean-Francois Remy Doug Blood Filippo Cavallarin Heiko Henning Aliaksandr Rahalevich Mario Visic Xavi Ramirez Max Schnur Saji Nediyanchath Corey Frang Aaron Peterson Ivan Peters Mohamed Cherif Bouchelaghem Marcos Sousa Michael DellaNoce George Marshall Tobias Brunner Martin Solli David Petersen Dan Heberden William Kevin Manire Gilmore Davidson Michael Wu Adam Parod Guillaume Gautreau Marcel Toele Dan Streetman Matt Hoskins Giovanni Giacobbi Kyle Florence Pavol Hluchý Hans Hillen Mark Johnson Trey Hunner Shane Whittet Edward A Faulkner Adam Baratz Kato Kazuyoshi Eike Send Kris Borchers Eddie Monge Israel Tsadok Carson McDonald Jason Davies Garrison Locke David Murdoch Benjamin Scott Boyle Jesse Baird Jonathan Vingiano Dylan Just Hiroshi Tomita Glenn Goodrich Tarafder Ashek-E-Elahi Ryan Neufeld Marc Neuwirth Philip Graham Benjamin Sterling Wesley Walser Kouhei Sutou Karl Kirch Chris Kelly Jason Oster Felix Nagel Alexander Polomoshnov David Leal Igor Milla Dave Methvin Florian Gutmann Marwan Al Jubeh Milan Broum Sebastian Sauer Gaëtan Muller Michel Weimerskirch William Griffiths Stojce Slavkovski David Soms David De Sloovere Michael P. Jung Shannon Pekary Dan Wellman Matthew Edward Hutton James Khoury Rob Loach Alberto Monteiro Alex Rhea Krzysztof Rosiński Ryan Olton Genie <386@mail.com> Rick Waldron Ian Simpson Lev Kitsis TJ VanToll Justin Domnitz Douglas Cerna Bert ter Heide Jasvir Nagra Yuriy Khabarov <13real008@gmail.com> Harri Kilpiö Lado Lomidze Amir E. Aharoni Simon Sattes Jo Liss Guntupalli Karunakar Shahyar Ghobadpour Lukasz Lipinski Timo Tijhof Jason Moon Martin Frost Eneko Illarramendi EungJun Yi Courtland Allen Viktar Varvanovich Danny Trunk Pavel Stetina Michael Stay Steven Roussey Michael Hollis Lee Rowlands Timmy Willison Karl Swedberg Baoju Yuan Maciej Mroziński Luis Dalmolin Mark Aaron Shirley Martin Hoch Jiayi Yang Philipp Benjamin Köppchen Sindre Sorhus Bernhard Sirlinger Jared A. Scheel Rafael Xavier de Souza John Chen Robert Beuligmann Dale Kocian Mike Sherov Andrew Couch Marc-Andre Lafortune Nate Eagle David Souther Mathias Stenbom Sergey Kartashov Avinash R Ethan Romba Cory Gackenheimer Juan Pablo Kaniefsky Roman Salnikov Anika Henke Samuel Bovée Fabrício Matté Viktor Kojouharov Pawel Maruszczyk (http://hrabstwo.net) Pavel Selitskas Bjørn Johansen Matthieu Penant Dominic Barnes David Sullivan Thomas Jaggi Vahid Sohrabloo Travis Carden Bruno M. Custódio Nathanael Silverman Christian Wenz Steve Urmston Zaven Muradyan Woody Gilk Zbigniew Motyka Suhail Alkowaileet Toshi MARUYAMA David Hansen Brian Grinstead Christian Klammer Steven Luscher Gan Eng Chin Gabriel Schulhof Alexander Schmitz Vilhjálmur Skúlason Siebrand Mazeland Mohsen Ekhtiari Pere Orga Jasper de Groot Stephane Deschamps Jyoti Deka Andrei Picus Ondrej Novy Jacob McCutcheon Monika Piotrowicz Imants Horsts Eric Dahl Dave Stein Dylan Barrell Daniel DeGroff Michael Wiencek Thomas Meyer Ruslan Yakhyaev Brian J. Dowling Ben Higgins Yermo Lamers Patrick Stapleton Trisha Crowley Usman Akeju Rodrigo Menezes Jacques Perrault Frederik Elvhage Will Holley Uri Gilad Richard Gibson Simen Bekkhus Chen Eshchar Bruno Pérel Mohammed Alshehri Lisa Seacat DeLuca Anne-Gaelle Colom Adam Foster Luke Page Daniel Owens Michael Orchard Marcus Warren Nils Heuermann Marco Ziech Patricia Juarez Ben Mosher Ablay Keldibek Thomas Applencourt Jiabao Wu Eric Lee Carraway Victor Homyakov Myeongjin Lee Liran Sharir Weston Ruter Mani Mishra Hannah Methvin Leonardo Balter Benjamin Albert Michał Gołębiowski-Owczarek Alyosha Pushak Fahad Ahmad Matt Brundage Francesc Baeta Piotr Baran Mukul Hase Konstantin Dinev Rand Scullard Dan Strohl Maksim Ryzhikov Amine HADDAD Amanpreet Singh Alexey Balchunas Peter Kehl Peter Dave Hello Johannes Schäfer Ville Skyttä Ryan Oriecuia Sergei Ratnikov milk54 Evelyn Masso Robin Simon Asika Kevin Cupp Jeremy Mickelson Kyle Rosenberg Petri Partio pallxk Luke Brookhart claudi Eirik Sletteberg Albert Johansson A. Wells Robert Brignull Horus68 Maksymenkov Eugene OskarNS Gez Quinn jigar gala Florian Wegscheider Fatér Zsolt Szabolcs Szabolcsi-Toth Jérémy Munsch Hrvoje Novosel Paul Capron Micah Miller sakshi87 <53863764+sakshi87@users.noreply.github.com> Mikolaj Wolicki Patrick McKay c-lambert <58025159+c-lambert@users.noreply.github.com> Josep Sanz Ben Mullins Christian Oliff dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Adam Lidén Hällgren James Hinderks Denny Septian Panggabean <97607754+ddevsr@users.noreply.github.com> Matías Cánepa Ashish Kurmi <100655670+boahc077@users.noreply.github.com> DeerBear Дилян Палаузов Kenneth DeBacker Timo Tijhof Timmy Willison divdeploy <166095818+divdeploy@users.noreply.github.com> mark van tilburg Ralf Koller <1665422+rpkoller@users.noreply.github.com> Porter Clevidence <116387727+porterclev@users.noreply.github.com> Daniel García <93217193+Daniel-Garmig@users.noreply.github.com> ================================================ FILE: CONTRIBUTING.md ================================================ # Contributing to jQuery UI Welcome! Thanks for your interest in contributing to jQuery UI. Most of our information on how to contribute to this and all other jQuery projects is over at [contribute.jquery.org](https://contribute.jquery.org). You'll definitely want to take a look at the articles on contributing [code](https://contribute.jquery.org/code). You may also want to take a look at our [commit & pull request guide](https://contribute.jquery.org/commits-and-pull-requests/) and [style guides](https://contribute.jquery.org/style-guide/) for instructions on how to maintain your fork and submit your code. Before we can merge any pull request, we'll also need you to sign our [contributor license agreement](https://contribute.jquery.org/cla). You can find us on [IRC](https://irc.jquery.org), specifically in #jqueryui-dev should you have any questions. If you've never contributed to open source before, we've put together [a short guide with tips, tricks, and ideas on getting started](https://contribute.jquery.org/open-source/). For other forms of discussion and support, please see the [jQuery UI support center](https://jqueryui.com/support/). ## Getting Involved There are a number of ways to get involved with the development of jQuery UI. Even if you've never contributed code to an Open Source project before, we're always looking for help identifying bugs, writing and reducing test cases and documentation. This is the best way to contribute to jQuery UI. Please read through the full guide detailing [How to Report Bugs](https://contribute.jquery.org/bug-reports/). ## Tips for Getting Started ### Environment: Minimum Required If you are contributing changes you will need a fork of jquery-ui (see [Getting the Source](#environment-getting-the-source)). If you just want the source code you could clone jquery-ui directly: ```bash git clone git://github.com/jquery/jquery-ui.git cd jquery-ui ``` The tests can run in any local web server. Ideally you should test your patch in appropriate web browsers and if possible run `npm test` to lint the code and run automated tests (this will happen automatically when you create a pull request). See the [Recommended Setup](#environment-recommended-setup) for setting up Node.js so that the `npm test` command works. ### Environment: Getting the Source * Create a fork of the jQuery UI repo on GitHub at https://github.com/jquery/jquery-ui. This will create a fork of jquery-ui in your Github account. * You may want to clone jquery-ui under the path to your web server. If so, change to the required directory ```bash cd /path/to/your/www/root/ ``` * Clone your jQuery UI git repo. ```bash git clone git://github.com/[USERNAME]/jquery-ui.git cd jquery-ui ``` *Note: be sure to replace `[USERNAME]` with your GitHub username.* * Add the official jQuery repository as a remote. We recommend naming it "upstream". ```bash git remote add upstream git://github.com/jquery/jquery-ui.git ``` * Get in the habit of pulling in the "upstream" main branch to stay up to date as jQuery UI receives new commits. ```bash git pull upstream main ``` ### Environment: Recommended Setup jQuery UI uses Node.js to automate the building and validation of source code. Here is how to set that up: * Get [Node.js](https://nodejs.org/) (includes NPM, necessary for the next step) * Install local Node.js modules ```bash npm install ``` The tests require a local web server and the samples contain some PHP, so a PHP web server may be useful. * Install a web server. Here are some you could use: * Windows: [WAMP download](https://www.wampserver.com/en/) * Mac: [MAMP download](https://www.mamp.info/en/mac/) * Linux: [Setting up LAMP](https://www.linux.com/learn/tutorials/288158-easy-lamp-server-installation) * [Mongoose (most platforms)](https://mongoose.ws/) * [http-server](https://www.npmjs.com/package/http-server) ### Running the Tests To lint the JavaScript, HTML, and CSS, as well as run the full test suite in Headless Chrome: ```bash npm test ``` To run the tests for a specific plugin in your browser, open the appropriate file from the `/tests/unit/` directory, for example: `http://localhost/tests/unit/accordion/accordion.html`. The domain will be dependent on your local server configuration; if there is a port, be sure to include it. Ideally you would test in all of our [supported browsers](https://jqueryui.com/browser-support/), but if you don't have all of these browsers available, that's ok. ================================================ FILE: Gruntfile.js ================================================ "use strict"; module.exports = function( grunt ) { const { gzipSync } = require( "node:zlib" ); // files const coreFiles = [ "widget.js", "widgets/mouse.js", "widgets/draggable.js", "widgets/droppable.js", "widgets/resizable.js", "widgets/selectable.js", "widgets/sortable.js", "effect.js" ]; const uiFiles = coreFiles.map( function( file ) { return "ui/" + file; } ).concat( expandFiles( "ui/**/*.js" ).filter( function( file ) { return coreFiles.indexOf( file.substring( 3 ) ) === -1; } ) ); const allI18nFiles = expandFiles( "ui/i18n/*.js" ); const cssFiles = [ "core", "accordion", "autocomplete", "button", "checkboxradio", "controlgroup", "datepicker", "dialog", "draggable", "menu", "progressbar", "resizable", "selectable", "selectmenu", "sortable", "slider", "spinner", "tabs", "tooltip", "theme" ].map( function( component ) { return "themes/base/" + component + ".css"; } ); // minified files const minify = { main: { options: { banner: createBanner( uiFiles ) }, files: { "dist/jquery-ui.min.js": "dist/jquery-ui.js" } }, i18n: { options: { banner: createBanner( allI18nFiles ) }, files: { "dist/i18n/jquery-ui-i18n.min.js": "dist/i18n/jquery-ui-i18n.js" } } }; const compareFiles = { all: [ "dist/jquery-ui.js", "dist/jquery-ui.min.js" ], options: { compress: { gz: function( contents ) { return gzipSync( contents ).length; } }, cache: "build/.sizecache.json" } }; const htmllintBad = [ "demos/tabs/ajax/content*.html", "demos/tooltip/ajax/content*.html", "tests/unit/core/core.html", "tests/unit/tabs/data/test.html" ]; function mapMinFile( file ) { return "dist/" + file.replace( /ui\//, "minified/" ); } function expandFiles( files ) { return grunt.util._.map( grunt.file.expandMapping( files ), "src" ).map( function( values ) { return values[ 0 ]; } ); } uiFiles.concat( allI18nFiles ).forEach( function( file ) { minify[ file ] = { options: { banner: createBanner() }, files: {} }; minify[ file ].files[ mapMinFile( file ) ] = file; } ); uiFiles.forEach( function( file ) { compareFiles[ file ] = [ file, mapMinFile( file ) ]; } ); function stripDirectory( file ) { return file.replace( /.+\/(.+?)>?$/, "$1" ); } function createBanner( files ) { // strip folders const fileNames = files && files.map( stripDirectory ); return "/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - " + "<%= grunt.template.today('isoDate') %>\n" + "<%= pkg.homepage ? '* ' + pkg.homepage + '\\n' : '' %>" + ( files ? "* Includes: " + fileNames.join( ", " ) + "\n" : "" ) + "* Copyright <%= pkg.author.name %>;" + " Licensed <%= _.map(pkg.licenses, 'type').join(', ') %> */\n"; } grunt.initConfig( { pkg: grunt.file.readJSON( "package.json" ), files: { dist: "<%= pkg.name %>-<%= pkg.version %>" }, compare_size: compareFiles, concat: { css: { options: { banner: createBanner( cssFiles ), stripBanners: { block: true } }, src: cssFiles, dest: "dist/jquery-ui.css" } }, requirejs: { js: { options: { baseUrl: "./", paths: { jquery: "./external/jquery/jquery", external: "./external/" }, preserveLicenseComments: false, optimize: "none", findNestedDependencies: true, skipModuleInsertion: true, exclude: [ "jquery" ], include: expandFiles( [ "ui/**/*.js", "!ui/i18n/*" ] ), out: "dist/jquery-ui.js", wrap: { start: createBanner( uiFiles ) } } } }, minify, htmllint: { good: { options: { ignore: [ /The text content of element “script” was not in the required format: Expected space, tab, newline, or slash but found “.” instead/, /This document appears to be written in .*. Consider using “lang=".*"” \(or variant\) instead/ ] }, src: [ "{demos,tests}/**/*.html", ...htmllintBad.map( pattern => `!${ pattern }` ) ] }, bad: { options: { ignore: [ /Start tag seen without seeing a doctype first/, /Element “head” is missing a required instance of child element “title”/, /Element “object” is missing one or more of the following/, /The “codebase” attribute on the “object” element is obsolete/, /Consider adding a “lang” attribute to the “html” start tag/, /This document appears to be written in .*. Consider (?:adding|using) “lang=".*"” \(or variant\)/ ] }, src: htmllintBad } }, eslint: { all: [ "ui/**/*.js", "!ui/vendor/**/*.js", "Gruntfile.js", "dist/jquery-ui.js", "dist/jquery-ui.min.js", "build/**/*.js", "tests/unit/**/*.js", "tests/lib/**/*.js", "!tests/lib/vendor/**/*.js", "demos/**/*.js" ] }, csslint: { base_theme: { src: "themes/base/*.css", options: { csslintrc: ".csslintrc" } } }, bowercopy: { inlineVendors: { options: { clean: true, destPrefix: "ui/vendor" }, files: { "jquery-color/jquery.color.js": "jquery-color/dist/jquery.color.js", "jquery-color/LICENSE.txt": "jquery-color/LICENSE.txt" } }, all: { options: { clean: true, ignore: [ "jquery" ], destPrefix: "external" }, files: { "qunit/qunit.js": "qunit/qunit/qunit.js", "qunit/qunit.css": "qunit/qunit/qunit.css", "qunit/LICENSE.txt": "qunit/LICENSE.txt", "requirejs/require.js": "requirejs/require.js", "jquery-mousewheel/jquery.mousewheel.js": "jquery-mousewheel/jquery.mousewheel.js", "jquery-mousewheel/LICENSE.txt": "jquery-mousewheel/LICENSE.txt", "jquery-simulate/jquery.simulate.js": "jquery-simulate/jquery.simulate.js", "jquery-simulate/LICENSE.txt": "jquery-simulate/LICENSE.txt", "jquery/jquery.js": "jquery/dist/jquery.js", "jquery/LICENSE.txt": "jquery/LICENSE.txt", "jquery-1.12.4/jquery.js": "jquery-1.12.4/dist/jquery.js", "jquery-1.12.4/LICENSE.txt": "jquery-1.12.4/LICENSE.txt", "jquery-2.2.4/jquery.js": "jquery-2.2.4/dist/jquery.js", "jquery-2.2.4/LICENSE.txt": "jquery-2.2.4/LICENSE.txt", "jquery-3.0.0/jquery.js": "jquery-3.0.0/dist/jquery.js", "jquery-3.0.0/LICENSE.txt": "jquery-3.0.0/LICENSE.txt", "jquery-3.1.0/jquery.js": "jquery-3.1.0/dist/jquery.js", "jquery-3.1.0/LICENSE.txt": "jquery-3.1.0/LICENSE.txt", "jquery-3.1.1/jquery.js": "jquery-3.1.1/dist/jquery.js", "jquery-3.1.1/LICENSE.txt": "jquery-3.1.1/LICENSE.txt", "jquery-3.2.0/jquery.js": "jquery-3.2.0/dist/jquery.js", "jquery-3.2.0/LICENSE.txt": "jquery-3.2.0/LICENSE.txt", "jquery-3.2.1/jquery.js": "jquery-3.2.1/dist/jquery.js", "jquery-3.2.1/LICENSE.txt": "jquery-3.2.1/LICENSE.txt", "jquery-3.3.0/jquery.js": "jquery-3.3.0/dist/jquery.js", "jquery-3.3.0/LICENSE.txt": "jquery-3.3.0/LICENSE.txt", "jquery-3.3.1/jquery.js": "jquery-3.3.1/dist/jquery.js", "jquery-3.3.1/LICENSE.txt": "jquery-3.3.1/LICENSE.txt", "jquery-3.4.0/jquery.js": "jquery-3.4.0/dist/jquery.js", "jquery-3.4.0/LICENSE.txt": "jquery-3.4.0/LICENSE.txt", "jquery-3.4.1/jquery.js": "jquery-3.4.1/dist/jquery.js", "jquery-3.4.1/LICENSE.txt": "jquery-3.4.1/LICENSE.txt", "jquery-3.5.0/jquery.js": "jquery-3.5.0/dist/jquery.js", "jquery-3.5.0/LICENSE.txt": "jquery-3.5.0/LICENSE.txt", "jquery-3.5.1/jquery.js": "jquery-3.5.1/dist/jquery.js", "jquery-3.5.1/LICENSE.txt": "jquery-3.5.1/LICENSE.txt", "jquery-3.6.0/jquery.js": "jquery-3.6.0/dist/jquery.js", "jquery-3.6.0/LICENSE.txt": "jquery-3.6.0/LICENSE.txt", "jquery-3.6.1/jquery.js": "jquery-3.6.1/dist/jquery.js", "jquery-3.6.1/LICENSE.txt": "jquery-3.6.1/LICENSE.txt", "jquery-3.6.2/jquery.js": "jquery-3.6.2/dist/jquery.js", "jquery-3.6.2/LICENSE.txt": "jquery-3.6.2/LICENSE.txt", "jquery-3.6.3/jquery.js": "jquery-3.6.3/dist/jquery.js", "jquery-3.6.3/LICENSE.txt": "jquery-3.6.3/LICENSE.txt", "jquery-3.6.4/jquery.js": "jquery-3.6.4/dist/jquery.js", "jquery-3.6.4/LICENSE.txt": "jquery-3.6.4/LICENSE.txt", "jquery-3.7.0/jquery.js": "jquery-3.7.0/dist/jquery.js", "jquery-3.7.0/LICENSE.txt": "jquery-3.7.0/LICENSE.txt", "jquery-3.7.1/jquery.js": "jquery-3.7.1/dist/jquery.js", "jquery-3.7.1/LICENSE.txt": "jquery-3.7.1/LICENSE.txt", "jquery-4.0.0/jquery.js": "jquery-4.0.0/dist/jquery.js", "jquery-4.0.0/LICENSE.txt": "jquery-4.0.0/LICENSE.txt", "jquery-migrate-1.x/jquery-migrate.js": "jquery-migrate-1.x/dist/jquery-migrate.js", "jquery-migrate-1.x/LICENSE.txt": "jquery-migrate-1.x/LICENSE.txt", "jquery-migrate-3.x/jquery-migrate.js": "jquery-migrate-3.x/dist/jquery-migrate.js", "jquery-migrate-3.x/LICENSE.txt": "jquery-migrate-3.x/LICENSE.txt", "jquery-migrate-4.x/jquery-migrate.js": "jquery-migrate-4.x/dist/jquery-migrate.js", "jquery-migrate-4.x/LICENSE.txt": "jquery-migrate-4.x/LICENSE.txt" } } }, authors: { prior: [ "Paul Bakaus ", "Richard Worth ", "Yehuda Katz ", "Sean Catchpole ", "John Resig ", "Tane Piper ", "Dmitri Gaskin ", "Klaus Hartl ", "Stefan Petre ", "Gilles van den Hoven ", "Micheil Bryan Smith ", "Jörn Zaefferer ", "Marc Grabanski ", "Keith Wood ", "Brandon Aaron ", "Scott González ", "Eduardo Lundgren ", "Aaron Eisenberger ", "Joan Piedra ", "Bruno Basto ", "Remy Sharp ", "Bohdan Ganicky " ] } } ); // grunt plugins require( "load-grunt-tasks" )( grunt ); // local tasks grunt.loadTasks( "build/tasks" ); grunt.registerTask( "update-authors", function() { const getAuthors = require( "grunt-git-authors" ).getAuthors; const done = this.async(); getAuthors( { priorAuthors: grunt.config( "authors.prior" ) }, function( error, authors ) { if ( error ) { grunt.log.error( error ); return done( false ); } authors = authors.map( function( author ) { if ( author.match( /^Jacek Jędrzejewski { const task = args.join( ":" ); grunt.log.writeln( "Old Node.js detected, running the task \"" + task + "\" skipped..." ); } ); // Keep this task list in sync with the testing steps in our GitHub action test workflow file! grunt.registerTask( "lint", [ "asciilint", "eslint", "csslint", "htmllint" ] ); grunt.registerTask( "build", [ "requirejs", "concat", "minify:main" ] ); grunt.registerTask( "default", [ "build", "lint" ] ); grunt.registerTask( "sizer", [ "requirejs:js", "minify:main", "compare_size:all" ] ); grunt.registerTask( "sizer_all", [ "requirejs:js", "minify", "compare_size" ] ); }; ================================================ FILE: LICENSE.txt ================================================ Copyright OpenJS Foundation and other contributors, https://openjsf.org/ This software consists of voluntary contributions made by many individuals. For exact contribution history, see the revision history available at https://github.com/jquery/jquery-ui The following license applies to all parts of this software except as documented below: ==== 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. ==== Copyright and related rights for sample code are waived via CC0. Sample code is defined as all source code contained within the demos directory. CC0: http://creativecommons.org/publicdomain/zero/1.0/ ==== All files located in the node_modules and external directories are externally maintained libraries used by this software which have their own licenses; we recommend you read them, as their terms may differ from the terms above. ================================================ FILE: README.md ================================================ # [jQuery UI](https://jqueryui.com/) - Interactions and Widgets for the web _**Note:** jQuery UI is in maintenance-only mode. Please read [the project status blog post](https://blog.jqueryui.com/2021/10/jquery-maintainers-update-and-transition-jquery-ui-as-part-of-overall-modernization-efforts/) for more information._ jQuery UI is a curated set of user interface interactions, effects, widgets, and themes built on top of jQuery. Whether you're building highly interactive web applications, or you just need to add a date picker to a form control, jQuery UI is the perfect choice. If you want to use jQuery UI, go to [jqueryui.com](https://jqueryui.com) to get started, [jqueryui.com/demos/](https://jqueryui.com/demos/) for demos, [api.jqueryui.com](https://api.jqueryui.com/) for API documentation, or the [Using jQuery UI Forum](https://forum.jquery.com/using-jquery-ui) for discussions and questions. If you want to report a bug/issue, please visit [the GitHub issues page](https://github.com/jquery/jquery-ui/issues). Archive of older bug reports is kept for historical reasons in read-only mode at [bugs.jqueryui.com](https://bugs.jqueryui.com). If any of them still matters to you, please open a bug about it on GitHub, linking to the legacy [bugs.jqueryui.com](https://bugs.jqueryui.com) issue for context. If you are interested in helping develop jQuery UI, you are in the right place. To discuss development with team members and the community, visit the [Developing jQuery UI Forum](https://forum.jquery.com/developing-jquery-ui) or [#jqueryui-dev on irc.freenode.net](https://irc.jquery.org/). ## For Contributors If you want to help and provide a patch for a bugfix or new feature, please take a few minutes and look at [our Getting Involved guide](https://wiki.jqueryui.com/w/page/35263114/Getting-Involved). In particular check out the [Coding standards](https://wiki.jqueryui.com/w/page/12137737/Coding-standards) and [Commit Message Style Guide](https://contribute.jquery.org/commits-and-pull-requests/#commit-guidelines). In general, fork the project, create a branch for a specific change and send a pull request for that branch. Don't mix unrelated changes. You can use the commit message as the description for the pull request. For more information, see the [contributing page](CONTRIBUTING.md). ## Running the Unit Tests Run the unit tests manually with appropriate browsers and any local web server. See our [environment setup](CONTRIBUTING.md#environment-minimum-required) and [information on running tests](CONTRIBUTING.md#running-the-tests). You can also run the unit tests `npm run test:unit -- --help`. ================================================ FILE: SECURITY.md ================================================ # Security Policy ## Supported Versions The [latest released version](https://github.com/jquery/jquery-ui/releases) of jQuery UI is supported. ## Reporting a Vulnerability Please email security@jquery.com, and we will respond as quickly as possible. If the vulnerability is considered valid and accepted, a patch will be made for the latest jQuery UI version. If the vulnerability is deemed invalid, no further action is required. ================================================ FILE: bower.json ================================================ { "name": "jquery-ui", "ignore": [ "**/.*", "build", "demos", "external", "tests" ], "license": "MIT", "dependencies": { "jquery": ">=1.12.0 <5.0.0" }, "devDependencies": { "jquery-color": "3.0.0", "jquery-mousewheel": "3.2.2", "jquery-simulate": "1.1.1", "qunit": "2.19.4", "requirejs": "2.3.8", "jquery": "jquery#4.0.0", "jquery-1.12.4": "jquery#1.12.4", "jquery-2.2.4": "jquery#2.2.4", "jquery-3.0.0": "jquery#3.0.0", "jquery-3.1.0": "jquery#3.1.0", "jquery-3.1.1": "jquery#3.1.1", "jquery-3.2.0": "jquery#3.2.0", "jquery-3.2.1": "jquery#3.2.1", "jquery-3.3.0": "jquery#3.3.0", "jquery-3.3.1": "jquery#3.3.1", "jquery-3.4.0": "jquery#3.4.0", "jquery-3.4.1": "jquery#3.4.1", "jquery-3.5.0": "jquery#3.5.0", "jquery-3.5.1": "jquery#3.5.1", "jquery-3.6.0": "jquery#3.6.0", "jquery-3.6.1": "jquery#3.6.1", "jquery-3.6.2": "jquery#3.6.2", "jquery-3.6.3": "jquery#3.6.3", "jquery-3.6.4": "jquery#3.6.4", "jquery-3.7.0": "jquery#3.7.0", "jquery-3.7.1": "jquery#3.7.1", "jquery-4.0.0": "jquery#4.0.0", "jquery-migrate-1.x": "https://registry.npmjs.org/jquery-migrate/-/jquery-migrate-1.4.1.tgz", "jquery-migrate-3.x": "https://registry.npmjs.org/jquery-migrate/-/jquery-migrate-3.6.0.tgz", "jquery-migrate-4.x": "https://registry.npmjs.org/jquery-migrate/-/jquery-migrate-4.0.2.tgz" } } ================================================ FILE: build/release-test.js ================================================ "use strict"; var shell = require( "shelljs" ); var Release = { define: function( props ) { for ( var key in props ) { Release[ key ] = props[ key ]; } }, exec: function( _options, errorMessage ) { var result, command = _options.command || _options, options = {}; if ( _options.silent ) { options.silent = true; } errorMessage = errorMessage || "Error executing command: " + command; result = shell.exec( command, options ); if ( result.code !== 0 ) { Release.abort( errorMessage ); } return result.output; }, abort: function() { console.error.apply( console, arguments ); process.exit( 1 ); }, newVersion: require( "../package" ).version }; var script = require( "./release" ); script( Release ); // Ignores actual version installed, should be good enough for a test if ( shell.exec( "npm ls --depth 0 | grep download.jqueryui.com" ).code === 1 ) { shell.exec( "npm install --no-save " + script.dependencies.join( " " ) ); } // If AUTHORS.txt is outdated, this will update it // Very annoying during an actual release shell.exec( "grunt update-authors" ); Release.generateArtifacts( function() { console.log( "Done generating artifacts, verify output, should be in dist/cdn" ); } ); ================================================ FILE: build/release.js ================================================ "use strict"; module.exports = function( Release ) { var crypto = require( "crypto" ); var shell = require( "shelljs" ), path = require( "path" ), fs = require( "fs" ); function replaceAtVersion() { console.log( "Replacing @VERSION..." ); var matches = []; function recurse( folder ) { fs.readdirSync( folder ).forEach( function( fileName ) { var content, fullPath = folder + "/" + fileName; if ( fs.statSync( fullPath ).isDirectory() ) { recurse( fullPath ); return; } content = fs.readFileSync( fullPath, { encoding: "utf-8" } ); if ( !/@VERSION/.test( content ) ) { return; } matches.push( fullPath ); fs.writeFileSync( fullPath, content.replace( /@VERSION/g, Release.newVersion ) ); } ); } [ "ui", "themes" ].forEach( recurse ); console.log( "Replaced @VERSION in " + matches.length + " files." ); return matches; } function removeExternals( packager ) { Object.keys( packager.builtFiles ).forEach( function( filepath ) { if ( /^external\//.test( filepath ) ) { delete packager.builtFiles[ filepath ]; } } ); } function addManifest( packager ) { var output = packager.builtFiles; output.MANIFEST = Object.keys( output ).sort( function( a, b ) { return a.localeCompare( b ); } ).map( function( filepath ) { var md5 = crypto.createHash( "md5" ); md5.update( output[ filepath ] ); return filepath + " " + md5.digest( "hex" ); } ).join( "\n" ); } function buildCDNPackage( callback ) { console.log( "Building CDN package" ); var JqueryUi = require( "download.jqueryui.com/lib/jquery-ui" ); var PackageWithoutThemes = require( "download.jqueryui.com/lib/package" ); var PackageOfThemes = require( "download.jqueryui.com/lib/package-themes" ); var Packager = require( "node-packager" ); // PackageOfThemes doesn't contain JS files, PackageWithoutThemes doesn't contain themes; // we need both. function Package() { // PackageOfThemes invokes PackageWithoutThemes's constructor in its own so we don't // need to do it by ourselves; we just need to handle prototypes that way. PackageOfThemes.apply( this, arguments ); } Object.assign( Package.prototype, PackageWithoutThemes.prototype, PackageOfThemes.prototype ); var jqueryUi = new JqueryUi( path.resolve( "." ) ); var target = fs.createWriteStream( "../" + jqueryUi.pkg.name + "-" + jqueryUi.pkg.version + "-cdn.zip" ); var packager = new Packager( jqueryUi.files().cache, Package, { components: jqueryUi.components().map( function( component ) { return component.name; } ), jqueryUi: jqueryUi, themeVars: null } ); packager.ready .then( function() { removeExternals( packager ); addManifest( packager ); packager.toZip( target, { basedir: "" }, function( error ) { if ( error ) { Release.abort( "Failed to zip the CDN package", error ); } callback(); } ); } ) .catch( function( error ) { Release.abort( "Failed to create the CDN package", error ); } ); } Release.define( { npmPublish: true, issueTracker: "github", changelogShell: function() { var monthNames = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ], now = new Date(); return "\n\nReleased on " + monthNames[ now.getMonth() ] + " " + now.getDate() + ", " + now.getFullYear() + "\n\n"; }, generateArtifacts: function( fn ) { var files = replaceAtVersion(); buildCDNPackage( function copyCdnFiles() { var zipFile = shell.ls( "../jquery*-cdn.zip" )[ 0 ], tmpFolder = "../tmp-zip-output", unzipCommand = "unzip -o " + zipFile + " -d " + tmpFolder; console.log( "Unzipping for dist/cdn copies" ); shell.mkdir( "-p", tmpFolder ); Release.exec( { command: unzipCommand, silent: true }, "Failed to unzip cdn files" ); shell.mkdir( "-p", "dist/cdn" ); shell.cp( tmpFolder + "/jquery-ui*.js", "dist/cdn" ); shell.cp( "-r", tmpFolder + "/themes", "dist/cdn" ); // Copy all the files to be published on the CDN to the dist directory // as well. shell.cp( "dist/cdn/jquery-ui.js", "dist" ); shell.cp( "dist/cdn/jquery-ui.min.js", "dist" ); shell.cp( "-r", "dist/cdn/themes", "dist" ); Release.exec( "git add --force dist/jquery-ui.js", "Error adding dist/jquery-ui.js." ); Release.exec( "git add --force dist/jquery-ui.min.js", "Error adding dist/jquery-ui.min.js." ); Release.exec( "git add --force dist/themes", "Error adding dist/themes." ); fn( files ); } ); } } ); }; module.exports.dependencies = [ "download.jqueryui.com@2.4.5", "node-packager@0.0.7", "shelljs@0.8.5" ]; ================================================ FILE: build/tasks/build.js ================================================ "use strict"; module.exports = function( grunt ) { grunt.registerTask( "clean", function() { require( "rimraf" ).rimrafSync( "dist" ); } ); grunt.registerTask( "asciilint", function() { var valid = true, files = grunt.file.expand( { filter: "isFile" }, "ui/*.js" ); files.forEach( function( filename ) { var i, c, text = grunt.file.read( filename ); // Ensure files use only \n for line endings, not \r\n if ( /\x0d\x0a/.test( text ) ) { grunt.log.error( filename + ": Incorrect line endings (\\r\\n)" ); valid = false; } // Ensure only ASCII chars so script tags don't need a charset attribute if ( text.length !== Buffer.byteLength( text, "utf8" ) ) { grunt.log.error( filename + ": Non-ASCII characters detected:" ); for ( i = 0; i < text.length; i++ ) { c = text.charCodeAt( i ); if ( c > 127 ) { grunt.log.error( "- position " + i + ": " + c ); grunt.log.error( "-- " + text.substring( i - 20, i + 20 ) ); break; } } valid = false; } } ); if ( valid ) { grunt.log.ok( files.length + " files lint free." ); } return valid; } ); }; ================================================ FILE: build/tasks/minify.js ================================================ "use strict"; const swc = require( "@swc/core" ); module.exports = function( grunt ) { grunt.registerMultiTask( "minify", async function() { const done = this.async(); const options = this.options(); for ( const file of this.files ) { if ( file.src.length === 0 ) { grunt.log.writeln( `No source file found, skipping minification to "${ file.dest }".` ); continue; } if ( file.src.length !== 1 ) { grunt.fail.warn( "Minifying multiple source files into one " + "destination file not supported" ); } const contents = grunt.file.read( file.src[ 0 ] ); const { code } = await swc.minify( contents, { compress: { ecma: 5, hoist_funs: false, loops: false }, format: { ecma: 5, asciiOnly: true, comments: false, preamble: options.banner }, inlineSourcesContent: false, mangle: true, module: false, sourceMap: false } ); grunt.file.write( file.dest, code ); grunt.log.writeln( `File ${ file.dest } created.` ); } done(); } ); }; ================================================ FILE: demos/accordion/collapsible.html ================================================ jQuery UI Accordion - Collapse content

Section 1

Mauris mauris ante, blandit et, ultrices a, suscipit eget, quam. Integer ut neque. Vivamus nisi metus, molestie vel, gravida in, condimentum sit amet, nunc. Nam a nibh. Donec suscipit eros. Nam mi. Proin viverra leo ut odio. Curabitur malesuada. Vestibulum a velit eu ante scelerisque vulputate.

Section 2

Sed non urna. Donec et ante. Phasellus eu ligula. Vestibulum sit amet purus. Vivamus hendrerit, dolor at aliquet laoreet, mauris turpis porttitor velit, faucibus interdum tellus libero ac justo. Vivamus non quam. In suscipit faucibus urna.

Section 3

Nam enim risus, molestie et, porta ac, aliquam ac, risus. Quisque lobortis. Phasellus pellentesque purus in massa. Aenean in pede. Phasellus ac libero ac tellus pellentesque semper. Sed ac felis. Sed commodo, magna quis lacinia ornare, quam ante aliquam nisi, eu iaculis leo purus venenatis dui.

  • List item one
  • List item two
  • List item three

Section 4

Cras dictum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean lacinia mauris vel est.

Suspendisse eu nisl. Nullam ut libero. Integer dignissim consequat lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.

By default, accordions always keep one section open. To allow for all sections to be collapsible, set the collapsible option to true. Click on the currently open section to collapse its content pane.

================================================ FILE: demos/accordion/custom-icons.html ================================================ jQuery UI Accordion - Customize icons

Section 1

Mauris mauris ante, blandit et, ultrices a, suscipit eget, quam. Integer ut neque. Vivamus nisi metus, molestie vel, gravida in, condimentum sit amet, nunc. Nam a nibh. Donec suscipit eros. Nam mi. Proin viverra leo ut odio. Curabitur malesuada. Vestibulum a velit eu ante scelerisque vulputate.

Section 2

Sed non urna. Donec et ante. Phasellus eu ligula. Vestibulum sit amet purus. Vivamus hendrerit, dolor at aliquet laoreet, mauris turpis porttitor velit, faucibus interdum tellus libero ac justo. Vivamus non quam. In suscipit faucibus urna.

Section 3

Nam enim risus, molestie et, porta ac, aliquam ac, risus. Quisque lobortis. Phasellus pellentesque purus in massa. Aenean in pede. Phasellus ac libero ac tellus pellentesque semper. Sed ac felis. Sed commodo, magna quis lacinia ornare, quam ante aliquam nisi, eu iaculis leo purus venenatis dui.

  • List item one
  • List item two
  • List item three

Section 4

Cras dictum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean lacinia mauris vel est.

Suspendisse eu nisl. Nullam ut libero. Integer dignissim consequat lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.

Customize the header icons with the icons option, which accepts classes for the header's default and active (open) state. Use any class from the UI CSS framework, or create custom classes with background images.

================================================ FILE: demos/accordion/default.html ================================================ jQuery UI Accordion - Default functionality

Section 1

Mauris mauris ante, blandit et, ultrices a, suscipit eget, quam. Integer ut neque. Vivamus nisi metus, molestie vel, gravida in, condimentum sit amet, nunc. Nam a nibh. Donec suscipit eros. Nam mi. Proin viverra leo ut odio. Curabitur malesuada. Vestibulum a velit eu ante scelerisque vulputate.

Section 2

Sed non urna. Donec et ante. Phasellus eu ligula. Vestibulum sit amet purus. Vivamus hendrerit, dolor at aliquet laoreet, mauris turpis porttitor velit, faucibus interdum tellus libero ac justo. Vivamus non quam. In suscipit faucibus urna.

Section 3

Nam enim risus, molestie et, porta ac, aliquam ac, risus. Quisque lobortis. Phasellus pellentesque purus in massa. Aenean in pede. Phasellus ac libero ac tellus pellentesque semper. Sed ac felis. Sed commodo, magna quis lacinia ornare, quam ante aliquam nisi, eu iaculis leo purus venenatis dui.

  • List item one
  • List item two
  • List item three

Section 4

Cras dictum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean lacinia mauris vel est.

Suspendisse eu nisl. Nullam ut libero. Integer dignissim consequat lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.

Click headers to expand/collapse content that is broken into logical sections, much like tabs. Optionally, toggle sections open/closed on mouseover.

The underlying HTML markup is a series of headers (H3 tags) and content divs so the content is usable without JavaScript.

================================================ FILE: demos/accordion/fillspace.html ================================================ jQuery UI Accordion - Fill space

Resize the outer container:

Section 1

Mauris mauris ante, blandit et, ultrices a, suscipit eget, quam. Integer ut neque. Vivamus nisi metus, molestie vel, gravida in, condimentum sit amet, nunc. Nam a nibh. Donec suscipit eros. Nam mi. Proin viverra leo ut odio. Curabitur malesuada. Vestibulum a velit eu ante scelerisque vulputate.

Section 2

Sed non urna. Donec et ante. Phasellus eu ligula. Vestibulum sit amet purus. Vivamus hendrerit, dolor at aliquet laoreet, mauris turpis porttitor velit, faucibus interdum tellus libero ac justo. Vivamus non quam. In suscipit faucibus urna.

Section 3

Nam enim risus, molestie et, porta ac, aliquam ac, risus. Quisque lobortis. Phasellus pellentesque purus in massa. Aenean in pede. Phasellus ac libero ac tellus pellentesque semper. Sed ac felis. Sed commodo, magna quis lacinia ornare, quam ante aliquam nisi, eu iaculis leo purus venenatis dui.

  • List item one
  • List item two
  • List item three

Section 4

Cras dictum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean lacinia mauris vel est.

Suspendisse eu nisl. Nullam ut libero. Integer dignissim consequat lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.

Because the accordion is comprised of block-level elements, by default its width fills the available horizontal space. To fill the vertical space allocated by its container, set the heightStyle option to "fill", and the script will automatically set the dimensions of the accordion to the height of its parent container.

================================================ FILE: demos/accordion/index.html ================================================ jQuery UI Accordion Demos ================================================ FILE: demos/accordion/no-auto-height.html ================================================ jQuery UI Accordion - No auto height

Section 1

Mauris mauris ante, blandit et, ultrices a, susceros. Nam mi. Proin viverra leo ut odio. Curabitur malesuada. Vestibulum a velit eu ante scelerisque vulputate.

Section 2

Sed non urna. Donec et ante. Phasellus eu ligula. Vestibulum sit amet purus. Vivamus hendrerit, dolor at aliquet laoreet, mauris turpis porttitor velit, faucibus interdum tellus libero ac justo. Vivamus non quam. In suscipit faucibus urna.

Section 3

Nam enim risus, molestie et, porta ac, aliquam ac, risus. Quisque lobortis. Phasellus pellentesque purus in massa. Aenean in pede. Phasellus ac libero ac tellus pellentesque semper. Sed ac felis. Sed commodo, magna quis lacinia ornare, quam ante aliquam nisi, eu iaculis leo purus venenatis dui.

  • List item
  • List item
  • List item
  • List item
  • List item
  • List item
  • List item

Setting heightStyle: "content" allows the accordion panels to keep their native height.

================================================ FILE: demos/accordion/sortable.html ================================================ jQuery UI Accordion - Sortable

Section 1

Mauris mauris ante, blandit et, ultrices a, suscipit eget, quam. Integer ut neque. Vivamus nisi metus, molestie vel, gravida in, condimentum sit amet, nunc. Nam a nibh. Donec suscipit eros. Nam mi. Proin viverra leo ut odio. Curabitur malesuada. Vestibulum a velit eu ante scelerisque vulputate.

Section 2

Sed non urna. Donec et ante. Phasellus eu ligula. Vestibulum sit amet purus. Vivamus hendrerit, dolor at aliquet laoreet, mauris turpis porttitor velit, faucibus interdum tellus libero ac justo. Vivamus non quam. In suscipit faucibus urna.

Section 3

Nam enim risus, molestie et, porta ac, aliquam ac, risus. Quisque lobortis. Phasellus pellentesque purus in massa. Aenean in pede. Phasellus ac libero ac tellus pellentesque semper. Sed ac felis. Sed commodo, magna quis lacinia ornare, quam ante aliquam nisi, eu iaculis leo purus venenatis dui.

  • List item one
  • List item two
  • List item three

Section 4

Cras dictum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean lacinia mauris vel est.

Suspendisse eu nisl. Nullam ut libero. Integer dignissim consequat lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.

Drag the header to re-order panels.

================================================ FILE: demos/autocomplete/categories.html ================================================ jQuery UI Autocomplete - Categories

A categorized search result. Try typing "a" or "n".

================================================ FILE: demos/autocomplete/combobox.html ================================================ jQuery UI Autocomplete - Combobox

A custom widget built by composition of Autocomplete and Button. You can either type something into the field to get filtered suggestions based on your input, or use the button to get the full list of selections.

The input is read from an existing select-element for progressive enhancement, passed to Autocomplete with a customized source-option.

This is not a supported or even complete widget. Its purely for demoing what autocomplete can do with a bit of customization. For a detailed explanation of how the widget works, check out this Learning jQuery article.

================================================ FILE: demos/autocomplete/custom-data.html ================================================ jQuery UI Autocomplete - Custom data and display
Select a project (type "j" for a start):

You can use your own custom data formats and displays by simply overriding the default focus and select actions.

Try typing "j" to get a list of projects or just press the down arrow.

================================================ FILE: demos/autocomplete/default.html ================================================ jQuery UI Autocomplete - Default functionality

The Autocomplete widgets provides suggestions while you type into the field. Here the suggestions are tags for programming languages, give "ja" (for Java or JavaScript) a try.

The datasource is a simple JavaScript array, provided to the widget using the source-option.

================================================ FILE: demos/autocomplete/folding.html ================================================ jQuery UI Autocomplete - Accent folding

The autocomplete field uses a custom source option which will match results that have accented characters even when the text field doesn't contain accented characters. However if the you type in accented characters in the text field it is smart enough not to show results that aren't accented.

Try typing "Jo" to see "John" and "Jörn", then type "Jö" to see only "Jörn".

================================================ FILE: demos/autocomplete/index.html ================================================ jQuery UI Autocomplete Demos ================================================ FILE: demos/autocomplete/london.xml ================================================ 6987 London 51.5084152563931 -0.125532746315002 2643743 GB United Kingdom P PPLC London 42.983389283 -81.233042387 6058560 CA Canada P PPL East London -33.0152850934643 27.9116249084473 1006984 ZA South Africa P PPL City 51.5133363996235 -0.0890064239501953 2643744 GB United Kingdom A ADM2 London 37.1289771 -84.0832646 4298960 US United States P PPL The Tower of London 51.5082349601834 -0.0763034820556641 6286786 GB United Kingdom S CSTL London Reefs 8.85 112.5333333 1879967 U RFSU Greater London 51.5 -0.1666667 2648110 GB United Kingdom A ADM2 London 46.1666667 6.0166667 2661811 CH Switzerland H STM London Borough of Islington 51.5333333 -0.1333333 3333156 GB United Kingdom A ADM2 ================================================ FILE: demos/autocomplete/maxheight.html ================================================ jQuery UI Autocomplete - Scrollable results

When displaying a long list of options, you can simply set the max-height for the autocomplete menu to prevent the menu from growing too large. Try typing "a" or "s" above to get a long list of results that you can scroll through.

================================================ FILE: demos/autocomplete/multiple-remote.html ================================================ jQuery UI Autocomplete - Multiple, remote

Usage: Enter at least two characters to get bird name suggestions. Select a value to continue adding more names.

This is an example showing how to use the source-option along with some events to enable autocompleting multiple values into a single field.

================================================ FILE: demos/autocomplete/multiple.html ================================================ jQuery UI Autocomplete - Multiple values

Usage: Type something, eg. "j" to see suggestions for tagging with programming languages. Select a value, then continue typing to add more.

This is an example showing how to use the source-option along with some events to enable autocompleting multiple values into a single field.

================================================ FILE: demos/autocomplete/remote-jsonp.html ================================================ jQuery UI Autocomplete - Remote JSONP datasource
Result:

The Autocomplete widgets provides suggestions while you type into the field. Here the suggestions are bird names, displayed when at least two characters are entered into the field.

The datasource is a server-side script which returns JSONP data, specified via a function which uses jQuery.ajax() for the source option.

================================================ FILE: demos/autocomplete/remote-with-cache.html ================================================ jQuery UI Autocomplete - Remote with caching

The Autocomplete widgets provides suggestions while you type into the field. Here the suggestions are bird names, displayed when at least two characters are entered into the field.

Similar to the remote datasource demo, though this adds some local caching to improve performance. The cache here saves just one query, and could be extended to cache multiple values, one for each term.

================================================ FILE: demos/autocomplete/remote.html ================================================ jQuery UI Autocomplete - Remote datasource
Result:

The Autocomplete widgets provides suggestions while you type into the field. Here the suggestions are bird names, displayed when at least two characters are entered into the field.

The datasource is a server-side script which returns JSON data, specified via a simple URL for the source-option. In addition, the minLength-option is set to 2 to avoid queries that would return too many results and the select-event is used to display some feedback.

================================================ FILE: demos/autocomplete/xml.html ================================================ jQuery UI Autocomplete - XML data parsed once
Result:

This demo shows how to retrieve some XML data, parse it using jQuery's methods, then provide it to the autocomplete as the datasource.

This should also serve as a reference on how to parse a remote XML datasource - the parsing would just happen for each request within the source-callback.

================================================ FILE: demos/bootstrap.js ================================================ /* globals window, document */ ( function() { "use strict"; var script = document.currentScript; // Read the modules var modules = script.getAttribute( "data-modules" ); var composite = script.getAttribute( "data-composite" ) || false; var pathParts = window.location.pathname.split( "/" ); var effectsAll = [ "effects/effect-blind", "effects/effect-bounce", "effects/effect-clip", "effects/effect-drop", "effects/effect-explode", "effects/effect-fade", "effects/effect-fold", "effects/effect-highlight", "effects/effect-puff", "effects/effect-pulsate", "effects/effect-scale", "effects/effect-shake", "effects/effect-size", "effects/effect-slide", "effects/effect-transfer" ]; var widgets = [ "accordion", "autocomplete", "button", "checkboxradio", "controlgroup", "datepicker", "dialog", "draggable", "droppable", "menu", "mouse", "progressbar", "resizable", "selectable", "selectmenu", "slider", "sortable", "spinner", "tabs", "tooltip" ]; function getPath( module ) { for ( var i = 0; i < widgets.length; i++ ) { if ( widgets[ i ] === module ) { return "widgets/" + module; } } for ( var j = 0; j < effectsAll.length; j++ ) { if ( module !== "effect" ) { if ( effectsAll[ j ] === module ) { return module; } if ( effectsAll[ j ].indexOf( module ) !== -1 ) { return "effects/" + module; } } } return module; } function fixPaths( modules ) { for ( var i = 0; i < modules.length; i++ ) { modules[ i ] = getPath( modules[ i ] ); } return modules; } // Hide the page while things are loading to prevent a FOUC document.documentElement.className = "demo-loading"; require.config( { baseUrl: window.location.pathname.indexOf( "demos/" ) !== -1 ? "../../ui" : "../../../ui", paths: { jquery: "../external/jquery/jquery", external: "../external/" }, shim: { "external/globalize/globalize.culture.de-DE": [ "external/globalize/globalize" ], "external/globalize/globalize.culture.ja-JP": [ "external/globalize/globalize" ] } } ); // Replace effects all shortcut modules with all the effects modules if ( modules && modules.indexOf( "effects-all" ) !== -1 ) { modules = modules.replace( /effects-all/, effectsAll.join( " " ) ); } modules = modules ? modules.replace( /^\s+|\s+$/g, "" ).split( /\s+/ ) : []; if ( !composite ) { modules.push( pathParts[ pathParts.length - 2 ] ); } modules = fixPaths( modules ); require( modules, function() { var newScript = document.createElement( "script" ); document.documentElement.className = ""; newScript.text = "( function() { " + script.innerHTML + " } )();"; document.body.appendChild( newScript ).parentNode.removeChild( newScript ); } ); } )(); ================================================ FILE: demos/button/default.html ================================================ jQuery UI Button - Default functionality

Widget Buttons

An anchor

CSS Buttons

An anchor

Examples of the markup that can be used for buttons: A button element, an input of type submit and an anchor.

Buttons can be styled via the button widget or by adding the classes yourself. This avoids the JavaScript overhead if you don't need any of the methods provided by the button widget.

================================================ FILE: demos/button/icons.html ================================================ jQuery UI Button - Icons

Widget

CSS

Some buttons with various combinations of text and icons.

================================================ FILE: demos/button/index.html ================================================ jQuery UI Button Demos ================================================ FILE: demos/checkboxradio/default.html ================================================ jQuery UI Checkboxradio - Default functionality

Checkbox and radio button widgets

Radio Group

Select a Location:

Checkbox

Hotel Ratings:

Checkbox nested in label

Bed Type:

Examples of the markup that can be used with checkboxes and radio buttons.

================================================ FILE: demos/checkboxradio/index.html ================================================ jQuery UI Checkboxradio Demos ================================================ FILE: demos/checkboxradio/no-icons.html ================================================ jQuery UI Checkboxradio - No Icons

Checkbox and radio button widgets

Radio Group

Select a Location:

Checkbox

Hotel Ratings:

Checkbox nested in label

Bed Type:

Examples of the markup that can be used with checkboxes and radio buttons, here showing both without icons.

================================================ FILE: demos/checkboxradio/product-selector.html ================================================ jQuery UI Checkboxradio - Product Selector

1.) Select a brand

2.) Select a shape

3.) Customize

Using two sets of radio buttons, as horizontal controlgroups, and one group of checkboxes, as a vertical controlgroup, to implement a product selector.

================================================ FILE: demos/checkboxradio/radiogroup.html ================================================ jQuery UI Checkboxradio - Radio Group

Radio Group

Select a Location:

Example markup using the controlgroup widget to create a radio group.

================================================ FILE: demos/controlgroup/default.html ================================================ jQuery UI Controlgroup - Default Functionality

Controlgroup

Rental Car

Rental Car

A controlgroup featuring various form controls. The first features a horizontal toolbar like orientation, the second is in a space saving vertical orientation for usages like mobile devices and panels.

================================================ FILE: demos/controlgroup/index.html ================================================ jQuery UI Controlgroup Demos ================================================ FILE: demos/controlgroup/splitbutton.html ================================================ jQuery UI Controlgroup - Split Button

Split button


Output:

    A controlgroup creating a split button, by combining a button and a selectmenu. We adjust the classes option on the selectmenu to show only the icon

    ================================================ FILE: demos/controlgroup/toolbar.html ================================================ jQuery UI Controlgroup - Toolbar
    	The Rime of the Ancient Mariner (text of 1834)
    	BY SAMUEL TAYLOR COLERIDGE
    	Argument
    
    	How a Ship having passed the Line was driven by storms to the cold Country towards the South Pole;
    	and how from thence she made her course to the tropical Latitude of the Great Pacific Ocean; and
    	of the strange things that befell; and in what manner the Ancyent Marinere came back to his own
    	Country.
    
    	PART I
    	It is an ancient Mariner,
    	And he stoppeth one of three.
    	'By thy long grey beard and glittering eye,
    	Now wherefore stopp'st thou me?
    
    	The Bridegroom's doors are opened wide,
    	And I am next of kin;
    	The guests are met, the feast is set:
    	May'st hear the merry din.'
    
    	He holds him with his skinny hand,
    	'There was a ship,' quoth he.
    	'Hold off! unhand me, grey-beard loon!'
    	Eftsoons his hand dropt he.
    
    	He holds him with his glittering eye—
    	The Wedding-Guest stood still,
    	And listens like a three years' child:
    	The Mariner hath his will.
    
    	The Wedding-Guest sat on a stone:
    	He cannot choose but hear;
    	And thus spake on that ancient man,
    	The bright-eyed Mariner.
    
    	'The ship was cheered, the harbour cleared,
    	Merrily did we drop
    	Below the kirk, below the hill,
    	Below the lighthouse top.
    
    	The Sun came up upon the left,
    	Out of the sea came he!
    	And he shone bright, and on the right
    	Went down into the sea.
    
    	Higher and higher every day,
    	Till over the mast at noon—'
    	The Wedding-Guest here beat his breast,
    	For he heard the loud bassoon.
    
    	The bride hath paced into the hall,
    	Red as a rose is she;
    	Nodding their heads before her goes
    	The merry minstrelsy.
    
    	The Wedding-Guest he beat his breast,
    	Yet he cannot choose but hear;
    	And thus spake on that ancient man,
    	The bright-eyed Mariner.
    
    	And now the STORM-BLAST came, and he
    	Was tyrannous and strong:
    	He struck with his o'ertaking wings,
    	And chased us south along.
    
    	With sloping masts and dipping prow,
    	As who pursued with yell and blow
    	Still treads the shadow of his foe,
    	And forward bends his head,
    	The ship drove fast, loud roared the blast,
    	And southward aye we fled.
    
    	And now there came both mist and snow,
    	And it grew wondrous cold:
    	And ice, mast-high, came floating by,
    	As green as emerald.
    
    	And through the drifts the snowy clifts
    	Did send a dismal sheen:
    	Nor shapes of men nor beasts we ken—
    	The ice was all between.
    
    	The ice was here, the ice was there,
    	The ice was all around:
    	It cracked and growled, and roared and howled,
    	Like noises in a swound!
    
    	At length did cross an Albatross,
    	Thorough the fog it came;
    	As if it had been a Christian soul,
    	We hailed it in God's name.
    
    	It ate the food it ne'er had eat,
    	And round and round it flew.
    	The ice did split with a thunder-fit;
    	The helmsman steered us through!
    
    	And a good south wind sprung up behind;
    	The Albatross did follow,
    	And every day, for food or play,
    	Came to the mariner's hollo!
    
    	In mist or cloud, on mast or shroud,
    	It perched for vespers nine;
    	Whiles all the night, through fog-smoke white,
    	Glimmered the white Moon-shine.'
    
    	'God save thee, ancient Mariner!
    	From the fiends, that plague thee thus!—
    	Why look'st thou so?'—With my cross-bow
    	I shot the ALBATROSS.
    	

    A sample editor toolbar

    Highlight text and edit it using the buttons and dropdowns in the toolbar.

    Remember: This is only a demo and shouldn't be used for anything in production. Use a proper editor like ProseMirror instead.

    ================================================ FILE: demos/datepicker/alt-field.html ================================================ jQuery UI Datepicker - Populate alternate field

    Date:  

    Populate an alternate field with its own date format whenever a date is selected using the altField and altFormat options. This feature could be used to present a human-friendly date for user selection, while passing a more computer-friendly date through for further processing.

    ================================================ FILE: demos/datepicker/animation.html ================================================ jQuery UI Datepicker - Animations

    Date:

    Animations:

    Use different animations when opening or closing the datepicker. Choose an animation from the dropdown, then click on the input to see its effect. You can use one of the three standard animations or any of the UI Effects.

    ================================================ FILE: demos/datepicker/buttonbar.html ================================================ jQuery UI Datepicker - Display button bar

    Date:

    Display a button for selecting Today's date and a Done button for closing the calendar with the boolean showButtonPanel option. Each button is enabled by default when the bar is displayed, but can be turned off with additional options. Button text is customizable.

    ================================================ FILE: demos/datepicker/date-formats.html ================================================ jQuery UI Datepicker - Format date

    Date:

    Format options:

    Display date feedback in a variety of ways. Choose a date format from the dropdown, then click on the input and select a date to see it in that format.

    ================================================ FILE: demos/datepicker/date-range.html ================================================ jQuery UI Datepicker - Select a Date Range

    Select the date range to search for.

    ================================================ FILE: demos/datepicker/default.html ================================================ jQuery UI Datepicker - Default functionality

    Date:

    The datepicker is tied to a standard form input field. Focus on the input (click, or use the tab key) to open an interactive calendar in a small overlay. Choose a date, click elsewhere on the page (blur the input), or hit the Esc key to close. If a date is chosen, feedback is shown as the input's value.

    ================================================ FILE: demos/datepicker/dropdown-month-year.html ================================================ jQuery UI Datepicker - Display month & year menus

    Date:

    Show month and year dropdowns in place of the static month/year header to facilitate navigation through large timeframes. Add the boolean changeMonth and changeYear options.

    ================================================ FILE: demos/datepicker/icon-trigger.html ================================================ jQuery UI Datepicker - Icon trigger

    Date:

    Click the icon next to the input field to show the datepicker. Set the datepicker to open on focus (default behavior), on icon click, or both.

    ================================================ FILE: demos/datepicker/index.html ================================================ jQuery UI Datepicker Demos ================================================ FILE: demos/datepicker/inline.html ================================================ jQuery UI Datepicker - Display inline Date:

    Display the datepicker embedded in the page instead of in an overlay. Simply call .datepicker() on a div instead of an input.

    ================================================ FILE: demos/datepicker/localization.html ================================================ jQuery UI Datepicker - Localize calendar

    Date:  

    Localize the datepicker calendar language and format (English / Western formatting is the default). The datepicker includes built-in support for languages that read right-to-left, such as Arabic and Hebrew.

    ================================================ FILE: demos/datepicker/min-max.html ================================================ jQuery UI Datepicker - Restrict date range

    Date:

    Restrict the range of selectable dates with the minDate and maxDate options. Set the beginning and end dates as actual dates (new Date(2009, 1 - 1, 26)), as a numeric offset from today (-20), or as a string of periods and units ('+1M +10D'). For the last, use 'D' for days, 'W' for weeks, 'M' for months, or 'Y' for years.

    ================================================ FILE: demos/datepicker/multiple-calendars.html ================================================ jQuery UI Datepicker - Display multiple months

    Date:

    Set the numberOfMonths option to an integer of 2 or more to show multiple months in a single datepicker.

    ================================================ FILE: demos/datepicker/other-months.html ================================================ jQuery UI Datepicker - Dates in other months

    Date:

    The datepicker can show dates that come from other than the main month being displayed. These other dates can also be made selectable.

    ================================================ FILE: demos/datepicker/show-week.html ================================================ jQuery UI Datepicker - Show week of the year

    Date:

    The datepicker can show the week of the year. The default calculation follows the ISO 8601 definition: the week starts on Monday, the first week of the year contains the first Thursday of the year. This means that some days from one year may be placed into weeks 'belonging' to another year.

    ================================================ FILE: demos/demos.css ================================================ body { font-family: Arial, Helvetica, sans-serif; } .demo-loading { visibility: hidden; } table { font-size: 1em; } .demo-description { clear: both; padding: 12px; } .ui-draggable, .ui-droppable { background-position: top; } ================================================ FILE: demos/dialog/animated.html ================================================ jQuery UI Dialog - Animation

    This is an animated dialog which is useful for displaying information. The dialog window can be moved, resized and closed with the 'x' icon.

    Dialogs may be animated by specifying an effect for the show and/or hide properties. You must include the individual effects file for any effects you would like to use.

    ================================================ FILE: demos/dialog/default.html ================================================ jQuery UI Dialog - Default functionality

    This is the default dialog which is useful for displaying information. The dialog window can be moved, resized and closed with the 'x' icon.

    The basic dialog window is an overlay positioned within the viewport and is protected from page content (like select elements) shining through with an iframe. It has a title bar and a content area, and can be moved, resized and closed with the 'x' icon by default.

    ================================================ FILE: demos/dialog/index.html ================================================ jQuery UI Dialog Demos ================================================ FILE: demos/dialog/modal-confirmation.html ================================================ jQuery UI Dialog - Modal confirmation

    These items will be permanently deleted and cannot be recovered. Are you sure?

    Sed vel diam id libero rutrum convallis. Donec aliquet leo vel magna. Phasellus rhoncus faucibus ante. Etiam bibendum, enim faucibus aliquet rhoncus, arcu felis ultricies neque, sit amet auctor elit eros a lectus.

    Confirm an action that may be destructive or important. Set the modal option to true, and specify primary and secondary user actions with the buttons option.

    ================================================ FILE: demos/dialog/modal-form.html ================================================ jQuery UI Dialog - Modal form

    All form fields are required.

    Existing Users:

    Name Email Password
    John Doe john.doe@example.com johndoe1

    Use a modal dialog to require that the user enter data during a multi-step process. Embed form markup in the content area, set the modal option to true, and specify primary and secondary user actions with the buttons option.

    ================================================ FILE: demos/dialog/modal-message.html ================================================ jQuery UI Dialog - Modal message

    Your files have downloaded successfully into the My Downloads folder.

    Currently using 36% of your storage space.

    Sed vel diam id libero rutrum convallis. Donec aliquet leo vel magna. Phasellus rhoncus faucibus ante. Etiam bibendum, enim faucibus aliquet rhoncus, arcu felis ultricies neque, sit amet auctor elit eros a lectus.

    Use a modal dialog to explicitly acknowledge information or an action before continuing their work. Set the modal option to true, and specify a primary action (Ok) with the buttons option.

    ================================================ FILE: demos/draggable/constrain-movement.html ================================================ jQuery UI Draggable - Constrain movement

    Constrain movement along an axis:

    I can be dragged only vertically

    I can be dragged only horizontally

    Or to within another DOM element:

    I'm contained within the box

    I'm contained within my parent

    Constrain the movement of each draggable by defining the boundaries of the draggable area. Set the axis option to limit the draggable's path to the x- or y-axis, or use the containment option to specify a parent DOM element or a jQuery selector, like 'document.'

    ================================================ FILE: demos/draggable/cursor-style.html ================================================ jQuery UI Draggable - Cursor style

    I will always stick to the center (relative to the mouse)

    My cursor is at left -5 and top -5

    My cursor position is only controlled for the 'bottom' value

    Position the cursor while dragging the object. By default the cursor appears in the center of the dragged object; use the cursorAt option to specify another location relative to the draggable (specify a pixel value from the top, right, bottom, and/or left). Customize the cursor's appearance by supplying the cursor option with a valid CSS cursor value: default, move, pointer, crosshair, etc.

    ================================================ FILE: demos/draggable/default.html ================================================ jQuery UI Draggable - Default functionality

    Drag me around

    Enable draggable functionality on any DOM element. Move the draggable object by clicking on it with the mouse and dragging it anywhere within the viewport.

    ================================================ FILE: demos/draggable/events.html ================================================ jQuery UI Draggable - Events

    Drag me to trigger the chain of events.

    • "start" invoked 0x
    • "drag" invoked 0x
    • "stop" invoked 0x

    Layer functionality onto the draggable using the start, drag, and stop events. Start is fired at the start of the drag; drag during the drag; and stop when dragging stops.

    ================================================ FILE: demos/draggable/handle.html ================================================ jQuery UI Draggable - Handles

    I can be dragged only by this handle

    You can drag me around…

    …but you can't drag me by this handle.

    Allow dragging only when the cursor is over a specific part of the draggable. Use the handle option to specify the jQuery selector of an element (or group of elements) used to drag the object.

    Or prevent dragging when the cursor is over a specific element (or group of elements) within the draggable. Use the cancel option to specify a jQuery selector over which to "cancel" draggable functionality.

    ================================================ FILE: demos/draggable/index.html ================================================ jQuery UI Draggable Demos ================================================ FILE: demos/draggable/revert.html ================================================ jQuery UI Draggable - Revert position

    Revert the original

    Revert the helper

    Return the draggable (or it's helper) to its original location when dragging stops with the boolean revert option.

    ================================================ FILE: demos/draggable/scroll.html ================================================ jQuery UI Draggable - Auto-scroll

    Scroll set to true, default settings

    scrollSensitivity set to 100

    scrollSpeed set to 100

    Automatically scroll the document when the draggable is moved beyond the viewport. Set the scroll option to true to enable auto-scrolling, and fine-tune when scrolling is triggered and its speed with the scrollSensitivity and scrollSpeed options.

    ================================================ FILE: demos/draggable/snap-to.html ================================================ jQuery UI Draggable - Snap to element or grid

    I'm a snap target


    Default (snap: true), snaps to all other draggable elements

    I only snap to the big box

    I only snap to the outer edges of the big box

    I snap to a 20 x 20 grid

    I snap to a 80 x 80 grid

    Snap the draggable to the inner or outer boundaries of a DOM element. Use the snap, snapMode (inner, outer, both), and snapTolerance (distance in pixels the draggable must be from the element when snapping is invoked) options.

    Or snap the draggable to a grid. Set the dimensions of grid cells (height and width in pixels) with the grid option.

    ================================================ FILE: demos/draggable/sortable.html ================================================ jQuery UI Draggable + Sortable
    • Drag me down
    • Item 1
    • Item 2
    • Item 3
    • Item 4
    • Item 5

    Draggables are built to interact seamlessly with sortables.

    ================================================ FILE: demos/draggable/visual-feedback.html ================================================ jQuery UI Draggable - Visual feedback

    With helpers:

    Original

    Semi-transparent clone

    Custom helper (in combination with cursorAt)

    Stacked:

    We are draggables..

    ..whose z-indexes are controlled automatically..

    ..with the stack option.

    Provide feedback to users as they drag an object in the form of a helper. The helper option accepts the values 'original' (the draggable object moves with the cursor), 'clone' (a duplicate of the draggable moves with the cursor), or a function that returns a DOM element (that element is shown near the cursor during drag). Control the helper's transparency with the opacity option.

    To clarify which draggable is in play, bring the draggable in motion to front. Use the zIndex option to set a higher z-index for the helper, if in play, or use the stack option to ensure that the last item dragged will appear on top of others in the same group on drag stop.

    ================================================ FILE: demos/droppable/accepted-elements.html ================================================ jQuery UI Droppable - Accept

    I'm draggable but can't be dropped

    Drag me to my target

    accept: '#draggable'

    Specify using the accept option which element (or group of elements) is accepted by the target droppable.

    ================================================ FILE: demos/droppable/default.html ================================================ jQuery UI Droppable - Default functionality

    Drag me to my target

    Drop here

    Enable any DOM element to be droppable, a target for draggable elements.

    ================================================ FILE: demos/droppable/index.html ================================================ jQuery UI Droppable Demos ================================================ FILE: demos/droppable/photo-manager.html ================================================ jQuery UI Droppable - Simple photo manager

    Trash Trash

    You can delete an image either by dragging it to the Trash or by clicking the trash icon.

    You can "recycle" an image by dragging it back to the gallery or by clicking the recycle icon.

    You can view larger image by clicking the zoom icon. jQuery UI dialog widget is used for the modal window.

    ================================================ FILE: demos/droppable/propagation.html ================================================ jQuery UI Droppable - Prevent propagation

    Drag me to my target

    Outer droppable

    Inner droppable (not greedy)

    Outer droppable

    Inner droppable (greedy)

    When working with nested droppables — for example, you may have an editable directory structure displayed as a tree, with folder and document nodes — the greedy option set to true prevents event propagation when a draggable is dropped on a child node (droppable).

    ================================================ FILE: demos/droppable/revert.html ================================================ jQuery UI Droppable - Revert draggable position

    I revert when I'm dropped

    I revert when I'm not dropped

    Drop me here

    Return the draggable (or it's helper) to its original location when dragging stops with the boolean revert option set on the draggable.

    ================================================ FILE: demos/droppable/visual-feedback.html ================================================ jQuery UI Droppable - Visual feedback

    Feedback on hover:

    Drag me to my target

    Drop here

    Feedback on activating draggable:

    Drag me to my target

    Drop here

    Change the droppable's appearance on hover, or when the droppable is active (an acceptable draggable is dropped on it). Set the values of the ui-droppable-hover or ui-droppable-active properties on the classes option to specify the respective classes.

    ================================================ FILE: demos/effect/addClass.html ================================================ jQuery UI Effects - addClass demo
    Etiam libero neque, luctus a, eleifend nec, semper at, lorem. Sed pede.

    This demo adds a class which animates: text-indent, letter-spacing, width, height, padding, margin, and font-size.

    ================================================ FILE: demos/effect/animate.html ================================================ jQuery UI Effects - Animate demo

    Animate

    Etiam libero neque, luctus a, eleifend nec, semper at, lorem. Sed pede. Nulla lorem metus, adipiscing ut, luctus sed, hendrerit vitae, mi.

    Click the button above to preview the effect.

    ================================================ FILE: demos/effect/default.html ================================================ jQuery UI Effects - Effect demo

    Effect

    Etiam libero neque, luctus a, eleifend nec, semper at, lorem. Sed pede. Nulla lorem metus, adipiscing ut, luctus sed, hendrerit vitae, mi.

    Click the button above to show the effect.

    ================================================ FILE: demos/effect/easing.html ================================================ jQuery UI Effects - Easing demo

    All easings provided by jQuery UI are drawn above, using an HTML canvas element. Click a diagram to see the easing in action.

    ================================================ FILE: demos/effect/hide.html ================================================ jQuery UI Effects - Hide Demo

    Hide

    Etiam libero neque, luctus a, eleifend nec, semper at, lorem. Sed pede. Nulla lorem metus, adipiscing ut, luctus sed, hendrerit vitae, mi.

    Click the button above to preview the effect.

    ================================================ FILE: demos/effect/index.html ================================================ jQuery UI Effects Demos ================================================ FILE: demos/effect/removeClass.html ================================================ jQuery UI Effects - removeClass Demo
    Etiam libero neque, luctus a, eleifend nec, semper at, lorem. Sed pede.

    Click the button above to preview the effect.

    ================================================ FILE: demos/effect/show.html ================================================ jQuery UI Effects - Show Demo

    Show

    Etiam libero neque, luctus a, eleifend nec, semper at, lorem. Sed pede. Nulla lorem metus, adipiscing ut, luctus sed, hendrerit vitae, mi.

    Click the button above to preview the effect.

    ================================================ FILE: demos/effect/switchClass.html ================================================ jQuery UI Effects - switchClass Demo
    Etiam libero neque, luctus a, eleifend nec, semper at, lorem. Sed pede.

    Click the button above to preview the effect.

    ================================================ FILE: demos/effect/toggle.html ================================================ jQuery UI Effects - Toggle Demo

    Toggle

    Etiam libero neque, luctus a, eleifend nec, semper at, lorem. Sed pede. Nulla lorem metus, adipiscing ut, luctus sed, hendrerit vitae, mi.

    Click the button above to preview the effect.

    ================================================ FILE: demos/effect/toggleClass.html ================================================ jQuery UI Effects - toggleClass Demo
    Etiam libero neque, luctus a, eleifend nec, semper at, lorem. Sed pede.

    Click the button above to preview the effect.

    ================================================ FILE: demos/index.html ================================================ jQuery UI Demos ================================================ FILE: demos/menu/categories.html ================================================ jQuery UI Menu - Categories

    By using the items option, you can configure which elements are converted into selectable menu items. Here this technique is used to create category headers.

    ================================================ FILE: demos/menu/default.html ================================================ jQuery UI Menu - Default functionality

    A menu with the default configuration, disabled items and nested menus. A list is transformed, adding theming, mouse and keyboard navigation support. Try to tab to the menu then use the cursor keys to navigate.

    ================================================ FILE: demos/menu/icons.html ================================================ jQuery UI Menu - Icons

    A menu with the default configuration, showing how to use a menu with icons.

    ================================================ FILE: demos/menu/index.html ================================================ jQuery UI Menu Demos ================================================ FILE: demos/position/cycler.html ================================================ jQuery UI Position - Image Cycler

    A photoviewer prototype using Position to place images at the center, left and right and cycle them.
    Use the links at the top to cycle, or click on the images on the left and right.
    Note how the images are repositioned when resizing the window.

    ================================================ FILE: demos/position/default.html ================================================ jQuery UI Position - Default functionality

    This is the position parent element.

    to position

    to position 2

    position...
    my:
    at:
    collision:

    Use the form controls to configure the positioning, or drag the positioned element to modify its offset.
    Drag around the parent element to see collision detection in action.

    ================================================ FILE: demos/position/index.html ================================================ jQuery UI Position Demo ================================================ FILE: demos/progressbar/default.html ================================================ jQuery UI Progressbar - Default functionality

    Default determinate progress bar.

    ================================================ FILE: demos/progressbar/download.html ================================================ jQuery UI Progressbar - Download Dialog
    Starting download...

    Download dialog progressbar demo.

    ================================================ FILE: demos/progressbar/indeterminate.html ================================================ jQuery UI Progressbar - Indeterminate Value

    Indeterminate progress bar and switching between determinate and indeterminate styles.

    ================================================ FILE: demos/progressbar/index.html ================================================ jQuery UI Progressbar Demos ================================================ FILE: demos/progressbar/label.html ================================================ jQuery UI Progressbar - Custom Label
    Loading...

    Custom updated label demo.

    ================================================ FILE: demos/resizable/animate.html ================================================ jQuery UI Resizable - Animate

    Animate

    Animate the resize action using the animate option (boolean). When this option is set to true, drag the outline to the desired location; the element animates to that size on drag stop.

    ================================================ FILE: demos/resizable/aspect-ratio.html ================================================ jQuery UI Resizable - Preserve aspect ratio

    Preserve aspect ratio

    Maintain the existing aspect ratio or set a new one to constrain the proportions on resize. Set the aspectRatio option to true, and optionally pass in a new ratio (i.e., 4/3)

    ================================================ FILE: demos/resizable/constrain-area.html ================================================ jQuery UI Resizable - Constrain resize area

    Containment

    Resizable

    Define the boundaries of the resizable area. Use the containment option to specify a parent DOM element or a jQuery selector, like 'document.'

    ================================================ FILE: demos/resizable/default.html ================================================ jQuery UI Resizable - Default functionality

    Resizable

    Enable any DOM element to be resizable. With the cursor grab the right or bottom border and drag to the desired width or height.

    ================================================ FILE: demos/resizable/helper.html ================================================ jQuery UI Resizable - Helper

    Helper

    Display only an outline of the element while resizing by setting the helper option to a CSS class.

    ================================================ FILE: demos/resizable/index.html ================================================ jQuery UI Resizable Demos ================================================ FILE: demos/resizable/max-min.html ================================================ jQuery UI Resizable - Maximum / minimum size

    Resize larger / smaller

    Limit the resizable element to a maximum or minimum height or width using the maxHeight, maxWidth, minHeight, and minWidth options.

    ================================================ FILE: demos/resizable/snap-to-grid.html ================================================ jQuery UI Resizable - Snap to grid

    Grid

    Snap the resizable element to a grid. Set the dimensions of grid cells (height and width in pixels) with the grid option.

    ================================================ FILE: demos/resizable/synchronous-resize.html ================================================ jQuery UI Resizable - Synchronous resize

    Resize

    will also resize

    Resize multiple elements simultaneously by clicking and dragging the sides of one. Pass a shared selector into the alsoResize option.

    ================================================ FILE: demos/resizable/textarea.html ================================================ jQuery UI Resizable - Textarea

    Resizable can be applied to a textarea. This allows the user to make the textarea bigger to type longer prose.

    ================================================ FILE: demos/resizable/visual-feedback.html ================================================ jQuery UI Resizable - Visual feedback

    Ghost

    Instead of showing the actual element during resize, set the ghost option to true to show a semi-transparent part of the element.

    ================================================ FILE: demos/search.js ================================================ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // Fetch jQuery as an AMD dependency require( [ "jquery" ], factory ); } else { // Use the jQuery browser global factory( jQuery ); } } )( function( $ ) { "use strict"; var database = { "Great Bittern": "Botaurus stellaris", "Little Grebe": "Tachybaptus ruficollis", "Black-necked Grebe": "Podiceps nigricollis", "Little Bittern": "Ixobrychus minutus", "Black-crowned Night Heron": "Nycticorax nycticorax", "Purple Heron": "Ardea purpurea", "White Stork": "Ciconia ciconia", "Spoonbill": "Platalea leucorodia", "Red-crested Pochard": "Netta rufina", "Common Eider": "Somateria mollissima", "Red Kite": "Milvus milvus", "Hen Harrier": "Circus cyaneus", "Montagu`s Harrier": "Circus pygargus", "Black Grouse": "Tetrao tetrix", "Grey Partridge": "Perdix perdix", "Spotted Crake": "Porzana porzana", "Corncrake": "Crex crex", "Common Crane": "Grus grus", "Avocet": "Recurvirostra avosetta", "Stone Curlew": "Burhinus oedicnemus", "Common Ringed Plover": "Charadrius hiaticula", "Kentish Plover": "Charadrius alexandrinus", "Ruff": "Philomachus pugnax", "Common Snipe": "Gallinago gallinago", "Black-tailed Godwit": "Limosa limosa", "Common Redshank": "Tringa totanus", "Sandwich Tern": "Sterna sandvicensis", "Common Tern": "Sterna hirundo", "Arctic Tern": "Sterna paradisaea", "Little Tern": "Sternula albifrons", "Black Tern": "Chlidonias niger", "Barn Owl": "Tyto alba", "Little Owl": "Athene noctua", "Short-eared Owl": "Asio flammeus", "European Nightjar": "Caprimulgus europaeus", "Common Kingfisher": "Alcedo atthis", "Eurasian Hoopoe": "Upupa epops", "Eurasian Wryneck": "Jynx torquilla", "European Green Woodpecker": "Picus viridis", "Crested Lark": "Galerida cristata", "White-headed Duck": "Oxyura leucocephala", "Pale-bellied Brent Goose": "Branta hrota", "Tawny Pipit": "Anthus campestris", "Whinchat": "Saxicola rubetra", "European Stonechat": "Saxicola rubicola", "Northern Wheatear": "Oenanthe oenanthe", "Savi`s Warbler": "Locustella luscinioides", "Sedge Warbler": "Acrocephalus schoenobaenus", "Great Reed Warbler": "Acrocephalus arundinaceus", "Bearded Reedling": "Panurus biarmicus", "Red-backed Shrike": "Lanius collurio", "Great Grey Shrike": "Lanius excubitor", "Woodchat Shrike": "Lanius senator", "Common Raven": "Corvus corax", "Yellowhammer": "Emberiza citrinella", "Ortolan Bunting": "Emberiza hortulana", "Corn Bunting": "Emberiza calandra", "Great Cormorant": "Phalacrocorax carbo", "Hawfinch": "Coccothraustes coccothraustes", "Common Shelduck": "Tadorna tadorna", "Bluethroat": "Luscinia svecica", "Grey Heron": "Ardea cinerea", "Barn Swallow": "Hirundo rustica", "Hooded Crow": "Corvus cornix", "Dunlin": "Calidris alpina", "Eurasian Pied Flycatcher": "Ficedula hypoleuca", "Eurasian Nuthatch": "Sitta europaea", "Short-toed Tree Creeper": "Certhia brachydactyla", "Wood Lark": "Lullula arborea", "Tree Pipit": "Anthus trivialis", "Eurasian Hobby": "Falco subbuteo", "Marsh Warbler": "Acrocephalus palustris", "Wood Sandpiper": "Tringa glareola", "Tawny Owl": "Strix aluco", "Lesser Whitethroat": "Sylvia curruca", "Barnacle Goose": "Branta leucopsis", "Common Goldeneye": "Bucephala clangula", "Western Marsh Harrier": "Circus aeruginosus", "Common Buzzard": "Buteo buteo", "Sanderling": "Calidris alba", "Little Gull": "Larus minutus", "Eurasian Magpie": "Pica pica", "Willow Warbler": "Phylloscopus trochilus", "Wood Warbler": "Phylloscopus sibilatrix", "Great Crested Grebe": "Podiceps cristatus", "Eurasian Jay": "Garrulus glandarius", "Common Redstart": "Phoenicurus phoenicurus", "Blue-headed Wagtail": "Motacilla flava", "Common Swift": "Apus apus", "Marsh Tit": "Poecile palustris", "Goldcrest": "Regulus regulus", "European Golden Plover": "Pluvialis apricaria", "Eurasian Bullfinch": "Pyrrhula pyrrhula", "Common Whitethroat": "Sylvia communis", "Meadow Pipit": "Anthus pratensis", "Greylag Goose": "Anser anser", "Spotted Flycatcher": "Muscicapa striata", "European Greenfinch": "Carduelis chloris", "Common Greenshank": "Tringa nebularia", "Great Spotted Woodpecker": "Dendrocopos major", "Greater Canada Goose": "Branta canadensis", "Mistle Thrush": "Turdus viscivorus", "Great Black-backed Gull": "Larus marinus", "Goosander": "Mergus merganser", "Great Egret": "Casmerodius albus", "Northern Goshawk": "Accipiter gentilis", "Dunnock": "Prunella modularis", "Stock Dove": "Columba oenas", "Common Wood Pigeon": "Columba palumbus", "Eurasian Woodcock": "Scolopax rusticola", "House Sparrow": "Passer domesticus", "Common House Martin": "Delichon urbicum", "Red Knot": "Calidris canutus", "Western Jackdaw": "Corvus monedula", "Brambling": "Fringilla montifringilla", "Northern Lapwing": "Vanellus vanellus", "European Reed Warbler": "Acrocephalus scirpaceus", "Lesser Black-backed Gull": "Larus fuscus", "Little Egret": "Egretta garzetta", "Little Stint": "Calidris minuta", "Common Linnet": "Carduelis cannabina", "Mute Swan": "Cygnus olor", "Common Cuckoo": "Cuculus canorus", "Black-headed Gull": "Larus ridibundus", "Greater White-fronted Goose": "Anser albifrons", "Great Tit": "Parus major", "Redwing": "Turdus iliacus", "Gadwall": "Anas strepera", "Fieldfare": "Turdus pilaris", "Tufted Duck": "Aythya fuligula", "Crested Tit": "Lophophanes cristatus", "Willow Tit": "Poecile montanus", "Eurasian Coot": "Fulica atra", "Common Blackbird": "Turdus merula", "Smew": "Mergus albellus", "Common Sandpiper": "Actitis hypoleucos", "Sand Martin": "Riparia riparia", "Purple Sandpiper": "Calidris maritima", "Northern Pintail": "Anas acuta", "Blue Tit": "Cyanistes caeruleus", "European Goldfinch": "Carduelis carduelis", "Eurasian Whimbrel": "Numenius phaeopus", "Common Reed Bunting": "Emberiza schoeniclus", "Eurasian Tree Sparrow": "Passer montanus", "Rook": "Corvus frugilegus", "European Robin": "Erithacus rubecula", "Bar-tailed Godwit": "Limosa lapponica", "Dark-bellied Brent Goose": "Branta bernicla", "Eurasian Oystercatcher": "Haematopus ostralegus", "Eurasian Siskin": "Carduelis spinus", "Northern Shoveler": "Anas clypeata", "Eurasian Wigeon": "Anas penelope", "Eurasian Sparrow Hawk": "Accipiter nisus", "Icterine Warbler": "Hippolais icterina", "Common Starling": "Sturnus vulgaris", "Long-tailed Tit": "Aegithalos caudatus", "Ruddy Turnstone": "Arenaria interpres", "Mew Gull": "Larus canus", "Common Pochard": "Aythya ferina", "Common Chiffchaff": "Phylloscopus collybita", "Greater Scaup": "Aythya marila", "Common Kestrel": "Falco tinnunculus", "Garden Warbler": "Sylvia borin", "Eurasian Collared Dove": "Streptopelia decaocto", "Eurasian Skylark": "Alauda arvensis", "Common Chaffinch": "Fringilla coelebs", "Common Moorhen": "Gallinula chloropus", "Water Pipit": "Anthus spinoletta", "Mallard": "Anas platyrhynchos", "Winter Wren": "Troglodytes troglodytes", "Common Teal": "Anas crecca", "Green Sandpiper": "Tringa ochropus", "White Wagtail": "Motacilla alba", "Eurasian Curlew": "Numenius arquata", "Song Thrush": "Turdus philomelos", "European Herring Gull": "Larus argentatus", "Grey Plover": "Pluvialis squatarola", "Carrion Crow": "Corvus corone", "Coal Tit": "Periparus ater", "Spotted Redshank": "Tringa erythropus", "Blackcap": "Sylvia atricapilla", "Egyptian Vulture": "Neophron percnopterus", "Razorbill": "Alca torda", "Alpine Swift": "Apus melba", "Long-legged Buzzard": "Buteo rufinus", "Audouin`s Gull": "Larus audouinii", "Balearic Shearwater": "Puffinus mauretanicus", "Upland Sandpiper": "Bartramia longicauda", "Greater Spotted Eagle": "Aquila clanga", "Ring Ouzel": "Turdus torquatus", "Yellow-browed Warbler": "Phylloscopus inornatus", "Blue Rock Thrush": "Monticola solitarius", "Buff-breasted Sandpiper": "Tryngites subruficollis", "Jack Snipe": "Lymnocryptes minimus", "White-rumped Sandpiper": "Calidris fuscicollis", "Ruddy Shelduck": "Tadorna ferruginea", "Cetti's Warbler": "Cettia cetti", "Citrine Wagtail": "Motacilla citreola", "Roseate Tern": "Sterna dougallii", "Black-legged Kittiwake": "Rissa tridactyla", "Pygmy Cormorant": "Phalacrocorax pygmeus", "Booted Eagle": "Aquila pennata", "Lesser White-fronted Goose": "Anser erythropus", "Little Bunting": "Emberiza pusilla", "Eleonora's Falcon": "Falco eleonorae", "European Serin": "Serinus serinus", "Twite": "Carduelis flavirostris", "Yellow-legged Gull": "Larus michahellis", "Gyr Falcon": "Falco rusticolus", "Greenish Warbler": "Phylloscopus trochiloides", "Red-necked Phalarope": "Phalaropus lobatus", "Mealy Redpoll": "Carduelis flammea", "Glaucous Gull": "Larus hyperboreus", "Great Skua": "Stercorarius skua", "Great Bustard": "Otis tarda", "Velvet Scoter": "Melanitta fusca", "Pine Grosbeak": "Pinicola enucleator", "House Crow": "Corvus splendens", "Hume`s Leaf Warbler": "Phylloscopus humei", "Great Northern Loon": "Gavia immer", "Long-tailed Duck": "Clangula hyemalis", "Lapland Longspur": "Calcarius lapponicus", "Northern Gannet": "Morus bassanus", "Eastern Imperial Eagle": "Aquila heliaca", "Little Auk": "Alle alle", "Lesser Spotted Woodpecker": "Dendrocopos minor", "Iceland Gull": "Larus glaucoides", "Parasitic Jaeger": "Stercorarius parasiticus", "Bewick`s Swan": "Cygnus bewickii", "Little Bustard": "Tetrax tetrax", "Little Crake": "Porzana parva", "Baillon`s Crake": "Porzana pusilla", "Long-tailed Jaeger": "Stercorarius longicaudus", "King Eider": "Somateria spectabilis", "Greater Short-toed Lark": "Calandrella brachydactyla", "Houbara Bustard": "Chlamydotis undulata", "Curlew Sandpiper": "Calidris ferruginea", "Common Crossbill": "Loxia curvirostra", "European Shag": "Phalacrocorax aristotelis", "Horned Grebe": "Podiceps auritus", "Common Quail": "Coturnix coturnix", "Bearded Vulture": "Gypaetus barbatus", "Lanner Falcon": "Falco biarmicus", "Middle Spotted Woodpecker": "Dendrocopos medius", "Pomarine Jaeger": "Stercorarius pomarinus", "Red-breasted Merganser": "Mergus serrator", "Eurasian Black Vulture": "Aegypius monachus", "Eurasian Dotterel": "Charadrius morinellus", "Common Nightingale": "Luscinia megarhynchos", "Northern willow warbler": "Phylloscopus trochilus acredula", "Manx Shearwater": "Puffinus puffinus", "Northern Fulmar": "Fulmarus glacialis", "Eurasian Eagle Owl": "Bubo bubo", "Orphean Warbler": "Sylvia hortensis", "Melodious Warbler": "Hippolais polyglotta", "Pallas's Leaf Warbler": "Phylloscopus proregulus", "Atlantic Puffin": "Fratercula arctica", "Black-throated Loon": "Gavia arctica", "Bohemian Waxwing": "Bombycilla garrulus", "Marsh Sandpiper": "Tringa stagnatilis", "Great Snipe": "Gallinago media", "Squacco Heron": "Ardeola ralloides", "Long-eared Owl": "Asio otus", "Caspian Tern": "Hydroprogne caspia", "Red-breasted Goose": "Branta ruficollis", "Red-throated Loon": "Gavia stellata", "Common Rosefinch": "Carpodacus erythrinus", "Red-footed Falcon": "Falco vespertinus", "Ross's Goose": "Anser rossii", "Red Phalarope": "Phalaropus fulicarius", "Pied Wagtail": "Motacilla yarrellii", "Rose-coloured Starling": "Sturnus roseus", "Rough-legged Buzzard": "Buteo lagopus", "Saker Falcon": "Falco cherrug", "European Roller": "Coracias garrulus", "Short-toed Eagle": "Circaetus gallicus", "Peregrine Falcon": "Falco peregrinus", "Merlin": "Falco columbarius", "Snow Goose": "Anser caerulescens", "Snowy Owl": "Bubo scandiacus", "Snow Bunting": "Plectrophenax nivalis", "Common Grasshopper Warbler": "Locustella naevia", "Golden Eagle": "Aquila chrysaetos", "Black-winged Stilt": "Himantopus himantopus", "Steppe Eagle": "Aquila nipalensis", "Pallid Harrier": "Circus macrourus", "European Storm-petrel": "Hydrobates pelagicus", "Horned Lark": "Eremophila alpestris", "Eurasian Treecreeper": "Certhia familiaris", "Taiga Bean Goose": "Anser fabalis", "Temminck`s Stint": "Calidris temminckii", "Terek Sandpiper": "Xenus cinereus", "Tundra Bean Goose": "Anser serrirostris", "European Turtle Dove": "Streptopelia turtur", "Leach`s Storm-petrel": "Oceanodroma leucorhoa", "Eurasian Griffon Vulture": "Gyps fulvus", "Paddyfield Warbler": "Acrocephalus agricola", "Osprey": "Pandion haliaetus", "Firecrest": "Regulus ignicapilla", "Water Rail": "Rallus aquaticus", "European Honey Buzzard": "Pernis apivorus", "Eurasian Golden Oriole": "Oriolus oriolus", "Whooper Swan": "Cygnus cygnus", "Two-barred Crossbill": "Loxia leucoptera", "White-tailed Eagle": "Haliaeetus albicilla", "Atlantic Murre": "Uria aalge", "Garganey": "Anas querquedula", "Black Redstart": "Phoenicurus ochruros", "Common Scoter": "Melanitta nigra", "Rock Pipit": "Anthus petrosus", "Lesser Spotted Eagle": "Aquila pomarina", "Cattle Egret": "Bubulcus ibis", "White-winged Black Tern": "Chlidonias leucopterus", "Black Stork": "Ciconia nigra", "Mediterranean Gull": "Larus melanocephalus", "Black Kite": "Milvus migrans", "Yellow Wagtail": "Motacilla flavissima", "Red-necked Grebe": "Podiceps grisegena", "Gull-billed Tern": "Gelochelidon nilotica", "Pectoral Sandpiper": "Calidris melanotos", "Barred Warbler": "Sylvia nisoria", "Red-throated Pipit": "Anthus cervinus", "Grey Wagtail": "Motacilla cinerea", "Richard`s Pipit": "Anthus richardi", "Black Woodpecker": "Dryocopus martius", "Little Ringed Plover": "Charadrius dubius", "Whiskered Tern": "Chlidonias hybrida", "Lesser Redpoll": "Carduelis cabaret", "Pallas' Bunting": "Emberiza pallasi", "Ferruginous Duck": "Aythya nyroca", "Whistling Swan": "Cygnus columbianus", "Black Brant": "Branta nigricans", "Marbled Teal": "Marmaronetta angustirostris", "Canvasback": "Aythya valisineria", "Redhead": "Aythya americana", "Lesser Scaup": "Aythya affinis", "Steller`s Eider": "Polysticta stelleri", "Spectacled Eider": "Somateria fischeri", "Harlequin Duck": "Histronicus histrionicus", "Black Scoter": "Melanitta americana", "Surf Scoter": "Melanitta perspicillata", "Barrow`s Goldeneye": "Bucephala islandica", "Falcated Duck": "Anas falcata", "American Wigeon": "Anas americana", "Blue-winged Teal": "Anas discors", "American Black Duck": "Anas rubripes", "Baikal Teal": "Anas formosa", "Green-Winged Teal": "Anas carolinensis", "Hazel Grouse": "Bonasa bonasia", "Rock Partridge": "Alectoris graeca", "Red-legged Partridge": "Alectoris rufa", "Yellow-billed Loon": "Gavia adamsii", "Cory`s Shearwater": "Calonectris borealis", "Madeiran Storm-Petrel": "Oceanodroma castro", "Great White Pelican": "Pelecanus onocrotalus", "Dalmatian Pelican": "Pelecanus crispus", "American Bittern": "Botaurus lentiginosus", "Glossy Ibis": "Plegadis falcinellus", "Spanish Imperial Eagle": "Aquila adalberti", "Lesser Kestrel": "Falco naumanni", "Crab-Plover": "Dromas ardeola", "Cream-coloured Courser": "Cursorius cursor", "Collared Pratincole": "Glareola pratincola", "Black-winged Pratincole": "Glareola nordmanni", "Killdeer": "Charadrius vociferus", "Lesser Sand Plover": "Charadrius mongolus", "Greater Sand Plover": "Charadrius leschenaultii", "Caspian Plover": "Charadrius asiaticus", "American Golden Plover": "Pluvialis dominica", "Pacific Golden Plover": "Pluvialis fulva", "Sharp-tailed Sandpiper": "Calidris acuminata", "Broad-billed Sandpiper": "Limicola falcinellus", "Spoon-Billed Sandpiper": "Eurynorhynchus pygmaeus", "Short-Billed Dowitcher": "Limnodromus griseus", "Long-billed Dowitcher": "Limnodromus scolopaceus", "Hudsonian Godwit": "Limosa haemastica", "Little Curlew": "Numenius minutus", "Lesser Yellowlegs": "Tringa flavipes", "Wilson`s Phalarope": "Phalaropus tricolor", "Pallas`s Gull": "Larus ichthyaetus", "Laughing Gull": "Larus atricilla", "Franklin`s Gull": "Larus pipixcan", "Bonaparte`s Gull": "Larus philadelphia", "Ring-billed Gull": "Larus delawarensis", "American Herring Gull": "Larus smithsonianus", "Caspian Gull": "Larus cachinnans", "Ivory Gull": "Pagophila eburnea", "Royal Tern": "Sterna maxima", "Brünnich`s Murre": "Uria lomvia", "Crested Auklet": "Aethia cristatella", "Parakeet Auklet": "Cyclorrhynchus psittacula", "Tufted Puffin": "Lunda cirrhata", "Laughing Dove": "Streptopelia senegalensis", "Great Spotted Cuckoo": "Clamator glandarius", "Great Grey Owl": "Strix nebulosa", "Tengmalm`s Owl": "Aegolius funereus", "Red-Necked Nightjar": "Caprimulgus ruficollis", "Chimney Swift": "Chaetura pelagica", "Green Bea-Eater": "Merops orientalis", "Grey-headed Woodpecker": "Picus canus", "Lesser Short-Toed Lark": "Calandrella rufescens", "Eurasian Crag Martin": "Hirundo rupestris", "Red-rumped Swallow": "Cecropis daurica", "Blyth`s Pipit": "Anthus godlewskii", "Pechora Pipit": "Anthus gustavi", "Grey-headed Wagtail": "Motacilla thunbergi", "Yellow-Headed Wagtail": "Motacilla lutea", "White-throated Dipper": "Cinclus cinclus", "Rufous-Tailed Scrub Robin": "Cercotrichas galactotes", "Thrush Nightingale": "Luscinia luscinia", "White-throated Robin": "Irania gutturalis", "Caspian Stonechat": "Saxicola maura variegata", "Western Black-eared Wheatear": "Oenanthe hispanica", "Rufous-tailed Rock Thrush": "Monticola saxatilis", "Red-throated Thrush/Black-throated": "Turdus ruficollis", "American Robin": "Turdus migratorius", "Zitting Cisticola": "Cisticola juncidis", "Lanceolated Warbler": "Locustella lanceolata", "River Warbler": "Locustella fluviatilis", "Blyth`s Reed Warbler": "Acrocephalus dumetorum", "Caspian Reed Warbler": "Acrocephalus fuscus", "Aquatic Warbler": "Acrocephalus paludicola", "Booted Warbler": "Acrocephalus caligatus", "Marmora's Warbler": "Sylvia sarda", "Dartford Warbler": "Sylvia undata", "Subalpine Warbler": "Sylvia cantillans", "Ménétries's Warbler": "Sylvia mystacea", "Rüppel's Warbler": "Sylvia rueppelli", "Asian Desert Warbler": "Sylvia nana", "Western Orphean Warbler": "Sylvia hortensis hortensis", "Arctic Warbler": "Phylloscopus borealis", "Radde`s Warbler": "Phylloscopus schwarzi", "Western Bonelli`s Warbler": "Phylloscopus bonelli", "Red-breasted Flycatcher": "Ficedula parva", "Eurasian Penduline Tit": "Remiz pendulinus", "Daurian Shrike": "Lanius isabellinus", "Long-Tailed Shrike": "Lanius schach", "Lesser Grey Shrike": "Lanius minor", "Southern Grey Shrike": "Lanius meridionalis", "Masked Shrike": "Lanius nubicus", "Spotted Nutcracker": "Nucifraga caryocatactes", "Daurian Jackdaw": "Corvus dauuricus", "Purple-Backed Starling": "Sturnus sturninus", "Red-Fronted Serin": "Serinus pusillus", "Arctic Redpoll": "Carduelis hornemanni", "Scottish Crossbill": "Loxia scotica", "Parrot Crossbill": "Loxia pytyopsittacus", "Black-faced Bunting": "Emberiza spodocephala", "Pink-footed Goose": "Anser brachyrhynchus", "Black-winged Kite": "Elanus caeruleus", "European Bee-eater": "Merops apiaster", "Sabine`s Gull": "Larus sabini", "Sooty Shearwater": "Puffinus griseus", "Lesser Canada Goose": "Branta hutchinsii", "Ring-necked Duck": "Aythya collaris", "Greater Flamingo": "Phoenicopterus roseus", "Iberian Chiffchaff": "Phylloscopus ibericus", "Ashy-headed Wagtail": "Motacilla cinereocapilla", "Stilt Sandpiper": "Calidris himantopus", "Siberian Stonechat": "Saxicola maurus", "Greater Yellowlegs": "Tringa melanoleuca", "Forster`s Tern": "Sterna forsteri", "Dusky Warbler": "Phylloscopus fuscatus", "Cirl Bunting": "Emberiza cirlus", "Olive-backed Pipit": "Anthus hodgsoni", "Sociable Lapwing": "Vanellus gregarius", "Spotted Sandpiper": "Actitis macularius", "Baird`s Sandpiper": "Calidris bairdii", "Rustic Bunting": "Emberiza rustica", "Yellow-browed Bunting": "Emberiza chrysophrys", "Great Shearwater": "Puffinus gravis", "Bonelli`s Eagle": "Aquila fasciata", "Calandra Lark": "Melanocorypha calandra", "Sardinian Warbler": "Sylvia melanocephala", "Ross's Gull": "Larus roseus", "Yellow-Breasted Bunting": "Emberiza aureola", "Pine Bunting": "Emberiza leucocephalos", "Black Guillemot": "Cepphus grylle", "Pied-billed Grebe": "Podilymbus podiceps", "Soft-plumaged Petrel": "Pterodroma mollis", "Bulwer's Petrel": "Bulweria bulwerii", "White-Faced Storm-Petrel": "Pelagodroma marina", "Pallas’s Fish Eagle": "Haliaeetus leucoryphus", "Sandhill Crane": "Grus canadensis", "Macqueen’s Bustard": "Chlamydotis macqueenii", "White-tailed Lapwing": "Vanellus leucurus", "Great Knot": "Calidris tenuirostris", "Semipalmated Sandpiper": "Calidris pusilla", "Red-necked Stint": "Calidris ruficollis", "Slender-billed Curlew": "Numenius tenuirostris", "Bridled Tern": "Onychoprion anaethetus", "Pallas’s Sandgrouse": "Syrrhaptes paradoxus", "European Scops Owl": "Otus scops", "Northern Hawk Owl": "Surnia ulula", "White-Throated Needletail": "Hirundapus caudacutus", "Belted Kingfisher": "Ceryle alcyon", "Blue-cheeked Bee-eater": "Merops persicus", "Black-headed Wagtail": "Motacilla feldegg", "Northern Mockingbird": "Mimus polyglottos", "Alpine Accentor": "Prunella collaris", "Red-flanked Bluetail": "Tarsiger cyanurus", "Isabelline Wheatear": "Oenanthe isabellina", "Pied Wheatear": "Oenanthe pleschanka", "Eastern Black-eared Wheatear": "Oenanthe melanoleuca", "Desert Wheatear": "Oenanthe deserti", "White`s Thrush": "Zoothera aurea", "Siberian Thrush": "Zoothera sibirica", "Eyebrowed Thrush": "Turdus obscurus", "Dusky Thrush": "Turdus eunomus", "Black-throated Thrush": "Turdus atrogularis", "Pallas`s Grasshopper Warbler": "Locustella certhiola", "Spectacled Warbler": "Sylvia conspicillata", "Two-barred Warbler": "Phylloscopus plumbeitarsus", "Eastern Bonelli’s Warbler": "Phylloscopus orientalis", "Collared Flycatcher": "Ficedula albicollis", "Wallcreeper": "Tichodroma muraria", "Turkestan Shrike": "Lanius phoenicuroides", "Steppe Grey Shrike": "Lanius pallidirostris", "Spanish Sparrow": "Passer hispaniolensis", "Red-eyed Vireo": "Vireo olivaceus", "Myrtle Warbler": "Dendroica coronata", "White-crowned Sparrow": "Zonotrichia leucophrys", "White-throated Sparrow": "Zonotrichia albicollis", "Cretzschmar`s Bunting": "Emberiza caesia", "Chestnut Bunting": "Emberiza rutila", "Red-headed Bunting": "Emberiza bruniceps", "Black-headed Bunting": "Emberiza melanocephala", "Indigo Bunting": "Passerina cyanea", "Balearic Woodchat Shrike": "Lanius senator badius", "Demoiselle Crane": "Grus virgo", "Chough": "Pyrrhocorax pyrrhocorax", "Red-Billed Chough": "Pyrrhocorax graculus", "Elegant Tern": "Sterna elegans", "Chukar": "Alectoris chukar", "Yellow-Billed Cuckoo": "Coccyzus americanus", "American Sandwich Tern": "Sterna sandvicensis acuflavida", "Olive-Tree Warbler": "Hippolais olivetorum", "Eastern Olivaceous Warbler": "Acrocephalus pallidus", "Indian Cormorant": "Phalacrocorax fuscicollis", "Spur-Winged Lapwing": "Vanellus spinosus", "Yelkouan Shearwater": "Puffinus yelkouan", "Trumpeter Finch": "Bucanetes githagineus", "Red Grouse": "Lagopus scoticus", "Rock Ptarmigan": "Lagopus mutus", "Long-Tailed Cormorant": "Phalacrocorax africanus", "Double-crested Cormorant": "Phalacrocorax auritus", "Magnificent Frigatebird": "Fregata magnificens", "Naumann's Thrush": "Turdus naumanni", "Oriental Pratincole": "Glareola maldivarum", "Bufflehead": "Bucephala albeola", "Snowfinch": "Montifrigilla nivalis", "Ural owl": "Strix uralensis", "Spanish Wagtail": "Motacilla iberiae", "Song Sparrow": "Melospiza melodia", "Rock Bunting": "Emberiza cia", "Siberian Rubythroat": "Luscinia calliope", "Pallid Swift": "Apus pallidus", "Eurasian Pygmy Owl": "Glaucidium passerinum", "Madeira Little Shearwater": "Puffinus baroli", "House Finch": "Carpodacus mexicanus", "Green Heron": "Butorides virescens", "Solitary Sandpiper": "Tringa solitaria", "Heuglin's Gull": "Larus heuglini" }; function searchResponse( term ) { term = term.toLowerCase(); var result = []; for ( var key in database ) { if ( key.toLowerCase().indexOf( term ) !== -1 ) { result.push( { id: database[ key ], label: key, value: key } ); if ( result.length > 11 ) { break; } } } return result; } $.ajaxTransport( "json", function( options, originalOptions ) { if ( options.url.indexOf( "search.json" ) === -1 ) { return; } return { abort: function() {}, send: function( headers, completeCallback ) { console.log( "Mocked AJAX response for " + options.url ); var result = searchResponse( originalOptions.data.term || "" ); setTimeout( function() { completeCallback( 200, "OK", { text: JSON.stringify( result ) }, [] ); }, 2000 ); } }; } ); $.ajaxTransport( "script", function( options, originalOptions ) { if ( options.url.indexOf( "search.json" ) === -1 ) { return; } return { abort: function() {}, send: function( headers, completeCallback ) { console.log( "Mocked AJAX response for " + options.url ); var result = searchResponse( originalOptions.data.term || "" ); var script = options.jsonpCallback + "(" + JSON.stringify( result ) + ")"; setTimeout( function() { completeCallback( 200, "OK", { text: script }, [] ); }, 2000 ); } }; } ); } ); ================================================ FILE: demos/selectable/default.html ================================================ jQuery UI Selectable - Default functionality
    1. Item 1
    2. Item 2
    3. Item 3
    4. Item 4
    5. Item 5
    6. Item 6
    7. Item 7

    Enable a DOM element (or group of elements) to be selectable. Draw a box with your cursor to select items. Hold down the Ctrl key to make multiple non-adjacent selections.

    ================================================ FILE: demos/selectable/display-grid.html ================================================ jQuery UI Selectable - Display as grid
    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    6. 6
    7. 7
    8. 8
    9. 9
    10. 10
    11. 11
    12. 12

    To arrange selectable items as a grid, give them identical dimensions and float them using CSS.

    ================================================ FILE: demos/selectable/index.html ================================================ jQuery UI Selectable Demos ================================================ FILE: demos/selectable/serialize.html ================================================ jQuery UI Selectable - Serialize

    You've selected: none.

    1. Item 1
    2. Item 2
    3. Item 3
    4. Item 4
    5. Item 5
    6. Item 6

    Write a function that fires on the stop event to collect the index values of selected items. Present values as feedback, or pass as a data string.

    ================================================ FILE: demos/selectmenu/custom_render.html ================================================ jQuery UI Selectmenu - Custom Rendering

    Selectmenu with framework icons

    Selectmenu with custom icon images

    Selectmenu with custom avatar 16x16 images as CSS background

    The whole rendering process is extendable to make custom styling as easy as possible.

    ================================================ FILE: demos/selectmenu/default.html ================================================ jQuery UI Selectmenu - Default functionality

    The Selectmenu widgets provides a styleable select element replacement. It will act as a proxy back to the original select element, controlling its state for form submission or serialization

    The datasource is a native select element. Supports optgroups.

    ================================================ FILE: demos/selectmenu/index.html ================================================ jQuery UI Selectmenu Demos ================================================ FILE: demos/selectmenu/product-selection.html ================================================ jQuery UI Selectmenu - Product Selection

    This Selectmenu Widget demo changes color and radius of a CSS circle. This demo is using the provided callback events.

    ================================================ FILE: demos/slider/colorpicker.html ================================================ jQuery UI Slider - Colorpicker

    Simple Colorpicker

    Combine three sliders to create a simple RGB colorpicker.

    ================================================ FILE: demos/slider/custom-handle.html ================================================ jQuery UI Slider - Custom handle

    The basic slider is horizontal and has a single handle that can be moved with the mouse or by using the arrow keys.

    ================================================ FILE: demos/slider/default.html ================================================ jQuery UI Slider - Default functionality

    The basic slider is horizontal and has a single handle that can be moved with the mouse or by using the arrow keys.

    ================================================ FILE: demos/slider/hotelrooms.html ================================================ jQuery UI Slider - Slider bound to select

    How to bind a slider to an existing select element. The select stays visible to display the change. When the select is changed, the slider is updated, too.

    ================================================ FILE: demos/slider/index.html ================================================ jQuery UI Slider Demos ================================================ FILE: demos/slider/multiple-vertical.html ================================================ jQuery UI Slider - Multiple sliders

    Master volume

    Graphic EQ

    88 77 55 33 40 45 70

    Combine horizontal and vertical sliders, each with their own options, to create the UI for a music player.

    ================================================ FILE: demos/slider/range-vertical.html ================================================ jQuery UI Slider - Vertical range slider

    Change the orientation of the range slider to vertical. Assign a height value via .height() or by setting the height through CSS, and set the orientation option to "vertical."

    ================================================ FILE: demos/slider/range.html ================================================ jQuery UI Slider - Range slider

    Set the range option to true to capture a range of values with two drag handles. The space between the handles is filled with a different background color to indicate those values are selected.

    ================================================ FILE: demos/slider/rangemax.html ================================================ jQuery UI Slider - Range with fixed maximum

    Fix the maximum value of the range slider so that the user can only select a minimum. Set the range option to "max."

    ================================================ FILE: demos/slider/rangemin.html ================================================ jQuery UI Slider - Range with fixed minimum

    Fix the minimum value of the range slider so that the user can only select a maximum. Set the range option to "min."

    ================================================ FILE: demos/slider/slider-vertical.html ================================================ jQuery UI Slider - Vertical slider

    Change the orientation of the slider to vertical. Assign a height value via .height() or by setting the height through CSS, and set the orientation option to "vertical."

    ================================================ FILE: demos/slider/steps.html ================================================ jQuery UI Slider - Snap to increments

    Increment slider values with the step option set to an integer, commonly a dividend of the slider's maximum value. The default increment is 1.

    ================================================ FILE: demos/sortable/connect-lists.html ================================================ jQuery UI Sortable - Connect lists
    • Item 1
    • Item 2
    • Item 3
    • Item 4
    • Item 5
    • Item 1
    • Item 2
    • Item 3
    • Item 4
    • Item 5

    Sort items from one list into another and vice versa, by passing a selector into the connectWith option. The simplest way to do this is to group all related lists with a CSS class, and then pass that class into the sortable function (i.e., connectWith: '.myclass').

    ================================================ FILE: demos/sortable/default.html ================================================ jQuery UI Sortable - Default functionality
    • Item 1
    • Item 2
    • Item 3
    • Item 4
    • Item 5
    • Item 6
    • Item 7

    Enable a group of DOM elements to be sortable. Click on and drag an element to a new spot within the list, and the other items will adjust to fit. By default, sortable items share draggable properties.

    ================================================ FILE: demos/sortable/display-grid.html ================================================ jQuery UI Sortable - Display as grid
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    To arrange sortable items as a grid, give them identical dimensions and float them using CSS.

    ================================================ FILE: demos/sortable/empty-lists.html ================================================ jQuery UI Sortable - Handle empty lists
    • Can be dropped..
    • ..on an empty list
    • Item 3
    • Item 4
    • Item 5
    • Cannot be dropped..
    • ..on an empty list
    • Item 3
    • Item 4
    • Item 5

    Prevent all items in a list from being dropped into a separate, empty list using the dropOnEmpty option set to false. By default, sortable items can be dropped on empty lists.

    ================================================ FILE: demos/sortable/index.html ================================================ jQuery UI Sortable Demos ================================================ FILE: demos/sortable/items.html ================================================ jQuery UI Sortable - Include / exclude items

    Specify which items are sortable:

    • Item 1
    • (I'm not sortable or a drop target)
    • (I'm not sortable or a drop target)
    • Item 4

    Cancel sorting (but keep as drop targets):

    • Item 1
    • (I'm not sortable)
    • (I'm not sortable)
    • Item 4

    Specify which items are eligible to sort by passing a jQuery selector into the items option. Items excluded from this option are not sortable, nor are they valid targets for sortable items.

    To only prevent sorting on certain items, pass a jQuery selector into the cancel option. Cancelled items remain valid sort targets for others.

    ================================================ FILE: demos/sortable/placeholder.html ================================================ jQuery UI Sortable - Drop placeholder
    • Item 1
    • Item 2
    • Item 3
    • Item 4
    • Item 5
    • Item 6
    • Item 7

    When dragging a sortable item to a new location, other items will make room for the that item by shifting to allow white space between them. Pass a class into the placeholder option to style that space to be visible. Use the boolean forcePlaceholderSize option to set dimensions on the placeholder.

    ================================================ FILE: demos/sortable/portlets.html ================================================ jQuery UI Sortable - Portlets
    Feeds
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit
    News
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit
    Shopping
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit
    Links
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit
    Images
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit

    Enable portlets (styled divs) as sortables and use the connectWith option to allow sorting between columns.

    ================================================ FILE: demos/spinner/currency.html ================================================ jQuery UI Spinner - Currency

    Example of a donation form, with currency selection and amount spinner.

    ================================================ FILE: demos/spinner/decimal.html ================================================ jQuery UI Spinner - Decimal

    Example of a decimal spinner. Step is set to 0.01.
    The code handling the culture change reads the current spinner value, then changes the culture, then sets the value again, resulting in an updated formatting, based on the new culture.

    ================================================ FILE: demos/spinner/default.html ================================================ jQuery UI Spinner - Default functionality

    Default spinner.

    ================================================ FILE: demos/spinner/index.html ================================================ jQuery UI Spinner Demos ================================================ FILE: demos/spinner/latlong.html ================================================ jQuery UI Spinner - Map

    Google Maps integration, using spinners to change latitude and longitude.

    ================================================ FILE: demos/spinner/overflow.html ================================================ jQuery UI Spinner - Overflow

    Overflowing spinner restricted to a range of -10 to 10. For anything above 10, it'll overflow to -10, and the other way round.

    ================================================ FILE: demos/spinner/time.html ================================================ jQuery UI Spinner - Time

    A custom widget extending spinner. Use the Globalization plugin to parse and output a timestamp, with custom step and page options. Cursor up/down spins minutes, page up/down spins hours.

    ================================================ FILE: demos/tabs/ajax/content1.html ================================================

    This content was loaded via ajax.

    Proin elit arcu, rutrum commodo, vehicula tempus, commodo a, risus. Curabitur nec arcu. Donec sollicitudin mi sit amet mauris. Nam elementum quam ullamcorper ante. Etiam aliquet massa et lorem. Mauris dapibus lacus auctor risus. Aenean tempor ullamcorper leo. Vivamus sed magna quis ligula eleifend adipiscing. Duis orci. Aliquam sodales tortor vitae ipsum. Aliquam nulla. Duis aliquam molestie erat. Ut et mauris vel pede varius sollicitudin. Sed ut dolor nec orci tincidunt interdum. Phasellus ipsum. Nunc tristique tempus lectus.

    Mauris vitae ante. Curabitur augue. Nulla purus nibh, lobortis ut, feugiat at, aliquam id, purus. Sed venenatis, lorem venenatis volutpat commodo, purus quam lacinia justo, mattis interdum pede pede a odio. Fusce nibh. Morbi nisl mauris, dapibus in, tristique eget, accumsan et, pede. Donec mauris risus, pulvinar ut, faucibus eu, mollis in, nunc. In augue massa, commodo a, cursus vehicula, varius eu, dui. Suspendisse sodales suscipit lorem. Morbi malesuada, eros quis condimentum dignissim, lectus nibh tristique urna, non bibendum diam massa vel risus. Morbi suscipit. Proin egestas, eros at scelerisque scelerisque, dolor lacus fringilla lacus, ut ullamcorper mi magna at quam. Aliquam sed elit. Aliquam turpis purus, congue quis, iaculis id, ullamcorper sit amet, justo. Maecenas sed mauris. Proin magna justo, interdum in, tincidunt eu, viverra eu, turpis. Suspendisse mollis. In magna. Phasellus pellentesque, urna pellentesque convallis pellentesque, augue sem blandit pede, at rhoncus libero nisl a odio.

    Sed vitae nibh non magna semper tempor. Duis dolor. Nam congue laoreet arcu. Fusce lobortis enim quis ligula. Maecenas commodo odio id mi. Maecenas scelerisque tellus eu odio. Etiam dolor purus, lacinia a, imperdiet in, aliquam et, eros. In pellentesque. Nullam ac massa. Integer et turpis. Ut quam augue, congue non, imperdiet id, eleifend ac, nisi. Etiam ac arcu. Cras iaculis accumsan erat. Nullam vulputate sapien nec nisi pretium rhoncus. Aliquam a nibh. Vivamus est ante, fermentum a, tincidunt ut, imperdiet nec, velit. Aenean non tortor. Sed nec mauris eget tellus condimentum rutrum.

    ================================================ FILE: demos/tabs/ajax/content2.html ================================================

    This other content was loaded via ajax.

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean nec turpis justo, et facilisis ligula. In congue interdum odio, a scelerisque eros posuere ac. Aenean massa tellus, dictum sit amet laoreet ut, aliquam in orci. Duis eu aliquam ligula. Nullam vel placerat ligula. Fusce venenatis viverra dictum. Phasellus dui dolor, imperdiet in sodales at, mattis sed libero. Morbi ac ipsum ligula. Quisque suscipit dui vel diam pretium nec cursus lacus malesuada. Donec sollicitudin, eros eget dignissim mollis, risus leo feugiat tellus, vel posuere nisl ipsum eu erat. Quisque posuere lacinia imperdiet. Quisque nunc leo, elementum quis ultricies et, vehicula sit amet turpis. Nullam sed nunc nec nibh condimentum mattis. Quisque sed ligula sit amet nisi ultricies bibendum eget id nisi.

    Proin ut erat vel nunc tincidunt commodo. Curabitur feugiat, nisi et vehicula viverra, nisl orci eleifend arcu, sed blandit lectus nisl quis nisi. In hac habitasse platea dictumst. In hac habitasse platea dictumst. Aenean rutrum gravida velit ac imperdiet. Integer vitae arcu risus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Proin tincidunt orci at leo egestas porta. Vivamus ac augue et enim bibendum hendrerit ut id urna. Donec sollicitudin pulvinar turpis vitae scelerisque. Etiam tempor porttitor est sed blandit. Phasellus varius consequat leo eget tincidunt. Aliquam ac dui lectus. In et consectetur orci. Duis posuere nulla ac turpis faucibus vestibulum. Sed ut velit et dolor rhoncus dapibus. Sed sit amet pellentesque est.

    Nam in volutpat orci. Morbi sit amet orci in erat egestas dignissim. Etiam mi sapien, tempus sed iaculis a, adipiscing quis tellus. Suspendisse potenti. Nam malesuada tristique vestibulum. In tempor tellus dignissim neque consectetur eu vestibulum nisl pellentesque. Phasellus ultrices cursus velit, id aliquam nisl fringilla quis. Cras varius elit sed urna ultrices congue. Sed ornare odio sed velit pellentesque id varius nisl sodales. Sed auctor ligula egestas mi pharetra ut consectetur erat pharetra.

    ================================================ FILE: demos/tabs/ajax/content3-slow.html ================================================

    This content was loaded via ajax, though it took a second.

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean nec turpis justo, et facilisis ligula. In congue interdum odio, a scelerisque eros posuere ac. Aenean massa tellus, dictum sit amet laoreet ut, aliquam in orci. Duis eu aliquam ligula. Nullam vel placerat ligula. Fusce venenatis viverra dictum. Phasellus dui dolor, imperdiet in sodales at, mattis sed libero. Morbi ac ipsum ligula. Quisque suscipit dui vel diam pretium nec cursus lacus malesuada. Donec sollicitudin, eros eget dignissim mollis, risus leo feugiat tellus, vel posuere nisl ipsum eu erat. Quisque posuere lacinia imperdiet. Quisque nunc leo, elementum quis ultricies et, vehicula sit amet turpis. Nullam sed nunc nec nibh condimentum mattis. Quisque sed ligula sit amet nisi ultricies bibendum eget id nisi.

    Proin ut erat vel nunc tincidunt commodo. Curabitur feugiat, nisi et vehicula viverra, nisl orci eleifend arcu, sed blandit lectus nisl quis nisi. In hac habitasse platea dictumst. In hac habitasse platea dictumst. Aenean rutrum gravida velit ac imperdiet. Integer vitae arcu risus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Proin tincidunt orci at leo egestas porta. Vivamus ac augue et enim bibendum hendrerit ut id urna. Donec sollicitudin pulvinar turpis vitae scelerisque. Etiam tempor porttitor est sed blandit. Phasellus varius consequat leo eget tincidunt. Aliquam ac dui lectus. In et consectetur orci. Duis posuere nulla ac turpis faucibus vestibulum. Sed ut velit et dolor rhoncus dapibus. Sed sit amet pellentesque est.

    Nam in volutpat orci. Morbi sit amet orci in erat egestas dignissim. Etiam mi sapien, tempus sed iaculis a, adipiscing quis tellus. Suspendisse potenti. Nam malesuada tristique vestibulum. In tempor tellus dignissim neque consectetur eu vestibulum nisl pellentesque. Phasellus ultrices cursus velit, id aliquam nisl fringilla quis. Cras varius elit sed urna ultrices congue. Sed ornare odio sed velit pellentesque id varius nisl sodales. Sed auctor ligula egestas mi pharetra ut consectetur erat pharetra.

    ================================================ FILE: demos/tabs/ajax.html ================================================ jQuery UI Tabs - Content via Ajax

    Proin elit arcu, rutrum commodo, vehicula tempus, commodo a, risus. Curabitur nec arcu. Donec sollicitudin mi sit amet mauris. Nam elementum quam ullamcorper ante. Etiam aliquet massa et lorem. Mauris dapibus lacus auctor risus. Aenean tempor ullamcorper leo. Vivamus sed magna quis ligula eleifend adipiscing. Duis orci. Aliquam sodales tortor vitae ipsum. Aliquam nulla. Duis aliquam molestie erat. Ut et mauris vel pede varius sollicitudin. Sed ut dolor nec orci tincidunt interdum. Phasellus ipsum. Nunc tristique tempus lectus.

    Fetch external content via Ajax for the tabs by setting an href value in the tab links.

    Tabs 3 and 4 demonstrate handling of pages that are slow-loading or have server-side HTTP status errors.

    ================================================ FILE: demos/tabs/collapsible.html ================================================ jQuery UI Tabs - Collapse content

    Click this tab again to close the content pane.

    Proin elit arcu, rutrum commodo, vehicula tempus, commodo a, risus. Curabitur nec arcu. Donec sollicitudin mi sit amet mauris. Nam elementum quam ullamcorper ante. Etiam aliquet massa et lorem. Mauris dapibus lacus auctor risus. Aenean tempor ullamcorper leo. Vivamus sed magna quis ligula eleifend adipiscing. Duis orci. Aliquam sodales tortor vitae ipsum. Aliquam nulla. Duis aliquam molestie erat. Ut et mauris vel pede varius sollicitudin. Sed ut dolor nec orci tincidunt interdum. Phasellus ipsum. Nunc tristique tempus lectus.

    Click this tab again to close the content pane.

    Morbi tincidunt, dui sit amet facilisis feugiat, odio metus gravida ante, ut pharetra massa metus id nunc. Duis scelerisque molestie turpis. Sed fringilla, massa eget luctus malesuada, metus eros molestie lectus, ut tempus eros massa ut dolor. Aenean aliquet fringilla sem. Suspendisse sed ligula in ligula suscipit aliquam. Praesent in eros vestibulum mi adipiscing adipiscing. Morbi facilisis. Curabitur ornare consequat nunc. Aenean vel metus. Ut posuere viverra nulla. Aliquam erat volutpat. Pellentesque convallis. Maecenas feugiat, tellus pellentesque pretium posuere, felis lorem euismod felis, eu ornare leo nisi vel felis. Mauris consectetur tortor et purus.

    Click this tab again to close the content pane.

    Duis cursus. Maecenas ligula eros, blandit nec, pharetra at, semper at, magna. Nullam ac lacus. Nulla facilisi. Praesent viverra justo vitae neque. Praesent blandit adipiscing velit. Suspendisse potenti. Donec mattis, pede vel pharetra blandit, magna ligula faucibus eros, id euismod lacus dolor eget odio. Nam scelerisque. Donec non libero sed nulla mattis commodo. Ut sagittis. Donec nisi lectus, feugiat porttitor, tempor ac, tempor vitae, pede. Aenean vehicula velit eu tellus interdum rutrum. Maecenas commodo. Pellentesque nec elit. Fusce in lacus. Vivamus a libero vitae lectus hendrerit hendrerit.

    Click the selected tab to toggle its content closed/open. To enable this functionality, set the collapsible option to true.

    collapsible: true
    
    ================================================ FILE: demos/tabs/default.html ================================================ jQuery UI Tabs - Default functionality

    Proin elit arcu, rutrum commodo, vehicula tempus, commodo a, risus. Curabitur nec arcu. Donec sollicitudin mi sit amet mauris. Nam elementum quam ullamcorper ante. Etiam aliquet massa et lorem. Mauris dapibus lacus auctor risus. Aenean tempor ullamcorper leo. Vivamus sed magna quis ligula eleifend adipiscing. Duis orci. Aliquam sodales tortor vitae ipsum. Aliquam nulla. Duis aliquam molestie erat. Ut et mauris vel pede varius sollicitudin. Sed ut dolor nec orci tincidunt interdum. Phasellus ipsum. Nunc tristique tempus lectus.

    Morbi tincidunt, dui sit amet facilisis feugiat, odio metus gravida ante, ut pharetra massa metus id nunc. Duis scelerisque molestie turpis. Sed fringilla, massa eget luctus malesuada, metus eros molestie lectus, ut tempus eros massa ut dolor. Aenean aliquet fringilla sem. Suspendisse sed ligula in ligula suscipit aliquam. Praesent in eros vestibulum mi adipiscing adipiscing. Morbi facilisis. Curabitur ornare consequat nunc. Aenean vel metus. Ut posuere viverra nulla. Aliquam erat volutpat. Pellentesque convallis. Maecenas feugiat, tellus pellentesque pretium posuere, felis lorem euismod felis, eu ornare leo nisi vel felis. Mauris consectetur tortor et purus.

    Mauris eleifend est et turpis. Duis id erat. Suspendisse potenti. Aliquam vulputate, pede vel vehicula accumsan, mi neque rutrum erat, eu congue orci lorem eget lorem. Vestibulum non ante. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce sodales. Quisque eu urna vel enim commodo pellentesque. Praesent eu risus hendrerit ligula tempus pretium. Curabitur lorem enim, pretium nec, feugiat nec, luctus a, lacus.

    Duis cursus. Maecenas ligula eros, blandit nec, pharetra at, semper at, magna. Nullam ac lacus. Nulla facilisi. Praesent viverra justo vitae neque. Praesent blandit adipiscing velit. Suspendisse potenti. Donec mattis, pede vel pharetra blandit, magna ligula faucibus eros, id euismod lacus dolor eget odio. Nam scelerisque. Donec non libero sed nulla mattis commodo. Ut sagittis. Donec nisi lectus, feugiat porttitor, tempor ac, tempor vitae, pede. Aenean vehicula velit eu tellus interdum rutrum. Maecenas commodo. Pellentesque nec elit. Fusce in lacus. Vivamus a libero vitae lectus hendrerit hendrerit.

    Click tabs to swap between content that is broken into logical sections.

    ================================================ FILE: demos/tabs/index.html ================================================ jQuery UI Tabs Demos ================================================ FILE: demos/tabs/manipulation.html ================================================ jQuery UI Tabs - Simple manipulation

    Proin elit arcu, rutrum commodo, vehicula tempus, commodo a, risus. Curabitur nec arcu. Donec sollicitudin mi sit amet mauris. Nam elementum quam ullamcorper ante. Etiam aliquet massa et lorem. Mauris dapibus lacus auctor risus. Aenean tempor ullamcorper leo. Vivamus sed magna quis ligula eleifend adipiscing. Duis orci. Aliquam sodales tortor vitae ipsum. Aliquam nulla. Duis aliquam molestie erat. Ut et mauris vel pede varius sollicitudin. Sed ut dolor nec orci tincidunt interdum. Phasellus ipsum. Nunc tristique tempus lectus.

    Simple tabs adding and removing.

    ================================================ FILE: demos/tabs/mouseover.html ================================================ jQuery UI Tabs - Open on mouseover

    Proin elit arcu, rutrum commodo, vehicula tempus, commodo a, risus. Curabitur nec arcu. Donec sollicitudin mi sit amet mauris. Nam elementum quam ullamcorper ante. Etiam aliquet massa et lorem. Mauris dapibus lacus auctor risus. Aenean tempor ullamcorper leo. Vivamus sed magna quis ligula eleifend adipiscing. Duis orci. Aliquam sodales tortor vitae ipsum. Aliquam nulla. Duis aliquam molestie erat. Ut et mauris vel pede varius sollicitudin. Sed ut dolor nec orci tincidunt interdum. Phasellus ipsum. Nunc tristique tempus lectus.

    Morbi tincidunt, dui sit amet facilisis feugiat, odio metus gravida ante, ut pharetra massa metus id nunc. Duis scelerisque molestie turpis. Sed fringilla, massa eget luctus malesuada, metus eros molestie lectus, ut tempus eros massa ut dolor. Aenean aliquet fringilla sem. Suspendisse sed ligula in ligula suscipit aliquam. Praesent in eros vestibulum mi adipiscing adipiscing. Morbi facilisis. Curabitur ornare consequat nunc. Aenean vel metus. Ut posuere viverra nulla. Aliquam erat volutpat. Pellentesque convallis. Maecenas feugiat, tellus pellentesque pretium posuere, felis lorem euismod felis, eu ornare leo nisi vel felis. Mauris consectetur tortor et purus.

    Mauris eleifend est et turpis. Duis id erat. Suspendisse potenti. Aliquam vulputate, pede vel vehicula accumsan, mi neque rutrum erat, eu congue orci lorem eget lorem. Vestibulum non ante. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce sodales. Quisque eu urna vel enim commodo pellentesque. Praesent eu risus hendrerit ligula tempus pretium. Curabitur lorem enim, pretium nec, feugiat nec, luctus a, lacus.

    Duis cursus. Maecenas ligula eros, blandit nec, pharetra at, semper at, magna. Nullam ac lacus. Nulla facilisi. Praesent viverra justo vitae neque. Praesent blandit adipiscing velit. Suspendisse potenti. Donec mattis, pede vel pharetra blandit, magna ligula faucibus eros, id euismod lacus dolor eget odio. Nam scelerisque. Donec non libero sed nulla mattis commodo. Ut sagittis. Donec nisi lectus, feugiat porttitor, tempor ac, tempor vitae, pede. Aenean vehicula velit eu tellus interdum rutrum. Maecenas commodo. Pellentesque nec elit. Fusce in lacus. Vivamus a libero vitae lectus hendrerit hendrerit.

    Toggle sections open/closed on mouseover with the event option. The default value for event is "click."

    ================================================ FILE: demos/tabs/sortable.html ================================================ jQuery UI Tabs - Sortable

    Proin elit arcu, rutrum commodo, vehicula tempus, commodo a, risus. Curabitur nec arcu. Donec sollicitudin mi sit amet mauris. Nam elementum quam ullamcorper ante. Etiam aliquet massa et lorem. Mauris dapibus lacus auctor risus. Aenean tempor ullamcorper leo. Vivamus sed magna quis ligula eleifend adipiscing. Duis orci. Aliquam sodales tortor vitae ipsum. Aliquam nulla. Duis aliquam molestie erat. Ut et mauris vel pede varius sollicitudin. Sed ut dolor nec orci tincidunt interdum. Phasellus ipsum. Nunc tristique tempus lectus.

    Morbi tincidunt, dui sit amet facilisis feugiat, odio metus gravida ante, ut pharetra massa metus id nunc. Duis scelerisque molestie turpis. Sed fringilla, massa eget luctus malesuada, metus eros molestie lectus, ut tempus eros massa ut dolor. Aenean aliquet fringilla sem. Suspendisse sed ligula in ligula suscipit aliquam. Praesent in eros vestibulum mi adipiscing adipiscing. Morbi facilisis. Curabitur ornare consequat nunc. Aenean vel metus. Ut posuere viverra nulla. Aliquam erat volutpat. Pellentesque convallis. Maecenas feugiat, tellus pellentesque pretium posuere, felis lorem euismod felis, eu ornare leo nisi vel felis. Mauris consectetur tortor et purus.

    Mauris eleifend est et turpis. Duis id erat. Suspendisse potenti. Aliquam vulputate, pede vel vehicula accumsan, mi neque rutrum erat, eu congue orci lorem eget lorem. Vestibulum non ante. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce sodales. Quisque eu urna vel enim commodo pellentesque. Praesent eu risus hendrerit ligula tempus pretium. Curabitur lorem enim, pretium nec, feugiat nec, luctus a, lacus.

    Duis cursus. Maecenas ligula eros, blandit nec, pharetra at, semper at, magna. Nullam ac lacus. Nulla facilisi. Praesent viverra justo vitae neque. Praesent blandit adipiscing velit. Suspendisse potenti. Donec mattis, pede vel pharetra blandit, magna ligula faucibus eros, id euismod lacus dolor eget odio. Nam scelerisque. Donec non libero sed nulla mattis commodo. Ut sagittis. Donec nisi lectus, feugiat porttitor, tempor ac, tempor vitae, pede. Aenean vehicula velit eu tellus interdum rutrum. Maecenas commodo. Pellentesque nec elit. Fusce in lacus. Vivamus a libero vitae lectus hendrerit hendrerit.

    Drag the tabs above to re-order them.

    Making tabs sortable is as simple as calling .sortable() on the .ui-tabs-nav element.

    ================================================ FILE: demos/tabs/vertical.html ================================================ jQuery UI Tabs - Vertical Tabs functionality

    Content heading 1

    Proin elit arcu, rutrum commodo, vehicula tempus, commodo a, risus. Curabitur nec arcu. Donec sollicitudin mi sit amet mauris. Nam elementum quam ullamcorper ante. Etiam aliquet massa et lorem. Mauris dapibus lacus auctor risus. Aenean tempor ullamcorper leo. Vivamus sed magna quis ligula eleifend adipiscing. Duis orci. Aliquam sodales tortor vitae ipsum. Aliquam nulla. Duis aliquam molestie erat. Ut et mauris vel pede varius sollicitudin. Sed ut dolor nec orci tincidunt interdum. Phasellus ipsum. Nunc tristique tempus lectus.

    Content heading 2

    Morbi tincidunt, dui sit amet facilisis feugiat, odio metus gravida ante, ut pharetra massa metus id nunc. Duis scelerisque molestie turpis. Sed fringilla, massa eget luctus malesuada, metus eros molestie lectus, ut tempus eros massa ut dolor. Aenean aliquet fringilla sem. Suspendisse sed ligula in ligula suscipit aliquam. Praesent in eros vestibulum mi adipiscing adipiscing. Morbi facilisis. Curabitur ornare consequat nunc. Aenean vel metus. Ut posuere viverra nulla. Aliquam erat volutpat. Pellentesque convallis. Maecenas feugiat, tellus pellentesque pretium posuere, felis lorem euismod felis, eu ornare leo nisi vel felis. Mauris consectetur tortor et purus.

    Content heading 3

    Mauris eleifend est et turpis. Duis id erat. Suspendisse potenti. Aliquam vulputate, pede vel vehicula accumsan, mi neque rutrum erat, eu congue orci lorem eget lorem. Vestibulum non ante. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce sodales. Quisque eu urna vel enim commodo pellentesque. Praesent eu risus hendrerit ligula tempus pretium. Curabitur lorem enim, pretium nec, feugiat nec, luctus a, lacus.

    Duis cursus. Maecenas ligula eros, blandit nec, pharetra at, semper at, magna. Nullam ac lacus. Nulla facilisi. Praesent viverra justo vitae neque. Praesent blandit adipiscing velit. Suspendisse potenti. Donec mattis, pede vel pharetra blandit, magna ligula faucibus eros, id euismod lacus dolor eget odio. Nam scelerisque. Donec non libero sed nulla mattis commodo. Ut sagittis. Donec nisi lectus, feugiat porttitor, tempor ac, tempor vitae, pede. Aenean vehicula velit eu tellus interdum rutrum. Maecenas commodo. Pellentesque nec elit. Fusce in lacus. Vivamus a libero vitae lectus hendrerit hendrerit.

    Click tabs to swap between content that is broken into logical sections.

    ================================================ FILE: demos/tooltip/ajax/content1.html ================================================

    This content was loaded via ajax.

    ================================================ FILE: demos/tooltip/ajax/content2.html ================================================

    This other content was loaded via ajax.

    ================================================ FILE: demos/tooltip/custom-animation.html ================================================ jQuery UI Tooltip - Custom animation demo

    There are various ways to customize the animation of a tooltip.

    You can use the show and hide options.

    You can also use the open event.

    This demo shows how to customize animations using the show and hide options, as well as the open event.

    ================================================ FILE: demos/tooltip/custom-content.html ================================================ jQuery UI Tooltip - Custom content

    St. Stephen's Cathedral

    Vienna, Austria

    St. Stephen's Cathedral

    Tower Bridge

    London, England

    Tower Bridge

    All images are part of Wikimedia Commons and are licensed under CC BY-SA 3.0 by the copyright holder.

    Shows how to combine different event delegated tooltips into a single instance, by customizing the items and content options.

    For interactive content, such as scrollable maps, use a dialog.

    ================================================ FILE: demos/tooltip/custom-style.html ================================================ jQuery UI Tooltip - Custom Styling

    Tooltips can be attached to any element. When you hover the element with your mouse, the title attribute is displayed in a little box next to the element, just like a native tooltip.

    But as it's not a native tooltip, it can be styled. Any themes built with ThemeRoller will also style tooltips accordingly.

    Tooltips are also useful for form elements, to show some additional information in the context of each field.

    Hover the field to see the tooltip.

    Hover the links above or use the tab key to cycle the focus on each element.

    ================================================ FILE: demos/tooltip/default.html ================================================ jQuery UI Tooltip - Default functionality

    Tooltips can be attached to any element. When you hover the element with your mouse, the title attribute is displayed in a little box next to the element, just like a native tooltip.

    But as it's not a native tooltip, it can be styled. Any themes built with ThemeRoller will also style tooltips accordingly.

    Tooltips are also useful for form elements, to show some additional information in the context of each field.

    Hover the field to see the tooltip.

    Hover the links above or use the tab key to cycle the focus on each element.

    ================================================ FILE: demos/tooltip/forms.html ================================================ jQuery UI Tooltip - Forms

    Use the button below to display the help texts, or just focus or mouseover the indivdual inputs.

    A fixed width is defined in CSS to make the tooltips look consistent when displayed all at once.

    ================================================ FILE: demos/tooltip/index.html ================================================ jQuery UI Tooltip Demos ================================================ FILE: demos/tooltip/tracking.html ================================================ jQuery UI Tooltip - Track the mouse

    Tooltips can be attached to any element. When you hover the element with your mouse, the title attribute is displayed in a little box next to the element, just like a native tooltip.

    But as it's not a native tooltip, it can be styled. Any themes built with ThemeRoller will also style tooltips accordingly.

    Tooltips are also useful for form elements, to show some additional information in the context of each field.

    Hover the field to see the tooltip.

    Here the tooltips are positioned relative to the mouse, and follow the mouse while it moves above the element, using the track option.

    ================================================ FILE: demos/tooltip/video-player.html ================================================ jQuery UI Tooltip - Video Player demo
    Here Be Video (HTML5?)
    • Favorites
    • Funnees
    • New playlist...

    A fake video player with like/share/stats button, each with a custom-styled tooltip.

    ================================================ FILE: demos/widget/default.html ================================================ jQuery UI Widget - Default functionality
    color me
    color me
    color me

    This demo shows a simple custom widget built using the widget factory (jquery.ui.widget.js).

    The three boxes are initialized in different ways. Clicking them changes their background color. View source to see how it works, its heavily commented

    To learn more about the widget factory, visit learn.jquery.com.

    ================================================ FILE: demos/widget/index.html ================================================ jQuery UI Widget Demo ================================================ FILE: eslint.config.mjs ================================================ import jqueryConfig from "eslint-config-jquery"; import globals from "globals"; export default [ { ignores: [ "dist/**/*", "!dist/jquery-ui.js", "!dist/jquery-ui.min.js", "external/**/*", "tests/lib/vendor/**/*", "ui/vendor/**/*" ] }, { ignores: [ "dist/**/*" ], rules: { ...jqueryConfig.rules, "no-unused-vars": [ "error", { argsIgnorePattern: "^_", caughtErrorsIgnorePattern: "^_" } ] } }, { files: [ "Gruntfile.js" ], languageOptions: { ecmaVersion: "latest", sourceType: "commonjs", globals: { ...globals.node } }, rules: { strict: [ "error", "global" ] } }, { files: [ "eslint.config.mjs" ], languageOptions: { ecmaVersion: "latest", sourceType: "module", globals: { ...globals.node } }, rules: { strict: [ "error", "global" ] } }, // Source, demos { files: [ "ui/**/*.js", "demos/**/*.js" ], languageOptions: { ecmaVersion: 5, sourceType: "script", globals: { ...globals.browser, ...globals.jquery, define: false, Globalize: false } }, rules: { strict: [ "error", "function" ], // The following rule is relaxed due to too many violations: "no-unused-vars": [ "error", { args: "after-used", argsIgnorePattern: "^_", caughtErrorsIgnorePattern: "^_" } ], // Too many violations: camelcase: "off", "no-nested-ternary": "off" } }, { files: [ "ui/i18n/**/*.js" ], rules: { // We want to keep all the strings in separate single lines "max-len": "off" } }, // Dist files // For dist files, we don't include any jQuery rules on purpose. // We just want to make sure the files are correct ES5. { files: [ "dist/jquery-ui.js", "dist/jquery-ui.min.js" ], languageOptions: { ecmaVersion: 5, sourceType: "script" }, linterOptions: { reportUnusedDisableDirectives: "off" } }, // Build { files: [ "build/**/*.js" ], languageOptions: { ecmaVersion: "latest", sourceType: "commonjs", globals: { ...globals.node } }, rules: { "no-implicit-globals": "error", strict: [ "error", "global" ] } }, // Demos { files: [ "demos/**/*.js" ], languageOptions: { globals: { require: true } } }, // Tests { files: [ "tests/**/*.js" ], languageOptions: { ecmaVersion: 5, sourceType: "script", globals: { ...globals.browser, ...globals.jquery, define: false, Globalize: false, QUnit: false, require: true, requirejs: true } }, "rules": { // Too many violations: "max-len": "off", "no-unused-vars": "off", strict: "off" // ideally, `[ "error", "function" ]` } } ]; ================================================ FILE: external/globalize/LICENSE ================================================ Copyright Software Freedom Conservancy, Inc. http://jquery.org/license 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. ================================================ FILE: external/globalize/globalize.culture.de-DE.js ================================================ /* * Globalize Culture de-DE * * http://github.com/jquery/globalize * * Copyright Software Freedom Conservancy, Inc. * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * This file was generated by the Globalize Culture Generator * Translation: bugs found in this file need to be fixed in the generator */ (function( window, undefined ) { var Globalize; if ( typeof require !== "undefined" && typeof exports !== "undefined" && typeof module !== "undefined" ) { // Assume CommonJS Globalize = require( "globalize" ); } else { // Global variable Globalize = window.Globalize; } Globalize.addCultureInfo( "de-DE", "default", { name: "de-DE", englishName: "German (Germany)", nativeName: "Deutsch (Deutschland)", language: "de", numberFormat: { ",": ".", ".": ",", NaN: "n. def.", negativeInfinity: "-unendlich", positiveInfinity: "+unendlich", percent: { pattern: ["-n%","n%"], ",": ".", ".": "," }, currency: { pattern: ["-n $","n $"], ",": ".", ".": ",", symbol: "€" } }, calendars: { standard: { "/": ".", firstDay: 1, days: { names: ["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"], namesAbbr: ["So","Mo","Di","Mi","Do","Fr","Sa"], namesShort: ["So","Mo","Di","Mi","Do","Fr","Sa"] }, months: { names: ["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember",""], namesAbbr: ["Jan","Feb","Mrz","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez",""] }, AM: null, PM: null, eras: [{"name":"n. Chr.","start":null,"offset":0}], patterns: { d: "dd.MM.yyyy", D: "dddd, d. MMMM yyyy", t: "HH:mm", T: "HH:mm:ss", f: "dddd, d. MMMM yyyy HH:mm", F: "dddd, d. MMMM yyyy HH:mm:ss", M: "dd MMMM", Y: "MMMM yyyy" } } } }); }( this )); ================================================ FILE: external/globalize/globalize.culture.ja-JP.js ================================================ /* * Globalize Culture ja-JP * * http://github.com/jquery/globalize * * Copyright Software Freedom Conservancy, Inc. * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * This file was generated by the Globalize Culture Generator * Translation: bugs found in this file need to be fixed in the generator */ (function( window, undefined ) { var Globalize; if ( typeof require !== "undefined" && typeof exports !== "undefined" && typeof module !== "undefined" ) { // Assume CommonJS Globalize = require( "globalize" ); } else { // Global variable Globalize = window.Globalize; } Globalize.addCultureInfo( "ja-JP", "default", { name: "ja-JP", englishName: "Japanese (Japan)", nativeName: "日本語 (日本)", language: "ja", numberFormat: { NaN: "NaN (非数値)", negativeInfinity: "-∞", positiveInfinity: "+∞", percent: { pattern: ["-n%","n%"] }, currency: { pattern: ["-$n","$n"], decimals: 0, symbol: "¥" } }, calendars: { standard: { days: { names: ["日曜日","月曜日","火曜日","水曜日","木曜日","金曜日","土曜日"], namesAbbr: ["日","月","火","水","木","金","土"], namesShort: ["日","月","火","水","木","金","土"] }, months: { names: ["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月",""], namesAbbr: ["1","2","3","4","5","6","7","8","9","10","11","12",""] }, AM: ["午前","午前","午前"], PM: ["午後","午後","午後"], eras: [{"name":"西暦","start":null,"offset":0}], patterns: { d: "yyyy/MM/dd", D: "yyyy'年'M'月'd'日'", t: "H:mm", T: "H:mm:ss", f: "yyyy'年'M'月'd'日' H:mm", F: "yyyy'年'M'月'd'日' H:mm:ss", M: "M'月'd'日'", Y: "yyyy'年'M'月'" } }, Japanese: { name: "Japanese", days: { names: ["日曜日","月曜日","火曜日","水曜日","木曜日","金曜日","土曜日"], namesAbbr: ["日","月","火","水","木","金","土"], namesShort: ["日","月","火","水","木","金","土"] }, months: { names: ["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月",""], namesAbbr: ["1","2","3","4","5","6","7","8","9","10","11","12",""] }, AM: ["午前","午前","午前"], PM: ["午後","午後","午後"], eras: [{"name":"平成","start":null,"offset":1867},{"name":"昭和","start":-1812153600000,"offset":1911},{"name":"大正","start":-1357603200000,"offset":1925},{"name":"明治","start":60022080000,"offset":1988}], twoDigitYearMax: 99, patterns: { d: "gg y/M/d", D: "gg y'年'M'月'd'日'", t: "H:mm", T: "H:mm:ss", f: "gg y'年'M'月'd'日' H:mm", F: "gg y'年'M'月'd'日' H:mm:ss", M: "M'月'd'日'", Y: "gg y'年'M'月'" } } } }); }( this )); ================================================ FILE: external/globalize/globalize.js ================================================ /*! * Globalize * * http://github.com/jquery/globalize * * Copyright Software Freedom Conservancy, Inc. * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license */ (function( window, undefined ) { var Globalize, // private variables regexHex, regexInfinity, regexParseFloat, regexTrim, // private JavaScript utility functions arrayIndexOf, endsWith, extend, isArray, isFunction, isObject, startsWith, trim, truncate, zeroPad, // private Globalization utility functions appendPreOrPostMatch, expandFormat, formatDate, formatNumber, getTokenRegExp, getEra, getEraYear, parseExact, parseNegativePattern; // Global variable (Globalize) or CommonJS module (globalize) Globalize = function( cultureSelector ) { return new Globalize.prototype.init( cultureSelector ); }; if ( typeof require !== "undefined" && typeof exports !== "undefined" && typeof module !== "undefined" ) { // Assume CommonJS module.exports = Globalize; } else { // Export as global variable window.Globalize = Globalize; } Globalize.cultures = {}; Globalize.prototype = { constructor: Globalize, init: function( cultureSelector ) { this.cultures = Globalize.cultures; this.cultureSelector = cultureSelector; return this; } }; Globalize.prototype.init.prototype = Globalize.prototype; // 1. When defining a culture, all fields are required except the ones stated as optional. // 2. Each culture should have a ".calendars" object with at least one calendar named "standard" // which serves as the default calendar in use by that culture. // 3. Each culture should have a ".calendar" object which is the current calendar being used, // it may be dynamically changed at any time to one of the calendars in ".calendars". Globalize.cultures[ "default" ] = { // A unique name for the culture in the form - name: "en", // the name of the culture in the english language englishName: "English", // the name of the culture in its own language nativeName: "English", // whether the culture uses right-to-left text isRTL: false, // "language" is used for so-called "specific" cultures. // For example, the culture "es-CL" means "Spanish, in Chili". // It represents the Spanish-speaking culture as it is in Chili, // which might have different formatting rules or even translations // than Spanish in Spain. A "neutral" culture is one that is not // specific to a region. For example, the culture "es" is the generic // Spanish culture, which may be a more generalized version of the language // that may or may not be what a specific culture expects. // For a specific culture like "es-CL", the "language" field refers to the // neutral, generic culture information for the language it is using. // This is not always a simple matter of the string before the dash. // For example, the "zh-Hans" culture is netural (Simplified Chinese). // And the "zh-SG" culture is Simplified Chinese in Singapore, whose lanugage // field is "zh-CHS", not "zh". // This field should be used to navigate from a specific culture to it's // more general, neutral culture. If a culture is already as general as it // can get, the language may refer to itself. language: "en", // numberFormat defines general number formatting rules, like the digits in // each grouping, the group separator, and how negative numbers are displayed. numberFormat: { // [negativePattern] // Note, numberFormat.pattern has no "positivePattern" unlike percent and currency, // but is still defined as an array for consistency with them. // negativePattern: one of "(n)|-n|- n|n-|n -" pattern: [ "-n" ], // number of decimal places normally shown decimals: 2, // string that separates number groups, as in 1,000,000 ",": ",", // string that separates a number from the fractional portion, as in 1.99 ".": ".", // array of numbers indicating the size of each number group. // TODO: more detailed description and example groupSizes: [ 3 ], // symbol used for positive numbers "+": "+", // symbol used for negative numbers "-": "-", // symbol used for NaN (Not-A-Number) "NaN": "NaN", // symbol used for Negative Infinity negativeInfinity: "-Infinity", // symbol used for Positive Infinity positiveInfinity: "Infinity", percent: { // [negativePattern, positivePattern] // negativePattern: one of "-n %|-n%|-%n|%-n|%n-|n-%|n%-|-% n|n %-|% n-|% -n|n- %" // positivePattern: one of "n %|n%|%n|% n" pattern: [ "-n %", "n %" ], // number of decimal places normally shown decimals: 2, // array of numbers indicating the size of each number group. // TODO: more detailed description and example groupSizes: [ 3 ], // string that separates number groups, as in 1,000,000 ",": ",", // string that separates a number from the fractional portion, as in 1.99 ".": ".", // symbol used to represent a percentage symbol: "%" }, currency: { // [negativePattern, positivePattern] // negativePattern: one of "($n)|-$n|$-n|$n-|(n$)|-n$|n-$|n$-|-n $|-$ n|n $-|$ n-|$ -n|n- $|($ n)|(n $)" // positivePattern: one of "$n|n$|$ n|n $" pattern: [ "($n)", "$n" ], // number of decimal places normally shown decimals: 2, // array of numbers indicating the size of each number group. // TODO: more detailed description and example groupSizes: [ 3 ], // string that separates number groups, as in 1,000,000 ",": ",", // string that separates a number from the fractional portion, as in 1.99 ".": ".", // symbol used to represent currency symbol: "$" } }, // calendars defines all the possible calendars used by this culture. // There should be at least one defined with name "standard", and is the default // calendar used by the culture. // A calendar contains information about how dates are formatted, information about // the calendar's eras, a standard set of the date formats, // translations for day and month names, and if the calendar is not based on the Gregorian // calendar, conversion functions to and from the Gregorian calendar. calendars: { standard: { // name that identifies the type of calendar this is name: "Gregorian_USEnglish", // separator of parts of a date (e.g. "/" in 11/05/1955) "/": "/", // separator of parts of a time (e.g. ":" in 05:44 PM) ":": ":", // the first day of the week (0 = Sunday, 1 = Monday, etc) firstDay: 0, days: { // full day names names: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], // abbreviated day names namesAbbr: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], // shortest day names namesShort: [ "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" ] }, months: { // full month names (13 months for lunar calendards -- 13th month should be "" if not lunar) names: [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" ], // abbreviated month names namesAbbr: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "" ] }, // AM and PM designators in one of these forms: // The usual view, and the upper and lower case versions // [ standard, lowercase, uppercase ] // The culture does not use AM or PM (likely all standard date formats use 24 hour time) // null AM: [ "AM", "am", "AM" ], PM: [ "PM", "pm", "PM" ], eras: [ // eras in reverse chronological order. // name: the name of the era in this culture (e.g. A.D., C.E.) // start: when the era starts in ticks (gregorian, gmt), null if it is the earliest supported era. // offset: offset in years from gregorian calendar { "name": "A.D.", "start": null, "offset": 0 } ], // when a two digit year is given, it will never be parsed as a four digit // year greater than this year (in the appropriate era for the culture) // Set it as a full year (e.g. 2029) or use an offset format starting from // the current year: "+19" would correspond to 2029 if the current year 2010. twoDigitYearMax: 2029, // set of predefined date and time patterns used by the culture // these represent the format someone in this culture would expect // to see given the portions of the date that are shown. patterns: { // short date pattern d: "M/d/yyyy", // long date pattern D: "dddd, MMMM dd, yyyy", // short time pattern t: "h:mm tt", // long time pattern T: "h:mm:ss tt", // long date, short time pattern f: "dddd, MMMM dd, yyyy h:mm tt", // long date, long time pattern F: "dddd, MMMM dd, yyyy h:mm:ss tt", // month/day pattern M: "MMMM dd", // month/year pattern Y: "yyyy MMMM", // S is a sortable format that does not vary by culture S: "yyyy\u0027-\u0027MM\u0027-\u0027dd\u0027T\u0027HH\u0027:\u0027mm\u0027:\u0027ss" } // optional fields for each calendar: /* monthsGenitive: Same as months but used when the day preceeds the month. Omit if the culture has no genitive distinction in month names. For an explaination of genitive months, see http://blogs.msdn.com/michkap/archive/2004/12/25/332259.aspx convert: Allows for the support of non-gregorian based calendars. This convert object is used to to convert a date to and from a gregorian calendar date to handle parsing and formatting. The two functions: fromGregorian( date ) Given the date as a parameter, return an array with parts [ year, month, day ] corresponding to the non-gregorian based year, month, and day for the calendar. toGregorian( year, month, day ) Given the non-gregorian year, month, and day, return a new Date() object set to the corresponding date in the gregorian calendar. */ } }, // For localized strings messages: {} }; Globalize.cultures[ "default" ].calendar = Globalize.cultures[ "default" ].calendars.standard; Globalize.cultures.en = Globalize.cultures[ "default" ]; Globalize.cultureSelector = "en"; // // private variables // regexHex = /^0x[a-f0-9]+$/i; regexInfinity = /^[+\-]?infinity$/i; regexParseFloat = /^[+\-]?\d*\.?\d*(e[+\-]?\d+)?$/; regexTrim = /^\s+|\s+$/g; // // private JavaScript utility functions // arrayIndexOf = function( array, item ) { if ( array.indexOf ) { return array.indexOf( item ); } for ( var i = 0, length = array.length; i < length; i++ ) { if ( array[i] === item ) { return i; } } return -1; }; endsWith = function( value, pattern ) { return value.substr( value.length - pattern.length ) === pattern; }; extend = function() { var options, name, src, copy, copyIsArray, clone, target = arguments[0] || {}, i = 1, length = arguments.length, deep = false; // Handle a deep copy situation if ( typeof target === "boolean" ) { deep = target; target = arguments[1] || {}; // skip the boolean and the target i = 2; } // Handle case when target is a string or something (possible in deep copy) if ( typeof target !== "object" && !isFunction(target) ) { target = {}; } for ( ; i < length; i++ ) { // Only deal with non-null/undefined values if ( (options = arguments[ i ]) != null ) { // Extend the base object for ( name in options ) { src = target[ name ]; copy = options[ name ]; // Prevent never-ending loop if ( target === copy ) { continue; } // Recurse if we're merging plain objects or arrays if ( deep && copy && ( isObject(copy) || (copyIsArray = isArray(copy)) ) ) { if ( copyIsArray ) { copyIsArray = false; clone = src && isArray(src) ? src : []; } else { clone = src && isObject(src) ? src : {}; } // Never move original objects, clone them target[ name ] = extend( deep, clone, copy ); // Don't bring in undefined values } else if ( copy !== undefined ) { target[ name ] = copy; } } } } // Return the modified object return target; }; isArray = Array.isArray || function( obj ) { return Object.prototype.toString.call( obj ) === "[object Array]"; }; isFunction = function( obj ) { return Object.prototype.toString.call( obj ) === "[object Function]"; }; isObject = function( obj ) { return Object.prototype.toString.call( obj ) === "[object Object]"; }; startsWith = function( value, pattern ) { return value.indexOf( pattern ) === 0; }; trim = function( value ) { return ( value + "" ).replace( regexTrim, "" ); }; truncate = function( value ) { if ( isNaN( value ) ) { return NaN; } return Math[ value < 0 ? "ceil" : "floor" ]( value ); }; zeroPad = function( str, count, left ) { var l; for ( l = str.length; l < count; l += 1 ) { str = ( left ? ("0" + str) : (str + "0") ); } return str; }; // // private Globalization utility functions // appendPreOrPostMatch = function( preMatch, strings ) { // appends pre- and post- token match strings while removing escaped characters. // Returns a single quote count which is used to determine if the token occurs // in a string literal. var quoteCount = 0, escaped = false; for ( var i = 0, il = preMatch.length; i < il; i++ ) { var c = preMatch.charAt( i ); switch ( c ) { case "\'": if ( escaped ) { strings.push( "\'" ); } else { quoteCount++; } escaped = false; break; case "\\": if ( escaped ) { strings.push( "\\" ); } escaped = !escaped; break; default: strings.push( c ); escaped = false; break; } } return quoteCount; }; expandFormat = function( cal, format ) { // expands unspecified or single character date formats into the full pattern. format = format || "F"; var pattern, patterns = cal.patterns, len = format.length; if ( len === 1 ) { pattern = patterns[ format ]; if ( !pattern ) { throw "Invalid date format string \'" + format + "\'."; } format = pattern; } else if ( len === 2 && format.charAt(0) === "%" ) { // %X escape format -- intended as a custom format string that is only one character, not a built-in format. format = format.charAt( 1 ); } return format; }; formatDate = function( value, format, culture ) { var cal = culture.calendar, convert = cal.convert, ret; if ( !format || !format.length || format === "i" ) { if ( culture && culture.name.length ) { if ( convert ) { // non-gregorian calendar, so we cannot use built-in toLocaleString() ret = formatDate( value, cal.patterns.F, culture ); } else { var eraDate = new Date( value.getTime() ), era = getEra( value, cal.eras ); eraDate.setFullYear( getEraYear(value, cal, era) ); ret = eraDate.toLocaleString(); } } else { ret = value.toString(); } return ret; } var eras = cal.eras, sortable = format === "s"; format = expandFormat( cal, format ); // Start with an empty string ret = []; var hour, zeros = [ "0", "00", "000" ], foundDay, checkedDay, dayPartRegExp = /([^d]|^)(d|dd)([^d]|$)/g, quoteCount = 0, tokenRegExp = getTokenRegExp(), converted; function padZeros( num, c ) { var r, s = num + ""; if ( c > 1 && s.length < c ) { r = ( zeros[c - 2] + s); return r.substr( r.length - c, c ); } else { r = s; } return r; } function hasDay() { if ( foundDay || checkedDay ) { return foundDay; } foundDay = dayPartRegExp.test( format ); checkedDay = true; return foundDay; } function getPart( date, part ) { if ( converted ) { return converted[ part ]; } switch ( part ) { case 0: return date.getFullYear(); case 1: return date.getMonth(); case 2: return date.getDate(); default: throw "Invalid part value " + part; } } if ( !sortable && convert ) { converted = convert.fromGregorian( value ); } for ( ; ; ) { // Save the current index var index = tokenRegExp.lastIndex, // Look for the next pattern ar = tokenRegExp.exec( format ); // Append the text before the pattern (or the end of the string if not found) var preMatch = format.slice( index, ar ? ar.index : format.length ); quoteCount += appendPreOrPostMatch( preMatch, ret ); if ( !ar ) { break; } // do not replace any matches that occur inside a string literal. if ( quoteCount % 2 ) { ret.push( ar[0] ); continue; } var current = ar[ 0 ], clength = current.length; switch ( current ) { case "ddd": //Day of the week, as a three-letter abbreviation case "dddd": // Day of the week, using the full name var names = ( clength === 3 ) ? cal.days.namesAbbr : cal.days.names; ret.push( names[value.getDay()] ); break; case "d": // Day of month, without leading zero for single-digit days case "dd": // Day of month, with leading zero for single-digit days foundDay = true; ret.push( padZeros( getPart(value, 2), clength ) ); break; case "MMM": // Month, as a three-letter abbreviation case "MMMM": // Month, using the full name var part = getPart( value, 1 ); ret.push( ( cal.monthsGenitive && hasDay() ) ? ( cal.monthsGenitive[ clength === 3 ? "namesAbbr" : "names" ][ part ] ) : ( cal.months[ clength === 3 ? "namesAbbr" : "names" ][ part ] ) ); break; case "M": // Month, as digits, with no leading zero for single-digit months case "MM": // Month, as digits, with leading zero for single-digit months ret.push( padZeros( getPart(value, 1) + 1, clength ) ); break; case "y": // Year, as two digits, but with no leading zero for years less than 10 case "yy": // Year, as two digits, with leading zero for years less than 10 case "yyyy": // Year represented by four full digits part = converted ? converted[ 0 ] : getEraYear( value, cal, getEra(value, eras), sortable ); if ( clength < 4 ) { part = part % 100; } ret.push( padZeros( part, clength ) ); break; case "h": // Hours with no leading zero for single-digit hours, using 12-hour clock case "hh": // Hours with leading zero for single-digit hours, using 12-hour clock hour = value.getHours() % 12; if ( hour === 0 ) hour = 12; ret.push( padZeros( hour, clength ) ); break; case "H": // Hours with no leading zero for single-digit hours, using 24-hour clock case "HH": // Hours with leading zero for single-digit hours, using 24-hour clock ret.push( padZeros( value.getHours(), clength ) ); break; case "m": // Minutes with no leading zero for single-digit minutes case "mm": // Minutes with leading zero for single-digit minutes ret.push( padZeros( value.getMinutes(), clength ) ); break; case "s": // Seconds with no leading zero for single-digit seconds case "ss": // Seconds with leading zero for single-digit seconds ret.push( padZeros( value.getSeconds(), clength ) ); break; case "t": // One character am/pm indicator ("a" or "p") case "tt": // Multicharacter am/pm indicator part = value.getHours() < 12 ? ( cal.AM ? cal.AM[0] : " " ) : ( cal.PM ? cal.PM[0] : " " ); ret.push( clength === 1 ? part.charAt(0) : part ); break; case "f": // Deciseconds case "ff": // Centiseconds case "fff": // Milliseconds ret.push( padZeros( value.getMilliseconds(), 3 ).substr( 0, clength ) ); break; case "z": // Time zone offset, no leading zero case "zz": // Time zone offset with leading zero hour = value.getTimezoneOffset() / 60; ret.push( ( hour <= 0 ? "+" : "-" ) + padZeros( Math.floor(Math.abs(hour)), clength ) ); break; case "zzz": // Time zone offset with leading zero hour = value.getTimezoneOffset() / 60; ret.push( ( hour <= 0 ? "+" : "-" ) + padZeros( Math.floor(Math.abs(hour)), 2 ) + // Hard coded ":" separator, rather than using cal.TimeSeparator // Repeated here for consistency, plus ":" was already assumed in date parsing. ":" + padZeros( Math.abs(value.getTimezoneOffset() % 60), 2 ) ); break; case "g": case "gg": if ( cal.eras ) { ret.push( cal.eras[ getEra(value, eras) ].name ); } break; case "/": ret.push( cal["/"] ); break; default: throw "Invalid date format pattern \'" + current + "\'."; } } return ret.join( "" ); }; // formatNumber (function() { var expandNumber; expandNumber = function( number, precision, formatInfo ) { var groupSizes = formatInfo.groupSizes, curSize = groupSizes[ 0 ], curGroupIndex = 1, factor = Math.pow( 10, precision ), rounded = Math.round( number * factor ) / factor; if ( !isFinite(rounded) ) { rounded = number; } number = rounded; var numberString = number+"", right = "", split = numberString.split( /e/i ), exponent = split.length > 1 ? parseInt( split[1], 10 ) : 0; numberString = split[ 0 ]; split = numberString.split( "." ); numberString = split[ 0 ]; right = split.length > 1 ? split[ 1 ] : ""; if ( exponent > 0 ) { right = zeroPad( right, exponent, false ); numberString += right.slice( 0, exponent ); right = right.substr( exponent ); } else if ( exponent < 0 ) { exponent = -exponent; numberString = zeroPad( numberString, exponent + 1, true ); right = numberString.slice( -exponent, numberString.length ) + right; numberString = numberString.slice( 0, -exponent ); } if ( precision > 0 ) { right = formatInfo[ "." ] + ( (right.length > precision) ? right.slice(0, precision) : zeroPad(right, precision) ); } else { right = ""; } var stringIndex = numberString.length - 1, sep = formatInfo[ "," ], ret = ""; while ( stringIndex >= 0 ) { if ( curSize === 0 || curSize > stringIndex ) { return numberString.slice( 0, stringIndex + 1 ) + ( ret.length ? (sep + ret + right) : right ); } ret = numberString.slice( stringIndex - curSize + 1, stringIndex + 1 ) + ( ret.length ? (sep + ret) : "" ); stringIndex -= curSize; if ( curGroupIndex < groupSizes.length ) { curSize = groupSizes[ curGroupIndex ]; curGroupIndex++; } } return numberString.slice( 0, stringIndex + 1 ) + sep + ret + right; }; formatNumber = function( value, format, culture ) { if ( !isFinite(value) ) { if ( value === Infinity ) { return culture.numberFormat.positiveInfinity; } if ( value === -Infinity ) { return culture.numberFormat.negativeInfinity; } return culture.numberFormat.NaN; } if ( !format || format === "i" ) { return culture.name.length ? value.toLocaleString() : value.toString(); } format = format || "D"; var nf = culture.numberFormat, number = Math.abs( value ), precision = -1, pattern; if ( format.length > 1 ) precision = parseInt( format.slice(1), 10 ); var current = format.charAt( 0 ).toUpperCase(), formatInfo; switch ( current ) { case "D": pattern = "n"; number = truncate( number ); if ( precision !== -1 ) { number = zeroPad( "" + number, precision, true ); } if ( value < 0 ) number = "-" + number; break; case "N": formatInfo = nf; /* falls through */ case "C": formatInfo = formatInfo || nf.currency; /* falls through */ case "P": formatInfo = formatInfo || nf.percent; pattern = value < 0 ? formatInfo.pattern[ 0 ] : ( formatInfo.pattern[1] || "n" ); if ( precision === -1 ) precision = formatInfo.decimals; number = expandNumber( number * (current === "P" ? 100 : 1), precision, formatInfo ); break; default: throw "Bad number format specifier: " + current; } var patternParts = /n|\$|-|%/g, ret = ""; for ( ; ; ) { var index = patternParts.lastIndex, ar = patternParts.exec( pattern ); ret += pattern.slice( index, ar ? ar.index : pattern.length ); if ( !ar ) { break; } switch ( ar[0] ) { case "n": ret += number; break; case "$": ret += nf.currency.symbol; break; case "-": // don't make 0 negative if ( /[1-9]/.test(number) ) { ret += nf[ "-" ]; } break; case "%": ret += nf.percent.symbol; break; } } return ret; }; }()); getTokenRegExp = function() { // regular expression for matching date and time tokens in format strings. return (/\/|dddd|ddd|dd|d|MMMM|MMM|MM|M|yyyy|yy|y|hh|h|HH|H|mm|m|ss|s|tt|t|fff|ff|f|zzz|zz|z|gg|g/g); }; getEra = function( date, eras ) { if ( !eras ) return 0; var start, ticks = date.getTime(); for ( var i = 0, l = eras.length; i < l; i++ ) { start = eras[ i ].start; if ( start === null || ticks >= start ) { return i; } } return 0; }; getEraYear = function( date, cal, era, sortable ) { var year = date.getFullYear(); if ( !sortable && cal.eras ) { // convert normal gregorian year to era-shifted gregorian // year by subtracting the era offset year -= cal.eras[ era ].offset; } return year; }; // parseExact (function() { var expandYear, getDayIndex, getMonthIndex, getParseRegExp, outOfRange, toUpper, toUpperArray; expandYear = function( cal, year ) { // expands 2-digit year into 4 digits. if ( year < 100 ) { var now = new Date(), era = getEra( now ), curr = getEraYear( now, cal, era ), twoDigitYearMax = cal.twoDigitYearMax; twoDigitYearMax = typeof twoDigitYearMax === "string" ? new Date().getFullYear() % 100 + parseInt( twoDigitYearMax, 10 ) : twoDigitYearMax; year += curr - ( curr % 100 ); if ( year > twoDigitYearMax ) { year -= 100; } } return year; }; getDayIndex = function ( cal, value, abbr ) { var ret, days = cal.days, upperDays = cal._upperDays; if ( !upperDays ) { cal._upperDays = upperDays = [ toUpperArray( days.names ), toUpperArray( days.namesAbbr ), toUpperArray( days.namesShort ) ]; } value = toUpper( value ); if ( abbr ) { ret = arrayIndexOf( upperDays[1], value ); if ( ret === -1 ) { ret = arrayIndexOf( upperDays[2], value ); } } else { ret = arrayIndexOf( upperDays[0], value ); } return ret; }; getMonthIndex = function( cal, value, abbr ) { var months = cal.months, monthsGen = cal.monthsGenitive || cal.months, upperMonths = cal._upperMonths, upperMonthsGen = cal._upperMonthsGen; if ( !upperMonths ) { cal._upperMonths = upperMonths = [ toUpperArray( months.names ), toUpperArray( months.namesAbbr ) ]; cal._upperMonthsGen = upperMonthsGen = [ toUpperArray( monthsGen.names ), toUpperArray( monthsGen.namesAbbr ) ]; } value = toUpper( value ); var i = arrayIndexOf( abbr ? upperMonths[1] : upperMonths[0], value ); if ( i < 0 ) { i = arrayIndexOf( abbr ? upperMonthsGen[1] : upperMonthsGen[0], value ); } return i; }; getParseRegExp = function( cal, format ) { // converts a format string into a regular expression with groups that // can be used to extract date fields from a date string. // check for a cached parse regex. var re = cal._parseRegExp; if ( !re ) { cal._parseRegExp = re = {}; } else { var reFormat = re[ format ]; if ( reFormat ) { return reFormat; } } // expand single digit formats, then escape regular expression characters. var expFormat = expandFormat( cal, format ).replace( /([\^\$\.\*\+\?\|\[\]\(\)\{\}])/g, "\\\\$1" ), regexp = [ "^" ], groups = [], index = 0, quoteCount = 0, tokenRegExp = getTokenRegExp(), match; // iterate through each date token found. while ( (match = tokenRegExp.exec(expFormat)) !== null ) { var preMatch = expFormat.slice( index, match.index ); index = tokenRegExp.lastIndex; // don't replace any matches that occur inside a string literal. quoteCount += appendPreOrPostMatch( preMatch, regexp ); if ( quoteCount % 2 ) { regexp.push( match[0] ); continue; } // add a regex group for the token. var m = match[ 0 ], len = m.length, add; switch ( m ) { case "dddd": case "ddd": case "MMMM": case "MMM": case "gg": case "g": add = "(\\D+)"; break; case "tt": case "t": add = "(\\D*)"; break; case "yyyy": case "fff": case "ff": case "f": add = "(\\d{" + len + "})"; break; case "dd": case "d": case "MM": case "M": case "yy": case "y": case "HH": case "H": case "hh": case "h": case "mm": case "m": case "ss": case "s": add = "(\\d\\d?)"; break; case "zzz": add = "([+-]?\\d\\d?:\\d{2})"; break; case "zz": case "z": add = "([+-]?\\d\\d?)"; break; case "/": add = "(\\/)"; break; default: throw "Invalid date format pattern \'" + m + "\'."; } if ( add ) { regexp.push( add ); } groups.push( match[0] ); } appendPreOrPostMatch( expFormat.slice(index), regexp ); regexp.push( "$" ); // allow whitespace to differ when matching formats. var regexpStr = regexp.join( "" ).replace( /\s+/g, "\\s+" ), parseRegExp = { "regExp": regexpStr, "groups": groups }; // cache the regex for this format. return re[ format ] = parseRegExp; }; outOfRange = function( value, low, high ) { return value < low || value > high; }; toUpper = function( value ) { // "he-IL" has non-breaking space in weekday names. return value.split( "\u00A0" ).join( " " ).toUpperCase(); }; toUpperArray = function( arr ) { var results = []; for ( var i = 0, l = arr.length; i < l; i++ ) { results[ i ] = toUpper( arr[i] ); } return results; }; parseExact = function( value, format, culture ) { // try to parse the date string by matching against the format string // while using the specified culture for date field names. value = trim( value ); var cal = culture.calendar, // convert date formats into regular expressions with groupings. // use the regexp to determine the input format and extract the date fields. parseInfo = getParseRegExp( cal, format ), match = new RegExp( parseInfo.regExp ).exec( value ); if ( match === null ) { return null; } // found a date format that matches the input. var groups = parseInfo.groups, era = null, year = null, month = null, date = null, weekDay = null, hour = 0, hourOffset, min = 0, sec = 0, msec = 0, tzMinOffset = null, pmHour = false; // iterate the format groups to extract and set the date fields. for ( var j = 0, jl = groups.length; j < jl; j++ ) { var matchGroup = match[ j + 1 ]; if ( matchGroup ) { var current = groups[ j ], clength = current.length, matchInt = parseInt( matchGroup, 10 ); switch ( current ) { case "dd": case "d": // Day of month. date = matchInt; // check that date is generally in valid range, also checking overflow below. if ( outOfRange(date, 1, 31) ) return null; break; case "MMM": case "MMMM": month = getMonthIndex( cal, matchGroup, clength === 3 ); if ( outOfRange(month, 0, 11) ) return null; break; case "M": case "MM": // Month. month = matchInt - 1; if ( outOfRange(month, 0, 11) ) return null; break; case "y": case "yy": case "yyyy": year = clength < 4 ? expandYear( cal, matchInt ) : matchInt; if ( outOfRange(year, 0, 9999) ) return null; break; case "h": case "hh": // Hours (12-hour clock). hour = matchInt; if ( hour === 12 ) hour = 0; if ( outOfRange(hour, 0, 11) ) return null; break; case "H": case "HH": // Hours (24-hour clock). hour = matchInt; if ( outOfRange(hour, 0, 23) ) return null; break; case "m": case "mm": // Minutes. min = matchInt; if ( outOfRange(min, 0, 59) ) return null; break; case "s": case "ss": // Seconds. sec = matchInt; if ( outOfRange(sec, 0, 59) ) return null; break; case "tt": case "t": // AM/PM designator. // see if it is standard, upper, or lower case PM. If not, ensure it is at least one of // the AM tokens. If not, fail the parse for this format. pmHour = cal.PM && ( matchGroup === cal.PM[0] || matchGroup === cal.PM[1] || matchGroup === cal.PM[2] ); if ( !pmHour && ( !cal.AM || ( matchGroup !== cal.AM[0] && matchGroup !== cal.AM[1] && matchGroup !== cal.AM[2] ) ) ) return null; break; case "f": // Deciseconds. case "ff": // Centiseconds. case "fff": // Milliseconds. msec = matchInt * Math.pow( 10, 3 - clength ); if ( outOfRange(msec, 0, 999) ) return null; break; case "ddd": // Day of week. case "dddd": // Day of week. weekDay = getDayIndex( cal, matchGroup, clength === 3 ); if ( outOfRange(weekDay, 0, 6) ) return null; break; case "zzz": // Time zone offset in +/- hours:min. var offsets = matchGroup.split( /:/ ); if ( offsets.length !== 2 ) return null; hourOffset = parseInt( offsets[0], 10 ); if ( outOfRange(hourOffset, -12, 13) ) return null; var minOffset = parseInt( offsets[1], 10 ); if ( outOfRange(minOffset, 0, 59) ) return null; tzMinOffset = ( hourOffset * 60 ) + ( startsWith(matchGroup, "-") ? -minOffset : minOffset ); break; case "z": case "zz": // Time zone offset in +/- hours. hourOffset = matchInt; if ( outOfRange(hourOffset, -12, 13) ) return null; tzMinOffset = hourOffset * 60; break; case "g": case "gg": var eraName = matchGroup; if ( !eraName || !cal.eras ) return null; eraName = trim( eraName.toLowerCase() ); for ( var i = 0, l = cal.eras.length; i < l; i++ ) { if ( eraName === cal.eras[i].name.toLowerCase() ) { era = i; break; } } // could not find an era with that name if ( era === null ) return null; break; } } } var result = new Date(), defaultYear, convert = cal.convert; defaultYear = convert ? convert.fromGregorian( result )[ 0 ] : result.getFullYear(); if ( year === null ) { year = defaultYear; } else if ( cal.eras ) { // year must be shifted to normal gregorian year // but not if year was not specified, its already normal gregorian // per the main if clause above. year += cal.eras[( era || 0 )].offset; } // set default day and month to 1 and January, so if unspecified, these are the defaults // instead of the current day/month. if ( month === null ) { month = 0; } if ( date === null ) { date = 1; } // now have year, month, and date, but in the culture's calendar. // convert to gregorian if necessary if ( convert ) { result = convert.toGregorian( year, month, date ); // conversion failed, must be an invalid match if ( result === null ) return null; } else { // have to set year, month and date together to avoid overflow based on current date. result.setFullYear( year, month, date ); // check to see if date overflowed for specified month (only checked 1-31 above). if ( result.getDate() !== date ) return null; // invalid day of week. if ( weekDay !== null && result.getDay() !== weekDay ) { return null; } } // if pm designator token was found make sure the hours fit the 24-hour clock. if ( pmHour && hour < 12 ) { hour += 12; } result.setHours( hour, min, sec, msec ); if ( tzMinOffset !== null ) { // adjust timezone to utc before applying local offset. var adjustedMin = result.getMinutes() - ( tzMinOffset + result.getTimezoneOffset() ); // Safari limits hours and minutes to the range of -127 to 127. We need to use setHours // to ensure both these fields will not exceed this range. adjustedMin will range // somewhere between -1440 and 1500, so we only need to split this into hours. result.setHours( result.getHours() + parseInt(adjustedMin / 60, 10), adjustedMin % 60 ); } return result; }; }()); parseNegativePattern = function( value, nf, negativePattern ) { var neg = nf[ "-" ], pos = nf[ "+" ], ret; switch ( negativePattern ) { case "n -": neg = " " + neg; pos = " " + pos; /* falls through */ case "n-": if ( endsWith(value, neg) ) { ret = [ "-", value.substr(0, value.length - neg.length) ]; } else if ( endsWith(value, pos) ) { ret = [ "+", value.substr(0, value.length - pos.length) ]; } break; case "- n": neg += " "; pos += " "; /* falls through */ case "-n": if ( startsWith(value, neg) ) { ret = [ "-", value.substr(neg.length) ]; } else if ( startsWith(value, pos) ) { ret = [ "+", value.substr(pos.length) ]; } break; case "(n)": if ( startsWith(value, "(") && endsWith(value, ")") ) { ret = [ "-", value.substr(1, value.length - 2) ]; } break; } return ret || [ "", value ]; }; // // public instance functions // Globalize.prototype.findClosestCulture = function( cultureSelector ) { return Globalize.findClosestCulture.call( this, cultureSelector ); }; Globalize.prototype.format = function( value, format, cultureSelector ) { return Globalize.format.call( this, value, format, cultureSelector ); }; Globalize.prototype.localize = function( key, cultureSelector ) { return Globalize.localize.call( this, key, cultureSelector ); }; Globalize.prototype.parseInt = function( value, radix, cultureSelector ) { return Globalize.parseInt.call( this, value, radix, cultureSelector ); }; Globalize.prototype.parseFloat = function( value, radix, cultureSelector ) { return Globalize.parseFloat.call( this, value, radix, cultureSelector ); }; Globalize.prototype.culture = function( cultureSelector ) { return Globalize.culture.call( this, cultureSelector ); }; // // public singleton functions // Globalize.addCultureInfo = function( cultureName, baseCultureName, info ) { var base = {}, isNew = false; if ( typeof cultureName !== "string" ) { // cultureName argument is optional string. If not specified, assume info is first // and only argument. Specified info deep-extends current culture. info = cultureName; cultureName = this.culture().name; base = this.cultures[ cultureName ]; } else if ( typeof baseCultureName !== "string" ) { // baseCultureName argument is optional string. If not specified, assume info is second // argument. Specified info deep-extends specified culture. // If specified culture does not exist, create by deep-extending default info = baseCultureName; isNew = ( this.cultures[ cultureName ] == null ); base = this.cultures[ cultureName ] || this.cultures[ "default" ]; } else { // cultureName and baseCultureName specified. Assume a new culture is being created // by deep-extending an specified base culture isNew = true; base = this.cultures[ baseCultureName ]; } this.cultures[ cultureName ] = extend(true, {}, base, info ); // Make the standard calendar the current culture if it's a new culture if ( isNew ) { this.cultures[ cultureName ].calendar = this.cultures[ cultureName ].calendars.standard; } }; Globalize.findClosestCulture = function( name ) { var match; if ( !name ) { return this.findClosestCulture( this.cultureSelector ) || this.cultures[ "default" ]; } if ( typeof name === "string" ) { name = name.split( "," ); } if ( isArray(name) ) { var lang, cultures = this.cultures, list = name, i, l = list.length, prioritized = []; for ( i = 0; i < l; i++ ) { name = trim( list[i] ); var pri, parts = name.split( ";" ); lang = trim( parts[0] ); if ( parts.length === 1 ) { pri = 1; } else { name = trim( parts[1] ); if ( name.indexOf("q=") === 0 ) { name = name.substr( 2 ); pri = parseFloat( name ); pri = isNaN( pri ) ? 0 : pri; } else { pri = 1; } } prioritized.push({ lang: lang, pri: pri }); } prioritized.sort(function( a, b ) { if ( a.pri < b.pri ) { return 1; } else if ( a.pri > b.pri ) { return -1; } return 0; }); // exact match for ( i = 0; i < l; i++ ) { lang = prioritized[ i ].lang; match = cultures[ lang ]; if ( match ) { return match; } } // neutral language match for ( i = 0; i < l; i++ ) { lang = prioritized[ i ].lang; do { var index = lang.lastIndexOf( "-" ); if ( index === -1 ) { break; } // strip off the last part. e.g. en-US => en lang = lang.substr( 0, index ); match = cultures[ lang ]; if ( match ) { return match; } } while ( 1 ); } // last resort: match first culture using that language for ( i = 0; i < l; i++ ) { lang = prioritized[ i ].lang; for ( var cultureKey in cultures ) { var culture = cultures[ cultureKey ]; if ( culture.language === lang ) { return culture; } } } } else if ( typeof name === "object" ) { return name; } return match || null; }; Globalize.format = function( value, format, cultureSelector ) { var culture = this.findClosestCulture( cultureSelector ); if ( value instanceof Date ) { value = formatDate( value, format, culture ); } else if ( typeof value === "number" ) { value = formatNumber( value, format, culture ); } return value; }; Globalize.localize = function( key, cultureSelector ) { return this.findClosestCulture( cultureSelector ).messages[ key ] || this.cultures[ "default" ].messages[ key ]; }; Globalize.parseDate = function( value, formats, culture ) { culture = this.findClosestCulture( culture ); var date, prop, patterns; if ( formats ) { if ( typeof formats === "string" ) { formats = [ formats ]; } if ( formats.length ) { for ( var i = 0, l = formats.length; i < l; i++ ) { var format = formats[ i ]; if ( format ) { date = parseExact( value, format, culture ); if ( date ) { break; } } } } } else { patterns = culture.calendar.patterns; for ( prop in patterns ) { date = parseExact( value, patterns[prop], culture ); if ( date ) { break; } } } return date || null; }; Globalize.parseInt = function( value, radix, cultureSelector ) { return truncate( Globalize.parseFloat(value, radix, cultureSelector) ); }; Globalize.parseFloat = function( value, radix, cultureSelector ) { // radix argument is optional if ( typeof radix !== "number" ) { cultureSelector = radix; radix = 10; } var culture = this.findClosestCulture( cultureSelector ); var ret = NaN, nf = culture.numberFormat; if ( value.indexOf(culture.numberFormat.currency.symbol) > -1 ) { // remove currency symbol value = value.replace( culture.numberFormat.currency.symbol, "" ); // replace decimal seperator value = value.replace( culture.numberFormat.currency["."], culture.numberFormat["."] ); } //Remove percentage character from number string before parsing if ( value.indexOf(culture.numberFormat.percent.symbol) > -1){ value = value.replace( culture.numberFormat.percent.symbol, "" ); } // remove spaces: leading, trailing and between - and number. Used for negative currency pt-BR value = value.replace( / /g, "" ); // allow infinity or hexidecimal if ( regexInfinity.test(value) ) { ret = parseFloat( value ); } else if ( !radix && regexHex.test(value) ) { ret = parseInt( value, 16 ); } else { // determine sign and number var signInfo = parseNegativePattern( value, nf, nf.pattern[0] ), sign = signInfo[ 0 ], num = signInfo[ 1 ]; // #44 - try parsing as "(n)" if ( sign === "" && nf.pattern[0] !== "(n)" ) { signInfo = parseNegativePattern( value, nf, "(n)" ); sign = signInfo[ 0 ]; num = signInfo[ 1 ]; } // try parsing as "-n" if ( sign === "" && nf.pattern[0] !== "-n" ) { signInfo = parseNegativePattern( value, nf, "-n" ); sign = signInfo[ 0 ]; num = signInfo[ 1 ]; } sign = sign || "+"; // determine exponent and number var exponent, intAndFraction, exponentPos = num.indexOf( "e" ); if ( exponentPos < 0 ) exponentPos = num.indexOf( "E" ); if ( exponentPos < 0 ) { intAndFraction = num; exponent = null; } else { intAndFraction = num.substr( 0, exponentPos ); exponent = num.substr( exponentPos + 1 ); } // determine decimal position var integer, fraction, decSep = nf[ "." ], decimalPos = intAndFraction.indexOf( decSep ); if ( decimalPos < 0 ) { integer = intAndFraction; fraction = null; } else { integer = intAndFraction.substr( 0, decimalPos ); fraction = intAndFraction.substr( decimalPos + decSep.length ); } // handle groups (e.g. 1,000,000) var groupSep = nf[ "," ]; integer = integer.split( groupSep ).join( "" ); var altGroupSep = groupSep.replace( /\u00A0/g, " " ); if ( groupSep !== altGroupSep ) { integer = integer.split( altGroupSep ).join( "" ); } // build a natively parsable number string var p = sign + integer; if ( fraction !== null ) { p += "." + fraction; } if ( exponent !== null ) { // exponent itself may have a number patternd var expSignInfo = parseNegativePattern( exponent, nf, "-n" ); p += "e" + ( expSignInfo[0] || "+" ) + expSignInfo[ 1 ]; } if ( regexParseFloat.test(p) ) { ret = parseFloat( p ); } } return ret; }; Globalize.culture = function( cultureSelector ) { // setter if ( typeof cultureSelector !== "undefined" ) { this.cultureSelector = cultureSelector; } // getter return this.findClosestCulture( cultureSelector ) || this.cultures[ "default" ]; }; }( this )); ================================================ FILE: external/jquery/LICENSE.txt ================================================ Copyright OpenJS Foundation and other contributors, https://openjsf.org/ 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. ================================================ FILE: external/jquery/MIT-LICENSE.txt ================================================ Copyright 2014 jQuery Foundation and other contributors http://jquery.com/ 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. ================================================ FILE: external/jquery/jquery.js ================================================ /*! * jQuery JavaScript Library v4.0.0 * https://jquery.com/ * * Copyright OpenJS Foundation and other contributors * Released under the MIT license * https://jquery.com/license/ * * Date: 2026-01-18T00:20Z */ ( function( global, factory ) { "use strict"; if ( typeof module === "object" && typeof module.exports === "object" ) { // For CommonJS and CommonJS-like environments where a proper `window` // is present, execute the factory and get jQuery. module.exports = factory( global, true ); } else { factory( global ); } // Pass this if window is not defined yet } )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { "use strict"; if ( !window.document ) { throw new Error( "jQuery requires a window with a document" ); } var arr = []; var getProto = Object.getPrototypeOf; var slice = arr.slice; // Support: IE 11+ // IE doesn't have Array#flat; provide a fallback. var flat = arr.flat ? function( array ) { return arr.flat.call( array ); } : function( array ) { return arr.concat.apply( [], array ); }; var push = arr.push; var indexOf = arr.indexOf; // [[Class]] -> type pairs var class2type = {}; var toString = class2type.toString; var hasOwn = class2type.hasOwnProperty; var fnToString = hasOwn.toString; var ObjectFunctionString = fnToString.call( Object ); // All support tests are defined in their respective modules. var support = {}; function toType( obj ) { if ( obj == null ) { return obj + ""; } return typeof obj === "object" ? class2type[ toString.call( obj ) ] || "object" : typeof obj; } function isWindow( obj ) { return obj != null && obj === obj.window; } function isArrayLike( obj ) { var length = !!obj && obj.length, type = toType( obj ); if ( typeof obj === "function" || isWindow( obj ) ) { return false; } return type === "array" || length === 0 || typeof length === "number" && length > 0 && ( length - 1 ) in obj; } var document$1 = window.document; var preservedScriptAttributes = { type: true, src: true, nonce: true, noModule: true }; function DOMEval( code, node, doc ) { doc = doc || document$1; var i, script = doc.createElement( "script" ); script.text = code; for ( i in preservedScriptAttributes ) { if ( node && node[ i ] ) { script[ i ] = node[ i ]; } } if ( doc.head.appendChild( script ).parentNode ) { script.parentNode.removeChild( script ); } } var version = "4.0.0", rhtmlSuffix = /HTML$/i, // Define a local copy of jQuery jQuery = function( selector, context ) { // The jQuery object is actually just the init constructor 'enhanced' // Need init if jQuery is called (just allow error to be thrown if not included) return new jQuery.fn.init( selector, context ); }; jQuery.fn = jQuery.prototype = { // The current version of jQuery being used jquery: version, constructor: jQuery, // The default length of a jQuery object is 0 length: 0, toArray: function() { return slice.call( this ); }, // Get the Nth element in the matched element set OR // Get the whole matched element set as a clean array get: function( num ) { // Return all the elements in a clean array if ( num == null ) { return slice.call( this ); } // Return just the one element from the set return num < 0 ? this[ num + this.length ] : this[ num ]; }, // Take an array of elements and push it onto the stack // (returning the new matched element set) pushStack: function( elems ) { // Build a new jQuery matched element set var ret = jQuery.merge( this.constructor(), elems ); // Add the old object onto the stack (as a reference) ret.prevObject = this; // Return the newly-formed element set return ret; }, // Execute a callback for every element in the matched set. each: function( callback ) { return jQuery.each( this, callback ); }, map: function( callback ) { return this.pushStack( jQuery.map( this, function( elem, i ) { return callback.call( elem, i, elem ); } ) ); }, slice: function() { return this.pushStack( slice.apply( this, arguments ) ); }, first: function() { return this.eq( 0 ); }, last: function() { return this.eq( -1 ); }, even: function() { return this.pushStack( jQuery.grep( this, function( _elem, i ) { return ( i + 1 ) % 2; } ) ); }, odd: function() { return this.pushStack( jQuery.grep( this, function( _elem, i ) { return i % 2; } ) ); }, eq: function( i ) { var len = this.length, j = +i + ( i < 0 ? len : 0 ); return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); }, end: function() { return this.prevObject || this.constructor(); } }; jQuery.extend = jQuery.fn.extend = function() { var options, name, src, copy, copyIsArray, clone, target = arguments[ 0 ] || {}, i = 1, length = arguments.length, deep = false; // Handle a deep copy situation if ( typeof target === "boolean" ) { deep = target; // Skip the boolean and the target target = arguments[ i ] || {}; i++; } // Handle case when target is a string or something (possible in deep copy) if ( typeof target !== "object" && typeof target !== "function" ) { target = {}; } // Extend jQuery itself if only one argument is passed if ( i === length ) { target = this; i--; } for ( ; i < length; i++ ) { // Only deal with non-null/undefined values if ( ( options = arguments[ i ] ) != null ) { // Extend the base object for ( name in options ) { copy = options[ name ]; // Prevent Object.prototype pollution // Prevent never-ending loop if ( name === "__proto__" || target === copy ) { continue; } // Recurse if we're merging plain objects or arrays if ( deep && copy && ( jQuery.isPlainObject( copy ) || ( copyIsArray = Array.isArray( copy ) ) ) ) { src = target[ name ]; // Ensure proper type for the source value if ( copyIsArray && !Array.isArray( src ) ) { clone = []; } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { clone = {}; } else { clone = src; } copyIsArray = false; // Never move original objects, clone them target[ name ] = jQuery.extend( deep, clone, copy ); // Don't bring in undefined values } else if ( copy !== undefined ) { target[ name ] = copy; } } } } // Return the modified object return target; }; jQuery.extend( { // Unique for each copy of jQuery on the page expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), // Assume jQuery is ready without the ready module isReady: true, error: function( msg ) { throw new Error( msg ); }, noop: function() {}, isPlainObject: function( obj ) { var proto, Ctor; // Detect obvious negatives // Use toString instead of jQuery.type to catch host objects if ( !obj || toString.call( obj ) !== "[object Object]" ) { return false; } proto = getProto( obj ); // Objects with no prototype (e.g., `Object.create( null )`) are plain if ( !proto ) { return true; } // Objects with prototype are plain iff they were constructed by a global Object function Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; }, isEmptyObject: function( obj ) { var name; for ( name in obj ) { return false; } return true; }, // Evaluates a script in a provided context; falls back to the global one // if not specified. globalEval: function( code, options, doc ) { DOMEval( code, { nonce: options && options.nonce }, doc ); }, each: function( obj, callback ) { var length, i = 0; if ( isArrayLike( obj ) ) { length = obj.length; for ( ; i < length; i++ ) { if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { break; } } } else { for ( i in obj ) { if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { break; } } } return obj; }, // Retrieve the text value of an array of DOM nodes text: function( elem ) { var node, ret = "", i = 0, nodeType = elem.nodeType; if ( !nodeType ) { // If no nodeType, this is expected to be an array while ( ( node = elem[ i++ ] ) ) { // Do not traverse comment nodes ret += jQuery.text( node ); } } if ( nodeType === 1 || nodeType === 11 ) { return elem.textContent; } if ( nodeType === 9 ) { return elem.documentElement.textContent; } if ( nodeType === 3 || nodeType === 4 ) { return elem.nodeValue; } // Do not include comment or processing instruction nodes return ret; }, // results is for internal usage only makeArray: function( arr, results ) { var ret = results || []; if ( arr != null ) { if ( isArrayLike( Object( arr ) ) ) { jQuery.merge( ret, typeof arr === "string" ? [ arr ] : arr ); } else { push.call( ret, arr ); } } return ret; }, inArray: function( elem, arr, i ) { return arr == null ? -1 : indexOf.call( arr, elem, i ); }, isXMLDoc: function( elem ) { var namespace = elem && elem.namespaceURI, docElem = elem && ( elem.ownerDocument || elem ).documentElement; // Assume HTML when documentElement doesn't yet exist, such as inside // document fragments. return !rhtmlSuffix.test( namespace || docElem && docElem.nodeName || "HTML" ); }, // Note: an element does not contain itself contains: function( a, b ) { var bup = b && b.parentNode; return a === bup || !!( bup && bup.nodeType === 1 && ( // Support: IE 9 - 11+ // IE doesn't have `contains` on SVG. a.contains ? a.contains( bup ) : a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 ) ); }, merge: function( first, second ) { var len = +second.length, j = 0, i = first.length; for ( ; j < len; j++ ) { first[ i++ ] = second[ j ]; } first.length = i; return first; }, grep: function( elems, callback, invert ) { var callbackInverse, matches = [], i = 0, length = elems.length, callbackExpect = !invert; // Go through the array, only saving the items // that pass the validator function for ( ; i < length; i++ ) { callbackInverse = !callback( elems[ i ], i ); if ( callbackInverse !== callbackExpect ) { matches.push( elems[ i ] ); } } return matches; }, // arg is for internal usage only map: function( elems, callback, arg ) { var length, value, i = 0, ret = []; // Go through the array, translating each of the items to their new values if ( isArrayLike( elems ) ) { length = elems.length; for ( ; i < length; i++ ) { value = callback( elems[ i ], i, arg ); if ( value != null ) { ret.push( value ); } } // Go through every key on the object, } else { for ( i in elems ) { value = callback( elems[ i ], i, arg ); if ( value != null ) { ret.push( value ); } } } // Flatten any nested arrays return flat( ret ); }, // A global GUID counter for objects guid: 1, // jQuery.support is not used in Core but other projects attach their // properties to it so it needs to exist. support: support } ); if ( typeof Symbol === "function" ) { jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; } // Populate the class2type map jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), function( _i, name ) { class2type[ "[object " + name + "]" ] = name.toLowerCase(); } ); function nodeName( elem, name ) { return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); } var pop = arr.pop; // https://www.w3.org/TR/css3-selectors/#whitespace var whitespace = "[\\x20\\t\\r\\n\\f]"; var isIE = document$1.documentMode; var rbuggyQSA = isIE && new RegExp( // Support: IE 9 - 11+ // IE's :disabled selector does not pick up the children of disabled fieldsets ":enabled|:disabled|" + // Support: IE 11+ // IE 11 doesn't find elements on a `[name='']` query in some cases. // Adding a temporary attribute to the document before the selection works // around the issue. "\\[" + whitespace + "*name" + whitespace + "*=" + whitespace + "*(?:''|\"\")" ); var rtrimCSS = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ); // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram var identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+"; var rleadingCombinator = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ); var rdescend = new RegExp( whitespace + "|>" ); var rsibling = /[+~]/; var documentElement$1 = document$1.documentElement; // Support: IE 9 - 11+ // IE requires a prefix. var matches = documentElement$1.matches || documentElement$1.msMatchesSelector; /** * Create key-value caches of limited size * @returns {function(string, object)} Returns the Object data after storing it on itself with * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) * deleting the oldest entry */ function createCache() { var keys = []; function cache( key, value ) { // Use (key + " ") to avoid collision with native prototype properties // (see https://github.com/jquery/sizzle/issues/157) if ( keys.push( key + " " ) > jQuery.expr.cacheLength ) { // Only keep the most recent entries delete cache[ keys.shift() ]; } return ( cache[ key + " " ] = value ); } return cache; } /** * Checks a node for validity as a jQuery selector context * @param {Element|Object=} context * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value */ function testContext( context ) { return context && typeof context.getElementsByTagName !== "undefined" && context; } // Attribute selectors: https://www.w3.org/TR/selectors/#attribute-selectors var attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + // Operator (capture 2) "*([*^$|!~]?=)" + whitespace + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + "*\\]"; var pseudos = ":(" + identifier + ")(?:\\((" + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: // 1. quoted (capture 3; capture 4 or capture 5) "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + // 2. simple (capture 6) "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + // 3. anything else (capture 2) ".*" + ")\\)|)"; var filterMatchExpr = { ID: new RegExp( "^#(" + identifier + ")" ), CLASS: new RegExp( "^\\.(" + identifier + ")" ), TAG: new RegExp( "^(" + identifier + "|[*])" ), ATTR: new RegExp( "^" + attributes ), PSEUDO: new RegExp( "^" + pseudos ), CHILD: new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ) }; var rpseudo = new RegExp( pseudos ); // CSS escapes // https://www.w3.org/TR/CSS21/syndata.html#escaped-characters var runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ), funescape = function( escape, nonHex ) { var high = "0x" + escape.slice( 1 ) - 0x10000; if ( nonHex ) { // Strip the backslash prefix from a non-hex escape sequence return nonHex; } // Replace a hexadecimal escape sequence with the encoded Unicode code point // Support: IE <=11+ // For values outside the Basic Multilingual Plane (BMP), manually construct a // surrogate pair return high < 0 ? String.fromCharCode( high + 0x10000 ) : String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); }; function unescapeSelector( sel ) { return sel.replace( runescape, funescape ); } function selectorError( msg ) { jQuery.error( "Syntax error, unrecognized expression: " + msg ); } var rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ); var tokenCache = createCache(); function tokenize( selector, parseOnly ) { var matched, match, tokens, type, soFar, groups, preFilters, cached = tokenCache[ selector + " " ]; if ( cached ) { return parseOnly ? 0 : cached.slice( 0 ); } soFar = selector; groups = []; preFilters = jQuery.expr.preFilter; while ( soFar ) { // Comma and first run if ( !matched || ( match = rcomma.exec( soFar ) ) ) { if ( match ) { // Don't consume trailing commas as valid soFar = soFar.slice( match[ 0 ].length ) || soFar; } groups.push( ( tokens = [] ) ); } matched = false; // Combinators if ( ( match = rleadingCombinator.exec( soFar ) ) ) { matched = match.shift(); tokens.push( { value: matched, // Cast descendant combinators to space type: match[ 0 ].replace( rtrimCSS, " " ) } ); soFar = soFar.slice( matched.length ); } // Filters for ( type in filterMatchExpr ) { if ( ( match = jQuery.expr.match[ type ].exec( soFar ) ) && ( !preFilters[ type ] || ( match = preFilters[ type ]( match ) ) ) ) { matched = match.shift(); tokens.push( { value: matched, type: type, matches: match } ); soFar = soFar.slice( matched.length ); } } if ( !matched ) { break; } } // Return the length of the invalid excess // if we're just parsing // Otherwise, throw an error or return tokens if ( parseOnly ) { return soFar.length; } return soFar ? selectorError( selector ) : // Cache the tokens tokenCache( selector, groups ).slice( 0 ); } var preFilter = { ATTR: function( match ) { match[ 1 ] = unescapeSelector( match[ 1 ] ); // Move the given value to match[3] whether quoted or unquoted match[ 3 ] = unescapeSelector( match[ 3 ] || match[ 4 ] || match[ 5 ] || "" ); if ( match[ 2 ] === "~=" ) { match[ 3 ] = " " + match[ 3 ] + " "; } return match.slice( 0, 4 ); }, CHILD: function( match ) { /* matches from filterMatchExpr["CHILD"] 1 type (only|nth|...) 2 what (child|of-type) 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) 4 xn-component of xn+y argument ([+-]?\d*n|) 5 sign of xn-component 6 x of xn-component 7 sign of y-component 8 y of y-component */ match[ 1 ] = match[ 1 ].toLowerCase(); if ( match[ 1 ].slice( 0, 3 ) === "nth" ) { // nth-* requires argument if ( !match[ 3 ] ) { selectorError( match[ 0 ] ); } // numeric x and y parameters for jQuery.expr.filter.CHILD // remember that false/true cast respectively to 0/1 match[ 4 ] = +( match[ 4 ] ? match[ 5 ] + ( match[ 6 ] || 1 ) : 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) ); match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" ); // other types prohibit arguments } else if ( match[ 3 ] ) { selectorError( match[ 0 ] ); } return match; }, PSEUDO: function( match ) { var excess, unquoted = !match[ 6 ] && match[ 2 ]; if ( filterMatchExpr.CHILD.test( match[ 0 ] ) ) { return null; } // Accept quoted arguments as-is if ( match[ 3 ] ) { match[ 2 ] = match[ 4 ] || match[ 5 ] || ""; // Strip excess characters from unquoted arguments } else if ( unquoted && rpseudo.test( unquoted ) && // Get excess from tokenize (recursively) ( excess = tokenize( unquoted, true ) ) && // advance to the next closing parenthesis ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) { // excess is a negative index match[ 0 ] = match[ 0 ].slice( 0, excess ); match[ 2 ] = unquoted.slice( 0, excess ); } // Return only captures needed by the pseudo filter method (type and argument) return match.slice( 0, 3 ); } }; function toSelector( tokens ) { var i = 0, len = tokens.length, selector = ""; for ( ; i < len; i++ ) { selector += tokens[ i ].value; } return selector; } // Multifunctional method to get and set values of a collection // The value/s can optionally be executed if it's a function function access( elems, fn, key, value, chainable, emptyGet, raw ) { var i = 0, len = elems.length, bulk = key == null; // Sets many values if ( toType( key ) === "object" ) { chainable = true; for ( i in key ) { access( elems, fn, i, key[ i ], true, emptyGet, raw ); } // Sets one value } else if ( value !== undefined ) { chainable = true; if ( typeof value !== "function" ) { raw = true; } if ( bulk ) { // Bulk operations run against the entire set if ( raw ) { fn.call( elems, value ); fn = null; // ...except when executing function values } else { bulk = fn; fn = function( elem, _key, value ) { return bulk.call( jQuery( elem ), value ); }; } } if ( fn ) { for ( ; i < len; i++ ) { fn( elems[ i ], key, raw ? value : value.call( elems[ i ], i, fn( elems[ i ], key ) ) ); } } } if ( chainable ) { return elems; } // Gets if ( bulk ) { return fn.call( elems ); } return len ? fn( elems[ 0 ], key ) : emptyGet; } // Only count HTML whitespace // Other whitespace should count in values // https://infra.spec.whatwg.org/#ascii-whitespace var rnothtmlwhite = /[^\x20\t\r\n\f]+/g; jQuery.fn.extend( { attr: function( name, value ) { return access( this, jQuery.attr, name, value, arguments.length > 1 ); }, removeAttr: function( name ) { return this.each( function() { jQuery.removeAttr( this, name ); } ); } } ); jQuery.extend( { attr: function( elem, name, value ) { var ret, hooks, nType = elem.nodeType; // Don't get/set attributes on text, comment and attribute nodes if ( nType === 3 || nType === 8 || nType === 2 ) { return; } // Fallback to prop when attributes are not supported if ( typeof elem.getAttribute === "undefined" ) { return jQuery.prop( elem, name, value ); } // Attribute hooks are determined by the lowercase version // Grab necessary hook if one is defined if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { hooks = jQuery.attrHooks[ name.toLowerCase() ]; } if ( value !== undefined ) { if ( value === null || // For compat with previous handling of boolean attributes, // remove when `false` passed. For ARIA attributes - // many of which recognize a `"false"` value - continue to // set the `"false"` value as jQuery <4 did. ( value === false && name.toLowerCase().indexOf( "aria-" ) !== 0 ) ) { jQuery.removeAttr( elem, name ); return; } if ( hooks && "set" in hooks && ( ret = hooks.set( elem, value, name ) ) !== undefined ) { return ret; } elem.setAttribute( name, value ); return value; } if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { return ret; } ret = elem.getAttribute( name ); // Non-existent attributes return null, we normalize to undefined return ret == null ? undefined : ret; }, attrHooks: {}, removeAttr: function( elem, value ) { var name, i = 0, // Attribute names can contain non-HTML whitespace characters // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 attrNames = value && value.match( rnothtmlwhite ); if ( attrNames && elem.nodeType === 1 ) { while ( ( name = attrNames[ i++ ] ) ) { elem.removeAttribute( name ); } } } } ); // Support: IE <=11+ // An input loses its value after becoming a radio if ( isIE ) { jQuery.attrHooks.type = { set: function( elem, value ) { if ( value === "radio" && nodeName( elem, "input" ) ) { var val = elem.value; elem.setAttribute( "type", value ); if ( val ) { elem.value = val; } return value; } } }; } // CSS string/identifier serialization // https://drafts.csswg.org/cssom/#common-serializing-idioms var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g; function fcssescape( ch, asCodePoint ) { if ( asCodePoint ) { // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER if ( ch === "\0" ) { return "\uFFFD"; } // Control characters and (dependent upon position) numbers get escaped as code points return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; } // Other potentially-special ASCII characters get backslash-escaped return "\\" + ch; } jQuery.escapeSelector = function( sel ) { return ( sel + "" ).replace( rcssescape, fcssescape ); }; var sort = arr.sort; var splice = arr.splice; var hasDuplicate; // Document order sorting function sortOrder( a, b ) { // Flag for duplicate removal if ( a === b ) { hasDuplicate = true; return 0; } // Sort on method existence if only one input has compareDocumentPosition var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; if ( compare ) { return compare; } // Calculate position if both inputs belong to the same document // Support: IE 11+ // IE sometimes throws a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. // eslint-disable-next-line eqeqeq compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ? a.compareDocumentPosition( b ) : // Otherwise we know they are disconnected 1; // Disconnected nodes if ( compare & 1 ) { // Choose the first element that is related to the document // Support: IE 11+ // IE sometimes throws a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. // eslint-disable-next-line eqeqeq if ( a == document$1 || a.ownerDocument == document$1 && jQuery.contains( document$1, a ) ) { return -1; } // Support: IE 11+ // IE sometimes throws a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. // eslint-disable-next-line eqeqeq if ( b == document$1 || b.ownerDocument == document$1 && jQuery.contains( document$1, b ) ) { return 1; } // Maintain original order return 0; } return compare & 4 ? -1 : 1; } /** * Document sorting and removing duplicates * @param {ArrayLike} results */ jQuery.uniqueSort = function( results ) { var elem, duplicates = [], j = 0, i = 0; hasDuplicate = false; sort.call( results, sortOrder ); if ( hasDuplicate ) { while ( ( elem = results[ i++ ] ) ) { if ( elem === results[ i ] ) { j = duplicates.push( i ); } } while ( j-- ) { splice.call( results, duplicates[ j ], 1 ); } } return results; }; jQuery.fn.uniqueSort = function() { return this.pushStack( jQuery.uniqueSort( slice.apply( this ) ) ); }; var i, outermostContext, // Local document vars document, documentElement, documentIsHTML, // Instance-specific data dirruns = 0, done = 0, classCache = createCache(), compilerCache = createCache(), nonnativeSelectorCache = createCache(), // Regular expressions // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter rwhitespace = new RegExp( whitespace + "+", "g" ), ridentifier = new RegExp( "^" + identifier + "$" ), matchExpr = jQuery.extend( { // For use in libraries implementing .is() // We use this for POS matching in `select` needsContext: new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) }, filterMatchExpr ), rinputs = /^(?:input|select|textarea|button)$/i, rheader = /^h\d$/i, // Easily-parseable/retrievable ID or TAG or CLASS selectors rquickExpr$1 = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, // Used for iframes; see `setDocument`. // Support: IE 9 - 11+ // Removing the function wrapper causes a "Permission Denied" // error in IE. unloadHandler = function() { setDocument(); }, inDisabledFieldset = addCombinator( function( elem ) { return elem.disabled === true && nodeName( elem, "fieldset" ); }, { dir: "parentNode", next: "legend" } ); function find( selector, context, results, seed ) { var m, i, elem, nid, match, groups, newSelector, newContext = context && context.ownerDocument, // nodeType defaults to 9, since context defaults to document nodeType = context ? context.nodeType : 9; results = results || []; // Return early from calls with invalid selector or context if ( typeof selector !== "string" || !selector || nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { return results; } // Try to shortcut find operations (as opposed to filters) in HTML documents if ( !seed ) { setDocument( context ); context = context || document; if ( documentIsHTML ) { // If the selector is sufficiently simple, try using a "get*By*" DOM method // (excepting DocumentFragment context, where the methods don't exist) if ( nodeType !== 11 && ( match = rquickExpr$1.exec( selector ) ) ) { // ID selector if ( ( m = match[ 1 ] ) ) { // Document context if ( nodeType === 9 ) { if ( ( elem = context.getElementById( m ) ) ) { push.call( results, elem ); } return results; // Element context } else { if ( newContext && ( elem = newContext.getElementById( m ) ) && jQuery.contains( context, elem ) ) { push.call( results, elem ); return results; } } // Type selector } else if ( match[ 2 ] ) { push.apply( results, context.getElementsByTagName( selector ) ); return results; // Class selector } else if ( ( m = match[ 3 ] ) && context.getElementsByClassName ) { push.apply( results, context.getElementsByClassName( m ) ); return results; } } // Take advantage of querySelectorAll if ( !nonnativeSelectorCache[ selector + " " ] && ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) ) { newSelector = selector; newContext = context; // qSA considers elements outside a scoping root when evaluating child or // descendant combinators, which is not what we want. // In such cases, we work around the behavior by prefixing every selector in the // list with an ID selector referencing the scope context. // The technique has to be used as well when a leading combinator is used // as such selectors are not recognized by querySelectorAll. // Thanks to Andrew Dupont for this technique. if ( nodeType === 1 && ( rdescend.test( selector ) || rleadingCombinator.test( selector ) ) ) { // Expand context for sibling selectors newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; // Outside of IE, if we're not changing the context we can // use :scope instead of an ID. // Support: IE 11+ // IE sometimes throws a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. // eslint-disable-next-line eqeqeq if ( newContext != context || isIE ) { // Capture the context ID, setting it first if necessary if ( ( nid = context.getAttribute( "id" ) ) ) { nid = jQuery.escapeSelector( nid ); } else { context.setAttribute( "id", ( nid = jQuery.expando ) ); } } // Prefix every selector in the list groups = tokenize( selector ); i = groups.length; while ( i-- ) { groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + toSelector( groups[ i ] ); } newSelector = groups.join( "," ); } try { push.apply( results, newContext.querySelectorAll( newSelector ) ); return results; } catch ( qsaError ) { nonnativeSelectorCache( selector, true ); } finally { if ( nid === jQuery.expando ) { context.removeAttribute( "id" ); } } } } } // All others return select( selector.replace( rtrimCSS, "$1" ), context, results, seed ); } /** * Mark a function for special use by jQuery selector module * @param {Function} fn The function to mark */ function markFunction( fn ) { fn[ jQuery.expando ] = true; return fn; } /** * Returns a function to use in pseudos for input types * @param {String} type */ function createInputPseudo( type ) { return function( elem ) { return nodeName( elem, "input" ) && elem.type === type; }; } /** * Returns a function to use in pseudos for buttons * @param {String} type */ function createButtonPseudo( type ) { return function( elem ) { return ( nodeName( elem, "input" ) || nodeName( elem, "button" ) ) && elem.type === type; }; } /** * Returns a function to use in pseudos for :enabled/:disabled * @param {Boolean} disabled true for :disabled; false for :enabled */ function createDisabledPseudo( disabled ) { // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable return function( elem ) { // Only certain elements can match :enabled or :disabled // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled if ( "form" in elem ) { // Check for inherited disabledness on relevant non-disabled elements: // * listed form-associated elements in a disabled fieldset // https://html.spec.whatwg.org/multipage/forms.html#category-listed // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled // * option elements in a disabled optgroup // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled // All such elements have a "form" property. if ( elem.parentNode && elem.disabled === false ) { // Option elements defer to a parent optgroup if present if ( "label" in elem ) { if ( "label" in elem.parentNode ) { return elem.parentNode.disabled === disabled; } else { return elem.disabled === disabled; } } // Support: IE 6 - 11+ // Use the isDisabled shortcut property to check for disabled fieldset ancestors return elem.isDisabled === disabled || // Where there is no isDisabled, check manually elem.isDisabled !== !disabled && inDisabledFieldset( elem ) === disabled; } return elem.disabled === disabled; // Try to winnow out elements that can't be disabled before trusting the disabled property. // Some victims get caught in our net (label, legend, menu, track), but it shouldn't // even exist on them, let alone have a boolean value. } else if ( "label" in elem ) { return elem.disabled === disabled; } // Remaining elements are neither :enabled nor :disabled return false; }; } /** * Returns a function to use in pseudos for positionals * @param {Function} fn */ function createPositionalPseudo( fn ) { return markFunction( function( argument ) { argument = +argument; return markFunction( function( seed, matches ) { var j, matchIndexes = fn( [], seed.length, argument ), i = matchIndexes.length; // Match elements found at the specified indexes while ( i-- ) { if ( seed[ ( j = matchIndexes[ i ] ) ] ) { seed[ j ] = !( matches[ j ] = seed[ j ] ); } } } ); } ); } /** * Sets document-related variables once based on the current document * @param {Element|Object} [node] An element or document object to use to set the document */ function setDocument( node ) { var subWindow, doc = node ? node.ownerDocument || node : document$1; // Return early if doc is invalid or already selected // Support: IE 11+ // IE sometimes throws a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. // eslint-disable-next-line eqeqeq if ( doc == document || doc.nodeType !== 9 ) { return; } // Update global variables document = doc; documentElement = document.documentElement; documentIsHTML = !jQuery.isXMLDoc( document ); // Support: IE 9 - 11+ // Accessing iframe documents after unload throws "permission denied" errors (see trac-13936) // Support: IE 11+ // IE sometimes throws a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. // eslint-disable-next-line eqeqeq if ( isIE && document$1 != document && ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { subWindow.addEventListener( "unload", unloadHandler ); } } find.matches = function( expr, elements ) { return find( expr, null, null, elements ); }; find.matchesSelector = function( elem, expr ) { setDocument( elem ); if ( documentIsHTML && !nonnativeSelectorCache[ expr + " " ] && ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { try { return matches.call( elem, expr ); } catch ( e ) { nonnativeSelectorCache( expr, true ); } } return find( expr, document, null, [ elem ] ).length > 0; }; jQuery.expr = { // Can be adjusted by the user cacheLength: 50, createPseudo: markFunction, match: matchExpr, find: { ID: function( id, context ) { if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { var elem = context.getElementById( id ); return elem ? [ elem ] : []; } }, TAG: function( tag, context ) { if ( typeof context.getElementsByTagName !== "undefined" ) { return context.getElementsByTagName( tag ); // DocumentFragment nodes don't have gEBTN } else { return context.querySelectorAll( tag ); } }, CLASS: function( className, context ) { if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { return context.getElementsByClassName( className ); } } }, relative: { ">": { dir: "parentNode", first: true }, " ": { dir: "parentNode" }, "+": { dir: "previousSibling", first: true }, "~": { dir: "previousSibling" } }, preFilter: preFilter, filter: { ID: function( id ) { var attrId = unescapeSelector( id ); return function( elem ) { return elem.getAttribute( "id" ) === attrId; }; }, TAG: function( nodeNameSelector ) { var expectedNodeName = unescapeSelector( nodeNameSelector ).toLowerCase(); return nodeNameSelector === "*" ? function() { return true; } : function( elem ) { return nodeName( elem, expectedNodeName ); }; }, CLASS: function( className ) { var pattern = classCache[ className + " " ]; return pattern || ( pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" ) ) && classCache( className, function( elem ) { return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute( "class" ) || "" ); } ); }, ATTR: function( name, operator, check ) { return function( elem ) { var result = jQuery.attr( elem, name ); if ( result == null ) { return operator === "!="; } if ( !operator ) { return true; } result += ""; if ( operator === "=" ) { return result === check; } if ( operator === "!=" ) { return result !== check; } if ( operator === "^=" ) { return check && result.indexOf( check ) === 0; } if ( operator === "*=" ) { return check && result.indexOf( check ) > -1; } if ( operator === "$=" ) { return check && result.slice( -check.length ) === check; } if ( operator === "~=" ) { return ( " " + result.replace( rwhitespace, " " ) + " " ) .indexOf( check ) > -1; } if ( operator === "|=" ) { return result === check || result.slice( 0, check.length + 1 ) === check + "-"; } return false; }; }, CHILD: function( type, what, _argument, first, last ) { var simple = type.slice( 0, 3 ) !== "nth", forward = type.slice( -4 ) !== "last", ofType = what === "of-type"; return first === 1 && last === 0 ? // Shortcut for :nth-*(n) function( elem ) { return !!elem.parentNode; } : function( elem, _context, xml ) { var cache, outerCache, node, nodeIndex, start, dir = simple !== forward ? "nextSibling" : "previousSibling", parent = elem.parentNode, name = ofType && elem.nodeName.toLowerCase(), useCache = !xml && !ofType, diff = false; if ( parent ) { // :(first|last|only)-(child|of-type) if ( simple ) { while ( dir ) { node = elem; while ( ( node = node[ dir ] ) ) { if ( ofType ? nodeName( node, name ) : node.nodeType === 1 ) { return false; } } // Reverse direction for :only-* (if we haven't yet done so) start = dir = type === "only" && !start && "nextSibling"; } return true; } start = [ forward ? parent.firstChild : parent.lastChild ]; // non-xml :nth-child(...) stores cache data on `parent` if ( forward && useCache ) { // Seek `elem` from a previously-cached index outerCache = parent[ jQuery.expando ] || ( parent[ jQuery.expando ] = {} ); cache = outerCache[ type ] || []; nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; diff = nodeIndex && cache[ 2 ]; node = nodeIndex && parent.childNodes[ nodeIndex ]; while ( ( node = ++nodeIndex && node && node[ dir ] || // Fallback to seeking `elem` from the start ( diff = nodeIndex = 0 ) || start.pop() ) ) { // When found, cache indexes on `parent` and break if ( node.nodeType === 1 && ++diff && node === elem ) { outerCache[ type ] = [ dirruns, nodeIndex, diff ]; break; } } } else { // Use previously-cached element index if available if ( useCache ) { outerCache = elem[ jQuery.expando ] || ( elem[ jQuery.expando ] = {} ); cache = outerCache[ type ] || []; nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; diff = nodeIndex; } // xml :nth-child(...) // or :nth-last-child(...) or :nth(-last)?-of-type(...) if ( diff === false ) { // Use the same loop as above to seek `elem` from the start while ( ( node = ++nodeIndex && node && node[ dir ] || ( diff = nodeIndex = 0 ) || start.pop() ) ) { if ( ( ofType ? nodeName( node, name ) : node.nodeType === 1 ) && ++diff ) { // Cache the index of each encountered element if ( useCache ) { outerCache = node[ jQuery.expando ] || ( node[ jQuery.expando ] = {} ); outerCache[ type ] = [ dirruns, diff ]; } if ( node === elem ) { break; } } } } } // Incorporate the offset, then check against cycle size diff -= last; return diff === first || ( diff % first === 0 && diff / first >= 0 ); } }; }, PSEUDO: function( pseudo, argument ) { // pseudo-class names are case-insensitive // https://www.w3.org/TR/selectors/#pseudo-classes // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters // Remember that setFilters inherits from pseudos var fn = jQuery.expr.pseudos[ pseudo ] || jQuery.expr.setFilters[ pseudo.toLowerCase() ] || selectorError( "unsupported pseudo: " + pseudo ); // The user may use createPseudo to indicate that // arguments are needed to create the filter function // just as jQuery does if ( fn[ jQuery.expando ] ) { return fn( argument ); } return fn; } }, pseudos: { // Potentially complex pseudos not: markFunction( function( selector ) { // Trim the selector passed to compile // to avoid treating leading and trailing // spaces as combinators var input = [], results = [], matcher = compile( selector.replace( rtrimCSS, "$1" ) ); return matcher[ jQuery.expando ] ? markFunction( function( seed, matches, _context, xml ) { var elem, unmatched = matcher( seed, null, xml, [] ), i = seed.length; // Match elements unmatched by `matcher` while ( i-- ) { if ( ( elem = unmatched[ i ] ) ) { seed[ i ] = !( matches[ i ] = elem ); } } } ) : function( elem, _context, xml ) { input[ 0 ] = elem; matcher( input, null, xml, results ); // Don't keep the element // (see https://github.com/jquery/sizzle/issues/299) input[ 0 ] = null; return !results.pop(); }; } ), has: markFunction( function( selector ) { return function( elem ) { return find( selector, elem ).length > 0; }; } ), contains: markFunction( function( text ) { text = unescapeSelector( text ); return function( elem ) { return ( elem.textContent || jQuery.text( elem ) ).indexOf( text ) > -1; }; } ), // "Whether an element is represented by a :lang() selector // is based solely on the element's language value // being equal to the identifier C, // or beginning with the identifier C immediately followed by "-". // The matching of C against the element's language value is performed case-insensitively. // The identifier C does not have to be a valid language name." // https://www.w3.org/TR/selectors/#lang-pseudo lang: markFunction( function( lang ) { // lang value must be a valid identifier if ( !ridentifier.test( lang || "" ) ) { selectorError( "unsupported lang: " + lang ); } lang = unescapeSelector( lang ).toLowerCase(); return function( elem ) { var elemLang; do { if ( ( elemLang = documentIsHTML ? elem.lang : elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) { elemLang = elemLang.toLowerCase(); return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; } } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 ); return false; }; } ), // Miscellaneous target: function( elem ) { var hash = window.location && window.location.hash; return hash && hash.slice( 1 ) === elem.id; }, root: function( elem ) { return elem === documentElement; }, focus: function( elem ) { return elem === document.activeElement && document.hasFocus() && !!( elem.type || elem.href || ~elem.tabIndex ); }, // Boolean properties enabled: createDisabledPseudo( false ), disabled: createDisabledPseudo( true ), checked: function( elem ) { // In CSS3, :checked should return both checked and selected elements // https://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked return ( nodeName( elem, "input" ) && !!elem.checked ) || ( nodeName( elem, "option" ) && !!elem.selected ); }, selected: function( elem ) { // Support: IE <=11+ // Accessing the selectedIndex property // forces the browser to treat the default option as // selected when in an optgroup. if ( isIE && elem.parentNode ) { // eslint-disable-next-line no-unused-expressions elem.parentNode.selectedIndex; } return elem.selected === true; }, // Contents empty: function( elem ) { // https://www.w3.org/TR/selectors/#empty-pseudo // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), // but not by others (comment: 8; processing instruction: 7; etc.) // nodeType < 6 works because attributes (2) do not appear as children for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { if ( elem.nodeType < 6 ) { return false; } } return true; }, parent: function( elem ) { return !jQuery.expr.pseudos.empty( elem ); }, // Element/input types header: function( elem ) { return rheader.test( elem.nodeName ); }, input: function( elem ) { return rinputs.test( elem.nodeName ); }, button: function( elem ) { return nodeName( elem, "input" ) && elem.type === "button" || nodeName( elem, "button" ); }, text: function( elem ) { return nodeName( elem, "input" ) && elem.type === "text"; }, // Position-in-collection first: createPositionalPseudo( function() { return [ 0 ]; } ), last: createPositionalPseudo( function( _matchIndexes, length ) { return [ length - 1 ]; } ), eq: createPositionalPseudo( function( _matchIndexes, length, argument ) { return [ argument < 0 ? argument + length : argument ]; } ), even: createPositionalPseudo( function( matchIndexes, length ) { var i = 0; for ( ; i < length; i += 2 ) { matchIndexes.push( i ); } return matchIndexes; } ), odd: createPositionalPseudo( function( matchIndexes, length ) { var i = 1; for ( ; i < length; i += 2 ) { matchIndexes.push( i ); } return matchIndexes; } ), lt: createPositionalPseudo( function( matchIndexes, length, argument ) { var i; if ( argument < 0 ) { i = argument + length; } else if ( argument > length ) { i = length; } else { i = argument; } for ( ; --i >= 0; ) { matchIndexes.push( i ); } return matchIndexes; } ), gt: createPositionalPseudo( function( matchIndexes, length, argument ) { var i = argument < 0 ? argument + length : argument; for ( ; ++i < length; ) { matchIndexes.push( i ); } return matchIndexes; } ) } }; jQuery.expr.pseudos.nth = jQuery.expr.pseudos.eq; // Add button/input type pseudos for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { jQuery.expr.pseudos[ i ] = createInputPseudo( i ); } for ( i in { submit: true, reset: true } ) { jQuery.expr.pseudos[ i ] = createButtonPseudo( i ); } // Easy API for creating new setFilters function setFilters() {} setFilters.prototype = jQuery.expr.pseudos; jQuery.expr.setFilters = new setFilters(); function addCombinator( matcher, combinator, base ) { var dir = combinator.dir, skip = combinator.next, key = skip || dir, checkNonElements = base && key === "parentNode", doneName = done++; return combinator.first ? // Check against closest ancestor/preceding element function( elem, context, xml ) { while ( ( elem = elem[ dir ] ) ) { if ( elem.nodeType === 1 || checkNonElements ) { return matcher( elem, context, xml ); } } return false; } : // Check against all ancestor/preceding elements function( elem, context, xml ) { var oldCache, outerCache, newCache = [ dirruns, doneName ]; // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching if ( xml ) { while ( ( elem = elem[ dir ] ) ) { if ( elem.nodeType === 1 || checkNonElements ) { if ( matcher( elem, context, xml ) ) { return true; } } } } else { while ( ( elem = elem[ dir ] ) ) { if ( elem.nodeType === 1 || checkNonElements ) { outerCache = elem[ jQuery.expando ] || ( elem[ jQuery.expando ] = {} ); if ( skip && nodeName( elem, skip ) ) { elem = elem[ dir ] || elem; } else if ( ( oldCache = outerCache[ key ] ) && oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { // Assign to newCache so results back-propagate to previous elements return ( newCache[ 2 ] = oldCache[ 2 ] ); } else { // Reuse newcache so results back-propagate to previous elements outerCache[ key ] = newCache; // A match means we're done; a fail means we have to keep checking if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) { return true; } } } } } return false; }; } function elementMatcher( matchers ) { return matchers.length > 1 ? function( elem, context, xml ) { var i = matchers.length; while ( i-- ) { if ( !matchers[ i ]( elem, context, xml ) ) { return false; } } return true; } : matchers[ 0 ]; } function multipleContexts( selector, contexts, results ) { var i = 0, len = contexts.length; for ( ; i < len; i++ ) { find( selector, contexts[ i ], results ); } return results; } function condense( unmatched, map, filter, context, xml ) { var elem, newUnmatched = [], i = 0, len = unmatched.length, mapped = map != null; for ( ; i < len; i++ ) { if ( ( elem = unmatched[ i ] ) ) { if ( !filter || filter( elem, context, xml ) ) { newUnmatched.push( elem ); if ( mapped ) { map.push( i ); } } } } return newUnmatched; } function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { if ( postFilter && !postFilter[ jQuery.expando ] ) { postFilter = setMatcher( postFilter ); } if ( postFinder && !postFinder[ jQuery.expando ] ) { postFinder = setMatcher( postFinder, postSelector ); } return markFunction( function( seed, results, context, xml ) { var temp, i, elem, matcherOut, preMap = [], postMap = [], preexisting = results.length, // Get initial elements from seed or context elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), // Prefilter to get matcher input, preserving a map for seed-results synchronization matcherIn = preFilter && ( seed || !selector ) ? condense( elems, preMap, preFilter, context, xml ) : elems; if ( matcher ) { // If we have a postFinder, or filtered seed, or non-seed postFilter // or preexisting results, matcherOut = postFinder || ( seed ? preFilter : preexisting || postFilter ) ? // ...intermediate processing is necessary [] : // ...otherwise use results directly results; // Find primary matches matcher( matcherIn, matcherOut, context, xml ); } else { matcherOut = matcherIn; } // Apply postFilter if ( postFilter ) { temp = condense( matcherOut, postMap ); postFilter( temp, [], context, xml ); // Un-match failing elements by moving them back to matcherIn i = temp.length; while ( i-- ) { if ( ( elem = temp[ i ] ) ) { matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem ); } } } if ( seed ) { if ( postFinder || preFilter ) { if ( postFinder ) { // Get the final matcherOut by condensing this intermediate into postFinder contexts temp = []; i = matcherOut.length; while ( i-- ) { if ( ( elem = matcherOut[ i ] ) ) { // Restore matcherIn since elem is not yet a final match temp.push( ( matcherIn[ i ] = elem ) ); } } postFinder( null, ( matcherOut = [] ), temp, xml ); } // Move matched elements from seed to results to keep them synchronized i = matcherOut.length; while ( i-- ) { if ( ( elem = matcherOut[ i ] ) && ( temp = postFinder ? indexOf.call( seed, elem ) : preMap[ i ] ) > -1 ) { seed[ temp ] = !( results[ temp ] = elem ); } } } // Add elements to results, through postFinder if defined } else { matcherOut = condense( matcherOut === results ? matcherOut.splice( preexisting, matcherOut.length ) : matcherOut ); if ( postFinder ) { postFinder( null, results, matcherOut, xml ); } else { push.apply( results, matcherOut ); } } } ); } function matcherFromTokens( tokens ) { var checkContext, matcher, j, len = tokens.length, leadingRelative = jQuery.expr.relative[ tokens[ 0 ].type ], implicitRelative = leadingRelative || jQuery.expr.relative[ " " ], i = leadingRelative ? 1 : 0, // The foundational matcher ensures that elements are reachable from top-level context(s) matchContext = addCombinator( function( elem ) { return elem === checkContext; }, implicitRelative, true ), matchAnyContext = addCombinator( function( elem ) { return indexOf.call( checkContext, elem ) > -1; }, implicitRelative, true ), matchers = [ function( elem, context, xml ) { // Support: IE 11+ // IE sometimes throws a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. // eslint-disable-next-line eqeqeq var ret = ( !leadingRelative && ( xml || context != outermostContext ) ) || ( ( checkContext = context ).nodeType ? matchContext( elem, context, xml ) : matchAnyContext( elem, context, xml ) ); // Avoid hanging onto element // (see https://github.com/jquery/sizzle/issues/299) checkContext = null; return ret; } ]; for ( ; i < len; i++ ) { if ( ( matcher = jQuery.expr.relative[ tokens[ i ].type ] ) ) { matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; } else { matcher = jQuery.expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches ); // Return special upon seeing a positional matcher if ( matcher[ jQuery.expando ] ) { // Find the next relative operator (if any) for proper handling j = ++i; for ( ; j < len; j++ ) { if ( jQuery.expr.relative[ tokens[ j ].type ] ) { break; } } return setMatcher( i > 1 && elementMatcher( matchers ), i > 1 && toSelector( // If the preceding token was a descendant combinator, insert an implicit any-element `*` tokens.slice( 0, i - 1 ) .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } ) ).replace( rtrimCSS, "$1" ), matcher, i < j && matcherFromTokens( tokens.slice( i, j ) ), j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ), j < len && toSelector( tokens ) ); } matchers.push( matcher ); } } return elementMatcher( matchers ); } function matcherFromGroupMatchers( elementMatchers, setMatchers ) { var bySet = setMatchers.length > 0, byElement = elementMatchers.length > 0, superMatcher = function( seed, context, xml, results, outermost ) { var elem, j, matcher, matchedCount = 0, i = "0", unmatched = seed && [], setMatched = [], contextBackup = outermostContext, // We must always have either seed elements or outermost context elems = seed || byElement && jQuery.expr.find.TAG( "*", outermost ), // Use integer dirruns iff this is the outermost matcher dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ); if ( outermost ) { // Support: IE 11+ // IE sometimes throws a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. // eslint-disable-next-line eqeqeq outermostContext = context == document || context || outermost; } // Add elements passing elementMatchers directly to results for ( ; ( elem = elems[ i ] ) != null; i++ ) { if ( byElement && elem ) { j = 0; // Support: IE 11+ // IE sometimes throws a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. // eslint-disable-next-line eqeqeq if ( !context && elem.ownerDocument != document ) { setDocument( elem ); xml = !documentIsHTML; } while ( ( matcher = elementMatchers[ j++ ] ) ) { if ( matcher( elem, context || document, xml ) ) { push.call( results, elem ); break; } } if ( outermost ) { dirruns = dirrunsUnique; } } // Track unmatched elements for set filters if ( bySet ) { // They will have gone through all possible matchers if ( ( elem = !matcher && elem ) ) { matchedCount--; } // Lengthen the array for every element, matched or not if ( seed ) { unmatched.push( elem ); } } } // `i` is now the count of elements visited above, and adding it to `matchedCount` // makes the latter nonnegative. matchedCount += i; // Apply set filters to unmatched elements // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` // equals `i`), unless we didn't visit _any_ elements in the above loop because we have // no element matchers and no seed. // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that // case, which will result in a "00" `matchedCount` that differs from `i` but is also // numerically zero. if ( bySet && i !== matchedCount ) { j = 0; while ( ( matcher = setMatchers[ j++ ] ) ) { matcher( unmatched, setMatched, context, xml ); } if ( seed ) { // Reintegrate element matches to eliminate the need for sorting if ( matchedCount > 0 ) { while ( i-- ) { if ( !( unmatched[ i ] || setMatched[ i ] ) ) { setMatched[ i ] = pop.call( results ); } } } // Discard index placeholder values to get only actual matches setMatched = condense( setMatched ); } // Add matches to results push.apply( results, setMatched ); // Seedless set matches succeeding multiple successful matchers stipulate sorting if ( outermost && !seed && setMatched.length > 0 && ( matchedCount + setMatchers.length ) > 1 ) { jQuery.uniqueSort( results ); } } // Override manipulation of globals by nested matchers if ( outermost ) { dirruns = dirrunsUnique; outermostContext = contextBackup; } return unmatched; }; return bySet ? markFunction( superMatcher ) : superMatcher; } function compile( selector, match /* Internal Use Only */ ) { var i, setMatchers = [], elementMatchers = [], cached = compilerCache[ selector + " " ]; if ( !cached ) { // Generate a function of recursive functions that can be used to check each element if ( !match ) { match = tokenize( selector ); } i = match.length; while ( i-- ) { cached = matcherFromTokens( match[ i ] ); if ( cached[ jQuery.expando ] ) { setMatchers.push( cached ); } else { elementMatchers.push( cached ); } } // Cache the compiled function cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); // Save selector and tokenization cached.selector = selector; } return cached; } /** * A low-level selection function that works with jQuery's compiled * selector functions * @param {String|Function} selector A selector or a pre-compiled * selector function built with jQuery selector compile * @param {Element} context * @param {Array} [results] * @param {Array} [seed] A set of elements to match against */ function select( selector, context, results, seed ) { var i, tokens, token, type, find, compiled = typeof selector === "function" && selector, match = !seed && tokenize( ( selector = compiled.selector || selector ) ); results = results || []; // Try to minimize operations if there is only one selector in the list and no seed // (the latter of which guarantees us context) if ( match.length === 1 ) { // Reduce context if the leading compound selector is an ID tokens = match[ 0 ] = match[ 0 ].slice( 0 ); if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" && context.nodeType === 9 && documentIsHTML && jQuery.expr.relative[ tokens[ 1 ].type ] ) { context = ( jQuery.expr.find.ID( unescapeSelector( token.matches[ 0 ] ), context ) || [] )[ 0 ]; if ( !context ) { return results; // Precompiled matchers will still verify ancestry, so step up a level } else if ( compiled ) { context = context.parentNode; } selector = selector.slice( tokens.shift().value.length ); } // Fetch a seed set for right-to-left matching i = matchExpr.needsContext.test( selector ) ? 0 : tokens.length; while ( i-- ) { token = tokens[ i ]; // Abort if we hit a combinator if ( jQuery.expr.relative[ ( type = token.type ) ] ) { break; } if ( ( find = jQuery.expr.find[ type ] ) ) { // Search, expanding context for leading sibling combinators if ( ( seed = find( unescapeSelector( token.matches[ 0 ] ), rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) || context ) ) ) { // If seed is empty or no tokens remain, we can return early tokens.splice( i, 1 ); selector = seed.length && toSelector( tokens ); if ( !selector ) { push.apply( results, seed ); return results; } break; } } } } // Compile and execute a filtering function if one is not provided // Provide `match` to avoid retokenization if we modified the selector above ( compiled || compile( selector, match ) )( seed, context, !documentIsHTML, results, !context || rsibling.test( selector ) && testContext( context.parentNode ) || context ); return results; } // Initialize against the default document setDocument(); jQuery.find = find; // These have always been private, but they used to be documented as part of // Sizzle so let's maintain them for now for backwards compatibility purposes. find.compile = compile; find.select = select; find.setDocument = setDocument; find.tokenize = tokenize; function dir( elem, dir, until ) { var matched = [], truncate = until !== undefined; while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { if ( elem.nodeType === 1 ) { if ( truncate && jQuery( elem ).is( until ) ) { break; } matched.push( elem ); } } return matched; } function siblings( n, elem ) { var matched = []; for ( ; n; n = n.nextSibling ) { if ( n.nodeType === 1 && n !== elem ) { matched.push( n ); } } return matched; } var rneedsContext = jQuery.expr.match.needsContext; // rsingleTag matches a string consisting of a single HTML element with no attributes // and captures the element's name var rsingleTag = /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i; function isObviousHtml( input ) { return input[ 0 ] === "<" && input[ input.length - 1 ] === ">" && input.length >= 3; } // Implement the identical functionality for filter and not function winnow( elements, qualifier, not ) { if ( typeof qualifier === "function" ) { return jQuery.grep( elements, function( elem, i ) { return !!qualifier.call( elem, i, elem ) !== not; } ); } // Single element if ( qualifier.nodeType ) { return jQuery.grep( elements, function( elem ) { return ( elem === qualifier ) !== not; } ); } // Arraylike of elements (jQuery, arguments, Array) if ( typeof qualifier !== "string" ) { return jQuery.grep( elements, function( elem ) { return ( indexOf.call( qualifier, elem ) > -1 ) !== not; } ); } // Filtered directly for both simple and complex selectors return jQuery.filter( qualifier, elements, not ); } jQuery.filter = function( expr, elems, not ) { var elem = elems[ 0 ]; if ( not ) { expr = ":not(" + expr + ")"; } if ( elems.length === 1 && elem.nodeType === 1 ) { return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; } return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { return elem.nodeType === 1; } ) ); }; jQuery.fn.extend( { find: function( selector ) { var i, ret, len = this.length, self = this; if ( typeof selector !== "string" ) { return this.pushStack( jQuery( selector ).filter( function() { for ( i = 0; i < len; i++ ) { if ( jQuery.contains( self[ i ], this ) ) { return true; } } } ) ); } ret = this.pushStack( [] ); for ( i = 0; i < len; i++ ) { jQuery.find( selector, self[ i ], ret ); } return len > 1 ? jQuery.uniqueSort( ret ) : ret; }, filter: function( selector ) { return this.pushStack( winnow( this, selector || [], false ) ); }, not: function( selector ) { return this.pushStack( winnow( this, selector || [], true ) ); }, is: function( selector ) { return !!winnow( this, // If this is a positional/relative selector, check membership in the returned set // so $("p:first").is("p:last") won't return true for a doc with two "p". typeof selector === "string" && rneedsContext.test( selector ) ? jQuery( selector ) : selector || [], false ).length; } } ); // Initialize a jQuery object // A central reference to the root jQuery(document) var rootjQuery, // A simple way to check for HTML strings // Prioritize #id over to avoid XSS via location.hash (trac-9521) // Strict HTML recognition (trac-11290: must start with <) // Shortcut simple #id case for speed rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, init = jQuery.fn.init = function( selector, context ) { var match, elem; // HANDLE: $(""), $(null), $(undefined), $(false) if ( !selector ) { return this; } // HANDLE: $(DOMElement) if ( selector.nodeType ) { this[ 0 ] = selector; this.length = 1; return this; // HANDLE: $(function) // Shortcut for document ready } else if ( typeof selector === "function" ) { return rootjQuery.ready !== undefined ? rootjQuery.ready( selector ) : // Execute immediately if ready is not present selector( jQuery ); } else { // Handle obvious HTML strings match = selector + ""; if ( isObviousHtml( match ) ) { // Assume that strings that start and end with <> are HTML and skip // the regex check. This also handles browser-supported HTML wrappers // like TrustedHTML. match = [ null, selector, null ]; // Handle HTML strings or selectors } else if ( typeof selector === "string" ) { match = rquickExpr.exec( selector ); } else { return jQuery.makeArray( selector, this ); } // Match html or make sure no context is specified for #id // Note: match[1] may be a string or a TrustedHTML wrapper if ( match && ( match[ 1 ] || !context ) ) { // HANDLE: $(html) -> $(array) if ( match[ 1 ] ) { context = context instanceof jQuery ? context[ 0 ] : context; // Option to run scripts is true for back-compat // Intentionally let the error be thrown if parseHTML is not present jQuery.merge( this, jQuery.parseHTML( match[ 1 ], context && context.nodeType ? context.ownerDocument || context : document$1, true ) ); // HANDLE: $(html, props) if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { for ( match in context ) { // Properties of context are called as methods if possible if ( typeof this[ match ] === "function" ) { this[ match ]( context[ match ] ); // ...and otherwise set as attributes } else { this.attr( match, context[ match ] ); } } } return this; // HANDLE: $(#id) } else { elem = document$1.getElementById( match[ 2 ] ); if ( elem ) { // Inject the element directly into the jQuery object this[ 0 ] = elem; this.length = 1; } return this; } // HANDLE: $(expr) & $(expr, $(...)) } else if ( !context || context.jquery ) { return ( context || rootjQuery ).find( selector ); // HANDLE: $(expr, context) // (which is just equivalent to: $(context).find(expr) } else { return this.constructor( context ).find( selector ); } } }; // Give the init function the jQuery prototype for later instantiation init.prototype = jQuery.fn; // Initialize central reference rootjQuery = jQuery( document$1 ); var rparentsprev = /^(?:parents|prev(?:Until|All))/, // Methods guaranteed to produce a unique set when starting from a unique set guaranteedUnique = { children: true, contents: true, next: true, prev: true }; jQuery.fn.extend( { has: function( target ) { var targets = jQuery( target, this ), l = targets.length; return this.filter( function() { var i = 0; for ( ; i < l; i++ ) { if ( jQuery.contains( this, targets[ i ] ) ) { return true; } } } ); }, closest: function( selectors, context ) { var cur, i = 0, l = this.length, matched = [], targets = typeof selectors !== "string" && jQuery( selectors ); // Positional selectors never match, since there's no _selection_ context if ( !rneedsContext.test( selectors ) ) { for ( ; i < l; i++ ) { for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { // Always skip document fragments if ( cur.nodeType < 11 && ( targets ? targets.index( cur ) > -1 : // Don't pass non-elements to jQuery#find cur.nodeType === 1 && jQuery.find.matchesSelector( cur, selectors ) ) ) { matched.push( cur ); break; } } } } return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); }, // Determine the position of an element within the set index: function( elem ) { // No argument, return index in parent if ( !elem ) { return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; } // Index in selector if ( typeof elem === "string" ) { return indexOf.call( jQuery( elem ), this[ 0 ] ); } // Locate the position of the desired element return indexOf.call( this, // If it receives a jQuery object, the first element is used elem.jquery ? elem[ 0 ] : elem ); }, add: function( selector, context ) { return this.pushStack( jQuery.uniqueSort( jQuery.merge( this.get(), jQuery( selector, context ) ) ) ); }, addBack: function( selector ) { return this.add( selector == null ? this.prevObject : this.prevObject.filter( selector ) ); } } ); function sibling( cur, dir ) { while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} return cur; } jQuery.each( { parent: function( elem ) { var parent = elem.parentNode; return parent && parent.nodeType !== 11 ? parent : null; }, parents: function( elem ) { return dir( elem, "parentNode" ); }, parentsUntil: function( elem, _i, until ) { return dir( elem, "parentNode", until ); }, next: function( elem ) { return sibling( elem, "nextSibling" ); }, prev: function( elem ) { return sibling( elem, "previousSibling" ); }, nextAll: function( elem ) { return dir( elem, "nextSibling" ); }, prevAll: function( elem ) { return dir( elem, "previousSibling" ); }, nextUntil: function( elem, _i, until ) { return dir( elem, "nextSibling", until ); }, prevUntil: function( elem, _i, until ) { return dir( elem, "previousSibling", until ); }, siblings: function( elem ) { return siblings( ( elem.parentNode || {} ).firstChild, elem ); }, children: function( elem ) { return siblings( elem.firstChild ); }, contents: function( elem ) { if ( elem.contentDocument != null && // Support: IE 11+ // elements with no `data` attribute has an object // `contentDocument` with a `null` prototype. getProto( elem.contentDocument ) ) { return elem.contentDocument; } // Support: IE 9 - 11+ // Treat the template element as a regular one in browsers that // don't support it. if ( nodeName( elem, "template" ) ) { elem = elem.content || elem; } return jQuery.merge( [], elem.childNodes ); } }, function( name, fn ) { jQuery.fn[ name ] = function( until, selector ) { var matched = jQuery.map( this, fn, until ); if ( name.slice( -5 ) !== "Until" ) { selector = until; } if ( selector && typeof selector === "string" ) { matched = jQuery.filter( selector, matched ); } if ( this.length > 1 ) { // Remove duplicates if ( !guaranteedUnique[ name ] ) { jQuery.uniqueSort( matched ); } // Reverse order for parents* and prev-derivatives if ( rparentsprev.test( name ) ) { matched.reverse(); } } return this.pushStack( matched ); }; } ); // Convert String-formatted options into Object-formatted ones function createOptions( options ) { var object = {}; jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { object[ flag ] = true; } ); return object; } /* * Create a callback list using the following parameters: * * options: an optional list of space-separated options that will change how * the callback list behaves or a more traditional option object * * By default a callback list will act like an event callback list and can be * "fired" multiple times. * * Possible options: * * once: will ensure the callback list can only be fired once (like a Deferred) * * memory: will keep track of previous values and will call any callback added * after the list has been fired right away with the latest "memorized" * values (like a Deferred) * * unique: will ensure a callback can only be added once (no duplicate in the list) * * stopOnFalse: interrupt callings when a callback returns false * */ jQuery.Callbacks = function( options ) { // Convert options from String-formatted to Object-formatted if needed // (we check in cache first) options = typeof options === "string" ? createOptions( options ) : jQuery.extend( {}, options ); var // Flag to know if list is currently firing firing, // Last fire value for non-forgettable lists memory, // Flag to know if list was already fired fired, // Flag to prevent firing locked, // Actual callback list list = [], // Queue of execution data for repeatable lists queue = [], // Index of currently firing callback (modified by add/remove as needed) firingIndex = -1, // Fire callbacks fire = function() { // Enforce single-firing locked = locked || options.once; // Execute callbacks for all pending executions, // respecting firingIndex overrides and runtime changes fired = firing = true; for ( ; queue.length; firingIndex = -1 ) { memory = queue.shift(); while ( ++firingIndex < list.length ) { // Run callback and check for early termination if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && options.stopOnFalse ) { // Jump to end and forget the data so .add doesn't re-fire firingIndex = list.length; memory = false; } } } // Forget the data if we're done with it if ( !options.memory ) { memory = false; } firing = false; // Clean up if we're done firing for good if ( locked ) { // Keep an empty list if we have data for future add calls if ( memory ) { list = []; // Otherwise, this object is spent } else { list = ""; } } }, // Actual Callbacks object self = { // Add a callback or a collection of callbacks to the list add: function() { if ( list ) { // If we have memory from a past run, we should fire after adding if ( memory && !firing ) { firingIndex = list.length - 1; queue.push( memory ); } ( function add( args ) { jQuery.each( args, function( _, arg ) { if ( typeof arg === "function" ) { if ( !options.unique || !self.has( arg ) ) { list.push( arg ); } } else if ( arg && arg.length && toType( arg ) !== "string" ) { // Inspect recursively add( arg ); } } ); } )( arguments ); if ( memory && !firing ) { fire(); } } return this; }, // Remove a callback from the list remove: function() { jQuery.each( arguments, function( _, arg ) { var index; while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { list.splice( index, 1 ); // Handle firing indexes if ( index <= firingIndex ) { firingIndex--; } } } ); return this; }, // Check if a given callback is in the list. // If no argument is given, return whether or not list has callbacks attached. has: function( fn ) { return fn ? jQuery.inArray( fn, list ) > -1 : list.length > 0; }, // Remove all callbacks from the list empty: function() { if ( list ) { list = []; } return this; }, // Disable .fire and .add // Abort any current/pending executions // Clear all callbacks and values disable: function() { locked = queue = []; list = memory = ""; return this; }, disabled: function() { return !list; }, // Disable .fire // Also disable .add unless we have memory (since it would have no effect) // Abort any pending executions lock: function() { locked = queue = []; if ( !memory && !firing ) { list = memory = ""; } return this; }, locked: function() { return !!locked; }, // Call all callbacks with the given context and arguments fireWith: function( context, args ) { if ( !locked ) { args = args || []; args = [ context, args.slice ? args.slice() : args ]; queue.push( args ); if ( !firing ) { fire(); } } return this; }, // Call all the callbacks with the given arguments fire: function() { self.fireWith( this, arguments ); return this; }, // To know if the callbacks have already been called at least once fired: function() { return !!fired; } }; return self; }; function Identity( v ) { return v; } function Thrower( ex ) { throw ex; } function adoptValue( value, resolve, reject, noValue ) { var method; try { // Check for promise aspect first to privilege synchronous behavior if ( value && typeof( method = value.promise ) === "function" ) { method.call( value ).done( resolve ).fail( reject ); // Other thenables } else if ( value && typeof( method = value.then ) === "function" ) { method.call( value, resolve, reject ); // Other non-thenables } else { // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: // * false: [ value ].slice( 0 ) => resolve( value ) // * true: [ value ].slice( 1 ) => resolve() resolve.apply( undefined, [ value ].slice( noValue ) ); } // For Promises/A+, convert exceptions into rejections // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in // Deferred#then to conditionally suppress rejection. } catch ( value ) { reject( value ); } } jQuery.extend( { Deferred: function( func ) { var tuples = [ // action, add listener, callbacks, // ... .then handlers, argument index, [final state] [ "notify", "progress", jQuery.Callbacks( "memory" ), jQuery.Callbacks( "memory" ), 2 ], [ "resolve", "done", jQuery.Callbacks( "once memory" ), jQuery.Callbacks( "once memory" ), 0, "resolved" ], [ "reject", "fail", jQuery.Callbacks( "once memory" ), jQuery.Callbacks( "once memory" ), 1, "rejected" ] ], state = "pending", promise = { state: function() { return state; }, always: function() { deferred.done( arguments ).fail( arguments ); return this; }, catch: function( fn ) { return promise.then( null, fn ); }, // Keep pipe for back-compat pipe: function( /* fnDone, fnFail, fnProgress */ ) { var fns = arguments; return jQuery.Deferred( function( newDefer ) { jQuery.each( tuples, function( _i, tuple ) { // Map tuples (progress, done, fail) to arguments (done, fail, progress) var fn = typeof fns[ tuple[ 4 ] ] === "function" && fns[ tuple[ 4 ] ]; // deferred.progress(function() { bind to newDefer or newDefer.notify }) // deferred.done(function() { bind to newDefer or newDefer.resolve }) // deferred.fail(function() { bind to newDefer or newDefer.reject }) deferred[ tuple[ 1 ] ]( function() { var returned = fn && fn.apply( this, arguments ); if ( returned && typeof returned.promise === "function" ) { returned.promise() .progress( newDefer.notify ) .done( newDefer.resolve ) .fail( newDefer.reject ); } else { newDefer[ tuple[ 0 ] + "With" ]( this, fn ? [ returned ] : arguments ); } } ); } ); fns = null; } ).promise(); }, then: function( onFulfilled, onRejected, onProgress ) { var maxDepth = 0; function resolve( depth, deferred, handler, special ) { return function() { var that = this, args = arguments, mightThrow = function() { var returned, then; // Support: Promises/A+ section 2.3.3.3.3 // https://promisesaplus.com/#point-59 // Ignore double-resolution attempts if ( depth < maxDepth ) { return; } returned = handler.apply( that, args ); // Support: Promises/A+ section 2.3.1 // https://promisesaplus.com/#point-48 if ( returned === deferred.promise() ) { throw new TypeError( "Thenable self-resolution" ); } // Support: Promises/A+ sections 2.3.3.1, 3.5 // https://promisesaplus.com/#point-54 // https://promisesaplus.com/#point-75 // Retrieve `then` only once then = returned && // Support: Promises/A+ section 2.3.4 // https://promisesaplus.com/#point-64 // Only check objects and functions for thenability ( typeof returned === "object" || typeof returned === "function" ) && returned.then; // Handle a returned thenable if ( typeof then === "function" ) { // Special processors (notify) just wait for resolution if ( special ) { then.call( returned, resolve( maxDepth, deferred, Identity, special ), resolve( maxDepth, deferred, Thrower, special ) ); // Normal processors (resolve) also hook into progress } else { // ...and disregard older resolution values maxDepth++; then.call( returned, resolve( maxDepth, deferred, Identity, special ), resolve( maxDepth, deferred, Thrower, special ), resolve( maxDepth, deferred, Identity, deferred.notifyWith ) ); } // Handle all other returned values } else { // Only substitute handlers pass on context // and multiple values (non-spec behavior) if ( handler !== Identity ) { that = undefined; args = [ returned ]; } // Process the value(s) // Default process is resolve ( special || deferred.resolveWith )( that, args ); } }, // Only normal processors (resolve) catch and reject exceptions process = special ? mightThrow : function() { try { mightThrow(); } catch ( e ) { if ( jQuery.Deferred.exceptionHook ) { jQuery.Deferred.exceptionHook( e, process.error ); } // Support: Promises/A+ section 2.3.3.3.4.1 // https://promisesaplus.com/#point-61 // Ignore post-resolution exceptions if ( depth + 1 >= maxDepth ) { // Only substitute handlers pass on context // and multiple values (non-spec behavior) if ( handler !== Thrower ) { that = undefined; args = [ e ]; } deferred.rejectWith( that, args ); } } }; // Support: Promises/A+ section 2.3.3.3.1 // https://promisesaplus.com/#point-57 // Re-resolve promises immediately to dodge false rejection from // subsequent errors if ( depth ) { process(); } else { // Call an optional hook to record the error, in case of exception // since it's otherwise lost when execution goes async if ( jQuery.Deferred.getErrorHook ) { process.error = jQuery.Deferred.getErrorHook(); } window.setTimeout( process ); } }; } return jQuery.Deferred( function( newDefer ) { // progress_handlers.add( ... ) tuples[ 0 ][ 3 ].add( resolve( 0, newDefer, typeof onProgress === "function" ? onProgress : Identity, newDefer.notifyWith ) ); // fulfilled_handlers.add( ... ) tuples[ 1 ][ 3 ].add( resolve( 0, newDefer, typeof onFulfilled === "function" ? onFulfilled : Identity ) ); // rejected_handlers.add( ... ) tuples[ 2 ][ 3 ].add( resolve( 0, newDefer, typeof onRejected === "function" ? onRejected : Thrower ) ); } ).promise(); }, // Get a promise for this deferred // If obj is provided, the promise aspect is added to the object promise: function( obj ) { return obj != null ? jQuery.extend( obj, promise ) : promise; } }, deferred = {}; // Add list-specific methods jQuery.each( tuples, function( i, tuple ) { var list = tuple[ 2 ], stateString = tuple[ 5 ]; // promise.progress = list.add // promise.done = list.add // promise.fail = list.add promise[ tuple[ 1 ] ] = list.add; // Handle state if ( stateString ) { list.add( function() { // state = "resolved" (i.e., fulfilled) // state = "rejected" state = stateString; }, // rejected_callbacks.disable // fulfilled_callbacks.disable tuples[ 3 - i ][ 2 ].disable, // rejected_handlers.disable // fulfilled_handlers.disable tuples[ 3 - i ][ 3 ].disable, // progress_callbacks.lock tuples[ 0 ][ 2 ].lock, // progress_handlers.lock tuples[ 0 ][ 3 ].lock ); } // progress_handlers.fire // fulfilled_handlers.fire // rejected_handlers.fire list.add( tuple[ 3 ].fire ); // deferred.notify = function() { deferred.notifyWith(...) } // deferred.resolve = function() { deferred.resolveWith(...) } // deferred.reject = function() { deferred.rejectWith(...) } deferred[ tuple[ 0 ] ] = function() { deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); return this; }; // deferred.notifyWith = list.fireWith // deferred.resolveWith = list.fireWith // deferred.rejectWith = list.fireWith deferred[ tuple[ 0 ] + "With" ] = list.fireWith; } ); // Make the deferred a promise promise.promise( deferred ); // Call given func if any if ( func ) { func.call( deferred, deferred ); } // All done! return deferred; }, // Deferred helper when: function( singleValue ) { var // count of uncompleted subordinates remaining = arguments.length, // count of unprocessed arguments i = remaining, // subordinate fulfillment data resolveContexts = Array( i ), resolveValues = slice.call( arguments ), // the primary Deferred primary = jQuery.Deferred(), // subordinate callback factory updateFunc = function( i ) { return function( value ) { resolveContexts[ i ] = this; resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; if ( !( --remaining ) ) { primary.resolveWith( resolveContexts, resolveValues ); } }; }; // Single- and empty arguments are adopted like Promise.resolve if ( remaining <= 1 ) { adoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject, !remaining ); // Use .then() to unwrap secondary thenables (cf. gh-3000) if ( primary.state() === "pending" || typeof( resolveValues[ i ] && resolveValues[ i ].then ) === "function" ) { return primary.then(); } } // Multiple arguments are aggregated like Promise.all array elements while ( i-- ) { adoptValue( resolveValues[ i ], updateFunc( i ), primary.reject ); } return primary.promise(); } } ); // These usually indicate a programmer mistake during development, // warn about them ASAP rather than swallowing them by default. var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; // If `jQuery.Deferred.getErrorHook` is defined, `asyncError` is an error // captured before the async barrier to get the original error cause // which may otherwise be hidden. jQuery.Deferred.exceptionHook = function( error, asyncError ) { if ( error && rerrorNames.test( error.name ) ) { window.console.warn( "jQuery.Deferred exception", error, asyncError ); } }; jQuery.readyException = function( error ) { window.setTimeout( function() { throw error; } ); }; // The deferred used on DOM ready var readyList = jQuery.Deferred(); jQuery.fn.ready = function( fn ) { readyList .then( fn ) // Wrap jQuery.readyException in a function so that the lookup // happens at the time of error handling instead of callback // registration. .catch( function( error ) { jQuery.readyException( error ); } ); return this; }; jQuery.extend( { // Is the DOM ready to be used? Set to true once it occurs. isReady: false, // A counter to track how many items to wait for before // the ready event fires. See trac-6781 readyWait: 1, // Handle when the DOM is ready ready: function( wait ) { // Abort if there are pending holds or we're already ready if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { return; } // Remember that the DOM is ready jQuery.isReady = true; // If a normal DOM Ready event fired, decrement, and wait if need be if ( wait !== true && --jQuery.readyWait > 0 ) { return; } // If there are functions bound, to execute readyList.resolveWith( document$1, [ jQuery ] ); } } ); jQuery.ready.then = readyList.then; // The ready event handler and self cleanup method function completed() { document$1.removeEventListener( "DOMContentLoaded", completed ); window.removeEventListener( "load", completed ); jQuery.ready(); } // Catch cases where $(document).ready() is called // after the browser event has already occurred. if ( document$1.readyState !== "loading" ) { // Handle it asynchronously to allow scripts the opportunity to delay ready window.setTimeout( jQuery.ready ); } else { // Use the handy event callback document$1.addEventListener( "DOMContentLoaded", completed ); // A fallback to window.onload, that will always work window.addEventListener( "load", completed ); } // Matches dashed string for camelizing var rdashAlpha = /-([a-z])/g; // Used by camelCase as callback to replace() function fcamelCase( _all, letter ) { return letter.toUpperCase(); } // Convert dashed to camelCase function camelCase( string ) { return string.replace( rdashAlpha, fcamelCase ); } /** * Determines whether an object can have data */ function acceptData( owner ) { // Accepts only: // - Node // - Node.ELEMENT_NODE // - Node.DOCUMENT_NODE // - Object // - Any return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); } function Data() { this.expando = jQuery.expando + Data.uid++; } Data.uid = 1; Data.prototype = { cache: function( owner ) { // Check if the owner object already has a cache var value = owner[ this.expando ]; // If not, create one if ( !value ) { value = Object.create( null ); // We can accept data for non-element nodes in modern browsers, // but we should not, see trac-8335. // Always return an empty object. if ( acceptData( owner ) ) { // If it is a node unlikely to be stringify-ed or looped over // use plain assignment if ( owner.nodeType ) { owner[ this.expando ] = value; // Otherwise secure it in a non-enumerable property // configurable must be true to allow the property to be // deleted when data is removed } else { Object.defineProperty( owner, this.expando, { value: value, configurable: true } ); } } } return value; }, set: function( owner, data, value ) { var prop, cache = this.cache( owner ); // Handle: [ owner, key, value ] args // Always use camelCase key (gh-2257) if ( typeof data === "string" ) { cache[ camelCase( data ) ] = value; // Handle: [ owner, { properties } ] args } else { // Copy the properties one-by-one to the cache object for ( prop in data ) { cache[ camelCase( prop ) ] = data[ prop ]; } } return value; }, get: function( owner, key ) { return key === undefined ? this.cache( owner ) : // Always use camelCase key (gh-2257) owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; }, access: function( owner, key, value ) { // In cases where either: // // 1. No key was specified // 2. A string key was specified, but no value provided // // Take the "read" path and allow the get method to determine // which value to return, respectively either: // // 1. The entire cache object // 2. The data stored at the key // if ( key === undefined || ( ( key && typeof key === "string" ) && value === undefined ) ) { return this.get( owner, key ); } // When the key is not a string, or both a key and value // are specified, set or extend (existing objects) with either: // // 1. An object of properties // 2. A key and value // this.set( owner, key, value ); // Since the "set" path can have two possible entry points // return the expected data based on which path was taken[*] return value !== undefined ? value : key; }, remove: function( owner, key ) { var i, cache = owner[ this.expando ]; if ( cache === undefined ) { return; } if ( key !== undefined ) { // Support array or space separated string of keys if ( Array.isArray( key ) ) { // If key is an array of keys... // We always set camelCase keys, so remove that. key = key.map( camelCase ); } else { key = camelCase( key ); // If a key with the spaces exists, use it. // Otherwise, create an array by matching non-whitespace key = key in cache ? [ key ] : ( key.match( rnothtmlwhite ) || [] ); } i = key.length; while ( i-- ) { delete cache[ key[ i ] ]; } } // Remove the expando if there's no more data if ( key === undefined || jQuery.isEmptyObject( cache ) ) { // Support: Chrome <=35 - 45+ // Webkit & Blink performance suffers when deleting properties // from DOM nodes, so set to undefined instead // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) if ( owner.nodeType ) { owner[ this.expando ] = undefined; } else { delete owner[ this.expando ]; } } }, hasData: function( owner ) { var cache = owner[ this.expando ]; return cache !== undefined && !jQuery.isEmptyObject( cache ); } }; var dataPriv = new Data(); var dataUser = new Data(); // Implementation Summary // // 1. Enforce API surface and semantic compatibility with 1.9.x branch // 2. Improve the module's maintainability by reducing the storage // paths to a single mechanism. // 3. Use the same single mechanism to support "private" and "user" data. // 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) // 5. Avoid exposing implementation details on user objects (eg. expando properties) // 6. Provide a clear path for implementation upgrade to WeakMap in 2014 var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, rmultiDash = /[A-Z]/g; function getData( data ) { if ( data === "true" ) { return true; } if ( data === "false" ) { return false; } if ( data === "null" ) { return null; } // Only convert to a number if it doesn't change the string if ( data === +data + "" ) { return +data; } if ( rbrace.test( data ) ) { return JSON.parse( data ); } return data; } function dataAttr( elem, key, data ) { var name; // If nothing was found internally, try to fetch any // data from the HTML5 data-* attribute if ( data === undefined && elem.nodeType === 1 ) { name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); data = elem.getAttribute( name ); if ( typeof data === "string" ) { try { data = getData( data ); } catch ( e ) {} // Make sure we set the data so it isn't changed later dataUser.set( elem, key, data ); } else { data = undefined; } } return data; } jQuery.extend( { hasData: function( elem ) { return dataUser.hasData( elem ) || dataPriv.hasData( elem ); }, data: function( elem, name, data ) { return dataUser.access( elem, name, data ); }, removeData: function( elem, name ) { dataUser.remove( elem, name ); }, // TODO: Now that all calls to _data and _removeData have been replaced // with direct calls to dataPriv methods, these can be deprecated. _data: function( elem, name, data ) { return dataPriv.access( elem, name, data ); }, _removeData: function( elem, name ) { dataPriv.remove( elem, name ); } } ); jQuery.fn.extend( { data: function( key, value ) { var i, name, data, elem = this[ 0 ], attrs = elem && elem.attributes; // Gets all values if ( key === undefined ) { if ( this.length ) { data = dataUser.get( elem ); if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { i = attrs.length; while ( i-- ) { // Support: IE 11+ // The attrs elements can be null (trac-14894) if ( attrs[ i ] ) { name = attrs[ i ].name; if ( name.indexOf( "data-" ) === 0 ) { name = camelCase( name.slice( 5 ) ); dataAttr( elem, name, data[ name ] ); } } } dataPriv.set( elem, "hasDataAttrs", true ); } } return data; } // Sets multiple values if ( typeof key === "object" ) { return this.each( function() { dataUser.set( this, key ); } ); } return access( this, function( value ) { var data; // The calling jQuery object (element matches) is not empty // (and therefore has an element appears at this[ 0 ]) and the // `value` parameter was not undefined. An empty jQuery object // will result in `undefined` for elem = this[ 0 ] which will // throw an exception if an attempt to read a data cache is made. if ( elem && value === undefined ) { // Attempt to get data from the cache // The key will always be camelCased in Data data = dataUser.get( elem, key ); if ( data !== undefined ) { return data; } // Attempt to "discover" the data in // HTML5 custom data-* attrs data = dataAttr( elem, key ); if ( data !== undefined ) { return data; } // We tried really hard, but the data doesn't exist. return; } // Set the data... this.each( function() { // We always store the camelCased key dataUser.set( this, key, value ); } ); }, null, value, arguments.length > 1, null, true ); }, removeData: function( key ) { return this.each( function() { dataUser.remove( this, key ); } ); } } ); jQuery.extend( { queue: function( elem, type, data ) { var queue; if ( elem ) { type = ( type || "fx" ) + "queue"; queue = dataPriv.get( elem, type ); // Speed up dequeue by getting out quickly if this is just a lookup if ( data ) { if ( !queue || Array.isArray( data ) ) { queue = dataPriv.set( elem, type, jQuery.makeArray( data ) ); } else { queue.push( data ); } } return queue || []; } }, dequeue: function( elem, type ) { type = type || "fx"; var queue = jQuery.queue( elem, type ), startLength = queue.length, fn = queue.shift(), hooks = jQuery._queueHooks( elem, type ), next = function() { jQuery.dequeue( elem, type ); }; // If the fx queue is dequeued, always remove the progress sentinel if ( fn === "inprogress" ) { fn = queue.shift(); startLength--; } if ( fn ) { // Add a progress sentinel to prevent the fx queue from being // automatically dequeued if ( type === "fx" ) { queue.unshift( "inprogress" ); } // Clear up the last queue stop function delete hooks.stop; fn.call( elem, next, hooks ); } if ( !startLength && hooks ) { hooks.empty.fire(); } }, // Not public - generate a queueHooks object, or return the current one _queueHooks: function( elem, type ) { var key = type + "queueHooks"; return dataPriv.get( elem, key ) || dataPriv.set( elem, key, { empty: jQuery.Callbacks( "once memory" ).add( function() { dataPriv.remove( elem, [ type + "queue", key ] ); } ) } ); } } ); jQuery.fn.extend( { queue: function( type, data ) { var setter = 2; if ( typeof type !== "string" ) { data = type; type = "fx"; setter--; } if ( arguments.length < setter ) { return jQuery.queue( this[ 0 ], type ); } return data === undefined ? this : this.each( function() { var queue = jQuery.queue( this, type, data ); // Ensure a hooks for this queue jQuery._queueHooks( this, type ); if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { jQuery.dequeue( this, type ); } } ); }, dequeue: function( type ) { return this.each( function() { jQuery.dequeue( this, type ); } ); }, clearQueue: function( type ) { return this.queue( type || "fx", [] ); }, // Get a promise resolved when queues of a certain type // are emptied (fx is the type by default) promise: function( type, obj ) { var tmp, count = 1, defer = jQuery.Deferred(), elements = this, i = this.length, resolve = function() { if ( !( --count ) ) { defer.resolveWith( elements, [ elements ] ); } }; if ( typeof type !== "string" ) { obj = type; type = undefined; } type = type || "fx"; while ( i-- ) { tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); if ( tmp && tmp.empty ) { count++; tmp.empty.add( resolve ); } } resolve(); return defer.promise( obj ); } } ); var pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source; var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; // isHiddenWithinTree reports if an element has a non-"none" display style (inline and/or // through the CSS cascade), which is useful in deciding whether or not to make it visible. // It differs from the :hidden selector (jQuery.expr.pseudos.hidden) in two important ways: // * A hidden ancestor does not force an element to be classified as hidden. // * Being disconnected from the document does not force an element to be classified as hidden. // These differences improve the behavior of .toggle() et al. when applied to elements that are // detached or contained within hidden ancestors (gh-2404, gh-2863). function isHiddenWithinTree( elem, el ) { // isHiddenWithinTree might be called from jQuery#filter function; // in that case, element will be second argument elem = el || elem; // Inline style trumps all return elem.style.display === "none" || elem.style.display === "" && jQuery.css( elem, "display" ) === "none"; } var ralphaStart = /^[a-z]/, // The regex visualized: // // /----------\ // | | /-------\ // | / Top \ | | | // /--- Border ---+-| Right |-+---+- Width -+---\ // | | Bottom | | // | \ Left / | // | | // | /----------\ | // | /-------------\ | | |- END // | | | | / Top \ | | // | | / Margin \ | | | Right | | | // |---------+-| |-+---+-| Bottom |-+----| // | \ Padding / \ Left / | // BEGIN -| | // | /---------\ | // | | | | // | | / Min \ | / Width \ | // \--------------+-| |-+---| |---/ // \ Max / \ Height / rautoPx = /^(?:Border(?:Top|Right|Bottom|Left)?(?:Width|)|(?:Margin|Padding)?(?:Top|Right|Bottom|Left)?|(?:Min|Max)?(?:Width|Height))$/; function isAutoPx( prop ) { // The first test is used to ensure that: // 1. The prop starts with a lowercase letter (as we uppercase it for the second regex). // 2. The prop is not empty. return ralphaStart.test( prop ) && rautoPx.test( prop[ 0 ].toUpperCase() + prop.slice( 1 ) ); } function adjustCSS( elem, prop, valueParts, tween ) { var adjusted, scale, maxIterations = 20, currentValue = tween ? function() { return tween.cur(); } : function() { return jQuery.css( elem, prop, "" ); }, initial = currentValue(), unit = valueParts && valueParts[ 3 ] || ( isAutoPx( prop ) ? "px" : "" ), // Starting value computation is required for potential unit mismatches initialInUnit = elem.nodeType && ( !isAutoPx( prop ) || unit !== "px" && +initial ) && rcssNum.exec( jQuery.css( elem, prop ) ); if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { // Support: Firefox <=54 - 66+ // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) initial = initial / 2; // Trust units reported by jQuery.css unit = unit || initialInUnit[ 3 ]; // Iteratively approximate from a nonzero starting point initialInUnit = +initial || 1; while ( maxIterations-- ) { // Evaluate and update our best guess (doubling guesses that zero out). // Finish if the scale equals or crosses 1 (making the old*new product non-positive). jQuery.style( elem, prop, initialInUnit + unit ); if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { maxIterations = 0; } initialInUnit = initialInUnit / scale; } initialInUnit = initialInUnit * 2; jQuery.style( elem, prop, initialInUnit + unit ); // Make sure we update the tween properties later on valueParts = valueParts || []; } if ( valueParts ) { initialInUnit = +initialInUnit || +initial || 0; // Apply relative offset (+=/-=) if specified adjusted = valueParts[ 1 ] ? initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : +valueParts[ 2 ]; if ( tween ) { tween.unit = unit; tween.start = initialInUnit; tween.end = adjusted; } } return adjusted; } // Matches dashed string for camelizing var rmsPrefix = /^-ms-/; // Convert dashed to camelCase, handle vendor prefixes. // Used by the css & effects modules. // Support: IE <=9 - 11+ // Microsoft forgot to hump their vendor prefix (trac-9572) function cssCamelCase( string ) { return camelCase( string.replace( rmsPrefix, "ms-" ) ); } var defaultDisplayMap = {}; function getDefaultDisplay( elem ) { var temp, doc = elem.ownerDocument, nodeName = elem.nodeName, display = defaultDisplayMap[ nodeName ]; if ( display ) { return display; } temp = doc.body.appendChild( doc.createElement( nodeName ) ); display = jQuery.css( temp, "display" ); temp.parentNode.removeChild( temp ); if ( display === "none" ) { display = "block"; } defaultDisplayMap[ nodeName ] = display; return display; } function showHide( elements, show ) { var display, elem, values = [], index = 0, length = elements.length; // Determine new display value for elements that need to change for ( ; index < length; index++ ) { elem = elements[ index ]; if ( !elem.style ) { continue; } display = elem.style.display; if ( show ) { // Since we force visibility upon cascade-hidden elements, an immediate (and slow) // check is required in this first loop unless we have a nonempty display value (either // inline or about-to-be-restored) if ( display === "none" ) { values[ index ] = dataPriv.get( elem, "display" ) || null; if ( !values[ index ] ) { elem.style.display = ""; } } if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { values[ index ] = getDefaultDisplay( elem ); } } else { if ( display !== "none" ) { values[ index ] = "none"; // Remember what we're overwriting dataPriv.set( elem, "display", display ); } } } // Set the display of the elements in a second loop to avoid constant reflow for ( index = 0; index < length; index++ ) { if ( values[ index ] != null ) { elements[ index ].style.display = values[ index ]; } } return elements; } jQuery.fn.extend( { show: function() { return showHide( this, true ); }, hide: function() { return showHide( this ); }, toggle: function( state ) { if ( typeof state === "boolean" ) { return state ? this.show() : this.hide(); } return this.each( function() { if ( isHiddenWithinTree( this ) ) { jQuery( this ).show(); } else { jQuery( this ).hide(); } } ); } } ); var isAttached = function( elem ) { return jQuery.contains( elem.ownerDocument, elem ) || elem.getRootNode( composed ) === elem.ownerDocument; }, composed = { composed: true }; // Support: IE 9 - 11+ // Check attachment across shadow DOM boundaries when possible (gh-3504). // Provide a fallback for browsers without Shadow DOM v1 support. if ( !documentElement$1.getRootNode ) { isAttached = function( elem ) { return jQuery.contains( elem.ownerDocument, elem ); }; } // rtagName captures the name from the first start tag in a string of HTML // https://html.spec.whatwg.org/multipage/syntax.html#tag-open-state // https://html.spec.whatwg.org/multipage/syntax.html#tag-name-state var rtagName = /<([a-z][^\/\0>\x20\t\r\n\f]*)/i; var wrapMap = { // Table parts need to be wrapped with `` or they're // stripped to their contents when put in a div. // XHTML parsers do not magically insert elements in the // same way that tag soup parsers do, so we cannot shorten // this by omitting or other required elements. thead: [ "table" ], col: [ "colgroup", "table" ], tr: [ "tbody", "table" ], td: [ "tr", "tbody", "table" ] }; wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; wrapMap.th = wrapMap.td; function getAll( context, tag ) { // Support: IE <=9 - 11+ // Use typeof to avoid zero-argument method invocation on host objects (trac-15151) var ret; if ( typeof context.getElementsByTagName !== "undefined" ) { // Use slice to snapshot the live collection from gEBTN ret = arr.slice.call( context.getElementsByTagName( tag || "*" ) ); } else if ( typeof context.querySelectorAll !== "undefined" ) { ret = context.querySelectorAll( tag || "*" ); } else { ret = []; } if ( tag === undefined || tag && nodeName( context, tag ) ) { return jQuery.merge( [ context ], ret ); } return ret; } var rscriptType = /^$|^module$|\/(?:java|ecma)script/i; // Mark scripts as having already been evaluated function setGlobalEval( elems, refElements ) { var i = 0, l = elems.length; for ( ; i < l; i++ ) { dataPriv.set( elems[ i ], "globalEval", !refElements || dataPriv.get( refElements[ i ], "globalEval" ) ); } } var rhtml = /<|&#?\w+;/; function buildFragment( elems, context, scripts, selection, ignored ) { var elem, tmp, tag, wrap, attached, j, fragment = context.createDocumentFragment(), nodes = [], i = 0, l = elems.length; for ( ; i < l; i++ ) { elem = elems[ i ]; if ( elem || elem === 0 ) { // Add nodes directly if ( toType( elem ) === "object" && ( elem.nodeType || isArrayLike( elem ) ) ) { jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); // Convert non-html into a text node } else if ( !rhtml.test( elem ) ) { nodes.push( context.createTextNode( elem ) ); // Convert html into DOM nodes } else { tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); // Deserialize a standard representation tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); wrap = wrapMap[ tag ] || arr; // Create wrappers & descend into them. j = wrap.length; while ( --j > -1 ) { tmp = tmp.appendChild( context.createElement( wrap[ j ] ) ); } tmp.innerHTML = jQuery.htmlPrefilter( elem ); jQuery.merge( nodes, tmp.childNodes ); // Remember the top-level container tmp = fragment.firstChild; // Ensure the created nodes are orphaned (trac-12392) tmp.textContent = ""; } } } // Remove wrapper from fragment fragment.textContent = ""; i = 0; while ( ( elem = nodes[ i++ ] ) ) { // Skip elements already in the context collection (trac-4087) if ( selection && jQuery.inArray( elem, selection ) > -1 ) { if ( ignored ) { ignored.push( elem ); } continue; } attached = isAttached( elem ); // Append to fragment tmp = getAll( fragment.appendChild( elem ), "script" ); // Preserve script evaluation history if ( attached ) { setGlobalEval( tmp ); } // Capture executables if ( scripts ) { j = 0; while ( ( elem = tmp[ j++ ] ) ) { if ( rscriptType.test( elem.type || "" ) ) { scripts.push( elem ); } } } } return fragment; } // Replace/restore the type attribute of script elements for safe DOM manipulation function disableScript( elem ) { elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; return elem; } function restoreScript( elem ) { if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { elem.type = elem.type.slice( 5 ); } else { elem.removeAttribute( "type" ); } return elem; } function domManip( collection, args, callback, ignored ) { // Flatten any nested arrays args = flat( args ); var fragment, first, scripts, hasScripts, node, doc, i = 0, l = collection.length, iNoClone = l - 1, value = args[ 0 ], valueIsFunction = typeof value === "function"; if ( valueIsFunction ) { return collection.each( function( index ) { var self = collection.eq( index ); args[ 0 ] = value.call( this, index, self.html() ); domManip( self, args, callback, ignored ); } ); } if ( l ) { fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); first = fragment.firstChild; if ( fragment.childNodes.length === 1 ) { fragment = first; } // Require either new content or an interest in ignored elements to invoke the callback if ( first || ignored ) { scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); hasScripts = scripts.length; // Use the original fragment for the last item // instead of the first because it can end up // being emptied incorrectly in certain situations (trac-8070). for ( ; i < l; i++ ) { node = fragment; if ( i !== iNoClone ) { node = jQuery.clone( node, true, true ); // Keep references to cloned scripts for later restoration if ( hasScripts ) { jQuery.merge( scripts, getAll( node, "script" ) ); } } callback.call( collection[ i ], node, i ); } if ( hasScripts ) { doc = scripts[ scripts.length - 1 ].ownerDocument; // Re-enable scripts jQuery.map( scripts, restoreScript ); // Evaluate executable scripts on first document insertion for ( i = 0; i < hasScripts; i++ ) { node = scripts[ i ]; if ( rscriptType.test( node.type || "" ) && !dataPriv.get( node, "globalEval" ) && jQuery.contains( doc, node ) ) { if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { // Optional AJAX dependency, but won't run scripts if not present if ( jQuery._evalUrl && !node.noModule ) { jQuery._evalUrl( node.src, { nonce: node.nonce, crossOrigin: node.crossOrigin }, doc ); } } else { DOMEval( node.textContent, node, doc ); } } } } } } return collection; } var rcheckableType = /^(?:checkbox|radio)$/i; var rtypenamespace = /^([^.]*)(?:\.(.+)|)/; function returnTrue() { return true; } function returnFalse() { return false; } function on( elem, types, selector, data, fn, one ) { var origFn, type; // Types can be a map of types/handlers if ( typeof types === "object" ) { // ( types-Object, selector, data ) if ( typeof selector !== "string" ) { // ( types-Object, data ) data = data || selector; selector = undefined; } for ( type in types ) { on( elem, type, selector, data, types[ type ], one ); } return elem; } if ( data == null && fn == null ) { // ( types, fn ) fn = selector; data = selector = undefined; } else if ( fn == null ) { if ( typeof selector === "string" ) { // ( types, selector, fn ) fn = data; data = undefined; } else { // ( types, data, fn ) fn = data; data = selector; selector = undefined; } } if ( fn === false ) { fn = returnFalse; } else if ( !fn ) { return elem; } if ( one === 1 ) { origFn = fn; fn = function( event ) { // Can use an empty set, since event contains the info jQuery().off( event ); return origFn.apply( this, arguments ); }; // Use same guid so caller can remove using origFn fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); } return elem.each( function() { jQuery.event.add( this, types, fn, data, selector ); } ); } /* * Helper functions for managing events -- not part of the public interface. * Props to Dean Edwards' addEvent library for many of the ideas. */ jQuery.event = { add: function( elem, types, handler, data, selector ) { var handleObjIn, eventHandle, tmp, events, t, handleObj, special, handlers, type, namespaces, origType, elemData = dataPriv.get( elem ); // Only attach events to objects that accept data if ( !acceptData( elem ) ) { return; } // Caller can pass in an object of custom data in lieu of the handler if ( handler.handler ) { handleObjIn = handler; handler = handleObjIn.handler; selector = handleObjIn.selector; } // Ensure that invalid selectors throw exceptions at attach time // Evaluate against documentElement in case elem is a non-element node (e.g., document) if ( selector ) { jQuery.find.matchesSelector( documentElement$1, selector ); } // Make sure that the handler has a unique ID, used to find/remove it later if ( !handler.guid ) { handler.guid = jQuery.guid++; } // Init the element's event structure and main handler, if this is the first if ( !( events = elemData.events ) ) { events = elemData.events = Object.create( null ); } if ( !( eventHandle = elemData.handle ) ) { eventHandle = elemData.handle = function( e ) { // Discard the second event of a jQuery.event.trigger() and // when an event is called after a page has unloaded return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? jQuery.event.dispatch.apply( elem, arguments ) : undefined; }; } // Handle multiple events separated by a space types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; t = types.length; while ( t-- ) { tmp = rtypenamespace.exec( types[ t ] ) || []; type = origType = tmp[ 1 ]; namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); // There *must* be a type, no attaching namespace-only handlers if ( !type ) { continue; } // If event changes its type, use the special event handlers for the changed type special = jQuery.event.special[ type ] || {}; // If selector defined, determine special event api type, otherwise given type type = ( selector ? special.delegateType : special.bindType ) || type; // Update special based on newly reset type special = jQuery.event.special[ type ] || {}; // handleObj is passed to all event handlers handleObj = jQuery.extend( { type: type, origType: origType, data: data, handler: handler, guid: handler.guid, selector: selector, needsContext: selector && jQuery.expr.match.needsContext.test( selector ), namespace: namespaces.join( "." ) }, handleObjIn ); // Init the event handler queue if we're the first if ( !( handlers = events[ type ] ) ) { handlers = events[ type ] = []; handlers.delegateCount = 0; // Only use addEventListener if the special events handler returns false if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { if ( elem.addEventListener ) { elem.addEventListener( type, eventHandle ); } } } if ( special.add ) { special.add.call( elem, handleObj ); if ( !handleObj.handler.guid ) { handleObj.handler.guid = handler.guid; } } // Add to the element's handler list, delegates in front if ( selector ) { handlers.splice( handlers.delegateCount++, 0, handleObj ); } else { handlers.push( handleObj ); } } }, // Detach an event or set of events from an element remove: function( elem, types, handler, selector, mappedTypes ) { var j, origCount, tmp, events, t, handleObj, special, handlers, type, namespaces, origType, elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); if ( !elemData || !( events = elemData.events ) ) { return; } // Once for each type.namespace in types; type may be omitted types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; t = types.length; while ( t-- ) { tmp = rtypenamespace.exec( types[ t ] ) || []; type = origType = tmp[ 1 ]; namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); // Unbind all events (on this namespace, if provided) for the element if ( !type ) { for ( type in events ) { jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); } continue; } special = jQuery.event.special[ type ] || {}; type = ( selector ? special.delegateType : special.bindType ) || type; handlers = events[ type ] || []; tmp = tmp[ 2 ] && new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); // Remove matching events origCount = j = handlers.length; while ( j-- ) { handleObj = handlers[ j ]; if ( ( mappedTypes || origType === handleObj.origType ) && ( !handler || handler.guid === handleObj.guid ) && ( !tmp || tmp.test( handleObj.namespace ) ) && ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { handlers.splice( j, 1 ); if ( handleObj.selector ) { handlers.delegateCount--; } if ( special.remove ) { special.remove.call( elem, handleObj ); } } } // Remove generic event handler if we removed something and no more handlers exist // (avoids potential for endless recursion during removal of special event handlers) if ( origCount && !handlers.length ) { if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { jQuery.removeEvent( elem, type, elemData.handle ); } delete events[ type ]; } } // Remove data and the expando if it's no longer used if ( jQuery.isEmptyObject( events ) ) { dataPriv.remove( elem, "handle events" ); } }, dispatch: function( nativeEvent ) { var i, j, ret, matched, handleObj, handlerQueue, args = new Array( arguments.length ), // Make a writable jQuery.Event from the native event object event = jQuery.event.fix( nativeEvent ), handlers = ( dataPriv.get( this, "events" ) || Object.create( null ) )[ event.type ] || [], special = jQuery.event.special[ event.type ] || {}; // Use the fix-ed jQuery.Event rather than the (read-only) native event args[ 0 ] = event; for ( i = 1; i < arguments.length; i++ ) { args[ i ] = arguments[ i ]; } event.delegateTarget = this; // Call the preDispatch hook for the mapped type, and let it bail if desired if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { return; } // Determine handlers handlerQueue = jQuery.event.handlers.call( this, event, handlers ); // Run delegates first; they may want to stop propagation beneath us i = 0; while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { event.currentTarget = matched.elem; j = 0; while ( ( handleObj = matched.handlers[ j++ ] ) && !event.isImmediatePropagationStopped() ) { // If the event is namespaced, then each handler is only invoked if it is // specially universal or its namespaces are a superset of the event's. if ( !event.rnamespace || handleObj.namespace === false || event.rnamespace.test( handleObj.namespace ) ) { event.handleObj = handleObj; event.data = handleObj.data; ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || handleObj.handler ).apply( matched.elem, args ); if ( ret !== undefined ) { if ( ( event.result = ret ) === false ) { event.preventDefault(); event.stopPropagation(); } } } } } // Call the postDispatch hook for the mapped type if ( special.postDispatch ) { special.postDispatch.call( this, event ); } return event.result; }, handlers: function( event, handlers ) { var i, handleObj, sel, matchedHandlers, matchedSelectors, handlerQueue = [], delegateCount = handlers.delegateCount, cur = event.target; // Find delegate handlers if ( delegateCount && // Support: Firefox <=42 - 66+ // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click // Support: IE 11+ // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) !( event.type === "click" && event.button >= 1 ) ) { for ( ; cur !== this; cur = cur.parentNode || this ) { // Don't check non-elements (trac-13208) // Don't process clicks on disabled elements (trac-6911, trac-8165, trac-11382, trac-11764) if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { matchedHandlers = []; matchedSelectors = {}; for ( i = 0; i < delegateCount; i++ ) { handleObj = handlers[ i ]; // Don't conflict with Object.prototype properties (trac-13203) sel = handleObj.selector + " "; if ( matchedSelectors[ sel ] === undefined ) { matchedSelectors[ sel ] = handleObj.needsContext ? jQuery( sel, this ).index( cur ) > -1 : jQuery.find( sel, this, null, [ cur ] ).length; } if ( matchedSelectors[ sel ] ) { matchedHandlers.push( handleObj ); } } if ( matchedHandlers.length ) { handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); } } } } // Add the remaining (directly-bound) handlers cur = this; if ( delegateCount < handlers.length ) { handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); } return handlerQueue; }, addProp: function( name, hook ) { Object.defineProperty( jQuery.Event.prototype, name, { enumerable: true, configurable: true, get: typeof hook === "function" ? function() { if ( this.originalEvent ) { return hook( this.originalEvent ); } } : function() { if ( this.originalEvent ) { return this.originalEvent[ name ]; } }, set: function( value ) { Object.defineProperty( this, name, { enumerable: true, configurable: true, writable: true, value: value } ); } } ); }, fix: function( originalEvent ) { return originalEvent[ jQuery.expando ] ? originalEvent : new jQuery.Event( originalEvent ); }, special: jQuery.extend( Object.create( null ), { load: { // Prevent triggered image.load events from bubbling to window.load noBubble: true }, click: { // Utilize native event to ensure correct state for checkable inputs setup: function( data ) { // For mutual compressibility with _default, replace `this` access with a local var. // `|| data` is dead code meant only to preserve the variable through minification. var el = this || data; // Claim the first handler if ( rcheckableType.test( el.type ) && el.click && nodeName( el, "input" ) ) { // dataPriv.set( el, "click", ... ) leverageNative( el, "click", true ); } // Return false to allow normal processing in the caller return false; }, trigger: function( data ) { // For mutual compressibility with _default, replace `this` access with a local var. // `|| data` is dead code meant only to preserve the variable through minification. var el = this || data; // Force setup before triggering a click if ( rcheckableType.test( el.type ) && el.click && nodeName( el, "input" ) ) { leverageNative( el, "click" ); } // Return non-false to allow normal event-path propagation return true; }, // For cross-browser consistency, suppress native .click() on links // Also prevent it if we're currently inside a leveraged native-event stack _default: function( event ) { var target = event.target; return rcheckableType.test( target.type ) && target.click && nodeName( target, "input" ) && dataPriv.get( target, "click" ) || nodeName( target, "a" ); } }, beforeunload: { postDispatch: function( event ) { if ( event.result !== undefined ) { // Setting `event.originalEvent.returnValue` in modern // browsers does the same as just calling `preventDefault()`, // the browsers ignore the value anyway. // Incidentally, IE 11 is the only browser from our supported // ones which respects the value returned from a `beforeunload` // handler attached by `addEventListener`; other browsers do // so only for inline handlers, so not setting the value // directly shouldn't reduce any functionality. event.preventDefault(); } } } } ) }; // Ensure the presence of an event listener that handles manually-triggered // synthetic events by interrupting progress until reinvoked in response to // *native* events that it fires directly, ensuring that state changes have // already occurred before other listeners are invoked. function leverageNative( el, type, isSetup ) { // Missing `isSetup` indicates a trigger call, which must force setup through jQuery.event.add if ( !isSetup ) { if ( dataPriv.get( el, type ) === undefined ) { jQuery.event.add( el, type, returnTrue ); } return; } // Register the controller as a special universal handler for all event namespaces dataPriv.set( el, type, false ); jQuery.event.add( el, type, { namespace: false, handler: function( event ) { var result, saved = dataPriv.get( this, type ); // This controller function is invoked under multiple circumstances, // differentiated by the stored value in `saved`: // 1. For an outer synthetic `.trigger()`ed event (detected by // `event.isTrigger & 1` and non-array `saved`), it records arguments // as an array and fires an [inner] native event to prompt state // changes that should be observed by registered listeners (such as // checkbox toggling and focus updating), then clears the stored value. // 2. For an [inner] native event (detected by `saved` being // an array), it triggers an inner synthetic event, records the // result, and preempts propagation to further jQuery listeners. // 3. For an inner synthetic event (detected by `event.isTrigger & 1` and // array `saved`), it prevents double-propagation of surrogate events // but otherwise allows everything to proceed (particularly including // further listeners). // Possible `saved` data shapes: `[...], `{ value }`, `false`. if ( ( event.isTrigger & 1 ) && this[ type ] ) { // Interrupt processing of the outer synthetic .trigger()ed event if ( !saved.length ) { // Store arguments for use when handling the inner native event // There will always be at least one argument (an event object), // so this array will not be confused with a leftover capture object. saved = slice.call( arguments ); dataPriv.set( this, type, saved ); // Trigger the native event and capture its result this[ type ](); result = dataPriv.get( this, type ); dataPriv.set( this, type, false ); if ( saved !== result ) { // Cancel the outer synthetic event event.stopImmediatePropagation(); event.preventDefault(); // Support: Chrome 86+ // In Chrome, if an element having a focusout handler is // blurred by clicking outside of it, it invokes the handler // synchronously. If that handler calls `.remove()` on // the element, the data is cleared, leaving `result` // undefined. We need to guard against this. return result && result.value; } // If this is an inner synthetic event for an event with a bubbling // surrogate (focus or blur), assume that the surrogate already // propagated from triggering the native event and prevent that // from happening again here. } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { event.stopPropagation(); } // If this is a native event triggered above, everything is now in order. // Fire an inner synthetic event with the original arguments. } else if ( saved.length ) { // ...and capture the result dataPriv.set( this, type, { value: jQuery.event.trigger( saved[ 0 ], saved.slice( 1 ), this ) } ); // Abort handling of the native event by all jQuery handlers while allowing // native handlers on the same element to run. On target, this is achieved // by stopping immediate propagation just on the jQuery event. However, // the native event is re-wrapped by a jQuery one on each level of the // propagation so the only way to stop it for jQuery is to stop it for // everyone via native `stopPropagation()`. This is not a problem for // focus/blur which don't bubble, but it does also stop click on checkboxes // and radios. We accept this limitation. event.stopPropagation(); event.isImmediatePropagationStopped = returnTrue; } } } ); } jQuery.removeEvent = function( elem, type, handle ) { // This "if" is needed for plain objects if ( elem.removeEventListener ) { elem.removeEventListener( type, handle ); } }; jQuery.Event = function( src, props ) { // Allow instantiation without the 'new' keyword if ( !( this instanceof jQuery.Event ) ) { return new jQuery.Event( src, props ); } // Event object if ( src && src.type ) { this.originalEvent = src; this.type = src.type; // Events bubbling up the document may have been marked as prevented // by a handler lower down the tree; reflect the correct value. this.isDefaultPrevented = src.defaultPrevented ? returnTrue : returnFalse; // Create target properties this.target = src.target; this.currentTarget = src.currentTarget; this.relatedTarget = src.relatedTarget; // Event type } else { this.type = src; } // Put explicitly provided properties onto the event object if ( props ) { jQuery.extend( this, props ); } // Create a timestamp if incoming event doesn't have one this.timeStamp = src && src.timeStamp || Date.now(); // Mark it as fixed this[ jQuery.expando ] = true; }; // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding // https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html jQuery.Event.prototype = { constructor: jQuery.Event, isDefaultPrevented: returnFalse, isPropagationStopped: returnFalse, isImmediatePropagationStopped: returnFalse, isSimulated: false, preventDefault: function() { var e = this.originalEvent; this.isDefaultPrevented = returnTrue; if ( e && !this.isSimulated ) { e.preventDefault(); } }, stopPropagation: function() { var e = this.originalEvent; this.isPropagationStopped = returnTrue; if ( e && !this.isSimulated ) { e.stopPropagation(); } }, stopImmediatePropagation: function() { var e = this.originalEvent; this.isImmediatePropagationStopped = returnTrue; if ( e && !this.isSimulated ) { e.stopImmediatePropagation(); } this.stopPropagation(); } }; // Includes all common event props including KeyEvent and MouseEvent specific props jQuery.each( { altKey: true, bubbles: true, cancelable: true, changedTouches: true, ctrlKey: true, detail: true, eventPhase: true, metaKey: true, pageX: true, pageY: true, shiftKey: true, view: true, "char": true, code: true, charCode: true, key: true, keyCode: true, button: true, buttons: true, clientX: true, clientY: true, offsetX: true, offsetY: true, pointerId: true, pointerType: true, screenX: true, screenY: true, targetTouches: true, toElement: true, touches: true, which: true }, jQuery.event.addProp ); jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { // Support: IE 11+ // Attach a single focusin/focusout handler on the document while someone wants focus/blur. // This is because the former are synchronous in IE while the latter are async. In other // browsers, all those handlers are invoked synchronously. function focusMappedHandler( nativeEvent ) { // `eventHandle` would already wrap the event, but we need to change the `type` here. var event = jQuery.event.fix( nativeEvent ); event.type = nativeEvent.type === "focusin" ? "focus" : "blur"; event.isSimulated = true; // focus/blur don't bubble while focusin/focusout do; simulate the former by only // invoking the handler at the lower level. if ( event.target === event.currentTarget ) { // The setup part calls `leverageNative`, which, in turn, calls // `jQuery.event.add`, so event handle will already have been set // by this point. dataPriv.get( this, "handle" )( event ); } } jQuery.event.special[ type ] = { // Utilize native event if possible so blur/focus sequence is correct setup: function() { // Claim the first handler // dataPriv.set( this, "focus", ... ) // dataPriv.set( this, "blur", ... ) leverageNative( this, type, true ); if ( isIE ) { this.addEventListener( delegateType, focusMappedHandler ); } else { // Return false to allow normal processing in the caller return false; } }, trigger: function() { // Force setup before trigger leverageNative( this, type ); // Return non-false to allow normal event-path propagation return true; }, teardown: function() { if ( isIE ) { this.removeEventListener( delegateType, focusMappedHandler ); } else { // Return false to indicate standard teardown should be applied return false; } }, // Suppress native focus or blur if we're currently inside // a leveraged native-event stack _default: function( event ) { return dataPriv.get( event.target, type ); }, delegateType: delegateType }; } ); // Create mouseenter/leave events using mouseover/out and event-time checks // so that event delegation works in jQuery. // Do the same for pointerenter/pointerleave and pointerover/pointerout jQuery.each( { mouseenter: "mouseover", mouseleave: "mouseout", pointerenter: "pointerover", pointerleave: "pointerout" }, function( orig, fix ) { jQuery.event.special[ orig ] = { delegateType: fix, bindType: fix, handle: function( event ) { var ret, target = this, related = event.relatedTarget, handleObj = event.handleObj; // For mouseenter/leave call the handler if related is outside the target. // NB: No relatedTarget if the mouse left/entered the browser window if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { event.type = handleObj.origType; ret = handleObj.handler.apply( this, arguments ); event.type = fix; } return ret; } }; } ); jQuery.fn.extend( { on: function( types, selector, data, fn ) { return on( this, types, selector, data, fn ); }, one: function( types, selector, data, fn ) { return on( this, types, selector, data, fn, 1 ); }, off: function( types, selector, fn ) { var handleObj, type; if ( types && types.preventDefault && types.handleObj ) { // ( event ) dispatched jQuery.Event handleObj = types.handleObj; jQuery( types.delegateTarget ).off( handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, handleObj.selector, handleObj.handler ); return this; } if ( typeof types === "object" ) { // ( types-object [, selector] ) for ( type in types ) { this.off( type, selector, types[ type ] ); } return this; } if ( selector === false || typeof selector === "function" ) { // ( types [, fn] ) fn = selector; selector = undefined; } if ( fn === false ) { fn = returnFalse; } return this.each( function() { jQuery.event.remove( this, types, fn, selector ); } ); } } ); var // Support: IE <=10 - 11+ // In IE using regex groups here causes severe slowdowns. rnoInnerhtml = / 0 ) { setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); } // Return the cloned set return clone; }, cleanData: function( elems ) { var data, elem, type, special = jQuery.event.special, i = 0; for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { if ( acceptData( elem ) ) { if ( ( data = elem[ dataPriv.expando ] ) ) { if ( data.events ) { for ( type in data.events ) { if ( special[ type ] ) { jQuery.event.remove( elem, type ); // This is a shortcut to avoid jQuery.event.remove's overhead } else { jQuery.removeEvent( elem, type, data.handle ); } } } // Support: Chrome <=35 - 45+ // Assign undefined instead of using delete, see Data#remove elem[ dataPriv.expando ] = undefined; } if ( elem[ dataUser.expando ] ) { // Support: Chrome <=35 - 45+ // Assign undefined instead of using delete, see Data#remove elem[ dataUser.expando ] = undefined; } } } } } ); jQuery.fn.extend( { detach: function( selector ) { return remove( this, selector, true ); }, remove: function( selector ) { return remove( this, selector ); }, text: function( value ) { return access( this, function( value ) { return value === undefined ? jQuery.text( this ) : this.empty().each( function() { if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { this.textContent = value; } } ); }, null, value, arguments.length ); }, append: function() { return domManip( this, arguments, function( elem ) { if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { var target = manipulationTarget( this, elem ); target.appendChild( elem ); } } ); }, prepend: function() { return domManip( this, arguments, function( elem ) { if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { var target = manipulationTarget( this, elem ); target.insertBefore( elem, target.firstChild ); } } ); }, before: function() { return domManip( this, arguments, function( elem ) { if ( this.parentNode ) { this.parentNode.insertBefore( elem, this ); } } ); }, after: function() { return domManip( this, arguments, function( elem ) { if ( this.parentNode ) { this.parentNode.insertBefore( elem, this.nextSibling ); } } ); }, empty: function() { var elem, i = 0; for ( ; ( elem = this[ i ] ) != null; i++ ) { if ( elem.nodeType === 1 ) { // Prevent memory leaks jQuery.cleanData( getAll( elem, false ) ); // Remove any remaining nodes elem.textContent = ""; } } return this; }, clone: function( dataAndEvents, deepDataAndEvents ) { dataAndEvents = dataAndEvents == null ? false : dataAndEvents; deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; return this.map( function() { return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); } ); }, html: function( value ) { return access( this, function( value ) { var elem = this[ 0 ] || {}, i = 0, l = this.length; if ( value === undefined && elem.nodeType === 1 ) { return elem.innerHTML; } // See if we can take a shortcut and just use innerHTML if ( typeof value === "string" && !rnoInnerhtml.test( value ) && !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { value = jQuery.htmlPrefilter( value ); try { for ( ; i < l; i++ ) { elem = this[ i ] || {}; // Remove element nodes and prevent memory leaks if ( elem.nodeType === 1 ) { jQuery.cleanData( getAll( elem, false ) ); elem.innerHTML = value; } } elem = 0; // If using innerHTML throws an exception, use the fallback method } catch ( e ) {} } if ( elem ) { this.empty().append( value ); } }, null, value, arguments.length ); }, replaceWith: function() { var ignored = []; // Make the changes, replacing each non-ignored context element with the new content return domManip( this, arguments, function( elem ) { var parent = this.parentNode; if ( jQuery.inArray( this, ignored ) < 0 ) { jQuery.cleanData( getAll( this ) ); if ( parent ) { parent.replaceChild( elem, this ); } } // Force callback invocation }, ignored ); } } ); jQuery.each( { appendTo: "append", prependTo: "prepend", insertBefore: "before", insertAfter: "after", replaceAll: "replaceWith" }, function( name, original ) { jQuery.fn[ name ] = function( selector ) { var elems, ret = [], insert = jQuery( selector ), last = insert.length - 1, i = 0; for ( ; i <= last; i++ ) { elems = i === last ? this : this.clone( true ); jQuery( insert[ i ] )[ original ]( elems ); push.apply( ret, elems ); } return this.pushStack( ret ); }; } ); var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); var rcustomProp = /^--/; function getStyles( elem ) { // Support: IE <=11+ (trac-14150) // In IE popup's `window` is the opener window which makes `window.getComputedStyle( elem )` // break. Using `elem.ownerDocument.defaultView` avoids the issue. var view = elem.ownerDocument.defaultView; // `document.implementation.createHTMLDocument( "" )` has a `null` `defaultView` // property; check `defaultView` truthiness to fallback to window in such a case. if ( !view ) { view = window; } return view.getComputedStyle( elem ); } // A method for quickly swapping in/out CSS properties to get correct calculations. function swap( elem, options, callback ) { var ret, name, old = {}; // Remember the old values, and insert the new ones for ( name in options ) { old[ name ] = elem.style[ name ]; elem.style[ name ] = options[ name ]; } ret = callback.call( elem ); // Revert the old values for ( name in options ) { elem.style[ name ] = old[ name ]; } return ret; } function curCSS( elem, name, computed ) { var ret, isCustomProp = rcustomProp.test( name ); computed = computed || getStyles( elem ); // getPropertyValue is needed for `.css('--customProperty')` (gh-3144) if ( computed ) { // A fallback to direct property access is needed as `computed`, being // the output of `getComputedStyle`, contains camelCased keys and // `getPropertyValue` requires kebab-case ones. // // Support: IE <=9 - 11+ // IE only supports `"float"` in `getPropertyValue`; in computed styles // it's only available as `"cssFloat"`. We no longer modify properties // sent to `.css()` apart from camelCasing, so we need to check both. // Normally, this would create difference in behavior: if // `getPropertyValue` returns an empty string, the value returned // by `.css()` would be `undefined`. This is usually the case for // disconnected elements. However, in IE even disconnected elements // with no styles return `"none"` for `getPropertyValue( "float" )` ret = computed.getPropertyValue( name ) || computed[ name ]; if ( isCustomProp && ret ) { // Support: Firefox 105 - 135+ // Spec requires trimming whitespace for custom properties (gh-4926). // Firefox only trims leading whitespace. // // Fall back to `undefined` if empty string returned. // This collapses a missing definition with property defined // and set to an empty string but there's no standard API // allowing us to differentiate them without a performance penalty // and returning `undefined` aligns with older jQuery. // // rtrimCSS treats U+000D CARRIAGE RETURN and U+000C FORM FEED // as whitespace while CSS does not, but this is not a problem // because CSS preprocessing replaces them with U+000A LINE FEED // (which *is* CSS whitespace) // https://www.w3.org/TR/css-syntax-3/#input-preprocessing ret = ret.replace( rtrimCSS, "$1" ) || undefined; } if ( ret === "" && !isAttached( elem ) ) { ret = jQuery.style( elem, name ); } } return ret !== undefined ? // Support: IE <=9 - 11+ // IE returns zIndex value as an integer. ret + "" : ret; } var cssPrefixes = [ "Webkit", "Moz", "ms" ], emptyStyle = document$1.createElement( "div" ).style; // Return a vendor-prefixed property or undefined function vendorPropName( name ) { // Check for vendor prefixed names var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), i = cssPrefixes.length; while ( i-- ) { name = cssPrefixes[ i ] + capName; if ( name in emptyStyle ) { return name; } } } // Return a potentially-mapped vendor prefixed property function finalPropName( name ) { if ( name in emptyStyle ) { return name; } return vendorPropName( name ) || name; } var reliableTrDimensionsVal, reliableColDimensionsVal, table = document$1.createElement( "table" ); // Executing table tests requires only one layout, so they're executed // at the same time to save the second computation. function computeTableStyleTests() { if ( // This is a singleton, we need to execute it only once !table || // Finish early in limited (non-browser) environments !table.style ) { return; } var trStyle, col = document$1.createElement( "col" ), tr = document$1.createElement( "tr" ), td = document$1.createElement( "td" ); table.style.cssText = "position:absolute;left:-11111px;" + "border-collapse:separate;border-spacing:0"; tr.style.cssText = "box-sizing:content-box;border:1px solid;height:1px"; td.style.cssText = "height:9px;width:9px;padding:0"; col.span = 2; documentElement$1 .appendChild( table ) .appendChild( col ) .parentNode .appendChild( tr ) .appendChild( td ) .parentNode .appendChild( td.cloneNode( true ) ); // Don't run until window is visible if ( table.offsetWidth === 0 ) { documentElement$1.removeChild( table ); return; } trStyle = window.getComputedStyle( tr ); // Support: Firefox 135+ // Firefox always reports computed width as if `span` was 1. // Support: Safari 18.3+ // In Safari, computed width for columns is always 0. // In both these browsers, using `offsetWidth` solves the issue. // Support: IE 11+ // In IE, `` computed width is `"auto"` unless `width` is set // explicitly via CSS so measurements there remain incorrect. Because of // the lack of a proper workaround, we accept this limitation, treating // IE as passing the test. reliableColDimensionsVal = isIE || Math.round( parseFloat( window.getComputedStyle( col ).width ) ) === 18; // Support: IE 10 - 11+ // IE misreports `getComputedStyle` of table rows with width/height // set in CSS while `offset*` properties report correct values. // Support: Firefox 70 - 135+ // Only Firefox includes border widths // in computed dimensions for table rows. (gh-4529) reliableTrDimensionsVal = Math.round( parseFloat( trStyle.height ) + parseFloat( trStyle.borderTopWidth ) + parseFloat( trStyle.borderBottomWidth ) ) === tr.offsetHeight; documentElement$1.removeChild( table ); // Nullify the table so it wouldn't be stored in the memory; // it will also be a sign that checks were already performed. table = null; } jQuery.extend( support, { reliableTrDimensions: function() { computeTableStyleTests(); return reliableTrDimensionsVal; }, reliableColDimensions: function() { computeTableStyleTests(); return reliableColDimensionsVal; } } ); var cssShow = { position: "absolute", visibility: "hidden", display: "block" }, cssNormalTransform = { letterSpacing: "0", fontWeight: "400" }; function setPositiveNumber( _elem, value, subtract ) { // Any relative (+/-) values have already been // normalized at this point var matches = rcssNum.exec( value ); return matches ? // Guard against undefined "subtract", e.g., when used as in cssHooks Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : value; } function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { var i = dimension === "width" ? 1 : 0, extra = 0, delta = 0, marginDelta = 0; // Adjustment may not be necessary if ( box === ( isBorderBox ? "border" : "content" ) ) { return 0; } for ( ; i < 4; i += 2 ) { // Both box models exclude margin // Count margin delta separately to only add it after scroll gutter adjustment. // This is needed to make negative margins work with `outerHeight( true )` (gh-3982). if ( box === "margin" ) { marginDelta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); } // If we get here with a content-box, we're seeking "padding" or "border" or "margin" if ( !isBorderBox ) { // Add padding delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); // For "border" or "margin", add border if ( box !== "padding" ) { delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); // But still keep track of it otherwise } else { extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); } // If we get here with a border-box (content + padding + border), we're seeking "content" or // "padding" or "margin" } else { // For "content", subtract padding if ( box === "content" ) { delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); } // For "content" or "padding", subtract border if ( box !== "margin" ) { delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); } } } // Account for positive content-box scroll gutter when requested by providing computedVal if ( !isBorderBox && computedVal >= 0 ) { // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border // Assuming integer scroll gutter, subtract the rest and round down delta += Math.max( 0, Math.ceil( elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - computedVal - delta - extra - 0.5 // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter // Use an explicit zero to avoid NaN (gh-3964) ) ) || 0; } return delta + marginDelta; } function getWidthOrHeight( elem, dimension, extra ) { // Start with computed style var styles = getStyles( elem ), // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). // Fake content-box until we know it's needed to know the true value. boxSizingNeeded = isIE || extra, isBorderBox = boxSizingNeeded && jQuery.css( elem, "boxSizing", false, styles ) === "border-box", valueIsBorderBox = isBorderBox, val = curCSS( elem, dimension, styles ), offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); // Return a confounding non-pixel value or feign ignorance, as appropriate. if ( rnumnonpx.test( val ) ) { if ( !extra ) { return val; } val = "auto"; } if ( ( // Fall back to offsetWidth/offsetHeight when value is "auto" // This happens for inline elements with no explicit setting (gh-3571) val === "auto" || // Support: IE 9 - 11+ // Use offsetWidth/offsetHeight for when box sizing is unreliable. // In those cases, the computed value can be trusted to be border-box. ( isIE && isBorderBox ) || ( !support.reliableColDimensions() && nodeName( elem, "col" ) ) || ( !support.reliableTrDimensions() && nodeName( elem, "tr" ) ) ) && // Make sure the element is visible & connected elem.getClientRects().length ) { isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; // Where available, offsetWidth/offsetHeight approximate border box dimensions. // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the // retrieved value as a content box dimension. valueIsBorderBox = offsetProp in elem; if ( valueIsBorderBox ) { val = elem[ offsetProp ]; } } // Normalize "" and auto val = parseFloat( val ) || 0; // Adjust for the element's box model return ( val + boxModelAdjustment( elem, dimension, extra || ( isBorderBox ? "border" : "content" ), valueIsBorderBox, styles, // Provide the current computed size to request scroll gutter calculation (gh-3589) val ) ) + "px"; } jQuery.extend( { // Add in style property hooks for overriding the default // behavior of getting and setting a style property cssHooks: {}, // Get and set the style property on a DOM Node style: function( elem, name, value, extra ) { // Don't set styles on text and comment nodes if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { return; } // Make sure that we're working with the right name var ret, type, hooks, origName = cssCamelCase( name ), isCustomProp = rcustomProp.test( name ), style = elem.style; // Make sure that we're working with the right name. We don't // want to query the value if it is a CSS custom property // since they are user-defined. if ( !isCustomProp ) { name = finalPropName( origName ); } // Gets hook for the prefixed version, then unprefixed version hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; // Check if we're setting a value if ( value !== undefined ) { type = typeof value; // Convert "+=" or "-=" to relative numbers (trac-7345) if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { value = adjustCSS( elem, name, ret ); // Fixes bug trac-9237 type = "number"; } // Make sure that null and NaN values aren't set (trac-7116) if ( value == null || value !== value ) { return; } // If the value is a number, add `px` for certain CSS properties if ( type === "number" ) { value += ret && ret[ 3 ] || ( isAutoPx( origName ) ? "px" : "" ); } // Support: IE <=9 - 11+ // background-* props of a cloned element affect the source element (trac-8908) if ( isIE && value === "" && name.indexOf( "background" ) === 0 ) { style[ name ] = "inherit"; } // If a hook was provided, use that value, otherwise just set the specified value if ( !hooks || !( "set" in hooks ) || ( value = hooks.set( elem, value, extra ) ) !== undefined ) { if ( isCustomProp ) { style.setProperty( name, value ); } else { style[ name ] = value; } } } else { // If a hook was provided get the non-computed value from there if ( hooks && "get" in hooks && ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { return ret; } // Otherwise just get the value from the style object return style[ name ]; } }, css: function( elem, name, extra, styles ) { var val, num, hooks, origName = cssCamelCase( name ), isCustomProp = rcustomProp.test( name ); // Make sure that we're working with the right name. We don't // want to modify the value if it is a CSS custom property // since they are user-defined. if ( !isCustomProp ) { name = finalPropName( origName ); } // Try prefixed name followed by the unprefixed name hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; // If a hook was provided get the computed value from there if ( hooks && "get" in hooks ) { val = hooks.get( elem, true, extra ); } // Otherwise, if a way to get the computed value exists, use that if ( val === undefined ) { val = curCSS( elem, name, styles ); } // Convert "normal" to computed value if ( val === "normal" && name in cssNormalTransform ) { val = cssNormalTransform[ name ]; } // Make numeric if forced or a qualifier was provided and val looks numeric if ( extra === "" || extra ) { num = parseFloat( val ); return extra === true || isFinite( num ) ? num || 0 : val; } return val; } } ); jQuery.each( [ "height", "width" ], function( _i, dimension ) { jQuery.cssHooks[ dimension ] = { get: function( elem, computed, extra ) { if ( computed ) { // Elements with `display: none` can have dimension info if // we invisibly show them. return jQuery.css( elem, "display" ) === "none" ? swap( elem, cssShow, function() { return getWidthOrHeight( elem, dimension, extra ); } ) : getWidthOrHeight( elem, dimension, extra ); } }, set: function( elem, value, extra ) { var matches, styles = getStyles( elem ), // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) isBorderBox = extra && jQuery.css( elem, "boxSizing", false, styles ) === "border-box", subtract = extra ? boxModelAdjustment( elem, dimension, extra, isBorderBox, styles ) : 0; // Convert to pixels if value adjustment is needed if ( subtract && ( matches = rcssNum.exec( value ) ) && ( matches[ 3 ] || "px" ) !== "px" ) { elem.style[ dimension ] = value; value = jQuery.css( elem, dimension ); } return setPositiveNumber( elem, value, subtract ); } }; } ); // These hooks are used by animate to expand properties jQuery.each( { margin: "", padding: "", border: "Width" }, function( prefix, suffix ) { jQuery.cssHooks[ prefix + suffix ] = { expand: function( value ) { var i = 0, expanded = {}, // Assumes a single number if not a string parts = typeof value === "string" ? value.split( " " ) : [ value ]; for ( ; i < 4; i++ ) { expanded[ prefix + cssExpand[ i ] + suffix ] = parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; } return expanded; } }; if ( prefix !== "margin" ) { jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; } } ); jQuery.fn.extend( { css: function( name, value ) { return access( this, function( elem, name, value ) { var styles, len, map = {}, i = 0; if ( Array.isArray( name ) ) { styles = getStyles( elem ); len = name.length; for ( ; i < len; i++ ) { map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); } return map; } return value !== undefined ? jQuery.style( elem, name, value ) : jQuery.css( elem, name ); }, name, value, arguments.length > 1 ); } } ); function Tween( elem, options, prop, end, easing ) { return new Tween.prototype.init( elem, options, prop, end, easing ); } jQuery.Tween = Tween; Tween.prototype = { constructor: Tween, init: function( elem, options, prop, end, easing, unit ) { this.elem = elem; this.prop = prop; this.easing = easing || jQuery.easing._default; this.options = options; this.start = this.now = this.cur(); this.end = end; this.unit = unit || ( isAutoPx( prop ) ? "px" : "" ); }, cur: function() { var hooks = Tween.propHooks[ this.prop ]; return hooks && hooks.get ? hooks.get( this ) : Tween.propHooks._default.get( this ); }, run: function( percent ) { var eased, hooks = Tween.propHooks[ this.prop ]; if ( this.options.duration ) { this.pos = eased = jQuery.easing[ this.easing ]( percent, this.options.duration * percent, 0, 1, this.options.duration ); } else { this.pos = eased = percent; } this.now = ( this.end - this.start ) * eased + this.start; if ( this.options.step ) { this.options.step.call( this.elem, this.now, this ); } if ( hooks && hooks.set ) { hooks.set( this ); } else { Tween.propHooks._default.set( this ); } return this; } }; Tween.prototype.init.prototype = Tween.prototype; Tween.propHooks = { _default: { get: function( tween ) { var result; // Use a property on the element directly when it is not a DOM element, // or when there is no matching style property that exists. if ( tween.elem.nodeType !== 1 || tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { return tween.elem[ tween.prop ]; } // Passing an empty string as a 3rd parameter to .css will automatically // attempt a parseFloat and fallback to a string if the parse fails. // Simple values such as "10px" are parsed to Float; // complex values such as "rotate(1rad)" are returned as-is. result = jQuery.css( tween.elem, tween.prop, "" ); // Empty strings, null, undefined and "auto" are converted to 0. return !result || result === "auto" ? 0 : result; }, set: function( tween ) { // Use step hook for back compat. // Use cssHook if its there. // Use .style if available and use plain properties where available. if ( jQuery.fx.step[ tween.prop ] ) { jQuery.fx.step[ tween.prop ]( tween ); } else if ( tween.elem.nodeType === 1 && ( jQuery.cssHooks[ tween.prop ] || tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); } else { tween.elem[ tween.prop ] = tween.now; } } } }; jQuery.easing = { linear: function( p ) { return p; }, swing: function( p ) { return 0.5 - Math.cos( p * Math.PI ) / 2; }, _default: "swing" }; jQuery.fx = Tween.prototype.init; // Back compat <1.8 extension point jQuery.fx.step = {}; var fxNow, inProgress, rfxtypes = /^(?:toggle|show|hide)$/, rrun = /queueHooks$/; function schedule() { if ( inProgress ) { if ( document$1.hidden === false && window.requestAnimationFrame ) { window.requestAnimationFrame( schedule ); } else { window.setTimeout( schedule, 13 ); } jQuery.fx.tick(); } } // Animations created synchronously will run synchronously function createFxNow() { window.setTimeout( function() { fxNow = undefined; } ); return ( fxNow = Date.now() ); } // Generate parameters to create a standard animation function genFx( type, includeWidth ) { var which, i = 0, attrs = { height: type }; // If we include width, step value is 1 to do all cssExpand values, // otherwise step value is 2 to skip over Left and Right includeWidth = includeWidth ? 1 : 0; for ( ; i < 4; i += 2 - includeWidth ) { which = cssExpand[ i ]; attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; } if ( includeWidth ) { attrs.opacity = attrs.width = type; } return attrs; } function createTween( value, prop, animation ) { var tween, collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), index = 0, length = collection.length; for ( ; index < length; index++ ) { if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { // We're done with this property return tween; } } } function defaultPrefilter( elem, props, opts ) { var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, isBox = "width" in props || "height" in props, anim = this, orig = {}, style = elem.style, hidden = elem.nodeType && isHiddenWithinTree( elem ), dataShow = dataPriv.get( elem, "fxshow" ); // Queue-skipping animations hijack the fx hooks if ( !opts.queue ) { hooks = jQuery._queueHooks( elem, "fx" ); if ( hooks.unqueued == null ) { hooks.unqueued = 0; oldfire = hooks.empty.fire; hooks.empty.fire = function() { if ( !hooks.unqueued ) { oldfire(); } }; } hooks.unqueued++; anim.always( function() { // Ensure the complete handler is called before this completes anim.always( function() { hooks.unqueued--; if ( !jQuery.queue( elem, "fx" ).length ) { hooks.empty.fire(); } } ); } ); } // Detect show/hide animations for ( prop in props ) { value = props[ prop ]; if ( rfxtypes.test( value ) ) { delete props[ prop ]; toggle = toggle || value === "toggle"; if ( value === ( hidden ? "hide" : "show" ) ) { // Pretend to be hidden if this is a "show" and // there is still data from a stopped show/hide if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { hidden = true; // Ignore all other no-op show/hide data } else { continue; } } orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); } } // Bail out if this is a no-op like .hide().hide() propTween = !jQuery.isEmptyObject( props ); if ( !propTween && jQuery.isEmptyObject( orig ) ) { return; } // Restrict "overflow" and "display" styles during box animations if ( isBox && elem.nodeType === 1 ) { // Support: IE <=9 - 11+ // Record all 3 overflow attributes because IE does not infer the shorthand // from identically-valued overflowX and overflowY. opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; // Identify a display type, preferring old show/hide data over the CSS cascade restoreDisplay = dataShow && dataShow.display; if ( restoreDisplay == null ) { restoreDisplay = dataPriv.get( elem, "display" ); } display = jQuery.css( elem, "display" ); if ( display === "none" ) { if ( restoreDisplay ) { display = restoreDisplay; } else { // Get nonempty value(s) by temporarily forcing visibility showHide( [ elem ], true ); restoreDisplay = elem.style.display || restoreDisplay; display = jQuery.css( elem, "display" ); showHide( [ elem ] ); } } // Animate inline elements as inline-block if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { if ( jQuery.css( elem, "float" ) === "none" ) { // Restore the original display value at the end of pure show/hide animations if ( !propTween ) { anim.done( function() { style.display = restoreDisplay; } ); if ( restoreDisplay == null ) { display = style.display; restoreDisplay = display === "none" ? "" : display; } } style.display = "inline-block"; } } } if ( opts.overflow ) { style.overflow = "hidden"; anim.always( function() { style.overflow = opts.overflow[ 0 ]; style.overflowX = opts.overflow[ 1 ]; style.overflowY = opts.overflow[ 2 ]; } ); } // Implement show/hide animations propTween = false; for ( prop in orig ) { // General show/hide setup for this element animation if ( !propTween ) { if ( dataShow ) { if ( "hidden" in dataShow ) { hidden = dataShow.hidden; } } else { dataShow = dataPriv.set( elem, "fxshow", { display: restoreDisplay } ); } // Store hidden/visible for toggle so `.stop().toggle()` "reverses" if ( toggle ) { dataShow.hidden = !hidden; } // Show elements before animating them if ( hidden ) { showHide( [ elem ], true ); } // eslint-disable-next-line no-loop-func anim.done( function() { // The final step of a "hide" animation is actually hiding the element if ( !hidden ) { showHide( [ elem ] ); } dataPriv.remove( elem, "fxshow" ); for ( prop in orig ) { jQuery.style( elem, prop, orig[ prop ] ); } } ); } // Per-property setup propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); if ( !( prop in dataShow ) ) { dataShow[ prop ] = propTween.start; if ( hidden ) { propTween.end = propTween.start; propTween.start = 0; } } } } function propFilter( props, specialEasing ) { var index, name, easing, value, hooks; // camelCase, specialEasing and expand cssHook pass for ( index in props ) { name = cssCamelCase( index ); easing = specialEasing[ name ]; value = props[ index ]; if ( Array.isArray( value ) ) { easing = value[ 1 ]; value = props[ index ] = value[ 0 ]; } if ( index !== name ) { props[ name ] = value; delete props[ index ]; } hooks = jQuery.cssHooks[ name ]; if ( hooks && "expand" in hooks ) { value = hooks.expand( value ); delete props[ name ]; // Not quite $.extend, this won't overwrite existing keys. // Reusing 'index' because we have the correct "name" for ( index in value ) { if ( !( index in props ) ) { props[ index ] = value[ index ]; specialEasing[ index ] = easing; } } } else { specialEasing[ name ] = easing; } } } function Animation( elem, properties, options ) { var result, stopped, index = 0, length = Animation.prefilters.length, deferred = jQuery.Deferred().always( function() { // Don't match elem in the :animated selector delete tick.elem; } ), tick = function() { if ( stopped ) { return false; } var currentTime = fxNow || createFxNow(), remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), percent = 1 - ( remaining / animation.duration || 0 ), index = 0, length = animation.tweens.length; for ( ; index < length; index++ ) { animation.tweens[ index ].run( percent ); } deferred.notifyWith( elem, [ animation, percent, remaining ] ); // If there's more to do, yield if ( percent < 1 && length ) { return remaining; } // If this was an empty animation, synthesize a final progress notification if ( !length ) { deferred.notifyWith( elem, [ animation, 1, 0 ] ); } // Resolve the animation and report its conclusion deferred.resolveWith( elem, [ animation ] ); return false; }, animation = deferred.promise( { elem: elem, props: jQuery.extend( {}, properties ), opts: jQuery.extend( true, { specialEasing: {}, easing: jQuery.easing._default }, options ), originalProperties: properties, originalOptions: options, startTime: fxNow || createFxNow(), duration: options.duration, tweens: [], createTween: function( prop, end ) { var tween = jQuery.Tween( elem, animation.opts, prop, end, animation.opts.specialEasing[ prop ] || animation.opts.easing ); animation.tweens.push( tween ); return tween; }, stop: function( gotoEnd ) { var index = 0, // If we are going to the end, we want to run all the tweens // otherwise we skip this part length = gotoEnd ? animation.tweens.length : 0; if ( stopped ) { return this; } stopped = true; for ( ; index < length; index++ ) { animation.tweens[ index ].run( 1 ); } // Resolve when we played the last frame; otherwise, reject if ( gotoEnd ) { deferred.notifyWith( elem, [ animation, 1, 0 ] ); deferred.resolveWith( elem, [ animation, gotoEnd ] ); } else { deferred.rejectWith( elem, [ animation, gotoEnd ] ); } return this; } } ), props = animation.props; propFilter( props, animation.opts.specialEasing ); for ( ; index < length; index++ ) { result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); if ( result ) { if ( typeof result.stop === "function" ) { jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = result.stop.bind( result ); } return result; } } jQuery.map( props, createTween, animation ); if ( typeof animation.opts.start === "function" ) { animation.opts.start.call( elem, animation ); } // Attach callbacks from options animation .progress( animation.opts.progress ) .done( animation.opts.done, animation.opts.complete ) .fail( animation.opts.fail ) .always( animation.opts.always ); jQuery.fx.timer( jQuery.extend( tick, { elem: elem, anim: animation, queue: animation.opts.queue } ) ); return animation; } jQuery.Animation = jQuery.extend( Animation, { tweeners: { "*": [ function( prop, value ) { var tween = this.createTween( prop, value ); adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); return tween; } ] }, tweener: function( props, callback ) { if ( typeof props === "function" ) { callback = props; props = [ "*" ]; } else { props = props.match( rnothtmlwhite ); } var prop, index = 0, length = props.length; for ( ; index < length; index++ ) { prop = props[ index ]; Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; Animation.tweeners[ prop ].unshift( callback ); } }, prefilters: [ defaultPrefilter ], prefilter: function( callback, prepend ) { if ( prepend ) { Animation.prefilters.unshift( callback ); } else { Animation.prefilters.push( callback ); } } } ); jQuery.speed = function( speed, easing, fn ) { var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { complete: fn || easing || typeof speed === "function" && speed, duration: speed, easing: fn && easing || easing && typeof easing !== "function" && easing }; // Go to the end state if fx are off if ( jQuery.fx.off ) { opt.duration = 0; } else { if ( typeof opt.duration !== "number" ) { if ( opt.duration in jQuery.fx.speeds ) { opt.duration = jQuery.fx.speeds[ opt.duration ]; } else { opt.duration = jQuery.fx.speeds._default; } } } // Normalize opt.queue - true/undefined/null -> "fx" if ( opt.queue == null || opt.queue === true ) { opt.queue = "fx"; } // Queueing opt.old = opt.complete; opt.complete = function() { if ( typeof opt.old === "function" ) { opt.old.call( this ); } if ( opt.queue ) { jQuery.dequeue( this, opt.queue ); } }; return opt; }; jQuery.fn.extend( { fadeTo: function( speed, to, easing, callback ) { // Show any hidden elements after setting opacity to 0 return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() // Animate to the value specified .end().animate( { opacity: to }, speed, easing, callback ); }, animate: function( prop, speed, easing, callback ) { var empty = jQuery.isEmptyObject( prop ), optall = jQuery.speed( speed, easing, callback ), doAnimation = function() { // Operate on a copy of prop so per-property easing won't be lost var anim = Animation( this, jQuery.extend( {}, prop ), optall ); // Empty animations, or finishing resolves immediately if ( empty || dataPriv.get( this, "finish" ) ) { anim.stop( true ); } }; doAnimation.finish = doAnimation; return empty || optall.queue === false ? this.each( doAnimation ) : this.queue( optall.queue, doAnimation ); }, stop: function( type, clearQueue, gotoEnd ) { var stopQueue = function( hooks ) { var stop = hooks.stop; delete hooks.stop; stop( gotoEnd ); }; if ( typeof type !== "string" ) { gotoEnd = clearQueue; clearQueue = type; type = undefined; } if ( clearQueue ) { this.queue( type || "fx", [] ); } return this.each( function() { var dequeue = true, index = type != null && type + "queueHooks", timers = jQuery.timers, data = dataPriv.get( this ); if ( index ) { if ( data[ index ] && data[ index ].stop ) { stopQueue( data[ index ] ); } } else { for ( index in data ) { if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { stopQueue( data[ index ] ); } } } for ( index = timers.length; index--; ) { if ( timers[ index ].elem === this && ( type == null || timers[ index ].queue === type ) ) { timers[ index ].anim.stop( gotoEnd ); dequeue = false; timers.splice( index, 1 ); } } // Start the next in the queue if the last step wasn't forced. // Timers currently will call their complete callbacks, which // will dequeue but only if they were gotoEnd. if ( dequeue || !gotoEnd ) { jQuery.dequeue( this, type ); } } ); }, finish: function( type ) { if ( type !== false ) { type = type || "fx"; } return this.each( function() { var index, data = dataPriv.get( this ), queue = data[ type + "queue" ], hooks = data[ type + "queueHooks" ], timers = jQuery.timers, length = queue ? queue.length : 0; // Enable finishing flag on private data data.finish = true; // Empty the queue first jQuery.queue( this, type, [] ); if ( hooks && hooks.stop ) { hooks.stop.call( this, true ); } // Look for any active animations, and finish them for ( index = timers.length; index--; ) { if ( timers[ index ].elem === this && timers[ index ].queue === type ) { timers[ index ].anim.stop( true ); timers.splice( index, 1 ); } } // Look for any animations in the old queue and finish them for ( index = 0; index < length; index++ ) { if ( queue[ index ] && queue[ index ].finish ) { queue[ index ].finish.call( this ); } } // Turn off finishing flag delete data.finish; } ); } } ); jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { var cssFn = jQuery.fn[ name ]; jQuery.fn[ name ] = function( speed, easing, callback ) { return speed == null || typeof speed === "boolean" ? cssFn.apply( this, arguments ) : this.animate( genFx( name, true ), speed, easing, callback ); }; } ); // Generate shortcuts for custom animations jQuery.each( { slideDown: genFx( "show" ), slideUp: genFx( "hide" ), slideToggle: genFx( "toggle" ), fadeIn: { opacity: "show" }, fadeOut: { opacity: "hide" }, fadeToggle: { opacity: "toggle" } }, function( name, props ) { jQuery.fn[ name ] = function( speed, easing, callback ) { return this.animate( props, speed, easing, callback ); }; } ); jQuery.timers = []; jQuery.fx.tick = function() { var timer, i = 0, timers = jQuery.timers; fxNow = Date.now(); for ( ; i < timers.length; i++ ) { timer = timers[ i ]; // Run the timer and safely remove it when done (allowing for external removal) if ( !timer() && timers[ i ] === timer ) { timers.splice( i--, 1 ); } } if ( !timers.length ) { jQuery.fx.stop(); } fxNow = undefined; }; jQuery.fx.timer = function( timer ) { jQuery.timers.push( timer ); jQuery.fx.start(); }; jQuery.fx.start = function() { if ( inProgress ) { return; } inProgress = true; schedule(); }; jQuery.fx.stop = function() { inProgress = null; }; jQuery.fx.speeds = { slow: 600, fast: 200, // Default speed _default: 400 }; // Based off of the plugin by Clint Helfers, with permission. jQuery.fn.delay = function( time, type ) { time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; type = type || "fx"; return this.queue( type, function( next, hooks ) { var timeout = window.setTimeout( next, time ); hooks.stop = function() { window.clearTimeout( timeout ); }; } ); }; var rfocusable = /^(?:input|select|textarea|button)$/i, rclickable = /^(?:a|area)$/i; jQuery.fn.extend( { prop: function( name, value ) { return access( this, jQuery.prop, name, value, arguments.length > 1 ); }, removeProp: function( name ) { return this.each( function() { delete this[ jQuery.propFix[ name ] || name ]; } ); } } ); jQuery.extend( { prop: function( elem, name, value ) { var ret, hooks, nType = elem.nodeType; // Don't get/set properties on text, comment and attribute nodes if ( nType === 3 || nType === 8 || nType === 2 ) { return; } if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { // Fix name and attach hooks name = jQuery.propFix[ name ] || name; hooks = jQuery.propHooks[ name ]; } if ( value !== undefined ) { if ( hooks && "set" in hooks && ( ret = hooks.set( elem, value, name ) ) !== undefined ) { return ret; } return ( elem[ name ] = value ); } if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { return ret; } return elem[ name ]; }, propHooks: { tabIndex: { get: function( elem ) { // Support: IE <=9 - 11+ // elem.tabIndex doesn't always return the // correct value when it hasn't been explicitly set // Use proper attribute retrieval (trac-12072) var tabindex = elem.getAttribute( "tabindex" ); if ( tabindex ) { return parseInt( tabindex, 10 ); } if ( rfocusable.test( elem.nodeName ) || // href-less anchor's `tabIndex` property value is `0` and // the `tabindex` attribute value: `null`. We want `-1`. rclickable.test( elem.nodeName ) && elem.href ) { return 0; } return -1; } } }, propFix: { "for": "htmlFor", "class": "className" } } ); // Support: IE <=11+ // Accessing the selectedIndex property forces the browser to respect // setting selected on the option. The getter ensures a default option // is selected when in an optgroup. ESLint rule "no-unused-expressions" // is disabled for this code since it considers such accessions noop. if ( isIE ) { jQuery.propHooks.selected = { get: function( elem ) { var parent = elem.parentNode; if ( parent && parent.parentNode ) { // eslint-disable-next-line no-unused-expressions parent.parentNode.selectedIndex; } return null; }, set: function( elem ) { var parent = elem.parentNode; if ( parent ) { // eslint-disable-next-line no-unused-expressions parent.selectedIndex; if ( parent.parentNode ) { // eslint-disable-next-line no-unused-expressions parent.parentNode.selectedIndex; } } } }; } jQuery.each( [ "tabIndex", "readOnly", "maxLength", "cellSpacing", "cellPadding", "rowSpan", "colSpan", "useMap", "frameBorder", "contentEditable" ], function() { jQuery.propFix[ this.toLowerCase() ] = this; } ); // Strip and collapse whitespace according to HTML spec // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace function stripAndCollapse( value ) { var tokens = value.match( rnothtmlwhite ) || []; return tokens.join( " " ); } function getClass( elem ) { return elem.getAttribute && elem.getAttribute( "class" ) || ""; } function classesToArray( value ) { if ( Array.isArray( value ) ) { return value; } if ( typeof value === "string" ) { return value.match( rnothtmlwhite ) || []; } return []; } jQuery.fn.extend( { addClass: function( value ) { var classNames, cur, curValue, className, i, finalValue; if ( typeof value === "function" ) { return this.each( function( j ) { jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); } ); } classNames = classesToArray( value ); if ( classNames.length ) { return this.each( function() { curValue = getClass( this ); cur = this.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); if ( cur ) { for ( i = 0; i < classNames.length; i++ ) { className = classNames[ i ]; if ( cur.indexOf( " " + className + " " ) < 0 ) { cur += className + " "; } } // Only assign if different to avoid unneeded rendering. finalValue = stripAndCollapse( cur ); if ( curValue !== finalValue ) { this.setAttribute( "class", finalValue ); } } } ); } return this; }, removeClass: function( value ) { var classNames, cur, curValue, className, i, finalValue; if ( typeof value === "function" ) { return this.each( function( j ) { jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); } ); } if ( !arguments.length ) { return this.attr( "class", "" ); } classNames = classesToArray( value ); if ( classNames.length ) { return this.each( function() { curValue = getClass( this ); // This expression is here for better compressibility (see addClass) cur = this.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); if ( cur ) { for ( i = 0; i < classNames.length; i++ ) { className = classNames[ i ]; // Remove *all* instances while ( cur.indexOf( " " + className + " " ) > -1 ) { cur = cur.replace( " " + className + " ", " " ); } } // Only assign if different to avoid unneeded rendering. finalValue = stripAndCollapse( cur ); if ( curValue !== finalValue ) { this.setAttribute( "class", finalValue ); } } } ); } return this; }, toggleClass: function( value, stateVal ) { var classNames, className, i, self; if ( typeof value === "function" ) { return this.each( function( i ) { jQuery( this ).toggleClass( value.call( this, i, getClass( this ), stateVal ), stateVal ); } ); } if ( typeof stateVal === "boolean" ) { return stateVal ? this.addClass( value ) : this.removeClass( value ); } classNames = classesToArray( value ); if ( classNames.length ) { return this.each( function() { // Toggle individual class names self = jQuery( this ); for ( i = 0; i < classNames.length; i++ ) { className = classNames[ i ]; // Check each className given, space separated list if ( self.hasClass( className ) ) { self.removeClass( className ); } else { self.addClass( className ); } } } ); } return this; }, hasClass: function( selector ) { var className, elem, i = 0; className = " " + selector + " "; while ( ( elem = this[ i++ ] ) ) { if ( elem.nodeType === 1 && ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { return true; } } return false; } } ); jQuery.fn.extend( { val: function( value ) { var hooks, ret, valueIsFunction, elem = this[ 0 ]; if ( !arguments.length ) { if ( elem ) { hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; if ( hooks && "get" in hooks && ( ret = hooks.get( elem, "value" ) ) !== undefined ) { return ret; } ret = elem.value; // Handle cases where value is null/undef or number return ret == null ? "" : ret; } return; } valueIsFunction = typeof value === "function"; return this.each( function( i ) { var val; if ( this.nodeType !== 1 ) { return; } if ( valueIsFunction ) { val = value.call( this, i, jQuery( this ).val() ); } else { val = value; } // Treat null/undefined as ""; convert numbers to string if ( val == null ) { val = ""; } else if ( typeof val === "number" ) { val += ""; } else if ( Array.isArray( val ) ) { val = jQuery.map( val, function( value ) { return value == null ? "" : value + ""; } ); } hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; // If set returns undefined, fall back to normal setting if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { this.value = val; } } ); } } ); jQuery.extend( { valHooks: { select: { get: function( elem ) { var value, option, i, options = elem.options, index = elem.selectedIndex, one = elem.type === "select-one", values = one ? null : [], max = one ? index + 1 : options.length; if ( index < 0 ) { i = max; } else { i = one ? index : 0; } // Loop through all the selected options for ( ; i < max; i++ ) { option = options[ i ]; if ( option.selected && // Don't return options that are disabled or in a disabled optgroup !option.disabled && ( !option.parentNode.disabled || !nodeName( option.parentNode, "optgroup" ) ) ) { // Get the specific value for the option value = jQuery( option ).val(); // We don't need an array for one selects if ( one ) { return value; } // Multi-Selects return an array values.push( value ); } } return values; }, set: function( elem, value ) { var optionSet, option, options = elem.options, values = jQuery.makeArray( value ), i = options.length; while ( i-- ) { option = options[ i ]; if ( ( option.selected = jQuery.inArray( jQuery( option ).val(), values ) > -1 ) ) { optionSet = true; } } // Force browsers to behave consistently when non-matching value is set if ( !optionSet ) { elem.selectedIndex = -1; } return values; } } } } ); if ( isIE ) { jQuery.valHooks.option = { get: function( elem ) { var val = elem.getAttribute( "value" ); return val != null ? val : // Support: IE <=10 - 11+ // option.text throws exceptions (trac-14686, trac-14858) // Strip and collapse whitespace // https://html.spec.whatwg.org/#strip-and-collapse-whitespace stripAndCollapse( jQuery.text( elem ) ); } }; } // Radios and checkboxes getter/setter jQuery.each( [ "radio", "checkbox" ], function() { jQuery.valHooks[ this ] = { set: function( elem, value ) { if ( Array.isArray( value ) ) { return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); } } }; } ); var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, stopPropagationCallback = function( e ) { e.stopPropagation(); }; jQuery.extend( jQuery.event, { trigger: function( event, data, elem, onlyHandlers ) { var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, eventPath = [ elem || document$1 ], type = hasOwn.call( event, "type" ) ? event.type : event, namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; cur = lastElement = tmp = elem = elem || document$1; // Don't do events on text and comment nodes if ( elem.nodeType === 3 || elem.nodeType === 8 ) { return; } // focus/blur morphs to focusin/out; ensure we're not firing them right now if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { return; } if ( type.indexOf( "." ) > -1 ) { // Namespaced trigger; create a regexp to match event type in handle() namespaces = type.split( "." ); type = namespaces.shift(); namespaces.sort(); } ontype = type.indexOf( ":" ) < 0 && "on" + type; // Caller can pass in a jQuery.Event object, Object, or just an event type string event = event[ jQuery.expando ] ? event : new jQuery.Event( type, typeof event === "object" && event ); // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) event.isTrigger = onlyHandlers ? 2 : 3; event.namespace = namespaces.join( "." ); event.rnamespace = event.namespace ? new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : null; // Clean up the event in case it is being reused event.result = undefined; if ( !event.target ) { event.target = elem; } // Clone any incoming data and prepend the event, creating the handler arg list data = data == null ? [ event ] : jQuery.makeArray( data, [ event ] ); // Allow special events to draw outside the lines special = jQuery.event.special[ type ] || {}; if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { return; } // Determine event propagation path in advance, per W3C events spec (trac-9951) // Bubble up to document, then to window; watch for a global ownerDocument var (trac-9724) if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { bubbleType = special.delegateType || type; if ( !rfocusMorph.test( bubbleType + type ) ) { cur = cur.parentNode; } for ( ; cur; cur = cur.parentNode ) { eventPath.push( cur ); tmp = cur; } // Only add window if we got to document (e.g., not plain obj or detached DOM) if ( tmp === ( elem.ownerDocument || document$1 ) ) { eventPath.push( tmp.defaultView || tmp.parentWindow || window ); } } // Fire handlers on the event path i = 0; while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { lastElement = cur; event.type = i > 1 ? bubbleType : special.bindType || type; // jQuery handler handle = ( dataPriv.get( cur, "events" ) || Object.create( null ) )[ event.type ] && dataPriv.get( cur, "handle" ); if ( handle ) { handle.apply( cur, data ); } // Native handler handle = ontype && cur[ ontype ]; if ( handle && handle.apply && acceptData( cur ) ) { event.result = handle.apply( cur, data ); if ( event.result === false ) { event.preventDefault(); } } } event.type = type; // If nobody prevented the default action, do it now if ( !onlyHandlers && !event.isDefaultPrevented() ) { if ( ( !special._default || special._default.apply( eventPath.pop(), data ) === false ) && acceptData( elem ) ) { // Call a native DOM method on the target with the same name as the event. // Don't do default actions on window, that's where global variables be (trac-6170) if ( ontype && typeof elem[ type ] === "function" && !isWindow( elem ) ) { // Don't re-trigger an onFOO event when we call its FOO() method tmp = elem[ ontype ]; if ( tmp ) { elem[ ontype ] = null; } // Prevent re-triggering of the same event, since we already bubbled it above jQuery.event.triggered = type; if ( event.isPropagationStopped() ) { lastElement.addEventListener( type, stopPropagationCallback ); } elem[ type ](); if ( event.isPropagationStopped() ) { lastElement.removeEventListener( type, stopPropagationCallback ); } jQuery.event.triggered = undefined; if ( tmp ) { elem[ ontype ] = tmp; } } } } return event.result; }, // Piggyback on a donor event to simulate a different one // Used only for `focus(in | out)` events simulate: function( type, elem, event ) { var e = jQuery.extend( new jQuery.Event(), event, { type: type, isSimulated: true } ); jQuery.event.trigger( e, null, elem ); } } ); jQuery.fn.extend( { trigger: function( type, data ) { return this.each( function() { jQuery.event.trigger( type, data, this ); } ); }, triggerHandler: function( type, data ) { var elem = this[ 0 ]; if ( elem ) { return jQuery.event.trigger( type, data, elem, true ); } } } ); var location = window.location; var nonce = { guid: Date.now() }; var rquery = /\?/; // Cross-browser xml parsing jQuery.parseXML = function( data ) { var xml, parserErrorElem; if ( !data || typeof data !== "string" ) { return null; } // Support: IE 9 - 11+ // IE throws on parseFromString with invalid input. try { xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); } catch ( e ) {} parserErrorElem = xml && xml.getElementsByTagName( "parsererror" )[ 0 ]; if ( !xml || parserErrorElem ) { jQuery.error( "Invalid XML: " + ( parserErrorElem ? jQuery.map( parserErrorElem.childNodes, function( el ) { return el.textContent; } ).join( "\n" ) : data ) ); } return xml; }; var rbracket = /\[\]$/, rCRLF = /\r?\n/g, rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, rsubmittable = /^(?:input|select|textarea|keygen)/i; function buildParams( prefix, obj, traditional, add ) { var name; if ( Array.isArray( obj ) ) { // Serialize array item. jQuery.each( obj, function( i, v ) { if ( traditional || rbracket.test( prefix ) ) { // Treat each array item as a scalar. add( prefix, v ); } else { // Item is non-scalar (array or object), encode its numeric index. buildParams( prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", v, traditional, add ); } } ); } else if ( !traditional && toType( obj ) === "object" ) { // Serialize object item. for ( name in obj ) { buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); } } else { // Serialize scalar item. add( prefix, obj ); } } // Serialize an array of form elements or a set of // key/values into a query string jQuery.param = function( a, traditional ) { var prefix, s = [], add = function( key, valueOrFunction ) { // If value is a function, invoke it and use its return value var value = typeof valueOrFunction === "function" ? valueOrFunction() : valueOrFunction; s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value == null ? "" : value ); }; if ( a == null ) { return ""; } // If an array was passed in, assume that it is an array of form elements. if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { // Serialize the form elements jQuery.each( a, function() { add( this.name, this.value ); } ); } else { // If traditional, encode the "old" way (the way 1.3.2 or older // did it), otherwise encode params recursively. for ( prefix in a ) { buildParams( prefix, a[ prefix ], traditional, add ); } } // Return the resulting serialization return s.join( "&" ); }; jQuery.fn.extend( { serialize: function() { return jQuery.param( this.serializeArray() ); }, serializeArray: function() { return this.map( function() { // Can add propHook for "elements" to filter or add form elements var elements = jQuery.prop( this, "elements" ); return elements ? jQuery.makeArray( elements ) : this; } ).filter( function() { var type = this.type; // Use .is( ":disabled" ) so that fieldset[disabled] works return this.name && !jQuery( this ).is( ":disabled" ) && rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && ( this.checked || !rcheckableType.test( type ) ); } ).map( function( _i, elem ) { var val = jQuery( this ).val(); if ( val == null ) { return null; } if ( Array.isArray( val ) ) { return jQuery.map( val, function( val ) { return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; } ); } return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; } ).get(); } } ); var r20 = /%20/g, rhash = /#.*$/, rantiCache = /([?&])_=[^&]*/, rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, // trac-7653, trac-8125, trac-8152: local protocol detection rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, rnoContent = /^(?:GET|HEAD)$/, rprotocol = /^\/\//, /* Prefilters * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) * 2) These are called: * - BEFORE asking for a transport * - AFTER param serialization (s.data is a string if s.processData is true) * 3) key is the dataType * 4) the catchall symbol "*" can be used * 5) execution will start with transport dataType and THEN continue down to "*" if needed */ prefilters = {}, /* Transports bindings * 1) key is the dataType * 2) the catchall symbol "*" can be used * 3) selection will start with transport dataType and THEN go to "*" if needed */ transports = {}, // Avoid comment-prolog char sequence (trac-10098); must appease lint and evade compression allTypes = "*/".concat( "*" ), // Anchor tag for parsing the document origin originAnchor = document$1.createElement( "a" ); originAnchor.href = location.href; // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport function addToPrefiltersOrTransports( structure ) { // dataTypeExpression is optional and defaults to "*" return function( dataTypeExpression, func ) { if ( typeof dataTypeExpression !== "string" ) { func = dataTypeExpression; dataTypeExpression = "*"; } var dataType, i = 0, dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; if ( typeof func === "function" ) { // For each dataType in the dataTypeExpression while ( ( dataType = dataTypes[ i++ ] ) ) { // Prepend if requested if ( dataType[ 0 ] === "+" ) { dataType = dataType.slice( 1 ) || "*"; ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); // Otherwise append } else { ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); } } } }; } // Base inspection function for prefilters and transports function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { var inspected = {}, seekingTransport = ( structure === transports ); function inspect( dataType ) { var selected; inspected[ dataType ] = true; jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); if ( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) { options.dataTypes.unshift( dataTypeOrTransport ); inspect( dataTypeOrTransport ); return false; } else if ( seekingTransport ) { return !( selected = dataTypeOrTransport ); } } ); return selected; } return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); } // A special extend for ajax options // that takes "flat" options (not to be deep extended) // Fixes trac-9887 function ajaxExtend( target, src ) { var key, deep, flatOptions = jQuery.ajaxSettings.flatOptions || {}; for ( key in src ) { if ( src[ key ] !== undefined ) { ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; } } if ( deep ) { jQuery.extend( true, target, deep ); } return target; } /* Handles responses to an ajax request: * - finds the right dataType (mediates between content-type and expected dataType) * - returns the corresponding response */ function ajaxHandleResponses( s, jqXHR, responses ) { var ct, type, finalDataType, firstDataType, contents = s.contents, dataTypes = s.dataTypes; // Remove auto dataType and get content-type in the process while ( dataTypes[ 0 ] === "*" ) { dataTypes.shift(); if ( ct === undefined ) { ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); } } // Check if we're dealing with a known content-type if ( ct ) { for ( type in contents ) { if ( contents[ type ] && contents[ type ].test( ct ) ) { dataTypes.unshift( type ); break; } } } // Check to see if we have a response for the expected dataType if ( dataTypes[ 0 ] in responses ) { finalDataType = dataTypes[ 0 ]; } else { // Try convertible dataTypes for ( type in responses ) { if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { finalDataType = type; break; } if ( !firstDataType ) { firstDataType = type; } } // Or just use first one finalDataType = finalDataType || firstDataType; } // If we found a dataType // We add the dataType to the list if needed // and return the corresponding response if ( finalDataType ) { if ( finalDataType !== dataTypes[ 0 ] ) { dataTypes.unshift( finalDataType ); } return responses[ finalDataType ]; } } /* Chain conversions given the request and the original response * Also sets the responseXXX fields on the jqXHR instance */ function ajaxConvert( s, response, jqXHR, isSuccess ) { var conv2, current, conv, tmp, prev, converters = {}, // Work with a copy of dataTypes in case we need to modify it for conversion dataTypes = s.dataTypes.slice(); // Create converters map with lowercased keys if ( dataTypes[ 1 ] ) { for ( conv in s.converters ) { converters[ conv.toLowerCase() ] = s.converters[ conv ]; } } current = dataTypes.shift(); // Convert to each sequential dataType while ( current ) { if ( s.responseFields[ current ] ) { jqXHR[ s.responseFields[ current ] ] = response; } // Apply the dataFilter if provided if ( !prev && isSuccess && s.dataFilter ) { response = s.dataFilter( response, s.dataType ); } prev = current; current = dataTypes.shift(); if ( current ) { // There's only work to do if current dataType is non-auto if ( current === "*" ) { current = prev; // Convert response if prev dataType is non-auto and differs from current } else if ( prev !== "*" && prev !== current ) { // Seek a direct converter conv = converters[ prev + " " + current ] || converters[ "* " + current ]; // If none found, seek a pair if ( !conv ) { for ( conv2 in converters ) { // If conv2 outputs current tmp = conv2.split( " " ); if ( tmp[ 1 ] === current ) { // If prev can be converted to accepted input conv = converters[ prev + " " + tmp[ 0 ] ] || converters[ "* " + tmp[ 0 ] ]; if ( conv ) { // Condense equivalence converters if ( conv === true ) { conv = converters[ conv2 ]; // Otherwise, insert the intermediate dataType } else if ( converters[ conv2 ] !== true ) { current = tmp[ 0 ]; dataTypes.unshift( tmp[ 1 ] ); } break; } } } } // Apply converter (if not an equivalence) if ( conv !== true ) { // Unless errors are allowed to bubble, catch and return them if ( conv && s.throws ) { response = conv( response ); } else { try { response = conv( response ); } catch ( e ) { return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current }; } } } } } } return { state: "success", data: response }; } jQuery.extend( { // Counter for holding the number of active queries active: 0, // Last-Modified header cache for next request lastModified: {}, etag: {}, ajaxSettings: { url: location.href, type: "GET", isLocal: rlocalProtocol.test( location.protocol ), global: true, processData: true, async: true, contentType: "application/x-www-form-urlencoded; charset=UTF-8", /* timeout: 0, data: null, dataType: null, username: null, password: null, cache: null, throws: false, traditional: false, headers: {}, */ accepts: { "*": allTypes, text: "text/plain", html: "text/html", xml: "application/xml, text/xml", json: "application/json, text/javascript" }, contents: { xml: /\bxml\b/, html: /\bhtml/, json: /\bjson\b/ }, responseFields: { xml: "responseXML", text: "responseText", json: "responseJSON" }, // Data converters // Keys separate source (or catchall "*") and destination types with a single space converters: { // Convert anything to text "* text": String, // Text to html (true = no transformation) "text html": true, // Evaluate text as a json expression "text json": JSON.parse, // Parse text as xml "text xml": jQuery.parseXML }, // For options that shouldn't be deep extended: // you can add your own custom options here if // and when you create one that shouldn't be // deep extended (see ajaxExtend) flatOptions: { url: true, context: true } }, // Creates a full fledged settings object into target // with both ajaxSettings and settings fields. // If target is omitted, writes into ajaxSettings. ajaxSetup: function( target, settings ) { return settings ? // Building a settings object ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : // Extending ajaxSettings ajaxExtend( jQuery.ajaxSettings, target ); }, ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), ajaxTransport: addToPrefiltersOrTransports( transports ), // Main method ajax: function( url, options ) { // If url is an object, simulate pre-1.5 signature if ( typeof url === "object" ) { options = url; url = undefined; } // Force options to be an object options = options || {}; var transport, // URL without anti-cache param cacheURL, // Response headers responseHeadersString, responseHeaders, // timeout handle timeoutTimer, // Url cleanup var urlAnchor, // Request state (becomes false upon send and true upon completion) completed, // To know if global events are to be dispatched fireGlobals, // Loop variable i, // uncached part of the url uncached, // Create the final options object s = jQuery.ajaxSetup( {}, options ), // Callbacks context callbackContext = s.context || s, // Context for global events is callbackContext if it is a DOM node or jQuery collection globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ? jQuery( callbackContext ) : jQuery.event, // Deferreds deferred = jQuery.Deferred(), completeDeferred = jQuery.Callbacks( "once memory" ), // Status-dependent callbacks statusCode = s.statusCode || {}, // Headers (they are sent all at once) requestHeaders = {}, requestHeadersNames = {}, // Default abort message strAbort = "canceled", // Fake xhr jqXHR = { readyState: 0, // Builds headers hashtable if needed getResponseHeader: function( key ) { var match; if ( completed ) { if ( !responseHeaders ) { responseHeaders = {}; while ( ( match = rheaders.exec( responseHeadersString ) ) ) { // Support: IE 11+ // `getResponseHeader( key )` in IE doesn't combine all header // values for the provided key into a single result with values // joined by commas as other browsers do. Instead, it returns // them on separate lines. responseHeaders[ match[ 1 ].toLowerCase() + " " ] = ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) .concat( match[ 2 ] ); } } match = responseHeaders[ key.toLowerCase() + " " ]; } return match == null ? null : match.join( ", " ); }, // Raw string getAllResponseHeaders: function() { return completed ? responseHeadersString : null; }, // Caches the header setRequestHeader: function( name, value ) { if ( completed == null ) { name = requestHeadersNames[ name.toLowerCase() ] = requestHeadersNames[ name.toLowerCase() ] || name; requestHeaders[ name ] = value; } return this; }, // Overrides response content-type header overrideMimeType: function( type ) { if ( completed == null ) { s.mimeType = type; } return this; }, // Status-dependent callbacks statusCode: function( map ) { var code; if ( map ) { if ( completed ) { // Execute the appropriate callbacks jqXHR.always( map[ jqXHR.status ] ); } else { // Lazy-add the new callbacks in a way that preserves old ones for ( code in map ) { statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; } } } return this; }, // Cancel the request abort: function( statusText ) { var finalText = statusText || strAbort; if ( transport ) { transport.abort( finalText ); } done( 0, finalText ); return this; } }; // Attach deferreds deferred.promise( jqXHR ); // Add protocol if not provided (prefilters might expect it) // Handle falsy url in the settings object (trac-10093: consistency with old signature) // We also use the url parameter if available s.url = ( ( url || s.url || location.href ) + "" ) .replace( rprotocol, location.protocol + "//" ); // Alias method option to type as per ticket trac-12004 s.type = options.method || options.type || s.method || s.type; // Extract dataTypes list s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; // A cross-domain request is in order when the origin doesn't match the current origin. if ( s.crossDomain == null ) { urlAnchor = document$1.createElement( "a" ); // Support: IE <=8 - 11+ // IE throws exception on accessing the href property if url is malformed, // e.g. http://example.com:80x/ try { urlAnchor.href = s.url; // Support: IE <=8 - 11+ // Anchor's host property isn't correctly set when s.url is relative urlAnchor.href = urlAnchor.href; s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== urlAnchor.protocol + "//" + urlAnchor.host; } catch ( e ) { // If there is an error parsing the URL, assume it is crossDomain, // it can be rejected by the transport if it is invalid s.crossDomain = true; } } // Apply prefilters inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); // Convert data if not already a string if ( s.data && s.processData && typeof s.data !== "string" ) { s.data = jQuery.param( s.data, s.traditional ); } // If request was aborted inside a prefilter, stop there if ( completed ) { return jqXHR; } // We can fire global events as of now if asked to // Don't fire events if jQuery.event is undefined in an ESM-usage scenario (trac-15118) fireGlobals = jQuery.event && s.global; // Watch for a new set of requests if ( fireGlobals && jQuery.active++ === 0 ) { jQuery.event.trigger( "ajaxStart" ); } // Uppercase the type s.type = s.type.toUpperCase(); // Determine if request has content s.hasContent = !rnoContent.test( s.type ); // Save the URL in case we're toying with the If-Modified-Since // and/or If-None-Match header later on // Remove hash to simplify url manipulation cacheURL = s.url.replace( rhash, "" ); // More options handling for requests with no content if ( !s.hasContent ) { // Remember the hash so we can put it back uncached = s.url.slice( cacheURL.length ); // If data is available and should be processed, append data to url if ( s.data && ( s.processData || typeof s.data === "string" ) ) { cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; // trac-9682: remove data so that it's not used in an eventual retry delete s.data; } // Add or update anti-cache param if needed if ( s.cache === false ) { cacheURL = cacheURL.replace( rantiCache, "$1" ); uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) + uncached; } // Put hash and anti-cache on the URL that will be requested (gh-1732) s.url = cacheURL + uncached; // Change '%20' to '+' if this is encoded form body content (gh-2658) } else if ( s.data && s.processData && ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { s.data = s.data.replace( r20, "+" ); } // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. if ( s.ifModified ) { if ( jQuery.lastModified[ cacheURL ] ) { jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); } if ( jQuery.etag[ cacheURL ] ) { jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); } } // Set the correct header, if data is being sent if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { jqXHR.setRequestHeader( "Content-Type", s.contentType ); } // Set the Accepts header for the server, depending on the dataType jqXHR.setRequestHeader( "Accept", s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? s.accepts[ s.dataTypes[ 0 ] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : s.accepts[ "*" ] ); // Check for headers option for ( i in s.headers ) { jqXHR.setRequestHeader( i, s.headers[ i ] ); } // Allow custom headers/mimetypes and early abort if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { // Abort if not done already and return return jqXHR.abort(); } // Aborting is no longer a cancellation strAbort = "abort"; // Install callbacks on deferreds completeDeferred.add( s.complete ); jqXHR.done( s.success ); jqXHR.fail( s.error ); // Get transport transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); // If no transport, we auto-abort if ( !transport ) { done( -1, "No Transport" ); } else { jqXHR.readyState = 1; // Send global event if ( fireGlobals ) { globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); } // If request was aborted inside ajaxSend, stop there if ( completed ) { return jqXHR; } // Timeout if ( s.async && s.timeout > 0 ) { timeoutTimer = window.setTimeout( function() { jqXHR.abort( "timeout" ); }, s.timeout ); } try { completed = false; transport.send( requestHeaders, done ); } catch ( e ) { // Rethrow post-completion exceptions if ( completed ) { throw e; } // Propagate others as results done( -1, e ); } } // Callback for when everything is done function done( status, nativeStatusText, responses, headers ) { var isSuccess, success, error, response, modified, statusText = nativeStatusText; // Ignore repeat invocations if ( completed ) { return; } completed = true; // Clear timeout if it exists if ( timeoutTimer ) { window.clearTimeout( timeoutTimer ); } // Dereference transport for early garbage collection // (no matter how long the jqXHR object will be used) transport = undefined; // Cache response headers responseHeadersString = headers || ""; // Set readyState jqXHR.readyState = status > 0 ? 4 : 0; // Determine if successful isSuccess = status >= 200 && status < 300 || status === 304; // Get response data if ( responses ) { response = ajaxHandleResponses( s, jqXHR, responses ); } // Use a noop converter for missing script but not if jsonp if ( !isSuccess && jQuery.inArray( "script", s.dataTypes ) > -1 && jQuery.inArray( "json", s.dataTypes ) < 0 ) { s.converters[ "text script" ] = function() {}; } // Convert no matter what (that way responseXXX fields are always set) response = ajaxConvert( s, response, jqXHR, isSuccess ); // If successful, handle type chaining if ( isSuccess ) { // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. if ( s.ifModified ) { modified = jqXHR.getResponseHeader( "Last-Modified" ); if ( modified ) { jQuery.lastModified[ cacheURL ] = modified; } modified = jqXHR.getResponseHeader( "etag" ); if ( modified ) { jQuery.etag[ cacheURL ] = modified; } } // if no content if ( status === 204 || s.type === "HEAD" ) { statusText = "nocontent"; // if not modified } else if ( status === 304 ) { statusText = "notmodified"; // If we have data, let's convert it } else { statusText = response.state; success = response.data; error = response.error; isSuccess = !error; } } else { // Extract error from statusText and normalize for non-aborts error = statusText; if ( status || !statusText ) { statusText = "error"; if ( status < 0 ) { status = 0; } } } // Set data for the fake xhr object jqXHR.status = status; jqXHR.statusText = ( nativeStatusText || statusText ) + ""; // Success/Error if ( isSuccess ) { deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); } else { deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); } // Status-dependent callbacks jqXHR.statusCode( statusCode ); statusCode = undefined; if ( fireGlobals ) { globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", [ jqXHR, s, isSuccess ? success : error ] ); } // Complete completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); if ( fireGlobals ) { globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); // Handle the global AJAX counter if ( !( --jQuery.active ) ) { jQuery.event.trigger( "ajaxStop" ); } } } return jqXHR; }, getJSON: function( url, data, callback ) { return jQuery.get( url, data, callback, "json" ); }, getScript: function( url, callback ) { return jQuery.get( url, undefined, callback, "script" ); } } ); jQuery.each( [ "get", "post" ], function( _i, method ) { jQuery[ method ] = function( url, data, callback, type ) { // Shift arguments if data argument was omitted. // Handle the null callback placeholder. if ( typeof data === "function" || data === null ) { type = type || callback; callback = data; data = undefined; } // The url can be an options object (which then must have .url) return jQuery.ajax( jQuery.extend( { url: url, type: method, dataType: type, data: data, success: callback }, jQuery.isPlainObject( url ) && url ) ); }; } ); jQuery.ajaxPrefilter( function( s ) { var i; for ( i in s.headers ) { if ( i.toLowerCase() === "content-type" ) { s.contentType = s.headers[ i ] || ""; } } } ); jQuery._evalUrl = function( url, options, doc ) { return jQuery.ajax( { url: url, // Make this explicit, since user can override this through ajaxSetup (trac-11264) type: "GET", dataType: "script", cache: true, async: false, global: false, scriptAttrs: options.crossOrigin ? { "crossOrigin": options.crossOrigin } : undefined, // Only evaluate the response if it is successful (gh-4126) // dataFilter is not invoked for failure responses, so using it instead // of the default converter is kludgy but it works. converters: { "text script": function() {} }, dataFilter: function( response ) { jQuery.globalEval( response, options, doc ); } } ); }; jQuery.fn.extend( { wrapAll: function( html ) { var wrap; if ( this[ 0 ] ) { if ( typeof html === "function" ) { html = html.call( this[ 0 ] ); } // The elements to wrap the target around wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); if ( this[ 0 ].parentNode ) { wrap.insertBefore( this[ 0 ] ); } wrap.map( function() { var elem = this; while ( elem.firstElementChild ) { elem = elem.firstElementChild; } return elem; } ).append( this ); } return this; }, wrapInner: function( html ) { if ( typeof html === "function" ) { return this.each( function( i ) { jQuery( this ).wrapInner( html.call( this, i ) ); } ); } return this.each( function() { var self = jQuery( this ), contents = self.contents(); if ( contents.length ) { contents.wrapAll( html ); } else { self.append( html ); } } ); }, wrap: function( html ) { var htmlIsFunction = typeof html === "function"; return this.each( function( i ) { jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); } ); }, unwrap: function( selector ) { this.parent( selector ).not( "body" ).each( function() { jQuery( this ).replaceWith( this.childNodes ); } ); return this; } } ); jQuery.expr.pseudos.hidden = function( elem ) { return !jQuery.expr.pseudos.visible( elem ); }; jQuery.expr.pseudos.visible = function( elem ) { return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); }; jQuery.ajaxSettings.xhr = function() { return new window.XMLHttpRequest(); }; var xhrSuccessStatus = { // File protocol always yields status code 0, assume 200 0: 200 }; jQuery.ajaxTransport( function( options ) { var callback; return { send: function( headers, complete ) { var i, xhr = options.xhr(); xhr.open( options.type, options.url, options.async, options.username, options.password ); // Apply custom fields if provided if ( options.xhrFields ) { for ( i in options.xhrFields ) { xhr[ i ] = options.xhrFields[ i ]; } } // Override mime type if needed if ( options.mimeType && xhr.overrideMimeType ) { xhr.overrideMimeType( options.mimeType ); } // X-Requested-With header // For cross-domain requests, seeing as conditions for a preflight are // akin to a jigsaw puzzle, we simply never set it to be sure. // (it can always be set on a per-request basis or even using ajaxSetup) // For same-domain requests, won't change header if already provided. if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { headers[ "X-Requested-With" ] = "XMLHttpRequest"; } // Set headers for ( i in headers ) { xhr.setRequestHeader( i, headers[ i ] ); } // Callback callback = function( type ) { return function() { if ( callback ) { callback = xhr.onload = xhr.onerror = xhr.onabort = xhr.ontimeout = null; if ( type === "abort" ) { xhr.abort(); } else if ( type === "error" ) { complete( // File: protocol always yields status 0; see trac-8605, trac-14207 xhr.status, xhr.statusText ); } else { complete( xhrSuccessStatus[ xhr.status ] || xhr.status, xhr.statusText, // For XHR2 non-text, let the caller handle it (gh-2498) ( xhr.responseType || "text" ) === "text" ? { text: xhr.responseText } : { binary: xhr.response }, xhr.getAllResponseHeaders() ); } } }; }; // Listen to events xhr.onload = callback(); xhr.onabort = xhr.onerror = xhr.ontimeout = callback( "error" ); // Create the abort callback callback = callback( "abort" ); try { // Do send the request (this may raise an exception) xhr.send( options.hasContent && options.data || null ); } catch ( e ) { // trac-14683: Only rethrow if this hasn't been notified as an error yet if ( callback ) { throw e; } } }, abort: function() { if ( callback ) { callback(); } } }; } ); function canUseScriptTag( s ) { // A script tag can only be used for async, cross domain or forced-by-attrs requests. // Requests with headers cannot use a script tag. However, when both `scriptAttrs` & // `headers` options are specified, both are impossible to satisfy together; we // prefer `scriptAttrs` then. // Sync requests remain handled differently to preserve strict script ordering. return s.scriptAttrs || ( !s.headers && ( s.crossDomain || // When dealing with JSONP (`s.dataTypes` include "json" then) // don't use a script tag so that error responses still may have // `responseJSON` set. Continue using a script tag for JSONP requests that: // * are cross-domain as AJAX requests won't work without a CORS setup // * have `scriptAttrs` set as that's a script-only functionality // Note that this means JSONP requests violate strict CSP script-src settings. // A proper solution is to migrate from using JSONP to a CORS setup. ( s.async && jQuery.inArray( "json", s.dataTypes ) < 0 ) ) ); } // Install script dataType. Don't specify `contents.script` so that an explicit // `dataType: "script"` is required (see gh-2432, gh-4822) jQuery.ajaxSetup( { accepts: { script: "text/javascript, application/javascript, " + "application/ecmascript, application/x-ecmascript" }, converters: { "text script": function( text ) { jQuery.globalEval( text ); return text; } } } ); // Handle cache's special case and crossDomain jQuery.ajaxPrefilter( "script", function( s ) { if ( s.cache === undefined ) { s.cache = false; } // These types of requests are handled via a script tag // so force their methods to GET. if ( canUseScriptTag( s ) ) { s.type = "GET"; } } ); // Bind script tag hack transport jQuery.ajaxTransport( "script", function( s ) { if ( canUseScriptTag( s ) ) { var script, callback; return { send: function( _, complete ) { script = jQuery( "

    jQuery UI Tests

    Unit Tests

    Unit tests exist for all functionality in jQuery UI. The unit tests can be run locally (some tests require a web server with PHP) to ensure proper functionality before committing changes. The unit tests are also run in Chrome, Firefox, Edge, and Safari on every commit.

    Visual Tests

    Visual tests only exist in cases where we can't verify proper functionality with unit tests. These may be either purely visual or just hard to automate. Most visual tests will provide a description of what is happening on the page and what to look for.

    ================================================ FILE: tests/index.js ================================================ $( function() { $( "#main" ) .addClass( "ui-widget" ) .find( "h1, h2" ) .addClass( "ui-widget-header ui-corner-top" ) .next() .addClass( "ui-widget-content ui-corner-bottom" ); } ); ================================================ FILE: tests/lib/bootstrap.js ================================================ ( function() { "use strict"; var DEFAULT_JQUERY_VERSION = "3.7.1"; requirejs.config( { paths: { "globalize": "../../../external/globalize/globalize", "globalize/ja-JP": "../../../external/globalize/globalize.culture.ja-JP", "jquery": jqueryUrl(), "jquery-migrate": migrateUrl(), "jquery-simulate": "../../../external/jquery-simulate/jquery.simulate", "lib": "../../lib", "qunit-assert-classes": "../../lib/vendor/qunit-assert-classes/qunit-assert-classes", "qunit-assert-close": "../../lib/vendor/qunit-assert-close/qunit-assert-close", "qunit": "../../../external/qunit/qunit", "ui": "../../../ui" }, shim: { "globalize/ja-JP": [ "globalize" ], "jquery-simulate": [ "jquery" ], "qunit-assert-close": [ "qunit" ] } } ); // Create a module that enables back compat for UI modules define( "jquery-back-compat", [ "jquery" ], function( $ ) { $.uiBackCompat = true; return $; } ); // Load all modules in series function requireModules( dependencies, callback, modules ) { if ( !dependencies.length ) { if ( callback ) { callback.apply( null, modules ); } return; } if ( !modules ) { modules = []; } var dependency = dependencies.shift(); require( [ dependency ], function( module ) { modules.push( module ); requireModules( dependencies, callback, modules ); } ); } // Load a set of test file along with the required test infrastructure function requireTests( dependencies, options ) { var backCompat = !!( options && options.backCompat ), preDependencies = [ "lib/qunit", backCompat ? "jquery-back-compat" : "jquery", "jquery-simulate" ]; // Load migrate before test files if ( parseUrl().migrate ) { preDependencies.push( "jquery-migrate" ); } dependencies = preDependencies.concat( dependencies ); requireModules( dependencies, function( QUnit ) { QUnit.start(); } ); } // Parse the URL into key/value pairs function parseUrl() { var data = {}; var parts = document.location.search.slice( 1 ).split( "&" ); var length = parts.length; var i = 0; var current; for ( ; i < length; i++ ) { if ( parts[ i ].match( "=" ) ) { current = parts[ i ].split( "=" ); data[ current[ 0 ] ] = current[ 1 ]; } else { data[ parts[ i ] ] = true; } } return data; } function jqueryUrl() { var version = parseUrl().jquery || DEFAULT_JQUERY_VERSION; var url; if ( version === "git" || version === "3.x-git" ) { url = "https://releases.jquery.com/git/jquery-" + version; } else { url = "../../../external/jquery-" + version + "/jquery"; } return url; } function migrateUrl() { var jqueryVersion = parseUrl().jquery || DEFAULT_JQUERY_VERSION; var url; if ( jqueryVersion === "git" ) { url = "https://releases.jquery.com/git/jquery-migrate-git"; } else if ( jqueryVersion[ 0 ] === "4" ) { url = "../../../external/jquery-migrate-4.x/jquery-migrate"; } else if ( jqueryVersion[ 0 ] === "3" ) { url = "../../../external/jquery-migrate-3.x/jquery-migrate"; } else if ( jqueryVersion[ 0 ] === "1" || jqueryVersion[ 0 ] === "2" ) { url = "../../../external/jquery-migrate-1.x/jquery-migrate"; } else if ( jqueryVersion === "custom" ) { if ( parseUrl().migrate ) { throw new Error( "Migrate not currently supported for custom build" ); } } else { throw new Error( "No migrate version known for jQuery " + jqueryVersion ); } return url; } // Load test modules based on data attributes // - data-modules: list of test modules to load // - data-widget: A widget to load test modules for // - Automatically loads common, core, events, methods, and options // - data-deprecated: Loads the deprecated test modules for a widget // - data-back-compat: Set $.uiBackCompat to `true` ( function() { // Find the script element var scripts = document.getElementsByTagName( "script" ); var script = scripts[ scripts.length - 1 ]; // Read the modules var modules = script.getAttribute( "data-modules" ); if ( modules ) { modules = modules .replace( /^\s+|\s+$/g, "" ) .split( /\s+/ ); } else { modules = []; } var widget = script.getAttribute( "data-widget" ); var deprecated = !!script.getAttribute( "data-deprecated" ); var backCompat = !!script.getAttribute( "data-back-compat" ); if ( widget ) { modules = modules.concat( [ ( deprecated ? "common-deprecated" : "common" ), "core", "events", "methods", "options" ] ); if ( deprecated ) { modules = modules.concat( "deprecated" ); } } requireTests( modules, { backCompat: backCompat } ); } )(); } )(); ================================================ FILE: tests/lib/common.js ================================================ define( [ "qunit", "jquery", "lib/helper" ], function( QUnit, $, helper ) { "use strict"; var exports = {}; function testWidgetDefaults( widget, defaults ) { var pluginDefaults = $.ui[ widget ].prototype.options; // Ensure that all defaults have the correct value QUnit.test( "defined defaults", function( assert ) { var count = 0; $.each( defaults, function( key, val ) { assert.expect( ++count ); if ( typeof val === "function" ) { assert.ok( typeof pluginDefaults[ key ] === "function", key ); return; } assert.deepEqual( pluginDefaults[ key ], val, key ); } ); } ); // Ensure that all defaults were tested QUnit.test( "tested defaults", function( assert ) { var count = 0; $.each( pluginDefaults, function( key ) { assert.expect( ++count ); assert.ok( key in defaults, key ); } ); } ); } function testWidgetOverrides( widget ) { if ( $.uiBackCompat !== true ) { QUnit.test( "$.widget overrides", function( assert ) { assert.expect( 4 ); $.each( [ "_createWidget", "destroy", "option", "_trigger" ], function( i, method ) { if ( method === "_trigger" && /^(?:draggable|sortable): common widget$/ .test( assert.test.module.name ) ) { // Draggable & sortable modules overwrite _trigger. They // should not, but we don't plan to change the API at this // stage of the project. assert.ok( true, "draggable & sortable modules overwrite _trigger" ); } else { assert.strictEqual( $.ui[ widget ].prototype[ method ], $.Widget.prototype[ method ], "should not override " + method ); } } ); } ); } } function testBasicUsage( widget ) { QUnit.test( "basic usage", function( assert ) { assert.expect( 3 ); var defaultElement = $.ui[ widget ].prototype.defaultElement; $( defaultElement ).appendTo( "body" )[ widget ]().remove(); assert.ok( true, "initialized on element" ); $( defaultElement )[ widget ]().remove(); assert.ok( true, "initialized on disconnected DOMElement - never connected" ); // Ensure manipulating removed elements works (#3664) $( defaultElement ).appendTo( "body" ).remove()[ widget ]().remove(); assert.ok( true, "initialized on disconnected DOMElement - removed" ); } ); } exports.testWidget = function( widget, settings ) { QUnit.module( widget + ": common widget", { afterEach: helper.moduleAfterEach } ); testWidgetDefaults( widget, settings.defaults ); testWidgetOverrides( widget ); if ( !settings.noDefaultElement ) { testBasicUsage( widget ); } QUnit.test( "version", function( assert ) { assert.expect( 1 ); assert.ok( "version" in $.ui[ widget ].prototype, "version property exists" ); } ); }; return exports; } ); ================================================ FILE: tests/lib/css.js ================================================ ( function() { "use strict"; function includeStyle( url ) { document.write( "" ); } // Find the script element var scripts = document.getElementsByTagName( "script" ); var script = scripts[ scripts.length - 1 ]; // Load the modules var modules = script.getAttribute( "data-modules" ); if ( modules ) { modules = modules.split( /\s+/ ); for ( var i = 0; i < modules.length; i++ ) { includeStyle( "themes/base/" + modules[ i ] + ".css" ); } } // Load the QUnit stylesheet includeStyle( "external/qunit/qunit.css" ); } )(); ================================================ FILE: tests/lib/grunt-contrib-qunit-bridges/bridge-wrapper.js.intro ================================================ // The bridge in `node_modules/grunt-contrib-qunit/chrome/bridge.js` is injected // into every iframe, even an empty one injected during QUnit tests. The bridge, // in turn, requires QUnit to be present on the page, throwing errors otherwise. // To workaround that, add another wrapper which detects a missing QUnit and skips // the whole logic. ( function ( factory ) { if ( typeof define === 'function' && define.amd ) { require( [ 'qunit' ], factory ); } else { factory( window.QUnit ); } } )( function( QUnit ) { if ( !QUnit ) { // No QUnit => possibly an empty iframe injected in tests; ignore. return; } ================================================ FILE: tests/lib/grunt-contrib-qunit-bridges/bridge-wrapper.js.outro ================================================ } ); ================================================ FILE: tests/lib/helper.js ================================================ define( [ "jquery" ], function( $ ) { var exports = {}, // Store the old count so that we only assert on tests that have actually leaked, // instead of asserting every time a test has leaked sometime in the past oldActive = 0, splice = [].splice; exports.forceScrollableWindow = function( appendTo ) { // The main testable area is 10000x10000 so to enforce scrolling, // this DIV must be greater than 10000 to work return $( "
    " ) .css( { height: "11000px", width: "11000px" } ) .appendTo( appendTo || "#qunit-fixture" ); }; exports.onFocus = function( element, onFocus ) { var fn = function( event ) { if ( !event.originalEvent ) { return; } element.off( "focus", fn ); onFocus(); }; element.on( "focus", fn )[ 0 ].focus(); }; /** * Ensures that tests have cleaned up properly after themselves. Should be passed as the * afterEach function on all modules' lifecycle object. */ exports.moduleAfterEach = function( assert ) { // Check for (and clean up, if possible) incomplete animations/requests/etc. if ( jQuery.timers && jQuery.timers.length !== 0 ) { assert.equal( jQuery.timers.length, 0, "No timers are still running" ); splice.call( jQuery.timers, 0, jQuery.timers.length ); jQuery.fx.stop(); } if ( jQuery.active !== undefined && jQuery.active !== oldActive ) { assert.equal( jQuery.active, oldActive, "No AJAX requests are still active" ); oldActive = jQuery.active; } }; exports.testIframe = function( title, fileName, func, wrapper, iframeStyles ) { if ( !wrapper ) { wrapper = QUnit.test; } wrapper.call( QUnit, title, function( assert ) { var done = assert.async(), $iframe = jQuery( "" ) .css( { position: "absolute", top: "0", left: "-600px", width: "500px", zIndex: 1, background: "white" } ) .attr( { id: "qunit-fixture-iframe", src: fileName } ); // Add other iframe styles if ( iframeStyles ) { $iframe.css( iframeStyles ); } // Test iframes are expected to invoke this via startIframeTest // (cf. iframeTest.js) window.iframeCallback = function() { var args = Array.prototype.slice.call( arguments ); args.unshift( assert ); setTimeout( function() { var result; this.iframeCallback = undefined; result = func.apply( this, args ); function finish() { func = function() {}; $iframe.remove(); done(); } // Wait for promises returned by `func`. if ( result && result.then ) { result.then( finish ); } else { finish(); } } ); }; // Attach iframe to the body for visibility-dependent code. // It will be removed by either the above code, or the testDone // callback in qunit.js. $iframe.prependTo( document.body ); } ); }; window.iframeCallback = undefined; return exports; } ); ================================================ FILE: tests/lib/qunit-assert-domequal.js ================================================ /* * Experimental assertion for comparing DOM objects. * * Serializes an element and some properties and attributes and its children if any, * otherwise the text. Then compares the result using deepEqual(). */ define( [ "qunit", "jquery" ], function( QUnit, $ ) { "use strict"; var domEqual = QUnit.assert.domEqual = function( selector, modifier, message ) { var assert = this; // Get current state prior to modifier var expected = extract( assert, selector, message ); function done() { var actual = extract( assert, selector, message ); assert.pushResult( { result: QUnit.equiv( actual, expected ), actual: actual, expected: expected, message: message } ); } // Run modifier (async or sync), then compare state via done() if ( modifier.length ) { modifier( done ); } else { modifier(); done(); } }; domEqual.properties = [ "disabled", "nodeName", "readOnly" ]; domEqual.attributes = [ "autocomplete", "aria-activedescendant", "aria-controls", "aria-describedby", "aria-disabled", "aria-expanded", "aria-haspopup", "aria-hidden", "aria-labelledby", "aria-pressed", "aria-selected", "aria-valuemax", "aria-valuemin", "aria-valuenow", "class", "href", "id", "role", "tabIndex", "title" ]; function camelCase( string ) { return string.replace( /-([\da-z])/gi, function( all, letter ) { return letter.toUpperCase(); } ); } function getElementStyles( elem ) { var styles = {}; var style = elem.ownerDocument.defaultView ? elem.ownerDocument.defaultView.getComputedStyle( elem, null ) : elem.currentStyle; var key, camelKey; var len = style.length; while ( len-- ) { key = style[ len ]; camelKey = camelCase( key ); if ( typeof style[ key ] === "string" ) { styles[ camelKey ] = style[ key ]; } } return styles; } // Returns 0 if v1 == v2, -1 if v1 < v2, 1 if v1 > v2 function compareVersions( v1, v2 ) { var i, rVersionParts = /^(\d+)\.(\d+)\.(\d+)/, v1p = rVersionParts.exec( v1 ) || [ ], v2p = rVersionParts.exec( v2 ) || [ ]; for ( i = 1; i <= 3; i++ ) { if ( +v1p[ i ] > +v2p[ i ] ) { return 1; } if ( +v1p[ i ] < +v2p[ i ] ) { return -1; } } return 0; } function jQueryVersionSince( version ) { return compareVersions( $.fn.jquery, version ) >= 0; } function extract( assert, selector, message ) { var elem = $( selector ); if ( !elem.length ) { assert.pushResult( { result: false, actual: null, expected: null, message: "domEqual failed, can't extract " + selector + ", message was: " + message } ); return; } var result = {}; var children; $.each( domEqual.properties, function( index, attr ) { var value = elem.prop( attr ); result[ attr ] = value != null ? value : ""; } ); $.each( domEqual.attributes, function( index, attr ) { var value = elem.attr( attr ); result[ attr ] = value != null ? value : ""; } ); result.style = getElementStyles( elem[ 0 ] ); result.events = $._data( elem[ 0 ], "events" ); // jQuery >=3.4.0 uses a special focus/blur handler pair // needed to fix various issues with checkboxes/radio buttons // as well as being able to pass data in focus triggers. // However, this leaves dummy focus & blur events if any of these // events were ever listened to at a particular element. There's not // a lot UI can do to fix this so just skip these handlers for // data comparisons in tests. // See https://github.com/jquery/jquery/issues/4496 if ( result.events && jQueryVersionSince( "3.4.0" ) ) { $.each( [ "focus", "blur" ], function( index, eventType ) { if ( !result.events[ eventType ] ) { return; } // Filter special jQuery focus-related handlers out. result.events[ eventType ] = result.events[ eventType ] .filter( function( eventData ) { var handlerBody = eventData.handler.toString().replace( /^[^{]+\{[\s\n]*((?:.|\n)*?)\s*;?\s*\}[^}]*$/, "$1" ); // Only these special jQuery internal handlers // have the `namespace` field set to `false`; // all other events use a string value, possibly // an empty string if no namespace was set. return eventData.namespace !== false && // If a focus event was triggered without adding a handler first, // jQuery attaches an empty handler at the beginning of a trigger // call. Ignore this handler as well; it's a function with just // `return true;` in the body. // Handle the minified version as well. handlerBody !== "return true" && handlerBody !== "return!0"; } ); // Remove empty eventData collections to follow jQuery behavior. if ( !result.events[ eventType ].length ) { delete result.events[ eventType ]; } } ); // Simulate empty events collections removal to follow jQuery behavior. if ( !Object.keys( result.events ).length ) { result.events = undefined; } } result.data = $.extend( {}, elem.data() ); delete result.data[ $.expando ]; children = elem.children(); if ( children.length ) { result.children = elem.children().map( function() { return extract( assert, $( this ) ); } ).get(); } else { result.text = elem.text(); } return result; } } ); ================================================ FILE: tests/lib/qunit.js ================================================ define( [ "qunit", "jquery", "qunit-assert-classes", "qunit-assert-close", "lib/qunit-assert-domequal" ], function( QUnit, $ ) { "use strict"; var ajaxSettings = $.ajaxSettings; QUnit.config.autostart = false; QUnit.config.requireExpects = true; QUnit.config.urlConfig.push( { id: "jquery", label: "jQuery version", value: [ "1.12.4", "2.2.4", "3.0.0", "3.1.0", "3.1.1", "3.2.0", "3.2.1", "3.3.0", "3.3.1", "3.4.0", "3.4.1", "3.5.0", "3.5.1", "3.6.0", "3.6.1", "3.6.2", "3.6.3", "3.6.4", "3.7.0", "3.7.1", "4.0.0", "3.x-git", "git", "custom" ], tooltip: "Which jQuery Core version to test against" } ); QUnit.config.urlConfig.push( { id: "migrate", label: "Enable jquery-migrate" } ); QUnit.testDone( function() { // Ensure jQuery events and data on the fixture are properly removed $( "#qunit-fixture" ).empty(); // Remove the iframe fixture $( "#qunit-fixture-iframe" ).remove(); // Reset internal $ state if ( ajaxSettings ) { $.ajaxSettings = $.extend( true, {}, ajaxSettings ); } else { delete $.ajaxSettings; } } ); return QUnit; } ); ================================================ FILE: tests/lib/testIframe.js ================================================ window.startIframeTest = function() { var args = Array.prototype.slice.call( arguments ); // Note: jQuery may be undefined if page did not load it args.unshift( window.jQuery, window, document ); window.parent.iframeCallback.apply( null, args ); }; ================================================ FILE: tests/lib/vendor/qunit-assert-classes/LICENSE.txt ================================================ The MIT License (MIT) Copyright (c) 2015 Alexander Schmitz 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. ================================================ FILE: tests/lib/vendor/qunit-assert-classes/qunit-assert-classes.js ================================================ // With custom modifications - all are marked with // a "Custom modification" comment. ( function( factory ) { if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "qunit" ], factory ); } else { // Browser globals factory( QUnit ); } }( function( QUnit ) { function inArray( haystack, needle ) { for ( var i = 0; i < haystack.length; i++ ) { if ( ( needle instanceof RegExp && needle.test( haystack[ i ] ) )|| ( typeof needle === "string" && haystack[ i ] === needle ) ) { return true; } } return false; } function check( element, search ) { var i, classAttribute, elementClassArray, missing = [], found = []; if ( element.jquery && element.length !== 1 ) { throw new Error( "Class checks can only be performed on a single element on a collection" ); } element = element.jquery ? element[ 0 ] : element; classAttribute = element.getAttribute( "class" ); if ( classAttribute ) { elementClassArray = splitClasses( classAttribute ); if ( search instanceof RegExp ) { if ( inArray( elementClassArray, search ) ) { found.push( search ); } else { missing.push( search ); } } else { for( i = 0; i < search.length; i++ ) { if ( !inArray( elementClassArray, search[ i ] ) ) { missing.push( search[ i ] ); } else { found.push( search[ i ] ); } } } } else { missing = search; } return { missing: missing, found: found, element: element, classAttribute: classAttribute }; } function splitClasses( classes ) { return classes.match( /\S+/g ) || []; } function pluralize( message, classes ) { return message + ( classes.length > 1 ? "es" : "" ); } // Custom modification: removing QUnit.extend var key; var qunitAssertExtensions = { hasClasses: function( element, classes, message ) { var classArray = splitClasses( classes ), results = check( element, classArray ); message = message || pluralize( "Element must have class", classArray ); // Custom modification: push -> pushResult this.pushResult( { result: !results.missing.length, actual: results.found.join( " " ), expected: classes, message: message } ); }, lacksClasses: function( element, classes, message ) { var classArray = splitClasses( classes ), results = check( element, classArray ); message = message || pluralize( "Element must not have class", classArray ); // Custom modification: push -> pushResult this.pushResult( { result: !results.found.length, actual: results.found.join( " " ), expected: classes, message: message } ); }, hasClassesStrict: function( element, classes, message ) { var result, classArray = splitClasses( classes ), results = check( element, classArray ); message = message || pluralize( "Element must only have class", classArray ); result = !results.missing.length && results.element.getAttribute( "class" ) && splitClasses( results.element.getAttribute( "class" ) ).length === results.found.length; // Custom modification: push -> pushResult this.pushResult( { result: result, actual: results.found.join( " " ), expected: classes, message: message } ); }, hasClassRegex: function( element, regex, message ) { var results = check( element, regex ); message = message || "Element must have class matching " + regex; // Custom modification: push -> pushResult this.pushResult( { result: !!results.found.length, actual: results.found.join( " " ), expected: regex, message: message } ); }, lacksClassRegex: function( element, regex, message ) { var results = check( element, regex ); message = message || "Element must not have class matching " + regex; // Custom modification: push -> pushResult this.pushResult( { result: results.missing.length, actual: results.missing.join( " " ), expected: regex, message: message } ); }, hasClassStart: function( element, partialClass, message ) { var results = check( element, new RegExp( "^" + partialClass ) ); message = message || "Element must have class starting with " + partialClass; // Custom modification: push -> pushResult this.pushResult( { result: results.found.length, actual: results.found.join( " " ), expected: partialClass, message: message } ); }, lacksClassStart: function( element, partialClass, message ) { var results = check( element, new RegExp( "^" + partialClass ) ); message = message || "Element must not have class starting with " + partialClass; // Custom modification: push -> pushResult this.pushResult( { result: results.missing.length, actual: results.missing.join( " " ), expected: partialClass, message: message } ); }, hasClassPartial: function( element, partialClass, message ) { var results = check( element, new RegExp( partialClass ) ); message = message || "Element must have class containing '" + partialClass + "'"; // Custom modification: push -> pushResult this.pushResult( { result: results.found.length, actual: results.found.join( " " ), expected: partialClass, message: message } ); }, lacksClassPartial: function( element, partialClass, message ) { var results = check( element, new RegExp( partialClass ) ); message = message || "Element must not have class containing '" + partialClass + "'"; // Custom modification: push -> pushResult this.pushResult( { result: results.missing.length, actual: results.missing.join( " " ), expected: partialClass, message: message } ); }, lacksAllClasses: function( element, message ) { element = element.jquery ? element[ 0 ] : element; var classAttribute = element.getAttribute( "class" ) || "", classes = splitClasses( classAttribute ); message = message || "Element must not have any classes"; // Custom modification: push -> pushResult this.pushResult( { result: !classes.length, actual: !classes.length, expected: true, message: message } ); }, hasSomeClass: function( element, message ) { element = element.jquery ? element[ 0 ] : element; var classAttribute = element.getAttribute( "class" ) || "", classes = splitClasses( classAttribute ); message = message || "Element must have a class"; // Custom modification: push -> pushResult this.pushResult( { result: classes.length, actual: classes.length, expected: true, message: message } ); } }; // Custom modification: removing QUnit.extend for ( key in qunitAssertExtensions ) { QUnit.assert[ key ] = qunitAssertExtensions[ key ]; } } ) ); ================================================ FILE: tests/lib/vendor/qunit-assert-close/MIT-LICENSE.txt ================================================ Copyright jQuery Foundation and other contributors http://jquery.com/ 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. ================================================ FILE: tests/lib/vendor/qunit-assert-close/qunit-assert-close.js ================================================ // With custom modifications - all are marked with // a "Custom modification" comment. (function(factory) { // NOTE: // All techniques except for the "browser globals" fallback will extend the // provided QUnit object but return the isolated API methods // For AMD: Register as an anonymous AMD module with a named dependency on "qunit". if (typeof define === "function" && define.amd) { define(["qunit"], factory); } // For Node.js else if (typeof module !== "undefined" && module && module.exports && typeof require === "function") { module.exports = factory(require("qunitjs")); } // Custom modification: remove the non-Node.js CommonJS part due to its // usage of QUnit.extend. // // For browser globals else { factory(QUnit); } }(function(QUnit) { /** * Find an appropriate `Assert` context to `push` results to. * @param * context - An unknown context, possibly `Assert`, `Test`, or neither * @private */ function _getPushContext(context) { var pushContext; if (context && typeof context.push === "function") { // `context` is an `Assert` context pushContext = context; } else if (context && context.assert && typeof context.assert.push === "function") { // `context` is a `Test` context pushContext = context.assert; } else if ( QUnit && QUnit.config && QUnit.config.current && QUnit.config.current.assert && typeof QUnit.config.current.assert.push === "function" ) { // `context` is an unknown context but we can find the `Assert` context via QUnit pushContext = QUnit.config.current.assert; } else if (QUnit && typeof QUnit.push === "function") { pushContext = QUnit.push; } else { throw new Error("Could not find the QUnit `Assert` context to push results"); } return pushContext; } /** * Checks that the first two arguments are equal, or are numbers close enough to be considered equal * based on a specified maximum allowable difference. * * @example assert.close(3.141, Math.PI, 0.001); * * @param Number actual * @param Number expected * @param Number maxDifference (the maximum inclusive difference allowed between the actual and expected numbers) * @param String message (optional) */ function close(actual, expected, maxDifference, message) { var actualDiff = (actual === expected) ? 0 : Math.abs(actual - expected), result = actualDiff <= maxDifference, pushContext = _getPushContext(this); message = message || (actual + " should be within " + maxDifference + " (inclusive) of " + expected + (result ? "" : ". Actual: " + actualDiff)); // Custom modification: push -> pushResult pushContext.pushResult({ result: result, actual: actual, expected: expected, message: message }); } /** * Checks that the first two arguments are equal, or are numbers close enough to be considered equal * based on a specified maximum allowable difference percentage. * * @example assert.close.percent(155, 150, 3.4); // Difference is ~3.33% * * @param Number actual * @param Number expected * @param Number maxPercentDifference (the maximum inclusive difference percentage allowed between the actual and expected numbers) * @param String message (optional) */ close.percent = function closePercent(actual, expected, maxPercentDifference, message) { var actualDiff, result, pushContext = _getPushContext(this); if (actual === expected) { actualDiff = 0; result = actualDiff <= maxPercentDifference; } else if (actual !== 0 && expected !== 0 && expected !== Infinity && expected !== -Infinity) { actualDiff = Math.abs(100 * (actual - expected) / expected); result = actualDiff <= maxPercentDifference; } else { // Dividing by zero (0)! Should return `false` unless the max percentage was `Infinity` actualDiff = Infinity; result = maxPercentDifference === Infinity; } message = message || (actual + " should be within " + maxPercentDifference + "% (inclusive) of " + expected + (result ? "" : ". Actual: " + actualDiff + "%")); // Custom modification: push -> pushResult pushContext.pushResult({ result: result, actual: actual, expected: expected, message: message }); }; /** * Checks that the first two arguments are numbers with differences greater than the specified * minimum difference. * * @example assert.notClose(3.1, Math.PI, 0.001); * * @param Number actual * @param Number expected * @param Number minDifference (the minimum exclusive difference allowed between the actual and expected numbers) * @param String message (optional) */ function notClose(actual, expected, minDifference, message) { var actualDiff = Math.abs(actual - expected), result = actualDiff > minDifference, pushContext = _getPushContext(this); message = message || (actual + " should not be within " + minDifference + " (exclusive) of " + expected + (result ? "" : ". Actual: " + actualDiff)); // Custom modification: push -> pushResult pushContext.pushResult({ result: result, actual: actual, expected: expected, message: message }); } /** * Checks that the first two arguments are numbers with differences greater than the specified * minimum difference percentage. * * @example assert.notClose.percent(156, 150, 3.5); // Difference is 4.0% * * @param Number actual * @param Number expected * @param Number minPercentDifference (the minimum exclusive difference percentage allowed between the actual and expected numbers) * @param String message (optional) */ notClose.percent = function notClosePercent(actual, expected, minPercentDifference, message) { var actualDiff, result, pushContext = _getPushContext(this); if (actual === expected) { actualDiff = 0; result = actualDiff > minPercentDifference; } else if (actual !== 0 && expected !== 0 && expected !== Infinity && expected !== -Infinity) { actualDiff = Math.abs(100 * (actual - expected) / expected); result = actualDiff > minPercentDifference; } else { // Dividing by zero (0)! Should only return `true` if the min percentage was `Infinity` actualDiff = Infinity; result = minPercentDifference !== Infinity; } message = message || (actual + " should not be within " + minPercentDifference + "% (exclusive) of " + expected + (result ? "" : ". Actual: " + actualDiff + "%")); // Custom modification: push -> pushResult pushContext.pushResult({ result: result, actual: actual, expected: expected, message: message }); }; var key; var api = { close: close, notClose: notClose, closePercent: close.percent, notClosePercent: notClose.percent }; for (key in api) { QUnit.assert[key] = api[key]; } return api; })); ================================================ FILE: tests/lib/vendor/qunit-composite/LICENSE.txt ================================================ Copyright jQuery Foundation and other contributors, https://jquery.org/ This software consists of voluntary contributions made by many individuals. For exact contribution history, see the revision history available at https://github.com/JamesMGreene/qunit-composite The following license applies to all parts of this software except as documented below: ==== 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. ==== All files located in the node_modules directory are externally maintained libraries used by this software which have their own licenses; we recommend you read them, as their terms may differ from the terms above. ================================================ FILE: tests/lib/vendor/qunit-composite/qunit-composite.css ================================================ .qunit-composite-suite { position: fixed; bottom: 0; left: 0; margin: 0; padding: 0; border-width: 1px 0 0; height: 45%; width: 100%; background: #fff; } #qunit-testsuites { margin: 0; padding: 0.5em 1.0em; font-family: "Helvetica Neue Light","HelveticaNeue-Light","Helvetica Neue",Calibri,Helvetica,Arial,sans-serif; font-size: small; background-color: #d2e0e6; border-bottom: 1px solid #fff; } #qunit-testsuites a { color: #00c; text-decoration: none; } #qunit-testsuites a:hover { text-decoration: underline; } #qunit-testsuites > li { display: inline-block; } #qunit-testsuites > li:first-child::before { content: "Suites: "; } #qunit-testsuites > li + li::before { content: "|\a0"; } #qunit-testsuites > li::after { content: "\a0"; } ================================================ FILE: tests/lib/vendor/qunit-composite/qunit-composite.js ================================================ /** * QUnit Composite * * With custom modifications - all are marked with * a "Custom modification" comment. * * https://github.com/JamesMGreene/qunit-composite * * Copyright jQuery Foundation and other contributors * Released under the MIT license. * https://jquery.org/license/ */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( [ "qunit" ], factory ); } else { factory( QUnit ); } }(function( QUnit ) { var iframe, hasBound, resumeTests, suiteAssert, modules = 1, executingComposite = false; function hasClass( elem, name ) { return ( " " + elem.className + " " ).indexOf( " " + name + " " ) > -1; } function addClass( elem, name ) { if ( !hasClass( elem, name ) ) { elem.className += ( elem.className ? " " : "" ) + name; } } function addEvent( elem, type, fn ) { if ( elem.addEventListener ) { // Standards-based browsers elem.addEventListener( type, fn, false ); } } function runSuite( suite ) { var path; if ( QUnit.is( "object", suite ) ) { path = suite.path; suite = suite.name; } else { path = suite; } QUnit.test( suite, function( assert ) { resumeTests = assert.async(); suiteAssert = assert; iframe.setAttribute( "src", path ); // QUnit.start is called from the child iframe's QUnit.done hook. }); } function initIframe() { var iframeWin, body = document.body; function onIframeLoad() { var moduleName, testName, count = 0; if ( !iframe.src ) { return; } // Deal with QUnit being loaded asynchronously via AMD if ( !iframeWin.QUnit && iframeWin.define && iframeWin.define.amd ) { return iframeWin.require( [ "qunit" ], onIframeLoad ); } iframeWin.QUnit.moduleStart(function( data ) { // Capture module name for messages moduleName = data.name; }); iframeWin.QUnit.testStart(function( data ) { // Capture test name for messages testName = data.name; }); iframeWin.QUnit.testDone(function() { testName = undefined; }); iframeWin.QUnit.log(function( data ) { if (testName === undefined) { return; } // Pass all test details through to the main page var message = ( moduleName ? moduleName + ": " : "" ) + testName + ": " + ( data.message || ( data.result ? "okay" : "failed" ) ); suiteAssert.expect( ++count ); suiteAssert.pushResult( { result: data.result, actual: data.actual, expected: data.expected, message: message } ); }); // Continue the outer test when the iframe's test is done iframeWin.QUnit.done(function() { resumeTests(); }); } iframe = document.createElement( "iframe" ); iframe.className = "qunit-composite-suite"; body.appendChild( iframe ); addEvent( iframe, "load", onIframeLoad ); iframeWin = iframe.contentWindow; } function appendSuitesToHeader( suites ) { var i, suitesLen, suite, path, name, suitesEl, testResultEl, newSuiteListItemEl, newSuiteLinkEl; suitesEl = document.getElementById("qunit-testsuites"); if (!suitesEl) { testResultEl = document.getElementById("qunit-testresult"); if (!testResultEl) { // QUnit has not been set up yet. Defer until QUnit is ready. QUnit.begin(function () { appendSuitesToHeader(suites); }); return; } suitesEl = document.createElement("ul"); suitesEl.id = "qunit-testsuites"; testResultEl.parentNode.insertBefore(suitesEl, testResultEl); } for (i = 0, suitesLen = suites.length; i < suitesLen; ++i) { suite = suites[i]; newSuiteLinkEl = document.createElement("a"); newSuiteLinkEl.innerHTML = suite.name || suite; newSuiteLinkEl.href = suite.path || suite; newSuiteListItemEl = document.createElement("li"); newSuiteListItemEl.appendChild(newSuiteLinkEl); suitesEl.appendChild(newSuiteListItemEl); } } /** * @param {string} [name] Module name to group these test suites. * @param {Array} suites List of suites where each suite * may either be a string (path to the html test page), * or an object with a path and name property. */ QUnit.testSuites = function( name, suites ) { var i, suitesLen; if ( arguments.length === 1 ) { suites = name; name = "Composition #" + modules++; } suitesLen = suites.length; appendSuitesToHeader(suites); if ( !hasBound ) { hasBound = true; QUnit.begin( initIframe ); // TODO: Would be better to use something like QUnit.once( 'moduleDone' ) // after the last test suite. QUnit.moduleDone( function () { executingComposite = false; } ); QUnit.done(function() { iframe.style.display = "none"; }); } QUnit.module( name, { beforeEach: function () { executingComposite = true; } }); for ( i = 0; i < suitesLen; i++ ) { runSuite( suites[ i ] ); } }; QUnit.testDone(function( data ) { if ( !executingComposite ) { return; } var i, len, testId = data.testId, current = document.getElementById( "qunit-test-output-" + testId ), children = current && current.children, src = iframe.src; if (!(current && children)) { return; } addEvent( current, "dblclick", function( e ) { var target = e && e.target ? e.target : window.event.srcElement; if ( target.nodeName.toLowerCase() === "span" || target.nodeName.toLowerCase() === "b" ) { target = target.parentNode; } if ( window.location && target.nodeName.toLowerCase() === "strong" ) { window.location = src; } }); // Undo QUnit's auto-expansion for bad tests for ( i = 0, len = children.length; i < len; i++ ) { if ( children[ i ].nodeName.toLowerCase() === "ol" ) { addClass( children[ i ], "qunit-collapsed" ); } } // Update Rerun link to point to the standalone test suite page current.getElementsByTagName( "a" )[ 0 ].href = src; }); })); ================================================ FILE: tests/unit/accordion/accordion.html ================================================ jQuery UI Accordion Test Suite

    There is one obvious advantage:

    You've seen it coming!
    Buy now and get nothing for free!
    Well, at least no free beer. Perhaps a bear, if you can afford it.

    Now that you've got...

    your bear, you have to admit it!
    No, we aren't selling bears.

    We could talk about renting one.

    Rent one bear, ...

    get two for three beer.

    And now, for something completely different.

    Accordion Header 1
    Accordion Content 1
    Accordion Header 2
    Accordion Content 2
    Accordion Header 3
    Accordion Content 3

    Header

    The calculated height of this accordion should be the same regardless of whether the accordion was collapsed or not when the height was calculated.

    ================================================ FILE: tests/unit/accordion/all.html ================================================ jQuery UI Accordion Test Suite
    ================================================ FILE: tests/unit/accordion/common.js ================================================ define( [ "lib/common", "ui/widgets/accordion" ], function( common ) { common.testWidget( "accordion", { defaults: { active: 0, animate: {}, classes: { "ui-accordion-header": "ui-corner-top", "ui-accordion-header-collapsed": "ui-corner-all", "ui-accordion-content": "ui-corner-bottom" }, collapsible: false, disabled: false, event: "click", header: function( elem ) { return elem .find( "> li > :first-child" ) .add( elem.find( "> :not(li)" ) // Support: jQuery <3.5 only // We could use `.even()` but that's unavailable in older jQuery. .filter( function( i ) { return i % 2 === 0; } ) ); }, heightStyle: "auto", icons: { "activeHeader": "ui-icon-triangle-1-s", "header": "ui-icon-triangle-1-e" }, // Callbacks activate: null, beforeActivate: null, create: null } } ); } ); ================================================ FILE: tests/unit/accordion/core.js ================================================ define( [ "qunit", "jquery", "./helper", "ui/widgets/accordion" ], function( QUnit, $, testHelper ) { "use strict"; var beforeAfterEach = testHelper.beforeAfterEach, state = testHelper.state; QUnit.module( "accordion: core", beforeAfterEach() ); $.each( { div: "#list1", ul: "#navigation", dl: "#accordion-dl" }, function( type, selector ) { QUnit.test( "markup structure: " + type, function( assert ) { assert.expect( 10 ); var element = $( selector ).accordion(), headers = element.find( ".ui-accordion-header" ), content = headers.next(); assert.hasClasses( element, "ui-accordion ui-widget" ); assert.equal( headers.length, 3, ".ui-accordion-header elements exist, correct number" ); assert.hasClasses( headers[ 0 ], "ui-accordion-header ui-accordion-header-active ui-accordion-icons" ); assert.hasClasses( headers[ 1 ], "ui-accordion-header ui-accordion-header-collapsed ui-accordion-icons" ); assert.hasClasses( headers[ 2 ], "ui-accordion-header ui-accordion-header-collapsed ui-accordion-icons" ); assert.equal( content.length, 3, ".ui-accordion-content elements exist, correct number" ); assert.hasClasses( content[ 0 ], "ui-accordion-content ui-widget-content ui-accordion-content-active" ); assert.hasClasses( content[ 1 ], "ui-accordion-content ui-widget-content" ); assert.hasClasses( content[ 2 ], "ui-accordion-content ui-widget-content" ); assert.deepEqual( element.find( ".ui-accordion-header" ).next().get(), element.find( ".ui-accordion-content" ).get(), "content panels come immediately after headers" ); } ); } ); QUnit.test( "handle click on header-descendant", function( assert ) { assert.expect( 1 ); var element = $( "#navigation" ).accordion(); $( "#navigation h2" ).eq( 1 ).find( "a" ).trigger( "click" ); state( assert, element, 0, 1, 0 ); } ); QUnit.test( "accessibility", function( assert ) { assert.expect( 61 ); var element = $( "#list1" ).accordion( { active: 1, collapsible: true } ), headers = element.find( ".ui-accordion-header" ); assert.equal( element.attr( "role" ), "tablist", "element role" ); headers.each( function( i ) { var header = headers.eq( i ), panel = header.next(); assert.equal( header.attr( "role" ), "tab", "header " + i + " role" ); assert.equal( header.attr( "aria-controls" ), panel.attr( "id" ), "header " + i + " aria-controls" ); assert.equal( panel.attr( "role" ), "tabpanel", "panel " + i + " role" ); assert.equal( panel.attr( "aria-labelledby" ), header.attr( "id" ), "panel " + i + " aria-labelledby" ); } ); assert.equal( headers.eq( 1 ).attr( "tabindex" ), 0, "active header has tabindex=0" ); assert.equal( headers.eq( 1 ).attr( "aria-selected" ), "true", "active tab (1) has aria-selected=true" ); assert.equal( headers.eq( 1 ).attr( "aria-expanded" ), "true", "active tab (1) has aria-expanded=true" ); assert.equal( headers.eq( 1 ).next().attr( "aria-hidden" ), "false", "active tabpanel (1) has aria-hidden=false" ); assert.equal( headers.eq( 0 ).attr( "tabindex" ), -1, "inactive header (0) has tabindex=-1" ); assert.equal( headers.eq( 0 ).attr( "aria-selected" ), "false", "inactive tab (0) has aria-selected=false" ); assert.equal( headers.eq( 0 ).attr( "aria-expanded" ), "false", "inactive tab (0) has aria-expanded=false" ); assert.equal( headers.eq( 0 ).next().attr( "aria-hidden" ), "true", "inactive tabpanel (0) has aria-hidden=true" ); assert.equal( headers.eq( 2 ).attr( "tabindex" ), -1, "inactive header (2) has tabindex=-1" ); assert.equal( headers.eq( 2 ).attr( "aria-selected" ), "false", "inactive tab (2) has aria-selected=false" ); assert.equal( headers.eq( 2 ).attr( "aria-expanded" ), "false", "inactive tab (2) has aria-expanded=false" ); assert.equal( headers.eq( 2 ).next().attr( "aria-hidden" ), "true", "inactive tabpanel (2) has aria-hidden=true" ); element.accordion( "option", "active", 0 ); assert.equal( headers.eq( 0 ).attr( "tabindex" ), 0, "active header (0) has tabindex=0" ); assert.equal( headers.eq( 0 ).attr( "aria-selected" ), "true", "active tab (0) has aria-selected=true" ); assert.equal( headers.eq( 0 ).attr( "aria-expanded" ), "true", "active tab (0) has aria-expanded=true" ); assert.equal( headers.eq( 0 ).next().attr( "aria-hidden" ), "false", "active tabpanel (0) has aria-hidden=false" ); assert.equal( headers.eq( 1 ).attr( "tabindex" ), -1, "inactive header (1) has tabindex=-1" ); assert.equal( headers.eq( 1 ).attr( "aria-selected" ), "false", "inactive tab (1) has aria-selected=false" ); assert.equal( headers.eq( 1 ).attr( "aria-expanded" ), "false", "inactive tab (1) has aria-expanded=false" ); assert.equal( headers.eq( 1 ).next().attr( "aria-hidden" ), "true", "inactive tabpanel (1) has aria-hidden=true" ); assert.equal( headers.eq( 2 ).attr( "tabindex" ), -1, "inactive header (2) has tabindex=-1" ); assert.equal( headers.eq( 2 ).attr( "aria-selected" ), "false", "inactive tab (2) has aria-selected=false" ); assert.equal( headers.eq( 2 ).attr( "aria-expanded" ), "false", "inactive tab (2) has aria-expanded=false" ); assert.equal( headers.eq( 2 ).next().attr( "aria-hidden" ), "true", "inactive tabpanel (2) has aria-hidden=true" ); element.accordion( "option", "active", false ); assert.equal( headers.eq( 0 ).attr( "tabindex" ), 0, "previously active header (0) has tabindex=0" ); assert.equal( headers.eq( 0 ).attr( "aria-selected" ), "false", "inactive tab (0) has aria-selected=false" ); assert.equal( headers.eq( 0 ).attr( "aria-expanded" ), "false", "inactive tab (0) has aria-expanded=false" ); assert.equal( headers.eq( 0 ).next().attr( "aria-hidden" ), "true", "inactive tabpanel (0) has aria-hidden=true" ); assert.equal( headers.eq( 1 ).attr( "tabindex" ), -1, "inactive header (1) has tabindex=-1" ); assert.equal( headers.eq( 1 ).attr( "aria-selected" ), "false", "inactive tab (1) has aria-selected=false" ); assert.equal( headers.eq( 1 ).attr( "aria-expanded" ), "false", "inactive tab (1) has aria-expanded=false" ); assert.equal( headers.eq( 1 ).next().attr( "aria-hidden" ), "true", "inactive tabpanel (1) has aria-hidden=true" ); assert.equal( headers.eq( 2 ).attr( "tabindex" ), -1, "inactive header (2) has tabindex=-1" ); assert.equal( headers.eq( 2 ).attr( "aria-selected" ), "false", "inactive tab (2) has aria-selected=false" ); assert.equal( headers.eq( 2 ).attr( "aria-expanded" ), "false", "inactive tab (2) has aria-expanded=false" ); assert.equal( headers.eq( 2 ).next().attr( "aria-hidden" ), "true", "inactive tabpanel (2) has aria-hidden=true" ); element.accordion( "option", "active", 1 ); assert.equal( headers.eq( 1 ).attr( "tabindex" ), 0, "active header has tabindex=0" ); assert.equal( headers.eq( 1 ).attr( "aria-selected" ), "true", "active tab (1) has aria-selected=true" ); assert.equal( headers.eq( 1 ).attr( "aria-expanded" ), "true", "active tab (1) has aria-expanded=true" ); assert.equal( headers.eq( 1 ).next().attr( "aria-hidden" ), "false", "active tabpanel (1) has aria-hidden=false" ); assert.equal( headers.eq( 0 ).attr( "tabindex" ), -1, "inactive header (0) has tabindex=-1" ); assert.equal( headers.eq( 0 ).attr( "aria-selected" ), "false", "inactive tab (0) has aria-selected=false" ); assert.equal( headers.eq( 0 ).attr( "aria-expanded" ), "false", "inactive tab (0) has aria-expanded=false" ); assert.equal( headers.eq( 0 ).next().attr( "aria-hidden" ), "true", "inactive tabpanel (0) has aria-hidden=true" ); assert.equal( headers.eq( 2 ).attr( "tabindex" ), -1, "inactive header (2) has tabindex=-1" ); assert.equal( headers.eq( 2 ).attr( "aria-selected" ), "false", "inactive tab (2) has aria-selected=false" ); assert.equal( headers.eq( 2 ).attr( "aria-expanded" ), "false", "inactive tab (2) has aria-expanded=false" ); assert.equal( headers.eq( 2 ).next().attr( "aria-hidden" ), "true", "inactive tabpanel (2) has aria-hidden=true" ); } ); QUnit.test( "keyboard support", function( assert ) { var ready = assert.async(); assert.expect( 13 ); var element = $( "#list1" ).accordion(), headers = element.find( ".ui-accordion-header" ), anchor = headers.eq( 1 ).next().find( "a" ).eq( 0 ), keyCode = $.ui.keyCode; assert.equal( headers.filter( ".ui-state-focus" ).length, 0, "no headers focused on init" ); headers.eq( 0 ).simulate( "focus" ); setTimeout( step1 ); function step1() { assert.hasClasses( headers.eq( 0 ), "ui-state-focus", "first header has focus" ); headers.eq( 0 ).simulate( "keydown", { keyCode: keyCode.DOWN } ); assert.hasClasses( headers.eq( 1 ), "ui-state-focus", "DOWN moves focus to next header" ); headers.eq( 1 ).simulate( "keydown", { keyCode: keyCode.RIGHT } ); assert.hasClasses( headers.eq( 2 ), "ui-state-focus", "RIGHT moves focus to next header" ); headers.eq( 2 ).simulate( "keydown", { keyCode: keyCode.DOWN } ); assert.hasClasses( headers.eq( 0 ), "ui-state-focus", "DOWN wraps focus to first header" ); headers.eq( 0 ).simulate( "keydown", { keyCode: keyCode.UP } ); assert.hasClasses( headers.eq( 2 ), "ui-state-focus", "UP wraps focus to last header" ); headers.eq( 2 ).simulate( "keydown", { keyCode: keyCode.LEFT } ); assert.hasClasses( headers.eq( 1 ), "ui-state-focus", "LEFT moves focus to previous header" ); headers.eq( 1 ).simulate( "keydown", { keyCode: keyCode.HOME } ); assert.hasClasses( headers.eq( 0 ), "ui-state-focus", "HOME moves focus to first header" ); headers.eq( 0 ).simulate( "keydown", { keyCode: keyCode.END } ); assert.hasClasses( headers.eq( 2 ), "ui-state-focus", "END moves focus to last header" ); headers.eq( 2 ).simulate( "keydown", { keyCode: keyCode.ENTER } ); assert.equal( element.accordion( "option", "active" ), 2, "ENTER activates panel" ); headers.eq( 1 ).simulate( "keydown", { keyCode: keyCode.SPACE } ); assert.equal( element.accordion( "option", "active" ), 1, "SPACE activates panel" ); anchor.simulate( "focus" ); setTimeout( step2 ); } function step2() { assert.lacksClasses( headers.eq( 1 ), "ui-state-focus", "header loses focus when focusing inside the panel" ); anchor.simulate( "keydown", { keyCode: keyCode.UP, ctrlKey: true } ); assert.hasClasses( headers.eq( 1 ), "ui-state-focus", "CTRL+UP moves focus to header" ); ready(); } } ); } ); ================================================ FILE: tests/unit/accordion/events.js ================================================ define( [ "qunit", "jquery", "./helper", "ui/widgets/accordion" ], function( QUnit, $, testHelper ) { "use strict"; var beforeAfterEach = testHelper.beforeAfterEach, state = testHelper.state; QUnit.module( "accordion: events", beforeAfterEach() ); QUnit.test( "create", function( assert ) { assert.expect( 10 ); var element = $( "#list1" ), headers = element.children( "h3" ), contents = headers.next(); element.accordion( { create: function( event, ui ) { assert.equal( ui.header.length, 1, "header length" ); assert.strictEqual( ui.header[ 0 ], headers[ 0 ], "header" ); assert.equal( ui.panel.length, 1, "panel length" ); assert.strictEqual( ui.panel[ 0 ], contents[ 0 ], "panel" ); } } ); element.accordion( "destroy" ); element.accordion( { active: 2, create: function( event, ui ) { assert.equal( ui.header.length, 1, "header length" ); assert.strictEqual( ui.header[ 0 ], headers[ 2 ], "header" ); assert.equal( ui.panel.length, 1, "panel length" ); assert.strictEqual( ui.panel[ 0 ], contents[ 2 ], "panel" ); } } ); element.accordion( "destroy" ); element.accordion( { active: false, collapsible: true, create: function( event, ui ) { assert.equal( ui.header.length, 0, "header length" ); assert.equal( ui.panel.length, 0, "panel length" ); } } ); element.accordion( "destroy" ); } ); QUnit.test( "beforeActivate", function( assert ) { assert.expect( 38 ); var element = $( "#list1" ).accordion( { active: false, collapsible: true } ), headers = element.find( ".ui-accordion-header" ), content = element.find( ".ui-accordion-content" ); element.one( "accordionbeforeactivate", function( event, ui ) { assert.ok( !( "originalEvent" in event ) ); assert.equal( ui.oldHeader.length, 0 ); assert.equal( ui.oldPanel.length, 0 ); assert.equal( ui.newHeader.length, 1 ); assert.strictEqual( ui.newHeader[ 0 ], headers[ 0 ] ); assert.equal( ui.newPanel.length, 1 ); assert.strictEqual( ui.newPanel[ 0 ], content[ 0 ] ); state( assert, element, 0, 0, 0 ); } ); element.accordion( "option", "active", 0 ); state( assert, element, 1, 0, 0 ); element.one( "accordionbeforeactivate", function( event, ui ) { assert.equal( event.originalEvent.type, "click" ); assert.equal( ui.oldHeader.length, 1 ); assert.strictEqual( ui.oldHeader[ 0 ], headers[ 0 ] ); assert.equal( ui.oldPanel.length, 1 ); assert.strictEqual( ui.oldPanel[ 0 ], content[ 0 ] ); assert.equal( ui.newHeader.length, 1 ); assert.strictEqual( ui.newHeader[ 0 ], headers[ 1 ] ); assert.equal( ui.newPanel.length, 1 ); assert.strictEqual( ui.newPanel[ 0 ], content[ 1 ] ); state( assert, element, 1, 0, 0 ); } ); headers.eq( 1 ).trigger( "click" ); state( assert, element, 0, 1, 0 ); element.one( "accordionbeforeactivate", function( event, ui ) { assert.ok( !( "originalEvent" in event ) ); assert.equal( ui.oldHeader.length, 1 ); assert.strictEqual( ui.oldHeader[ 0 ], headers[ 1 ] ); assert.equal( ui.oldPanel.length, 1 ); assert.strictEqual( ui.oldPanel[ 0 ], content[ 1 ] ); assert.equal( ui.newHeader.length, 0 ); assert.equal( ui.newPanel.length, 0 ); state( assert, element, 0, 1, 0 ); } ); element.accordion( "option", "active", false ); state( assert, element, 0, 0, 0 ); element.one( "accordionbeforeactivate", function( event, ui ) { assert.ok( !( "originalEvent" in event ) ); assert.equal( ui.oldHeader.length, 0 ); assert.equal( ui.oldPanel.length, 0 ); assert.equal( ui.newHeader.length, 1 ); assert.strictEqual( ui.newHeader[ 0 ], headers[ 2 ] ); assert.equal( ui.newPanel.length, 1 ); assert.strictEqual( ui.newPanel[ 0 ], content[ 2 ] ); event.preventDefault(); state( assert, element, 0, 0, 0 ); } ); element.accordion( "option", "active", 2 ); state( assert, element, 0, 0, 0 ); } ); QUnit.test( "activate", function( assert ) { assert.expect( 21 ); var element = $( "#list1" ).accordion( { active: false, collapsible: true } ), headers = element.find( ".ui-accordion-header" ), content = element.find( ".ui-accordion-content" ); element.one( "accordionactivate", function( event, ui ) { assert.equal( ui.oldHeader.length, 0 ); assert.equal( ui.oldPanel.length, 0 ); assert.equal( ui.newHeader.length, 1 ); assert.strictEqual( ui.newHeader[ 0 ], headers[ 0 ] ); assert.equal( ui.newPanel.length, 1 ); assert.strictEqual( ui.newPanel[ 0 ], content[ 0 ] ); } ); element.accordion( "option", "active", 0 ); element.one( "accordionactivate", function( event, ui ) { assert.equal( ui.oldHeader.length, 1 ); assert.strictEqual( ui.oldHeader[ 0 ], headers[ 0 ] ); assert.equal( ui.oldPanel.length, 1 ); assert.strictEqual( ui.oldPanel[ 0 ], content[ 0 ] ); assert.equal( ui.newHeader.length, 1 ); assert.strictEqual( ui.newHeader[ 0 ], headers[ 1 ] ); assert.equal( ui.newPanel.length, 1 ); assert.strictEqual( ui.newPanel[ 0 ], content[ 1 ] ); } ); headers.eq( 1 ).trigger( "click" ); element.one( "accordionactivate", function( event, ui ) { assert.equal( ui.oldHeader.length, 1 ); assert.strictEqual( ui.oldHeader[ 0 ], headers[ 1 ] ); assert.equal( ui.oldPanel.length, 1 ); assert.strictEqual( ui.oldPanel[ 0 ], content[ 1 ] ); assert.equal( ui.newHeader.length, 0 ); assert.equal( ui.newPanel.length, 0 ); } ); element.accordion( "option", "active", false ); // Prevent activation element.one( "accordionbeforeactivate", function( event ) { assert.ok( true ); event.preventDefault(); } ); element.one( "accordionactivate", function() { assert.ok( false ); } ); element.accordion( "option", "active", 1 ); } ); } ); ================================================ FILE: tests/unit/accordion/helper.js ================================================ define( [ "qunit", "jquery", "lib/helper", "ui/widgets/accordion" ], function( QUnit, $, helper ) { "use strict"; return $.extend( helper, { equalHeight: function( assert, accordion, height ) { accordion.find( ".ui-accordion-content" ).each( function() { assert.equal( $( this ).outerHeight(), height ); } ); }, beforeAfterEach: function() { var animate = $.ui.accordion.prototype.options.animate; return { beforeEach: function() { $.ui.accordion.prototype.options.animate = false; }, afterEach: function() { $.ui.accordion.prototype.options.animate = animate; return helper.moduleAfterEach.apply( this, arguments ); } }; }, state: function( assert, accordion ) { var expected = $.makeArray( arguments ).slice( 2 ), actual = accordion.find( ".ui-accordion-content" ).map( function() { return $( this ).css( "display" ) === "none" ? 0 : 1; } ).get(); assert.deepEqual( actual, expected ); } } ); } ); ================================================ FILE: tests/unit/accordion/methods.js ================================================ define( [ "qunit", "jquery", "./helper", "ui/widgets/accordion" ], function( QUnit, $, testHelper ) { "use strict"; var equalHeight = testHelper.equalHeight, beforeAfterEach = testHelper.beforeAfterEach, state = testHelper.state; QUnit.module( "accordion: methods", beforeAfterEach() ); QUnit.test( "destroy", function( assert ) { assert.expect( 1 ); assert.domEqual( "#list1", function() { $( "#list1" ).accordion().accordion( "destroy" ); } ); } ); QUnit.test( "enable/disable", function( assert ) { assert.expect( 7 ); var element = $( "#list1" ).accordion(); state( assert, element, 1, 0, 0 ); element.accordion( "disable" ); assert.hasClasses( element, "ui-state-disabled" ); assert.equal( element.attr( "aria-disabled" ), "true", "element gets aria-disabled" ); assert.hasClasses( element, "ui-accordion-disabled" ); // Event does nothing element.find( ".ui-accordion-header" ).eq( 1 ).trigger( "click" ); state( assert, element, 1, 0, 0 ); // Option still works element.accordion( "option", "active", 1 ); state( assert, element, 0, 1, 0 ); element.accordion( "enable" ); element.accordion( "option", "active", 2 ); state( assert, element, 0, 0, 1 ); } ); QUnit.test( "refresh", function( assert ) { assert.expect( 19 ); var element = $( "#navigation" ) .parent() .height( 300 ) .end() .accordion( { heightStyle: "fill" } ); equalHeight( assert, element, 255 ); element.parent().height( 500 ); element.accordion( "refresh" ); equalHeight( assert, element, 455 ); element = $( "#list1" ); element.accordion(); state( assert, element, 1, 0, 0 ); // Disable panel via markup element.find( "h3.bar" ).eq( 1 ).addClass( "ui-state-disabled" ); element.accordion( "refresh" ); state( assert, element, 1, 0, 0 ); // Don't add multiple icons element.accordion( "refresh" ); assert.equal( element.find( ".ui-accordion-header-icon" ).length, 3 ); // Add a panel element .append( "

    new 1

    " ) .append( "
    new 1
    " ); element.accordion( "refresh" ); state( assert, element, 1, 0, 0, 0 ); // Remove all tabs element.find( "h3.bar, div.foo" ).remove(); element.accordion( "refresh" ); state( assert, element ); assert.equal( element.accordion( "option", "active" ), false, "no active accordion panel" ); // Add panels element .append( "

    new 2

    " ) .append( "
    new 2
    " ) .append( "

    new 3

    " ) .append( "
    new 3
    " ) .append( "

    new 4

    " ) .append( "
    new 4
    " ) .append( "

    new 5

    " ) .append( "
    new 5
    " ); element.accordion( "refresh" ); state( assert, element, 1, 0, 0, 0 ); // Activate third tab element.accordion( "option", "active", 2 ); state( assert, element, 0, 0, 1, 0 ); // Remove fourth panel, third panel should stay active element.find( "h3.bar" ).eq( 3 ).remove(); element.find( "div.foo" ).eq( 3 ).remove(); element.accordion( "refresh" ); state( assert, element, 0, 0, 1 ); // Remove third (active) panel, second panel should become active element.find( "h3.bar" ).eq( 2 ).remove(); element.find( "div.foo" ).eq( 2 ).remove(); element.accordion( "refresh" ); state( assert, element, 0, 1 ); // Remove first panel, previously active panel (now first) should stay active element.find( "h3.bar" ).eq( 0 ).remove(); element.find( "div.foo" ).eq( 0 ).remove(); element.accordion( "refresh" ); state( assert, element, 1 ); // Collapse all panels element.accordion( "option", { collapsible: true, active: false } ); state( assert, element, 0 ); element.accordion( "refresh" ); state( assert, element, 0 ); } ); QUnit.test( "widget", function( assert ) { assert.expect( 2 ); var element = $( "#list1" ).accordion(), widgetElement = element.accordion( "widget" ); assert.equal( widgetElement.length, 1, "one element" ); assert.strictEqual( widgetElement[ 0 ], element[ 0 ], "same element" ); } ); } ); ================================================ FILE: tests/unit/accordion/options.js ================================================ define( [ "qunit", "jquery", "./helper", "ui/widgets/accordion" ], function( QUnit, $, testHelper ) { "use strict"; var equalHeight = testHelper.equalHeight, beforeAfterEach = testHelper.beforeAfterEach, state = testHelper.state; QUnit.module( "accordion: options", beforeAfterEach() ); QUnit.test( "{ active: default }", function( assert ) { assert.expect( 2 ); var element = $( "#list1" ).accordion(); assert.equal( element.accordion( "option", "active" ), 0 ); state( assert, element, 1, 0, 0 ); } ); QUnit.test( "{ active: null }", function( assert ) { assert.expect( 2 ); var element = $( "#list1" ).accordion( { active: null } ); assert.equal( element.accordion( "option", "active" ), 0 ); state( assert, element, 1, 0, 0 ); } ); QUnit.test( "{ active: false }", function( assert ) { assert.expect( 7 ); var element = $( "#list1" ).accordion( { active: false, collapsible: true } ); state( assert, element, 0, 0, 0 ); assert.equal( element.find( ".ui-accordion-header.ui-state-active" ).length, 0, "no headers selected" ); assert.equal( element.accordion( "option", "active" ), false ); element.accordion( "option", "collapsible", false ); state( assert, element, 1, 0, 0 ); assert.equal( element.accordion( "option", "active" ), 0 ); element.accordion( "destroy" ); element.accordion( { active: false } ); state( assert, element, 1, 0, 0 ); assert.strictEqual( element.accordion( "option", "active" ), 0 ); } ); // https://bugs.jqueryui.com/ticket/11938 QUnit.test( "{ active: false, collapsible: true }", function( assert ) { assert.expect( 1 ); var element = $( "#collapsible" ).accordion(), height = element.outerHeight(); element .accordion( "destroy" ) .accordion( { active: false, collapsible: true } ) .accordion( "option", "active", 0 ); assert.equal( element.outerHeight(), height ); } ); QUnit.test( "{ active: Number }", function( assert ) { assert.expect( 8 ); var element = $( "#list1" ).accordion( { active: 2 } ); assert.equal( element.accordion( "option", "active" ), 2 ); state( assert, element, 0, 0, 1 ); element.accordion( "option", "active", 0 ); assert.equal( element.accordion( "option", "active" ), 0 ); state( assert, element, 1, 0, 0 ); element.find( ".ui-accordion-header" ).eq( 1 ).trigger( "click" ); assert.equal( element.accordion( "option", "active" ), 1 ); state( assert, element, 0, 1, 0 ); element.accordion( "option", "active", 10 ); assert.equal( element.accordion( "option", "active" ), 1 ); state( assert, element, 0, 1, 0 ); } ); QUnit.test( "{ active: -Number }", function( assert ) { assert.expect( 8 ); var element = $( "#list1" ).accordion( { active: -1 } ); assert.equal( element.accordion( "option", "active" ), 2 ); state( assert, element, 0, 0, 1 ); element.accordion( "option", "active", -2 ); assert.equal( element.accordion( "option", "active" ), 1 ); state( assert, element, 0, 1, 0 ); element.accordion( "option", "active", -10 ); assert.equal( element.accordion( "option", "active" ), 1 ); state( assert, element, 0, 1, 0 ); element.accordion( "option", "active", -3 ); assert.equal( element.accordion( "option", "active" ), 0 ); state( assert, element, 1, 0, 0 ); } ); QUnit.test( "{ animate: false }", function( assert ) { assert.expect( 3 ); var element = $( "#list1" ).accordion( { animate: false } ), panels = element.find( ".ui-accordion-content" ), animate = $.fn.animate; $.fn.animate = function() { assert.ok( false, ".animate() called" ); }; assert.ok( panels.eq( 0 ).is( ":visible" ), "first panel visible" ); element.accordion( "option", "active", 1 ); assert.ok( panels.eq( 0 ).is( ":hidden" ), "first panel hidden" ); assert.ok( panels.eq( 1 ).is( ":visible" ), "second panel visible" ); $.fn.animate = animate; } ); QUnit.test( "{ animate: Number }", function( assert ) { var ready = assert.async(); assert.expect( 7 ); var element = $( "#list1" ).accordion( { animate: 100 } ), panels = element.find( ".ui-accordion-content" ), animate = $.fn.animate; // Called twice (both panels) $.fn.animate = function( props, options ) { assert.equal( options.duration, 100, "correct duration" ); assert.equal( options.easing, undefined, "default easing" ); animate.apply( this, arguments ); }; assert.ok( panels.eq( 0 ).is( ":visible" ), "first panel visible" ); element.accordion( "option", "active", 1 ); panels.promise().done( function() { assert.ok( panels.eq( 0 ).is( ":hidden" ), "first panel hidden" ); assert.ok( panels.eq( 1 ).is( ":visible" ), "second panel visible" ); $.fn.animate = animate; ready(); } ); } ); QUnit.test( "{ animate: String }", function( assert ) { var ready = assert.async(); assert.expect( 7 ); var element = $( "#list1" ).accordion( { animate: "linear" } ), panels = element.find( ".ui-accordion-content" ), animate = $.fn.animate; // Called twice (both panels) $.fn.animate = function( props, options ) { assert.equal( options.duration, undefined, "default duration" ); assert.equal( options.easing, "linear", "correct easing" ); animate.apply( this, arguments ); }; assert.ok( panels.eq( 0 ).is( ":visible" ), "first panel visible" ); element.accordion( "option", "active", 1 ); panels.promise().done( function() { assert.ok( panels.eq( 0 ).is( ":hidden" ), "first panel hidden" ); assert.ok( panels.eq( 1 ).is( ":visible" ), "second panel visible" ); $.fn.animate = animate; ready(); } ); } ); QUnit.test( "{ animate: {} }", function( assert ) { var ready = assert.async(); assert.expect( 7 ); var element = $( "#list1" ).accordion( { animate: {} } ), panels = element.find( ".ui-accordion-content" ), animate = $.fn.animate; // Called twice (both panels) $.fn.animate = function( props, options ) { assert.equal( options.duration, undefined, "default duration" ); assert.equal( options.easing, undefined, "default easing" ); animate.apply( this, arguments ); }; assert.ok( panels.eq( 0 ).is( ":visible" ), "first panel visible" ); element.accordion( "option", "active", 1 ); panels.promise().done( function() { assert.ok( panels.eq( 0 ).is( ":hidden" ), "first panel hidden" ); assert.ok( panels.eq( 1 ).is( ":visible" ), "second panel visible" ); $.fn.animate = animate; ready(); } ); } ); QUnit.test( "{ animate: { duration, easing } }", function( assert ) { var ready = assert.async(); assert.expect( 7 ); var element = $( "#list1" ).accordion( { animate: { duration: 100, easing: "linear" } } ), panels = element.find( ".ui-accordion-content" ), animate = $.fn.animate; // Called twice (both panels) $.fn.animate = function( props, options ) { assert.equal( options.duration, 100, "correct duration" ); assert.equal( options.easing, "linear", "correct easing" ); animate.apply( this, arguments ); }; assert.ok( panels.eq( 0 ).is( ":visible" ), "first panel visible" ); element.accordion( "option", "active", 1 ); panels.promise().done( function() { assert.ok( panels.eq( 0 ).is( ":hidden" ), "first panel hidden" ); assert.ok( panels.eq( 1 ).is( ":visible" ), "second panel visible" ); $.fn.animate = animate; ready(); } ); } ); QUnit.test( "{ animate: { duration, easing } }, animate down", function( assert ) { var ready = assert.async(); assert.expect( 7 ); var element = $( "#list1" ).accordion( { active: 1, animate: { duration: 100, easing: "linear" } } ), panels = element.find( ".ui-accordion-content" ), animate = $.fn.animate; // Called twice (both panels) $.fn.animate = function( props, options ) { assert.equal( options.duration, 100, "correct duration" ); assert.equal( options.easing, "linear", "correct easing" ); animate.apply( this, arguments ); }; assert.ok( panels.eq( 1 ).is( ":visible" ), "first panel visible" ); element.accordion( "option", "active", 0 ); panels.promise().done( function() { assert.ok( panels.eq( 1 ).is( ":hidden" ), "first panel hidden" ); assert.ok( panels.eq( 0 ).is( ":visible" ), "second panel visible" ); $.fn.animate = animate; ready(); } ); } ); QUnit.test( "{ animate: { duration, easing, down } }, animate down", function( assert ) { var ready = assert.async(); assert.expect( 7 ); var element = $( "#list1" ).accordion( { active: 1, animate: { duration: 100, easing: "linear", down: { easing: "swing" } } } ), panels = element.find( ".ui-accordion-content" ), animate = $.fn.animate; // Called twice (both panels) $.fn.animate = function( props, options ) { assert.equal( options.duration, 100, "correct duration" ); assert.equal( options.easing, "swing", "correct easing" ); animate.apply( this, arguments ); }; assert.ok( panels.eq( 1 ).is( ":visible" ), "first panel visible" ); element.accordion( "option", "active", 0 ); panels.promise().done( function() { assert.ok( panels.eq( 1 ).is( ":hidden" ), "first panel hidden" ); assert.ok( panels.eq( 0 ).is( ":visible" ), "second panel visible" ); $.fn.animate = animate; ready(); } ); } ); QUnit.test( "{ collapsible: false }", function( assert ) { assert.expect( 4 ); var element = $( "#list1" ).accordion( { active: 1 } ); element.accordion( "option", "active", false ); assert.equal( element.accordion( "option", "active" ), 1 ); state( assert, element, 0, 1, 0 ); element.find( ".ui-accordion-header" ).eq( 1 ).trigger( "click" ); assert.equal( element.accordion( "option", "active" ), 1 ); state( assert, element, 0, 1, 0 ); } ); QUnit.test( "{ collapsible: true }", function( assert ) { assert.expect( 6 ); var element = $( "#list1" ).accordion( { active: 1, collapsible: true } ); element.accordion( "option", "active", false ); assert.equal( element.accordion( "option", "active" ), false ); state( assert, element, 0, 0, 0 ); element.accordion( "option", "active", 1 ); assert.equal( element.accordion( "option", "active" ), 1 ); state( assert, element, 0, 1, 0 ); element.find( ".ui-accordion-header" ).eq( 1 ).trigger( "click" ); assert.equal( element.accordion( "option", "active" ), false ); state( assert, element, 0, 0, 0 ); } ); QUnit.test( "{ event: null }", function( assert ) { assert.expect( 5 ); var element = $( "#list1" ).accordion( { event: null } ); state( assert, element, 1, 0, 0 ); element.accordion( "option", "active", 1 ); assert.equal( element.accordion( "option", "active" ), 1 ); state( assert, element, 0, 1, 0 ); // Ensure default click handler isn't bound element.find( ".ui-accordion-header" ).eq( 2 ).trigger( "click" ); assert.equal( element.accordion( "option", "active" ), 1 ); state( assert, element, 0, 1, 0 ); } ); QUnit.test( "{ event: custom }", function( assert ) { assert.expect( 11 ); var element = $( "#list1" ).accordion( { event: "custom1 custom2" } ); state( assert, element, 1, 0, 0 ); element.find( ".ui-accordion-header" ).eq( 1 ).trigger( "custom1" ); assert.equal( element.accordion( "option", "active" ), 1 ); state( assert, element, 0, 1, 0 ); // Ensure default click handler isn't bound element.find( ".ui-accordion-header" ).eq( 2 ).trigger( "click" ); assert.equal( element.accordion( "option", "active" ), 1 ); state( assert, element, 0, 1, 0 ); element.find( ".ui-accordion-header" ).eq( 2 ).trigger( "custom2" ); assert.equal( element.accordion( "option", "active" ), 2 ); state( assert, element, 0, 0, 1 ); element.accordion( "option", "event", "custom3" ); // Ensure old event handlers are unbound element.find( ".ui-accordion-header" ).eq( 1 ).trigger( "custom1" ); element.find( ".ui-accordion-header" ).eq( 1 ).trigger( "custom2" ); assert.equal( element.accordion( "option", "active" ), 2 ); state( assert, element, 0, 0, 1 ); element.find( ".ui-accordion-header" ).eq( 1 ).trigger( "custom3" ); assert.equal( element.accordion( "option", "active" ), 1 ); state( assert, element, 0, 1, 0 ); } ); QUnit.test( "{ header: default }", function( assert ) { assert.expect( 2 ); // Default: elem.find( "> li > :first-child" ).add( elem.find( "> :not(li)" ).even() ) // elem.find( "> :not(li)" ).even() state( assert, $( "#list1" ).accordion(), 1, 0, 0 ); // > li > :first-child state( assert, $( "#navigation" ).accordion(), 1, 0, 0 ); } ); QUnit.test( "{ header: customString }", function( assert ) { assert.expect( 6 ); var element = $( "#navigationWrapper" ).accordion( { header: "h2" } ); element.find( "h2" ).each( function() { assert.hasClasses( this, "ui-accordion-header" ); } ); assert.equal( element.find( ".ui-accordion-header" ).length, 3 ); state( assert, element, 1, 0, 0 ); element.accordion( "option", "active", 2 ); state( assert, element, 0, 0, 1 ); } ); QUnit.test( "{ header: customFunction }", function( assert ) { assert.expect( 6 ); var element = $( "#navigationWrapper" ).accordion( { header: function( elem ) { return elem.find( "h2" ); } } ); element.find( "h2" ).each( function() { assert.hasClasses( this, "ui-accordion-header" ); } ); assert.equal( element.find( ".ui-accordion-header" ).length, 3 ); state( assert, element, 1, 0, 0 ); element.accordion( "option", "active", 2 ); state( assert, element, 0, 0, 1 ); } ); QUnit.test( "{ heightStyle: 'auto' }", function( assert ) { assert.expect( 3 ); var element = $( "#navigation" ).accordion( { heightStyle: "auto" } ); equalHeight( assert, element, 105 ); } ); QUnit.test( "{ heightStyle: 'content' }", function( assert ) { assert.expect( 3 ); var element = $( "#navigation" ).accordion( { heightStyle: "content" } ), sizes = element.find( ".ui-accordion-content" ).map( function() { return $( this ).height(); } ).get(); assert.equal( sizes[ 0 ], 75 ); assert.equal( sizes[ 1 ], 105 ); assert.equal( sizes[ 2 ], 45 ); } ); QUnit.test( "{ heightStyle: 'fill' }", function( assert ) { assert.expect( 3 ); $( "#navigationWrapper" ).height( 500 ); var element = $( "#navigation" ).accordion( { heightStyle: "fill" } ); equalHeight( assert, element, 455 ); } ); QUnit.test( "{ heightStyle: 'fill' } with sibling", function( assert ) { assert.expect( 3 ); $( "#navigationWrapper" ).height( 500 ); $( "

    Lorem Ipsum

    " ) .css( { height: 50, marginTop: 20, marginBottom: 30 } ) .prependTo( "#navigationWrapper" ); var element = $( "#navigation" ).accordion( { heightStyle: "fill" } ); equalHeight( assert, element, 355 ); } ); QUnit.test( "{ heightStyle: 'fill' } with multiple siblings", function( assert ) { assert.expect( 3 ); $( "#navigationWrapper" ).height( 500 ); $( "

    Lorem Ipsum

    " ) .css( { height: 50, marginTop: 20, marginBottom: 30 } ) .prependTo( "#navigationWrapper" ); $( "

    Lorem Ipsum

    " ) .css( { height: 50, marginTop: 20, marginBottom: 30, position: "absolute" } ) .prependTo( "#navigationWrapper" ); $( "

    Lorem Ipsum

    " ) .css( { height: 25, marginTop: 10, marginBottom: 15 } ) .prependTo( "#navigationWrapper" ); var element = $( "#navigation" ).accordion( { heightStyle: "fill" } ); equalHeight( assert, element, 305 ); } ); QUnit.test( "{ icons: false }", function( assert ) { assert.expect( 8 ); var element = $( "#list1" ); function icons( on ) { assert.deepEqual( element.find( "span.ui-icon" ).length, on ? 3 : 0 ); assert.deepEqual( element.find( ".ui-accordion-header.ui-accordion-icons" ).length, on ? 3 : 0 ); } element.accordion(); icons( true ); element.accordion( "destroy" ).accordion( { icons: false } ); icons( false ); element.accordion( "option", "icons", { header: "foo", activeHeader: "bar" } ); icons( true ); element.accordion( "option", "icons", false ); icons( false ); } ); QUnit.test( "{ icons: hash }", function( assert ) { assert.expect( 3 ); var element = $( "#list1" ).accordion( { icons: { activeHeader: "a1", header: "h1" } } ); assert.hasClasses( element.find( ".ui-accordion-header.ui-state-active span.ui-icon" ), "a1" ); element.accordion( "option", "icons", { activeHeader: "a2", header: "h2" } ); assert.lacksClasses( element.find( ".ui-accordion-header.ui-state-active span.ui-icon" ), "a1" ); assert.hasClasses( element.find( ".ui-accordion-header.ui-state-active span.ui-icon" ), "a2" ); } ); } ); ================================================ FILE: tests/unit/all.html ================================================ jQuery UI Test Suite
    ================================================ FILE: tests/unit/autocomplete/all.html ================================================ jQuery UI Autocomplete Test Suite
    ================================================ FILE: tests/unit/autocomplete/autocomplete.html ================================================ jQuery UI Autocomplete Test Suite
    ================================================ FILE: tests/unit/autocomplete/common.js ================================================ define( [ "lib/common", "ui/widgets/autocomplete" ], function( common ) { common.testWidget( "autocomplete", { defaults: { appendTo: null, autoFocus: false, classes: {}, delay: 300, disabled: false, messages: { noResults: "No search results.", results: $.ui.autocomplete.prototype.options.messages.results }, minLength: 1, position: { my: "left top", at: "left bottom", collision: "none" }, source: null, // Callbacks change: null, close: null, create: null, focus: null, open: null, response: null, search: null, select: null } } ); } ); ================================================ FILE: tests/unit/autocomplete/core.js ================================================ define( [ "qunit", "jquery", "lib/helper", "ui/widgets/autocomplete" ], function( QUnit, $, helper ) { "use strict"; QUnit.module( "autocomplete: core", { afterEach: helper.moduleAfterEach } ); QUnit.test( "markup structure", function( assert ) { assert.expect( 2 ); var element = $( "#autocomplete" ).autocomplete(), menu = element.autocomplete( "widget" ); assert.hasClasses( element, "ui-autocomplete-input" ); assert.hasClasses( menu, "ui-autocomplete ui-widget ui-widget-content" ); } ); QUnit.test( "prevent form submit on enter when menu is active", function( assert ) { assert.expect( 2 ); var event, element = $( "#autocomplete" ) .autocomplete( { source: [ "java", "javascript" ] } ) .val( "ja" ) .autocomplete( "search" ), menu = element.autocomplete( "widget" ); event = $.Event( "keydown" ); event.keyCode = $.ui.keyCode.DOWN; element.trigger( event ); assert.equal( menu.find( ".ui-menu-item-wrapper.ui-state-active" ).length, 1, "menu item is active" ); event = $.Event( "keydown" ); event.keyCode = $.ui.keyCode.ENTER; element.trigger( event ); assert.ok( event.isDefaultPrevented(), "default action is prevented" ); } ); QUnit.test( "allow form submit on enter when menu is not active", function( assert ) { assert.expect( 1 ); var event, element = $( "#autocomplete" ) .autocomplete( { autoFocus: false, source: [ "java", "javascript" ] } ) .val( "ja" ) .autocomplete( "search" ); event = $.Event( "keydown" ); event.keyCode = $.ui.keyCode.ENTER; element.trigger( event ); assert.ok( !event.isDefaultPrevented(), "default action is prevented" ); } ); ( function() { QUnit.test( "up arrow invokes search - input", function( assert ) { arrowsInvokeSearch( assert, "#autocomplete", true, true ); } ); QUnit.test( "down arrow invokes search - input", function( assert ) { arrowsInvokeSearch( assert, "#autocomplete", false, true ); } ); QUnit.test( "up arrow invokes search - textarea", function( assert ) { arrowsInvokeSearch( assert, "#autocomplete-textarea", true, false ); } ); QUnit.test( "down arrow invokes search - textarea", function( assert ) { arrowsInvokeSearch( assert, "#autocomplete-textarea", false, false ); } ); QUnit.test( "up arrow invokes search - contenteditable", function( assert ) { arrowsInvokeSearch( assert, "#autocomplete-contenteditable", true, false ); } ); QUnit.test( "down arrow invokes search - contenteditable", function( assert ) { arrowsInvokeSearch( assert, "#autocomplete-contenteditable", false, false ); } ); QUnit.test( "up arrow moves focus - input", function( assert ) { arrowsMoveFocus( assert, "#autocomplete", true ); } ); QUnit.test( "down arrow moves focus - input", function( assert ) { arrowsMoveFocus( assert, "#autocomplete", false ); } ); QUnit.test( "up arrow moves focus - textarea", function( assert ) { arrowsMoveFocus( assert, "#autocomplete-textarea", true ); } ); QUnit.test( "down arrow moves focus - textarea", function( assert ) { arrowsMoveFocus( assert, "#autocomplete-textarea", false ); } ); QUnit.test( "up arrow moves focus - contenteditable", function( assert ) { arrowsMoveFocus( assert, "#autocomplete-contenteditable", true ); } ); QUnit.test( "down arrow moves focus - contenteditable", function( assert ) { arrowsMoveFocus( assert, "#autocomplete-contenteditable", false ); } ); QUnit.test( "up arrow moves cursor - input", function( assert ) { arrowsNavigateElement( assert, "#autocomplete", true, false ); } ); QUnit.test( "down arrow moves cursor - input", function( assert ) { arrowsNavigateElement( assert, "#autocomplete", false, false ); } ); QUnit.test( "up arrow moves cursor - textarea", function( assert ) { arrowsNavigateElement( assert, "#autocomplete-textarea", true, true ); } ); QUnit.test( "down arrow moves cursor - textarea", function( assert ) { arrowsNavigateElement( assert, "#autocomplete-textarea", false, true ); } ); QUnit.test( "up arrow moves cursor - contenteditable", function( assert ) { arrowsNavigateElement( assert, "#autocomplete-contenteditable", true, true ); } ); QUnit.test( "down arrow moves cursor - contenteditable", function( assert ) { arrowsNavigateElement( assert, "#autocomplete-contenteditable", false, true ); } ); function arrowsInvokeSearch( assert, id, isKeyUp, shouldMove ) { assert.expect( 1 ); var didMove = false, element = $( id ).autocomplete( { source: [ "a" ], delay: 0, minLength: 0 } ); element.autocomplete( "instance" )._move = function() { didMove = true; }; element.simulate( "keydown", { keyCode: ( isKeyUp ? $.ui.keyCode.UP : $.ui.keyCode.DOWN ) } ); assert.equal( didMove, shouldMove, "respond to arrow" ); } function arrowsMoveFocus( assert, id, isKeyUp ) { assert.expect( 1 ); var element = $( id ).autocomplete( { source: [ "a" ], delay: 0, minLength: 0 } ); element.autocomplete( "instance" )._move = function() { assert.ok( true, "repsond to arrow" ); }; element.autocomplete( "search" ); element.simulate( "keydown", { keyCode: ( isKeyUp ? $.ui.keyCode.UP : $.ui.keyCode.DOWN ) } ); } function arrowsNavigateElement( assert, id, isKeyUp, shouldMove ) { assert.expect( 1 ); var didMove = false, element = $( id ).autocomplete( { source: [ "a" ], delay: 0, minLength: 0 } ); element.on( "keypress", function( e ) { didMove = !e.isDefaultPrevented(); } ); element.simulate( "keydown", { keyCode: ( isKeyUp ? $.ui.keyCode.UP : $.ui.keyCode.DOWN ) } ); element.simulate( "keypress" ); assert.equal( didMove, shouldMove, "respond to arrow" ); } } )(); QUnit.test( "past end of menu in multiline autocomplete", function( assert ) { var ready = assert.async(); assert.expect( 2 ); var customVal = "custom value", element = $( "#autocomplete-contenteditable" ).autocomplete( { delay: 0, source: [ "javascript" ], focus: function( event, ui ) { assert.equal( ui.item.value, "javascript", "Item gained focus" ); $( this ).text( customVal ); event.preventDefault(); } } ); element .simulate( "focus" ) .autocomplete( "search", "ja" ); setTimeout( function() { element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); assert.equal( element.text(), customVal ); ready(); } ); } ); QUnit.test( "ESCAPE in multiline autocomplete", function( assert ) { var ready = assert.async(); assert.expect( 2 ); var customVal = "custom value", element = $( "#autocomplete-contenteditable" ).autocomplete( { delay: 0, source: [ "javascript" ], focus: function( event, ui ) { assert.equal( ui.item.value, "javascript", "Item gained focus" ); $( this ).text( customVal ); event.preventDefault(); } } ); element .simulate( "focus" ) .autocomplete( "search", "ja" ); setTimeout( function() { element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); element.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); assert.equal( element.text(), customVal ); ready(); } ); } ); QUnit.test( "handle race condition", function( assert ) { var ready = assert.async(); assert.expect( 3 ); var count = 0, element = $( "#autocomplete" ).autocomplete( { source: function( request, response ) { count++; if ( request.term.length === 1 ) { assert.equal( count, 1, "request with 1 character is first" ); setTimeout( function() { response( [ "one" ] ); setTimeout( checkResults ); } ); return; } assert.equal( count, 2, "request with 2 characters is second" ); response( [ "two" ] ); } } ); element.autocomplete( "search", "a" ); element.autocomplete( "search", "ab" ); function checkResults() { assert.equal( element.autocomplete( "widget" ).find( ".ui-menu-item" ).text(), "two", "correct results displayed" ); ready(); } } ); QUnit.test( "simultaneous searches (#9334)", function( assert ) { var ready = assert.async(); assert.expect( 2 ); var element = $( "#autocomplete" ).autocomplete( { source: function( request, response ) { setTimeout( function() { response( [ request.term ] ); } ); }, response: function() { assert.ok( true, "response from first instance" ); } } ), element2 = $( "#autocomplete-textarea" ).autocomplete( { source: function( request, response ) { setTimeout( function() { response( [ request.term ] ); } ); }, response: function() { assert.ok( true, "response from second instance" ); ready(); } } ); element.autocomplete( "search", "test" ); element2.autocomplete( "search", "test" ); } ); QUnit.test( "ARIA", function( assert ) { var ready = assert.async(); assert.expect( 13 ); var element = $( "#autocomplete" ).autocomplete( { source: [ "java", "javascript" ] } ), liveRegion = element.autocomplete( "instance" ).liveRegion; assert.equal( liveRegion.children().length, 0, "Empty live region on create" ); assert.equal( liveRegion.attr( "aria-live" ), "assertive", "Live region's aria-live attribute must be assertive" ); assert.equal( liveRegion.attr( "aria-relevant" ), "additions", "Live region's aria-relevant attribute must be additions" ); assert.equal( liveRegion.attr( "role" ), "status", "Live region's role attribute must be status" ); element.autocomplete( "search", "j" ); setTimeout( function() { assert.equal( liveRegion.children().first().text(), "2 results are available, use up and down arrow keys to navigate.", "Live region for multiple values" ); element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout( function() { assert.equal( liveRegion.children().filter( ":visible" ).text(), "java", "Live region changed on keydown to announce the highlighted value" ); element.one( "autocompletefocus", function( event ) { event.preventDefault(); } ); element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout( function() { assert.equal( liveRegion.children().filter( ":visible" ).text(), "javascript", "Live region updated when default focus is prevented" ); element.autocomplete( "search", "javas" ); setTimeout( function() { assert.equal( liveRegion.children().filter( ":visible" ).text(), "1 result is available, use up and down arrow keys to navigate.", "Live region for one value" ); element.autocomplete( "search", "z" ); setTimeout( function() { assert.equal( liveRegion.children().filter( ":visible" ).text(), "No search results.", "Live region for no values" ); assert.equal( liveRegion.children().length, 1, "Should be one child in the live region after the above" ); assert.equal( liveRegion.children().filter( ":visible" ).length, 1, "Only one should be still visible" ); assert.ok( liveRegion.children().filter( ":visible" )[ 0 ] === liveRegion.children().last()[ 0 ], "The last one should be the visible one" ); element.autocomplete( "destroy" ); assert.equal( liveRegion.parent().length, 0, "The liveRegion should be detached after destroy" ); ready(); }, 110 ); }, 110 ); }, 110 ); }, 110 ); }, 110 ); } ); QUnit.test( "ARIA, aria-label announcement", function( assert ) { var ready = assert.async(); assert.expect( 1 ); $.widget( "custom.catcomplete", $.ui.autocomplete, { _renderMenu: function( ul, items ) { var that = this; $.each( items, function( index, item ) { that._renderItemData( ul, item ) .attr( "aria-label", item.category + " : " + item.label ); } ); } } ); var element = $( "#autocomplete" ).catcomplete( { source: [ { label: "anders andersson", category: "People" } ] } ), liveRegion = element.catcomplete( "instance" ).liveRegion; element.catcomplete( "search", "a" ); element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout( function() { assert.equal( liveRegion.children().filter( ":visible" ).text(), "People : anders andersson", "Live region changed on keydown to announce the highlighted value's aria-label attribute" ); ready(); }, 110 ); } ); QUnit.test( "ARIA, init on detached input", function( assert ) { assert.expect( 1 ); var element = $( "" ).autocomplete( { source: [ "java", "javascript" ] } ), liveRegion = element.autocomplete( "instance" ).liveRegion; assert.equal( liveRegion.parent().length, 1, "liveRegion must have a parent" ); } ); QUnit.test( ".replaceWith() (#9172)", function( assert ) { assert.expect( 1 ); var element = $( "#autocomplete" ).autocomplete(), replacement = "
    test
    ", parent = element.parent(); element.replaceWith( replacement ); assert.equal( parent.html().toLowerCase(), replacement ); } ); QUnit.test( "Search if the user retypes the same value (#7434)", function( assert ) { var ready = assert.async(); assert.expect( 3 ); var element = $( "#autocomplete" ).autocomplete( { source: [ "java", "javascript" ], delay: 0 } ), menu = element.autocomplete( "instance" ).menu.element; element.val( "j" ).simulate( "keydown" ); setTimeout( function() { assert.ok( menu.is( ":visible" ), "menu displays initially" ); element.trigger( "blur" ); assert.ok( !menu.is( ":visible" ), "menu hidden after blur" ); element.val( "j" ).simulate( "keydown" ); setTimeout( function() { assert.ok( menu.is( ":visible" ), "menu displays after typing the same value" ); ready(); } ); } ); } ); QUnit.test( "Close on click outside when focus remains", function( assert ) { var ready = assert.async(); assert.expect( 2 ); var element = $( "#autocomplete" ).autocomplete( { source: [ "java", "javascript" ], delay: 0 } ); var menu = element.autocomplete( "widget" ); $( "body" ).on( "mousedown", function( event ) { event.preventDefault(); } ); element.val( "j" ).autocomplete( "search", "j" ); setTimeout( function() { assert.ok( menu.is( ":visible" ), "menu displays initially" ); $( "body" ).simulate( "mousedown" ); setTimeout( function() { assert.ok( menu.is( ":hidden" ), "menu closes after clicking elsewhere" ); ready(); } ); } ); } ); QUnit.test( "extra listeners created during typing (trac-15082, trac-15095)", function( assert ) { assert.expect( 2 ); var origRemoveListenersCount; var element = $( "#autocomplete" ).autocomplete( { source: [ "java", "javascript" ], delay: 0 } ); element.val( "j" ).autocomplete( "search", "j" ); origRemoveListenersCount = jQuery._data( element[ 0 ], "events" ).remove.length; element.val( "ja" ).autocomplete( "search", "ja" ); assert.equal( jQuery._data( element[ 0 ], "events" ).remove.length, origRemoveListenersCount, "No extra listeners after typing multiple letters" ); element.val( "jav" ).autocomplete( "search", "jav" ); assert.equal( jQuery._data( element[ 0 ], "events" ).remove.length, origRemoveListenersCount, "No extra listeners after typing multiple letters" ); } ); } ); ================================================ FILE: tests/unit/autocomplete/events.js ================================================ define( [ "qunit", "jquery", "lib/helper", "ui/widgets/autocomplete" ], function( QUnit, $, helper ) { "use strict"; QUnit.module( "autocomplete: events", { afterEach: helper.moduleAfterEach } ); var data = [ "Clojure", "COBOL", "ColdFusion", "Java", "JavaScript", "Scala", "Scheme" ]; $.each( [ { type: "input", selector: "#autocomplete", valueMethod: "val" }, { type: "textarea", selector: "#autocomplete-textarea", valueMethod: "val" }, { type: "contenteditable", selector: "#autocomplete-contenteditable", valueMethod: "text" } ], function( i, settings ) { QUnit.test( "all events - " + settings.type, function( assert ) { var ready = assert.async(); assert.expect( 13 ); var element = $( settings.selector ) .autocomplete( { autoFocus: false, delay: 0, source: data, search: function( event ) { assert.equal( event.originalEvent.type, "keydown", "search originalEvent" ); }, response: function( event, ui ) { assert.deepEqual( ui.content, [ { label: "Clojure", value: "Clojure" }, { label: "Java", value: "Java" }, { label: "JavaScript", value: "JavaScript" } ], "response ui.content" ); ui.content.splice( 0, 1 ); }, open: function() { assert.ok( menu.is( ":visible" ), "menu open on open" ); }, focus: function( event, ui ) { assert.equal( event.originalEvent.type, "menufocus", "focus originalEvent" ); assert.deepEqual( ui.item, { label: "Java", value: "Java" }, "focus ui.item" ); }, close: function( event ) { assert.equal( event.originalEvent.type, "menuselect", "close originalEvent" ); assert.ok( menu.is( ":hidden" ), "menu closed on close" ); }, select: function( event, ui ) { assert.equal( event.originalEvent.type, "menuselect", "select originalEvent" ); assert.deepEqual( ui.item, { label: "Java", value: "Java" }, "select ui.item" ); }, change: function( event, ui ) { assert.equal( event.originalEvent.type, "blur", "change originalEvent" ); assert.deepEqual( ui.item, { label: "Java", value: "Java" }, "change ui.item" ); assert.ok( menu.is( ":hidden" ), "menu closed on change" ); ready(); } } ), menu = element.autocomplete( "widget" ); element.simulate( "focus" )[ settings.valueMethod ]( "j" ).trigger( "keydown" ); setTimeout( function() { assert.ok( menu.is( ":visible" ), "menu is visible after delay" ); element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); element.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); element.simulate( "blur" ); } ); } ); } ); QUnit.test( "change without selection", function( assert ) { var ready = assert.async(); assert.expect( 1 ); var element = $( "#autocomplete" ).autocomplete( { delay: 0, source: data, change: function( event, ui ) { assert.strictEqual( ui.item, null ); ready(); } } ); element.triggerHandler( "focus" ); element.val( "ja" ).triggerHandler( "blur" ); } ); QUnit.test( "cancel search", function( assert ) { var ready = assert.async(); assert.expect( 6 ); var first = true, element = $( "#autocomplete" ).autocomplete( { delay: 0, source: data, search: function() { if ( first ) { assert.equal( element.val(), "ja", "val on first search" ); first = false; return false; } assert.equal( element.val(), "java", "val on second search" ); }, open: function() { assert.ok( true, "menu opened" ); } } ), menu = element.autocomplete( "widget" ); element.val( "ja" ).trigger( "keydown" ); setTimeout( function() { assert.ok( menu.is( ":hidden" ), "menu is hidden after first search" ); element.val( "java" ).trigger( "keydown" ); setTimeout( function() { assert.ok( menu.is( ":visible" ), "menu is visible after second search" ); assert.equal( menu.find( ".ui-menu-item" ).length, 2, "# of menu items" ); ready(); } ); } ); } ); QUnit.test( "cancel focus", function( assert ) { var ready = assert.async(); assert.expect( 1 ); var customVal = "custom value", element = $( "#autocomplete" ).autocomplete( { delay: 0, source: data, focus: function() { $( this ).val( customVal ); return false; } } ); element.val( "ja" ).trigger( "keydown" ); setTimeout( function() { element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); assert.equal( element.val(), customVal ); ready(); } ); } ); QUnit.test( "cancel select", function( assert ) { var ready = assert.async(); assert.expect( 1 ); var customVal = "custom value", element = $( "#autocomplete" ).autocomplete( { delay: 0, source: data, select: function() { $( this ).val( customVal ); return false; } } ); element.val( "ja" ).trigger( "keydown" ); setTimeout( function() { element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); element.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); assert.equal( element.val(), customVal ); ready(); } ); } ); QUnit.test( "blur during remote search", function( assert ) { var ready = assert.async(); assert.expect( 1 ); var ac = $( "#autocomplete" ).autocomplete( { delay: 0, source: function( request, response ) { assert.ok( true, "trigger request" ); ac.simulate( "blur" ); setTimeout( function() { response( [ "result" ] ); ready(); }, 25 ); }, open: function() { assert.ok( false, "opened after a blur" ); } } ); ac.val( "ro" ).trigger( "keydown" ); } ); } ); ================================================ FILE: tests/unit/autocomplete/methods.js ================================================ define( [ "qunit", "jquery", "lib/helper", "ui/widgets/autocomplete" ], function( QUnit, $, helper ) { "use strict"; QUnit.module( "autocomplete: methods", { afterEach: helper.moduleAfterEach } ); QUnit.test( "destroy", function( assert ) { assert.expect( 1 ); assert.domEqual( "#autocomplete", function() { $( "#autocomplete" ).autocomplete().autocomplete( "destroy" ); } ); } ); QUnit.test( "search, close", function( assert ) { assert.expect( 6 ); var data = [ "c++", "java", "php", "coldfusion", "javascript", "asp", "ruby", "python", "c", "scala", "groovy", "haskell", "perl" ], element = $( "#autocomplete" ).autocomplete( { source: data, minLength: 0 } ), menu = element.autocomplete( "widget" ); assert.ok( menu.is( ":hidden" ), "menu is hidden on init" ); element.autocomplete( "search" ); assert.ok( menu.is( ":visible" ), "menu is visible after search" ); assert.equal( menu.find( ".ui-menu-item" ).length, data.length, "all items for a blank search" ); element.val( "has" ).autocomplete( "search" ); assert.equal( menu.find( ".ui-menu-item" ).text(), "haskell", "only one item for set input value" ); element.autocomplete( "search", "ja" ); assert.equal( menu.find( ".ui-menu-item" ).length, 2, "only java and javascript for 'ja'" ); element.autocomplete( "close" ); assert.ok( menu.is( ":hidden" ), "menu is hidden after close" ); } ); QUnit.test( "widget", function( assert ) { assert.expect( 2 ); var element = $( "#autocomplete" ).autocomplete(), widgetElement = element.autocomplete( "widget" ); assert.equal( widgetElement.length, 1, "one element" ); assert.hasClasses( widgetElement, "ui-menu" ); } ); } ); ================================================ FILE: tests/unit/autocomplete/options.js ================================================ define( [ "qunit", "jquery", "lib/helper", "ui/widgets/autocomplete" ], function( QUnit, $, helper ) { "use strict"; QUnit.module( "autocomplete: options", { afterEach: helper.moduleAfterEach } ); var data = [ "c++", "java", "php", "coldfusion", "javascript", "asp", "ruby", "python", "c", "scala", "groovy", "haskell", "perl" ]; QUnit.test( "appendTo: null", function( assert ) { assert.expect( 1 ); var element = $( "#autocomplete" ).autocomplete(); assert.equal( element.autocomplete( "widget" ).parent()[ 0 ], document.body, "defaults to body" ); element.autocomplete( "destroy" ); } ); QUnit.test( "appendTo: explicit", function( assert ) { assert.expect( 6 ); var detached = $( "
    " ), element = $( "#autocomplete" ); element.autocomplete( { appendTo: ".autocomplete-wrap" } ); assert.equal( element.autocomplete( "widget" ).parent()[ 0 ], $( "#autocomplete-wrap1" )[ 0 ], "first found element" ); assert.equal( $( "#autocomplete-wrap2 .ui-autocomplete" ).length, 0, "only appends to one element" ); element.autocomplete( "destroy" ); element.autocomplete().autocomplete( "option", "appendTo", "#autocomplete-wrap1" ); assert.equal( element.autocomplete( "widget" ).parent()[ 0 ], $( "#autocomplete-wrap1" )[ 0 ], "modified after init" ); element.autocomplete( "destroy" ); element.autocomplete( { appendTo: detached } ); assert.equal( element.autocomplete( "widget" ).parent()[ 0 ], detached[ 0 ], "detached jQuery object" ); element.autocomplete( "destroy" ); element.autocomplete( { appendTo: detached[ 0 ] } ); assert.equal( element.autocomplete( "widget" ).parent()[ 0 ], detached[ 0 ], "detached DOM element" ); element.autocomplete( "destroy" ); element.autocomplete().autocomplete( "option", "appendTo", detached ); assert.equal( element.autocomplete( "widget" ).parent()[ 0 ], detached[ 0 ], "detached DOM element via option()" ); element.autocomplete( "destroy" ); } ); QUnit.test( "appendTo: ui-front", function( assert ) { assert.expect( 2 ); var element = $( "#autocomplete" ); $( "#autocomplete-wrap2" ).addClass( "ui-front" ); element.autocomplete(); assert.equal( element.autocomplete( "widget" ).parent()[ 0 ], $( "#autocomplete-wrap2" )[ 0 ], "null, inside .ui-front" ); element.autocomplete( "destroy" ); element.autocomplete( { appendTo: $() } ); assert.equal( element.autocomplete( "widget" ).parent()[ 0 ], $( "#autocomplete-wrap2" )[ 0 ], "empty jQuery object, inside .ui-front" ); } ); function autoFocusTest( assert, afValue, focusedLength ) { var ready = assert.async(); var element = $( "#autocomplete" ).autocomplete( { autoFocus: afValue, delay: 0, source: data, open: function() { assert.equal( element.autocomplete( "widget" ) .find( ".ui-menu-item-wrapper.ui-state-active" ) .length, focusedLength, "first item is " + ( afValue ? "" : "not" ) + " auto focused" ); ready(); } } ); element.val( "ja" ).trigger( "keydown" ); } QUnit.test( "autoFocus: false", function( assert ) { assert.expect( 1 ); autoFocusTest( assert, false, 0 ); } ); QUnit.test( "autoFocus: true", function( assert ) { assert.expect( 1 ); autoFocusTest( assert, true, 1 ); } ); QUnit.test( "delay", function( assert ) { var ready = assert.async(); assert.expect( 2 ); var element = $( "#autocomplete" ).autocomplete( { source: data, delay: 25 } ), menu = element.autocomplete( "widget" ); element.val( "ja" ).trigger( "keydown" ); assert.ok( menu.is( ":hidden" ), "menu is closed immediately after search" ); setTimeout( function() { assert.ok( menu.is( ":visible" ), "menu is open after delay" ); ready(); }, 50 ); } ); QUnit.test( "disabled", function( assert ) { var ready = assert.async(); assert.expect( 5 ); var element = $( "#autocomplete" ).autocomplete( { source: data, delay: 0 } ), menu = element.autocomplete( "disable" ).autocomplete( "widget" ); element.val( "ja" ).trigger( "keydown" ); assert.ok( menu.is( ":hidden" ) ); assert.lacksClasses( element, "ui-state-disabled" ); assert.hasClasses( menu, "ui-autocomplete-disabled" ); assert.ok( !element.attr( "aria-disabled" ), "element doesn't get aria-disabled" ); setTimeout( function() { assert.ok( menu.is( ":hidden" ) ); ready(); } ); } ); QUnit.test( "minLength", function( assert ) { assert.expect( 2 ); var element = $( "#autocomplete" ).autocomplete( { source: data } ), menu = element.autocomplete( "widget" ); element.autocomplete( "search", "" ); assert.ok( menu.is( ":hidden" ), "blank not enough for minLength: 1" ); element.autocomplete( "option", "minLength", 0 ); element.autocomplete( "search", "" ); assert.ok( menu.is( ":visible" ), "blank enough for minLength: 0" ); } ); QUnit.test( "minLength, exceed then drop below", function( assert ) { var ready = assert.async(); assert.expect( 4 ); var element = $( "#autocomplete" ).autocomplete( { minLength: 2, source: function( req, res ) { assert.equal( req.term, "12", "correct search term" ); setTimeout( function() { res( [ "item" ] ); } ); } } ), menu = element.autocomplete( "widget" ); assert.ok( menu.is( ":hidden" ), "menu is hidden before first search" ); element.autocomplete( "search", "12" ); assert.ok( menu.is( ":hidden" ), "menu is hidden before second search" ); element.autocomplete( "search", "1" ); setTimeout( function() { assert.ok( menu.is( ":hidden" ), "menu is hidden after searches" ); ready(); } ); } ); QUnit.test( "minLength, exceed then drop below then exceed", function( assert ) { assert.expect( 3 ); var _res = [], element = $( "#autocomplete" ).autocomplete( { minLength: 2, source: function( req, res ) { _res.push( res ); } } ), menu = element.autocomplete( "widget" ); // Trigger a valid search assert.ok( menu.is( ":hidden" ), "menu is hidden before first search" ); element.autocomplete( "search", "12" ); // Trigger a search below the minLength, to turn on cancelSearch flag assert.ok( menu.is( ":hidden" ), "menu is hidden before second search" ); element.autocomplete( "search", "1" ); // Trigger a valid search element.autocomplete( "search", "13" ); // React as if the first search was cancelled (default ajax behavior) _res[ 0 ]( [] ); // React to second search _res[ 1 ]( [ "13" ] ); assert.ok( menu.is( ":visible" ), "menu is visible after searches" ); } ); QUnit.test( "source, local string array", function( assert ) { assert.expect( 1 ); var element = $( "#autocomplete" ).autocomplete( { source: data } ), menu = element.autocomplete( "widget" ); element.val( "ja" ).autocomplete( "search" ); assert.equal( menu.find( ".ui-menu-item" ).text(), "javajavascript" ); } ); function sourceTest( assert, source, async ) { var ready; var element = $( "#autocomplete" ).autocomplete( { source: source } ), menu = element.autocomplete( "widget" ); function result() { var items = menu.find( ".ui-menu-item" ); assert.equal( items.length, 3, "Should find three results." ); assert.deepEqual( items.eq( 0 ).data( "ui-autocomplete-item" ), { label: "java", value: "java" } ); assert.deepEqual( items.eq( 1 ).data( "ui-autocomplete-item" ), { label: "javascript", value: "javascript" } ); assert.deepEqual( items.eq( 2 ).data( "ui-autocomplete-item" ), { label: "clojure", value: "clojure" } ); element.autocomplete( "destroy" ); if ( async ) { ready(); } } if ( async ) { ready = assert.async(); $( document ).one( "ajaxStop", result ); } element.val( "j" ).autocomplete( "search" ); if ( !async ) { result(); } } QUnit.test( "source, local object array, only labels", function( assert ) { assert.expect( 4 ); sourceTest( assert, [ { label: "java", value: null }, { label: "php", value: null }, { label: "coldfusion", value: "" }, { label: "javascript", value: "" }, { label: "clojure" } ] ); } ); QUnit.test( "source, local object array, only values", function( assert ) { assert.expect( 4 ); sourceTest( assert, [ { value: "java", label: null }, { value: "php", label: null }, { value: "coldfusion", label: "" }, { value: "javascript", label: "" }, { value: "clojure" } ] ); } ); QUnit.test( "source, url string with remote json string array", function( assert ) { assert.expect( 4 ); sourceTest( assert, "remote_string_array.txt", true ); } ); QUnit.test( "source, url string with remote json object array, only value properties", function( assert ) { assert.expect( 4 ); sourceTest( assert, "remote_object_array_values.txt", true ); } ); QUnit.test( "source, url string with remote json object array, only label properties", function( assert ) { assert.expect( 4 ); sourceTest( assert, "remote_object_array_labels.txt", true ); } ); QUnit.test( "source, custom", function( assert ) { assert.expect( 5 ); sourceTest( assert, function( request, response ) { assert.equal( request.term, "j" ); response( [ "java", { label: "javascript", value: null }, { value: "clojure", label: null } ] ); } ); } ); QUnit.test( "source, update after init", function( assert ) { assert.expect( 2 ); var element = $( "#autocomplete" ).autocomplete( { source: [ "java", "javascript", "haskell" ] } ), menu = element.autocomplete( "widget" ); element.val( "ja" ).autocomplete( "search" ); assert.equal( menu.find( ".ui-menu-item" ).text(), "javajavascript" ); element.autocomplete( "option", "source", [ "php", "asp" ] ); element.val( "ph" ).autocomplete( "search" ); assert.equal( menu.find( ".ui-menu-item" ).text(), "php" ); } ); } ); ================================================ FILE: tests/unit/autocomplete/remote_object_array_labels.txt ================================================ [ { "label": "java", "value": null }, { "label": "javascript", "value": "" }, { "label": "clojure" } ] ================================================ FILE: tests/unit/autocomplete/remote_object_array_values.txt ================================================ [ { "value": "java", "label": null }, { "value": "javascript", "label": "" }, { "value": "clojure" } ] ================================================ FILE: tests/unit/autocomplete/remote_string_array.txt ================================================ [ "java", "javascript", "clojure" ] ================================================ FILE: tests/unit/button/all.html ================================================ jQuery UI Button Test Suite
    ================================================ FILE: tests/unit/button/button.html ================================================ jQuery UI Button Test Suite
    Anchor Button
    ================================================ FILE: tests/unit/button/common-deprecated.js ================================================ define( [ "lib/common", "ui/widgets/button" ], function( common ) { common.testWidget( "button", { defaults: { classes: { "ui-button": "ui-corner-all" }, disabled: null, icon: null, iconPosition: "beginning", icons: { primary: null, secondary: null }, label: null, showLabel: true, text: true, // Callbacks create: null } } ); } ); ================================================ FILE: tests/unit/button/common.js ================================================ define( [ "lib/common", "ui/widgets/button" ], function( common ) { common.testWidget( "button", { defaults: { classes: { "ui-button": "ui-corner-all" }, disabled: null, icon: null, iconPosition: "beginning", label: null, showLabel: true, // Callbacks create: null } } ); } ); ================================================ FILE: tests/unit/button/core.js ================================================ define( [ "qunit", "jquery", "lib/helper", "ui/widgets/button" ], function( QUnit, $, helper ) { "use strict"; QUnit.module( "Button: core", { afterEach: helper.moduleAfterEach } ); QUnit.test( "Disabled button loses focus", function( assert ) { var ready = assert.async(); assert.expect( 2 ); var element = $( "#button" ).button(); element.trigger( "focus" ); setTimeout( function() { assert.equal( element[ 0 ], document.activeElement, "Button is focused" ); element.button( "disable" ); assert.notEqual( element[ 0 ], document.activeElement, "Button has had focus removed" ); ready(); } ); } ); } ); ================================================ FILE: tests/unit/button/deprecated.html ================================================ jQuery UI Button Deprecated Test Suite
    Anchor Button
    Anchor
    ================================================ FILE: tests/unit/button/deprecated.js ================================================ define( [ "qunit", "jquery", "lib/helper", "ui/widgets/button" ], function( QUnit, $, helper ) { "use strict"; QUnit.module( "Button (deprecated): core", { afterEach: helper.moduleAfterEach } ); QUnit.test( "Calling button on a checkbox input calls checkboxradio widget", function( assert ) { var checkbox = $( "#checkbox01" ); assert.expect( 2 ); checkbox.button(); assert.ok( !!checkbox.checkboxradio( "instance" ), "Calling button on a checkbox creates checkboxradio instance" ); assert.ok( !checkbox.checkboxradio( "option", "icon" ), "Calling button on a checkbox sets the checkboxradio icon option to false" ); } ); QUnit.test( "Calling buttonset calls controlgroup", function( assert ) { var controlgroup = $( ".buttonset" ); assert.expect( 1 ); controlgroup.buttonset(); assert.ok( controlgroup.is( ":ui-controlgroup" ), "Calling buttonset creates controlgroup instance" ); } ); QUnit.module( "Button (deprecated): methods", { afterEach: helper.moduleAfterEach } ); QUnit.test( "destroy", function( assert ) { assert.expect( 1 ); assert.domEqual( "#checkbox02", function() { $( "#checkbox02" ).button().button( "destroy" ); } ); } ); QUnit.test( "refresh: Ensure disabled state is preserved correctly.", function( assert ) { assert.expect( 5 ); var element = null; element = $( "#checkbox02" ); element.button( { disabled: true } ).button( "refresh" ); assert.ok( element.button( "option", "disabled" ), "Checkboxes should remain disabled after refresh" ); assert.ok( element.prop( "disabled" ), "Input remains disabled after refresh" ); element = $( "#radio02" ); element.button( { disabled: true } ).button( "refresh" ); assert.ok( element.button( "option", "disabled" ), "Radio buttons should remain disabled after refresh" ); element = $( "#checkbox02" ); element.button( { disabled: true } ).prop( "disabled", false ).button( "refresh" ); assert.ok( !element.button( "option", "disabled" ), "Changing a checkbox's disabled property should update the state after refresh." ); element = $( "#radio02" ); element.button( { disabled: true } ).prop( "disabled", false ).button( "refresh" ); assert.ok( !element.button( "option", "disabled" ), "Changing a radio button's disabled property should update the state after refresh." ); } ); QUnit.module( "button (deprecated): options", { afterEach: helper.moduleAfterEach } ); QUnit.test( "Setting items option on buttonset sets the button properties on the items option", function( assert ) { assert.expect( 2 ); var controlgroup = $( ".buttonset" ); controlgroup.buttonset( { items: "bar" } ); assert.equal( controlgroup.controlgroup( "option", "items.button" ), "bar", "items.button set when setting items option on init on buttonset" ); controlgroup.buttonset( "option", "items", "foo" ); assert.equal( controlgroup.controlgroup( "option", "items.button" ), "foo", "items.button set when setting items option on buttonset" ); } ); QUnit.test( "disabled, null", function( assert ) { assert.expect( 2 ); $( "#radio02" ).prop( "disabled", true ).button( { disabled: null } ); assert.deepEqual( $( "#radio02" ).button( "option", "disabled" ), true, "disabled option set to true" ); assert.deepEqual( true, $( "#radio02" ).prop( "disabled" ), "element is not disabled" ); } ); QUnit.test( "text / showLabel options proxied", function( assert ) { assert.expect( 8 ); var button = $( "#button" ); button.button( { text: false, icon: "ui-icon-gear" } ); assert.equal( button.button( "option", "showLabel" ), false, "Setting the text option to false sets the showLabel option to false on init" ); button.button( "option", "showLabel", true ); assert.equal( button.button( "option", "text" ), true, "Setting showLabel true with option method sets text option to true" ); button.button( "option", "text", false ); assert.equal( button.button( "option", "showLabel" ), false, "Setting text false with option method sets showLabel option to false" ); button.button( "option", "text", true ); assert.equal( button.button( "option", "showLabel" ), true, "Setting text true with option method sets showLabel option to true" ); button.button( "option", "showLabel", false ); assert.equal( button.button( "option", "text" ), false, "Setting showLabel false with option method sets text option to false" ); button.button( "destroy" ); button.button( { text: true, icon: "ui-icon-gear" } ); assert.equal( button.button( "option", "showLabel" ), true, "Setting the text option to true sets the showLabel option to true on init" ); button.button( "destroy" ); button.button( { showLabel: true, icon: "ui-icon-gear" } ); assert.equal( button.button( "option", "text" ), true, "Setting the showLabel option to true sets the text option to true on init" ); button.button( "destroy" ); button.button( { showLabel: false, icon: "ui-icon-gear" } ); assert.equal( button.button( "option", "text" ), false, "Setting the showLabel option to false sets the text option to false on init" ); } ); QUnit.test( "icon / icons options properly proxied", function( assert ) { assert.expect( 10 ); var button = $( "#button" ); button.button( { icon: "foo" } ); assert.equal( button.button( "option", "icons.primary" ), "foo", "Icon option properly proxied on init" ); button.button( { icon: "bar" } ); assert.equal( button.button( "option", "icons.primary" ), "bar", "Icon option properly proxied with option method" ); button.button( { icons: { primary: "foo" } } ); assert.equal( button.button( "option", "icon" ), "foo", "Icons primary option properly proxied with option method" ); assert.equal( button.button( "option", "iconPosition" ), "beginning", "Icons primary option sets iconPosition option to beginning" ); button.button( { icons: { secondary: "bar" } } ); assert.equal( button.button( "option", "icon" ), "bar", "Icons secondary option properly proxied with option method" ); assert.equal( button.button( "option", "iconPosition" ), "end", "Icons secondary option sets iconPosition option to end" ); button.button( "destroy" ); button.button( { icons: { primary: "foo" } } ); assert.equal( button.button( "option", "icon" ), "foo", "Icons primary option properly proxied on init" ); assert.equal( button.button( "option", "iconPosition" ), "beginning", "Icons primary option sets iconPosition option to beginning on init" ); button.button( { icons: { secondary: "bar" } } ); assert.equal( button.button( "option", "icon" ), "bar", "Icons secondary option properly proxied on init" ); assert.equal( button.button( "option", "iconPosition" ), "end", "Icons secondary option sets iconPosition option to end on init" ); } ); QUnit.test( "Calling button on a collection of mixed types works correctly", function( assert ) { assert.expect( 5 ); var group = $( ".mixed" ).children(); group.button(); $.each( { anchor: "button", button: "button", check: "checkboxradio", input: "button", radio: "checkboxradio" }, function( type, widget ) { assert.ok( $( "#mixed-" + type )[ widget ]( "instance" ), type + " is a " + widget ); } ); } ); } ); ================================================ FILE: tests/unit/button/events.js ================================================ define( [ "qunit", "jquery", "lib/helper", "ui/widgets/button" ], function( QUnit, $, helper ) { "use strict"; QUnit.module( "Button: events", { afterEach: helper.moduleAfterEach } ); QUnit.test( "Anchor recieves click event when spacebar is pressed", function( assert ) { var ready = assert.async(); assert.expect( 1 ); var element = $( "#anchor-button" ).button(); element.on( "click", function( event ) { event.preventDefault(); assert.ok( true, "click occcured as a result of spacebar" ); ready(); } ); element.trigger( $.Event( "keyup", { keyCode: $.ui.keyCode.SPACE } ) ); } ); } ); ================================================ FILE: tests/unit/button/methods.js ================================================ define( [ "qunit", "jquery", "lib/helper", "ui/widgets/button" ], function( QUnit, $, helper ) { "use strict"; QUnit.module( "Button: methods", { afterEach: helper.moduleAfterEach } ); QUnit.test( "destroy", function( assert ) { assert.expect( 1 ); assert.domEqual( "#button", function() { $( "#button" ).button().button( "destroy" ); } ); } ); QUnit.test( "refresh: Ensure disabled state is preserved correctly.", function( assert ) { assert.expect( 3 ); var element = $( "" ); element.button( { disabled: true } ).button( "refresh" ); assert.ok( element.button( "option", "disabled" ), "Anchor button should remain disabled after refresh" ); element = $( "" ); element.button( { disabled: true } ).button( "refresh" ); assert.ok( element.button( "option", "disabled" ), "" ); element.button( { disabled: true } ).prop( "disabled", false ).button( "refresh" ); assert.ok( !element.button( "option", "disabled" ), "Changing a
    ================================================ FILE: tests/unit/controlgroup/core.js ================================================ define( [ "qunit", "jquery", "lib/helper", "ui/widgets/controlgroup", "ui/widgets/checkboxradio", "ui/widgets/selectmenu", "ui/widgets/button", "ui/widgets/spinner" ], function( QUnit, $, helper ) { "use strict"; QUnit.module( "Controlgroup: Core", { afterEach: helper.moduleAfterEach } ); QUnit.test( "selectmenu: open/close corners", function( assert ) { assert.expect( 12 ); var element = $( ".controlgroup" ).controlgroup(), selects = element.find( "select" ), selectButton = selects.eq( 0 ).selectmenu( "widget" ); selects.eq( 0 ).selectmenu( "open" ); assert.hasClasses( selectButton, "ui-corner-tl", "Horizontal: First selectmenu gets ui-corner-tl when opened" ); selects.eq( 0 ).selectmenu( "close" ); assert.hasClasses( selectButton, "ui-corner-left", "Horizontal: First selectmenu gets ui-corner-left when closed" ); selectButton = selects.eq( 1 ).selectmenu( "widget" ); selects.eq( 1 ).selectmenu( "open" ); assert.lacksClassStart( selectButton, "ui-corner" ); selects.eq( 1 ).selectmenu( "close" ); assert.lacksClassStart( selectButton, "ui-corner" ); selectButton = selects.eq( 2 ).selectmenu( "widget" ); selects.eq( 2 ).selectmenu( "open" ); assert.hasClasses( selectButton, "ui-corner-tr", "Horizontal: Last selectmenu gets ui-corner-tr when opened" ); selects.eq( 2 ).selectmenu( "close" ); assert.hasClasses( selectButton, "ui-corner-right", "Horizontal: Last selectmenu gets ui-corner-right when closed" ); element.controlgroup( "option", "direction", "vertical" ); selectButton = selects.eq( 0 ).selectmenu( "widget" ); selects.eq( 0 ).selectmenu( "open" ); assert.hasClasses( selectButton, "ui-corner-top", "vertical: First selectmenu gets ui-corner-top when opened" ); selects.eq( 0 ).selectmenu( "close" ); assert.hasClasses( selectButton, "ui-corner-top", "vertical: First selectmenu gets ui-corner-top when closed" ); selectButton = selects.eq( 1 ).selectmenu( "widget" ); selects.eq( 1 ).selectmenu( "open" ); assert.lacksClassStart( selectButton, "ui-corner" ); selects.eq( 1 ).selectmenu( "close" ); assert.lacksClassStart( selectButton, "ui-corner" ); selectButton = selects.eq( 2 ).selectmenu( "widget" ); selects.eq( 2 ).selectmenu( "open" ); assert.lacksClassStart( selectButton, "ui-corner" ); selects.eq( 2 ).selectmenu( "close" ); assert.hasClasses( selectButton, "ui-corner-bottom", "vertical: Last selectmenu gets ui-corner-bottom when closed" ); } ); QUnit.test( "selectmenu: controlgroupLabel", function( assert ) { assert.expect( 2 ); var element = $( ".controlgroup" ).controlgroup(); var label = element.find( ".ui-controlgroup-label" ); assert.hasClasses( label, "ui-widget ui-widget-content ui-state-default ui-controlgroup-item" ); assert.hasClasses( label.find( "span" ), "ui-controlgroup-label-contents" ); } ); var assertSanatized = function( assert, initClasses, expectedClasses, message ) { var selectmenu = $( "#select-sanatize" ).selectmenu( { classes: { "ui-selectmenu-button-open": initClasses } } ).selectmenu( "instance" ); var classes = { "ui-selectmenu-button-open": "ui-corner-top" }; var result = $.ui.controlgroup.prototype._resolveClassesValues( classes, selectmenu ); assert.deepEqual( result, { "ui-selectmenu-button-open": expectedClasses + " ui-corner-top" }, message ); }; QUnit.test( "_resolveClassesValues", function( assert ) { assert.expect( 6 ); assertSanatized( assert, "bar ui-corner-bottom", "bar", "Single corner class removed end" ); assertSanatized( assert, "ui-corner-bottom bar", "bar", "Single corner class removed beginning" ); assertSanatized( assert, "bar ui-corner-bottom ui-corner-left", "bar", "Multiple corner classes removed end" ); assertSanatized( assert, "ui-corner-bottom ui-corner-left bar", "bar", "Multiple corner classes removed beginning" ); assertSanatized( assert, "bar ui-corner-bottom ui-corner-left foo", "bar foo", "Multiple corner class removed middle" ); assertSanatized( assert, "bar", "bar", "No corner classes" ); } ); QUnit.test( "Single controlgroup select - horizontal", function( assert ) { assert.expect( 4 ); var group = $( ".controlgroup-single-select" ).controlgroup(); var select = group.find( ".ui-selectmenu-button" ); assert.hasClasses( select, "ui-corner-all" ); assert.lacksClasses( select, "ui-corner-left ui-corner-right ui-corner-top ui-corner-left" + " ui-corner-tr ui-corner-tl ui-corner-bl ui corner-br" ); group.find( "select" ).selectmenu( "open" ); assert.hasClasses( select, "ui-corner-top" ); assert.lacksClasses( select, "ui-corner-left ui-corner-right ui-corner-all ui-corner-left" + " ui-corner-tr ui-corner-tl ui-corner-bl ui corner-br" ); } ); QUnit.test( "Single controlgroup select - vertical", function( assert ) { assert.expect( 4 ); var group = $( ".controlgroup-single-select" ).controlgroup( { direction: "verticle" } ); var select = group.find( ".ui-selectmenu-button" ); assert.hasClasses( select, "ui-corner-all" ); assert.lacksClasses( select, "ui-corner-left ui-corner-right ui-corner-top ui-corner-left" + " ui-corner-tr ui-corner-tl ui-corner-bl ui corner-br" ); group.find( "select" ).selectmenu( "open" ); assert.hasClasses( select, "ui-corner-top" ); assert.lacksClasses( select, "ui-corner-left ui-corner-right ui-corner-all ui-corner-left" + " ui-corner-tr ui-corner-tl ui-corner-bl ui corner-br" ); } ); QUnit.test( "Single controlgroup button - horizontal", function( assert ) { assert.expect( 2 ); var group = $( ".controlgroup-single-button" ).controlgroup(); var button = group.find( "button" ); assert.hasClasses( button, "ui-corner-all" ); assert.lacksClasses( button, "ui-corner-left ui-corner-right ui-corner-top ui-corner-left" + " ui-corner-tr ui-corner-tl ui-corner-bl ui corner-br" ); } ); QUnit.test( "Single controlgroup button - vertical", function( assert ) { assert.expect( 2 ); var group = $( ".controlgroup-single-button" ).controlgroup( { direction: "verticle" } ); var button = group.find( "button" ); assert.hasClasses( button, "ui-corner-all" ); assert.lacksClasses( button, "ui-corner-left ui-corner-right ui-corner-top ui-corner-left" + " ui-corner-tr ui-corner-tl ui-corner-bl ui corner-br" ); } ); QUnit.module( "Controlgroup: Non-empty class key", { beforeEach: function() { this.classKey = $.ui.selectmenu.prototype.options.classes[ "ui-selectmenu-button-closed" ]; $.ui.selectmenu.prototype.options.classes[ "ui-selectmenu-button-closed" ] = "something-custom"; }, afterEach: function() { $.ui.selectmenu.prototype.options.classes[ "ui-selectmenu-button-closed" ] = this.classKey; } } ); QUnit.test( "Controlgroup instantiates child widgets with correct options", function( assert ) { assert.expect( 1 ); $( ".controlgroup-class-key-init" ).controlgroup(); assert.hasClasses( $( "#class-key-init-child" ).next(), "something-custom" ); } ); QUnit.test( "Controlgroup correctly assigns child widget classes options key", function( assert ) { assert.expect( 2 ); $( ".controlgroup-class-key-dupe" ).controlgroup(); assert.strictEqual( ( $( "#class-key-dupe-first" ) .selectmenu( "option", "classes.ui-selectmenu-button-closed" ) .match( /something-custom/g ) || [] ).length, 1, "Class 'something-custom' appears exactly once in the first widget's class key value" ); assert.strictEqual( ( $( "#class-key-dupe-second" ) .selectmenu( "option", "classes.ui-selectmenu-button-closed" ) .match( /something-custom/g ) || [] ).length, 1, "Class 'something-custom' appears exactly once in the second widget's class key value" ); } ); } ); ================================================ FILE: tests/unit/controlgroup/methods.js ================================================ define( [ "qunit", "jquery", "lib/helper", "ui/widgets/controlgroup", "ui/widgets/checkboxradio", "ui/widgets/selectmenu", "ui/widgets/button", "ui/widgets/spinner" ], function( QUnit, $, helper ) { "use strict"; QUnit.module( "Controlgroup: methods", { afterEach: helper.moduleAfterEach } ); QUnit.test( "destroy", function( assert ) { assert.expect( 1 ); assert.domEqual( ".controlgroup", function() { $( ".controlgroup" ).controlgroup().controlgroup( "destroy" ); $( "#spinner" ).addClass( "ui-spinner-input" ); } ); } ); QUnit.test( "disable", function( assert ) { assert.expect( 2 ); var element = $( ".controlgroup" ).controlgroup().controlgroup( "disable" ); assert.lacksClasses( element, "ui-state-disabled", "The widget does not get the disabled class, because we disable each child widget" ); assert.strictEqual( element.find( ".ui-state-disabled" ).length, 9, "Child widgets are disabled" ); } ); QUnit.test( "enable", function( assert ) { assert.expect( 2 ); var element = $( ".controlgroup" ).controlgroup().controlgroup( "enable" ); assert.lacksClasses( element, "ui-state-disabled", "ui-state-disabled is not present on widget after enabling" ); assert.strictEqual( element.find( "ui-state-disabled" ).length, 0, "Child widgets are disabled" ); } ); var tests = { "checkboxradio": "", "selectmenu": "", "button": "", "spinner": "" }, orientations = { "horizontal": [ "ui-corner-left", false, false, "ui-corner-right" ], "vertical": [ "ui-corner-top", false, false, "ui-corner-bottom" ] }; // Iterate through supported element markup $.each( tests, function( widget, html ) { // Check in both horizontal and vertical orientations $.each( orientations, function( name, classes ) { QUnit.test( "refresh: " + widget + ": " + name, function( assert ) { assert.expect( 41 ); var i, control, label, currentClasses, controls = [], element = $( "
    " ).controlgroup( { direction: name } ).appendTo( "body" ); // Checks the elements with in the controlgroup against the expected class list function checkCornerClasses( classList ) { for ( var j = 0; j < 4; j++ ) { if ( classList[ j ] ) { assert.hasClasses( controls[ j ][ widget ]( "widget" ), classList[ j ] ); } else { assert.lacksClassStart( controls[ j ][ widget ]( "widget" ), "ui-corner" ); } } } function showElements( index, value ) { $( value )[ widget ]( "widget" ).show(); } // Hide each element and check the corner classes function iterateHidden( onlyVisible ) { for ( i = 0; i < 4; i++ ) { $( controls ).each( showElements ); controls[ i ][ widget ]( "widget" ).hide(); currentClasses = classes.slice( 0 ); if ( onlyVisible ) { if ( i === 0 ) { currentClasses[ i + 1 ] = classes[ i ]; currentClasses[ i ] = false; } else if ( i === 3 ) { currentClasses[ i - 1 ] = classes[ i ]; currentClasses[ i ] = false; } } element.controlgroup( "refresh" ); checkCornerClasses( currentClasses ); } } // Add a label for each element and then append the element to the control group for ( i = 0; i < 4; i++ ) { control = $( html ).attr( "id", "id" + i ); label = $( "" ).attr( "for", "id" + i ); controls.push( control ); element.append( control, label ); } // Refresh the controlgroup now that its populated element.controlgroup( "refresh" ); for ( i = 0; i < 4; i++ ) { assert.strictEqual( controls[ i ].is( ":ui-" + widget ), true, name + ": " + widget + " " + i + ": is a " + widget + " widget" ); } // Check that we have the right classes checkCornerClasses( classes ); // Hide each element and then check its classes iterateHidden( true ); // Set the exclude option to false so we no longer care about hidden element.controlgroup( "option", "onlyVisible", false ); // Iterate hiding the elements again and check their corner classes iterateHidden(); // Disable the first control if ( widget === "spinner" ) { controls[ 0 ].spinner( "disable" ); } controls[ 0 ].prop( "disabled", true ); element.controlgroup( "refresh" ); assert.hasClasses( controls[ 0 ][ widget ]( "widget" ), "ui-state-disabled" ); // Remove the controlgroup before we start the next set element.remove(); } ); } ); } ); QUnit.test( "Child Classes Option: init", function( assert ) { assert.expect( 1 ); var selectmenu = $( "#select-pre" ).selectmenu( { classes: { "ui-selectmenu-button-closed": "test-class" } } ); $( ".controlgroup-pre" ).controlgroup(); assert.hasClasses( selectmenu.selectmenu( "widget" ), "test-class" ); } ); QUnit.test( "Child Classes Option: refresh", function( assert ) { assert.expect( 1 ); var controlgroup = $( ".controlgroup-refresh" ).controlgroup(); var selectmenu = $( "#select-refresh" ).selectmenu( { classes: { "ui-selectmenu-button-closed": "test-class" } } ); controlgroup.controlgroup( "refresh" ); assert.hasClasses( selectmenu.selectmenu( "widget" ), "test-class" ); } ); QUnit.test( "Controlgroup Label: refresh", function( assert ) { assert.expect( 1 ); var controlgroup = $( ".controlgroup-refresh" ).controlgroup(); controlgroup.controlgroup( "refresh" ); assert.strictEqual( controlgroup.find( ".ui-controlgroup-label-contents" ).length, 1, "Controlgroup label does not re-wrap on refresh" ); } ); } ); ================================================ FILE: tests/unit/controlgroup/options.js ================================================ define( [ "qunit", "jquery", "lib/helper", "ui/widgets/controlgroup", "ui/widgets/checkboxradio", "ui/widgets/selectmenu", "ui/widgets/button", "ui/widgets/spinner" ], function( QUnit, $, helper ) { "use strict"; QUnit.module( "Controlgroup: options", { afterEach: helper.moduleAfterEach } ); QUnit.test( "disabled", function( assert ) { assert.expect( 4 ); var element = $( ".controlgroup" ).controlgroup().controlgroup( "option", "disabled", true ); assert.lacksClasses( element, "ui-state-disabled" ); assert.equal( element.find( ".ui-state-disabled" ).length, 9, "Child widgets are disabled" ); element.controlgroup( "option", "disabled", false ); assert.lacksClasses( element, "ui-state-disabled" ); assert.strictEqual( element.find( ".ui-state-disabled" ).length, 0, "Child widgets are not disabled" ); } ); QUnit.test( "items - null", function( assert ) { assert.expect( 2 ); var element = $( ".controlgroup" ).controlgroup( { items: { "button": null, "selectmenu": null, "checkboxradio": null } } ); assert.strictEqual( element.children( ".ui-button" ).length, 0, "Child widgets are not called when selector is null" ); element.controlgroup( "option", "items", { "button": "button" } ); assert.strictEqual( element.children( ".ui-button" ).length, 2, "Correct child widgets are called when selector is updated" ); } ); QUnit.test( "items: custom selector", function( assert ) { assert.expect( 1 ); var element = $( ".controlgroup" ).controlgroup( { items: { "button": ".button" } } ); assert.strictEqual( element.children( ".ui-button" ).length, 4, "Correct child widgets are called when custom selector used" ); } ); $.widget( "ui.test", { _create: function() { this.element.addClass( "ui-test ui-button" ); }, // Controlgroup requires a refresh method to exist refresh: $.noop } ); QUnit.test( "items: custom widget", function( assert ) { assert.expect( 2 ); var element = $( ".controlgroup" ).controlgroup( { items: { "test": ".test" } } ); assert.strictEqual( element.children( ".ui-button" ).length, 7, "Correct child widgets are called when custom selector used" ); assert.strictEqual( element.children( ".ui-test" ).length, 1, "Custom widget called" ); } ); QUnit.test( "onlyVisible", function( assert ) { assert.expect( 4 ); var element = $( ".controlgroup" ).controlgroup( { onlyVisible: false } ), buttons = element.children( ".ui-button" ); assert.lacksClassStart( buttons.eq( 1 ), "ui-corner" ); assert.hasClasses( buttons.eq( 0 ), "ui-corner-left", "onlyVisible: false: First button hidden second button doesn't get a corner class" ); element.controlgroup( "option", "onlyVisible", true ); assert.lacksClassStart( buttons.eq( 0 ), "ui-corner" ); assert.hasClasses( buttons.eq( 1 ), "ui-corner-left", "onlyVisible: true: First button is hidden second button get corner class" ); } ); QUnit.test( "direction", function( assert ) { assert.expect( 6 ); var element = $( ".controlgroup" ).controlgroup(), buttons = element.children( ".ui-button" ).filter( ":visible" ); assert.hasClasses( element, "ui-controlgroup-horizontal" ); assert.hasClasses( buttons.first(), "ui-corner-left" ); assert.hasClasses( buttons.last(), "ui-corner-right" ); element.controlgroup( "option", "direction", "vertical" ); assert.hasClasses( element, "ui-controlgroup-vertical" ); assert.hasClasses( buttons.first(), "ui-corner-top" ); assert.hasClasses( buttons.last(), "ui-corner-bottom" ); } ); } ); ================================================ FILE: tests/unit/core/all.html ================================================ jQuery UI Core Test Suite
    ================================================ FILE: tests/unit/core/core.html ================================================ jQuery UI Core Test Suite
    xxx anchor anchor x
    x
    x
    x
    .
    .
    .
    . . . .
    ================================================ FILE: tests/unit/core/core.js ================================================ define( [ "qunit", "jquery", "lib/common", "lib/helper", "ui/labels", "ui/unique-id" ], function( QUnit, $, common, helper ) { "use strict"; QUnit.module( "core - jQuery extensions", { afterEach: helper.moduleAfterEach } ); QUnit.test( "innerWidth - getter", function( assert ) { assert.expect( 2 ); var el = $( "#dimensions" ); assert.equal( el.innerWidth(), 122, "getter passthru" ); el.hide(); assert.equal( el.innerWidth(), 122, "getter passthru when hidden" ); } ); QUnit.test( "innerWidth - setter", function( assert ) { assert.expect( 2 ); var el = $( "#dimensions" ); el.innerWidth( 120 ); assert.equal( el.width(), 98, "width set properly" ); el.hide(); el.innerWidth( 100 ); assert.equal( el.width(), 78, "width set properly when hidden" ); } ); QUnit.test( "innerHeight - getter", function( assert ) { assert.expect( 2 ); var el = $( "#dimensions" ); assert.equal( el.innerHeight(), 70, "getter passthru" ); el.hide(); assert.equal( el.innerHeight(), 70, "getter passthru when hidden" ); } ); QUnit.test( "innerHeight - setter", function( assert ) { assert.expect( 2 ); var el = $( "#dimensions" ); el.innerHeight( 60 ); assert.equal( el.height(), 40, "height set properly" ); el.hide(); el.innerHeight( 50 ); assert.equal( el.height(), 30, "height set properly when hidden" ); } ); QUnit.test( "outerWidth - getter", function( assert ) { assert.expect( 2 ); var el = $( "#dimensions" ); assert.equal( el.outerWidth(), 140, "getter passthru" ); el.hide(); assert.equal( el.outerWidth(), 140, "getter passthru when hidden" ); } ); QUnit.test( "outerWidth - setter", function( assert ) { assert.expect( 2 ); var el = $( "#dimensions" ); el.outerWidth( 130 ); assert.equal( el.width(), 90, "width set properly" ); el.hide(); el.outerWidth( 120 ); assert.equal( el.width(), 80, "width set properly when hidden" ); } ); QUnit.test( "outerWidth(true) - getter", function( assert ) { assert.expect( 2 ); var el = $( "#dimensions" ); assert.equal( el.outerWidth( true ), 154, "getter passthru w/ margin" ); el.hide(); assert.equal( el.outerWidth( true ), 154, "getter passthru w/ margin when hidden" ); } ); QUnit.test( "outerWidth(true) - setter", function( assert ) { assert.expect( 2 ); var el = $( "#dimensions" ); el.outerWidth( 130, true ); assert.equal( el.width(), 76, "width set properly" ); el.hide(); el.outerWidth( 120, true ); assert.equal( el.width(), 66, "width set properly when hidden" ); } ); QUnit.test( "outerHeight - getter", function( assert ) { assert.expect( 2 ); var el = $( "#dimensions" ); assert.equal( el.outerHeight(), 86, "getter passthru" ); el.hide(); assert.equal( el.outerHeight(), 86, "getter passthru when hidden" ); } ); QUnit.test( "outerHeight - setter", function( assert ) { assert.expect( 2 ); var el = $( "#dimensions" ); el.outerHeight( 80 ); assert.equal( el.height(), 44, "height set properly" ); el.hide(); el.outerHeight( 70 ); assert.equal( el.height(), 34, "height set properly when hidden" ); } ); QUnit.test( "outerHeight(true) - getter", function( assert ) { assert.expect( 2 ); var el = $( "#dimensions" ); assert.equal( el.outerHeight( true ), 98, "getter passthru w/ margin" ); el.hide(); assert.equal( el.outerHeight( true ), 98, "getter passthru w/ margin when hidden" ); } ); QUnit.test( "outerHeight(true) - setter", function( assert ) { assert.expect( 2 ); var el = $( "#dimensions" ); el.outerHeight( 90, true ); assert.equal( el.height(), 42, "height set properly" ); el.hide(); el.outerHeight( 80, true ); assert.equal( el.height(), 32, "height set properly when hidden" ); } ); QUnit.test( "uniqueId / removeUniqueId", function( assert ) { assert.expect( 3 ); var el = $( "img" ).eq( 0 ); assert.equal( el.attr( "id" ), null, "element has no initial id" ); el.uniqueId(); assert.ok( /ui-id-\d+$/.test( el.attr( "id" ) ), "element has generated id" ); el.removeUniqueId(); assert.equal( el.attr( "id" ), null, "unique id has been removed from element" ); } ); QUnit.test( "Labels", function( assert ) { assert.expect( 3 ); var expected = [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" ]; var dom = $( "#labels-fragment" ); function testLabels( testType ) { var labels = dom.find( "#test" ).labels(); var found = labels.map( function() { return String.prototype.trim.call( $( this ).text() ); } ).get(); assert.deepEqual( found, expected, ".labels() finds all labels in " + testType + ", and sorts them in DOM order" ); } testLabels( "the DOM" ); // Detach the dom to test on a fragment dom.detach(); testLabels( "document fragments" ); assert.equal( $().labels().length, 0, "No element" ); } ); ( function() { var domAttached = $( "#form-test" ); var domDetached = $( "#form-test-detached" ).detach(); function testForm( name, dom ) { var inputs = dom.find( "input" ); inputs.each( function() { var input = $( this ); QUnit.test( name + this.id.replace( /_/g, " " ), function( assert ) { var ready = assert.async(); assert.expect( 1 ); var form = $( input.prop( "form" ) ); // If input has a form the value should reset to "" if not it should be "changed" var value = form.length ? "" : "changed"; input.val( "changed" ); // If there is a form we reset just that. If there is not a form, reset every form. // The idea is if a form is found resetting that form should reset the input. // If no form is found no amount of resetting should change the value. ( form.length ? form : dom.find( "form" ).addBack( "form" ) ).each( function() { this.reset(); } ); setTimeout( function() { assert.equal( input.val(), value, "Proper form found for #" + input.attr( "id" ) ); ready(); } ); } ); } ); } testForm( "form: attached: ", domAttached ); testForm( "form: detached: ", domDetached ); } )(); } ); ================================================ FILE: tests/unit/core/selector.js ================================================ define( [ "qunit", "jquery", "lib/helper", "ui/data", "ui/focusable", "ui/tabbable" ], function( QUnit, $, helper ) { "use strict"; QUnit.module( "core - selectors", { afterEach: helper.moduleAfterEach } ); QUnit.assert.isFocusable = function( selector, msg ) { this.pushResult( { result: $( selector ).is( ":focusable" ), actual: null, expected: null, message: msg + " - selector " + selector + " is focusable" } ); }; QUnit.assert.isNotFocusable = function( selector, msg ) { this.pushResult( { result: $( selector ).length && !$( selector ).is( ":focusable" ), actual: null, expected: null, message: msg + " - selector " + selector + " is not focusable" } ); }; QUnit.assert.isTabbable = function( selector, msg ) { this.pushResult( { result: $( selector ).is( ":tabbable" ), actual: null, expected: null, message: msg + " - selector " + selector + " is tabbable" } ); }; QUnit.assert.isNotTabbable = function( selector, msg ) { this.pushResult( { result: $( selector ).length && !$( selector ).is( ":tabbable" ), actual: null, expected: null, message: msg + " - selector " + selector + " is not tabbable" } ); }; QUnit.test( "data", function( assert ) { assert.expect( 15 ); var element; function shouldHaveData( msg ) { assert.ok( element.is( ":data(test)" ), msg ); } function shouldNotHaveData( msg ) { assert.ok( !element.is( ":data(test)" ), msg ); } element = $( "
    " ); shouldNotHaveData( "data never set" ); element = $( "
    " ).data( "test", null ); shouldNotHaveData( "data is null" ); element = $( "
    " ).data( "test", true ); shouldHaveData( "data set to true" ); element = $( "
    " ).data( "test", false ); shouldNotHaveData( "data set to false" ); element = $( "
    " ).data( "test", 0 ); shouldNotHaveData( "data set to 0" ); element = $( "
    " ).data( "test", 1 ); shouldHaveData( "data set to 1" ); element = $( "
    " ).data( "test", "" ); shouldNotHaveData( "data set to empty string" ); element = $( "
    " ).data( "test", "foo" ); shouldHaveData( "data set to string" ); element = $( "
    " ).data( "test", [] ); shouldHaveData( "data set to empty array" ); element = $( "
    " ).data( "test", [ 1 ] ); shouldHaveData( "data set to array" ); element = $( "
    " ).data( "test", {} ); shouldHaveData( "data set to empty object" ); element = $( "
    " ).data( "test", { foo: "bar" } ); shouldHaveData( "data set to object" ); element = $( "
    " ).data( "test", new Date() ); shouldHaveData( "data set to date" ); element = $( "
    " ).data( "test", /test/ ); shouldHaveData( "data set to regexp" ); element = $( "
    " ).data( "test", function() {} ); shouldHaveData( "data set to function" ); } ); QUnit.test( "focusable - visible, enabled elements", function( assert ) { assert.expect( 22 ); assert.isNotFocusable( "#formNoTabindex", "form" ); assert.isFocusable( "#formTabindex", "form with tabindex" ); assert.isFocusable( "#enabledFieldset input", "input in enabled fieldset" ); assert.isNotFocusable( "#disabledFieldset input", "input in disabled fieldset" ); assert.isFocusable( "#visibleAncestor-inputTypeNone", "input, no type" ); assert.isFocusable( "#visibleAncestor-inputTypeText", "input, type text" ); assert.isFocusable( "#visibleAncestor-inputTypeCheckbox", "input, type checkbox" ); assert.isFocusable( "#visibleAncestor-inputTypeRadio", "input, type radio" ); assert.isFocusable( "#visibleAncestor-inputTypeButton", "input, type button" ); assert.isNotFocusable( "#visibleAncestor-inputTypeHidden", "input, type hidden" ); assert.isFocusable( "#visibleAncestor-button", "button" ); assert.isFocusable( "#visibleAncestor-select", "select" ); assert.isFocusable( "#visibleAncestor-textarea", "textarea" ); assert.isFocusable( "#visibleAncestor-object", "object" ); assert.isFocusable( "#visibleAncestor-anchorWithHref", "anchor with href" ); assert.isNotFocusable( "#visibleAncestor-anchorWithoutHref", "anchor without href" ); assert.isNotFocusable( "#visibleAncestor-span", "span" ); assert.isNotFocusable( "#visibleAncestor-div", "div" ); assert.isFocusable( "#visibleAncestor-spanWithTabindex", "span with tabindex" ); assert.isFocusable( "#visibleAncestor-divWithNegativeTabindex", "div with tabindex" ); assert.isFocusable( "#nestedVisibilityInheritWithVisibleAncestor", "span, visibility: inherit inside visibility: visible parent" ); assert.isFocusable( "#nestedVisibilityInheritWithVisibleAncestor-input", "input, visibility: inherit inside visibility: visible parent" ); } ); QUnit.test( "focusable - disabled elements", function( assert ) { assert.expect( 9 ); assert.isNotFocusable( "#disabledElement-inputTypeNone", "input, no type" ); assert.isNotFocusable( "#disabledElement-inputTypeText", "input, type text" ); assert.isNotFocusable( "#disabledElement-inputTypeCheckbox", "input, type checkbox" ); assert.isNotFocusable( "#disabledElement-inputTypeRadio", "input, type radio" ); assert.isNotFocusable( "#disabledElement-inputTypeButton", "input, type button" ); assert.isNotFocusable( "#disabledElement-inputTypeHidden", "input, type hidden" ); assert.isNotFocusable( "#disabledElement-button", "button" ); assert.isNotFocusable( "#disabledElement-select", "select" ); assert.isNotFocusable( "#disabledElement-textarea", "textarea" ); } ); QUnit.test( "focusable - hidden styles", function( assert ) { assert.expect( 15 ); assert.isNotFocusable( "#displayNoneAncestor-input", "input, display: none parent" ); assert.isNotFocusable( "#displayNoneAncestor-span", "span with tabindex, display: none parent" ); assert.isNotFocusable( "#visibilityHiddenAncestor-input", "input, visibility: hidden parent" ); assert.isNotFocusable( "#visibilityHiddenAncestor-span", "span with tabindex, visibility: hidden parent" ); assert.isFocusable( "#nestedVisibilityOverrideAncestor-input", "input, visibility: visible parent but visibility: hidden grandparent" ); assert.isFocusable( "#nestedVisibilityOverrideAncestor-span", "span with tabindex, visibility: visible parent but visibility: hidden grandparent " ); assert.isNotFocusable( "#nestedVisibilityInheritWithHiddenAncestor", "span, visibility: inherit inside visibility: hidden parent" ); assert.isNotFocusable( "#nestedVisibilityInheritWithHiddenAncestor-input", "input, visibility: inherit inside visibility: hidden parent" ); assert.isNotFocusable( "#displayNone-input", "input, display: none" ); assert.isNotFocusable( "#visibilityHidden-input", "input, visibility: hidden" ); assert.isNotFocusable( "#visibilityCollapse-input", "input, visibility: collapse" ); assert.isNotFocusable( "#displayNone-span", "span with tabindex, display: none" ); assert.isNotFocusable( "#visibilityHidden-span", "span with tabindex, visibility: hidden" ); assert.isNotFocusable( "#visibilityCollapse-span", "span with tabindex, visibility: collapse" ); assert.isNotFocusable( "#visibilityCollapse-td", "td with tabindex, visibility: collapse" ); } ); QUnit.test( "focusable - natively focusable with various tabindex", function( assert ) { assert.expect( 4 ); assert.isFocusable( "#inputTabindex0", "input, tabindex 0" ); assert.isFocusable( "#inputTabindex10", "input, tabindex 10" ); assert.isFocusable( "#inputTabindex-1", "input, tabindex -1" ); assert.isFocusable( "#inputTabindex-50", "input, tabindex -50" ); } ); QUnit.test( "focusable - not natively focusable with various tabindex", function( assert ) { assert.expect( 4 ); assert.isFocusable( "#spanTabindex0", "span, tabindex 0" ); assert.isFocusable( "#spanTabindex10", "span, tabindex 10" ); assert.isFocusable( "#spanTabindex-1", "span, tabindex -1" ); assert.isFocusable( "#spanTabindex-50", "span, tabindex -50" ); } ); QUnit.test( "focusable - area elements", function( assert ) { assert.expect( 3 ); assert.isFocusable( "#areaCoordsHref", "coords and href" ); assert.isFocusable( "#areaNoCoordsHref", "href but no coords" ); assert.isNotFocusable( "#areaNoImg", "not associated with an image" ); } ); QUnit.test( "focusable - dimensionless parent with overflow", function( assert ) { assert.expect( 1 ); assert.isFocusable( "#dimensionlessParent", "input" ); } ); QUnit.test( "tabbable - visible, enabled elements", function( assert ) { assert.expect( 20 ); assert.isNotTabbable( "#formNoTabindex", "form" ); assert.isTabbable( "#formTabindex", "form with tabindex" ); assert.isTabbable( "#enabledFieldset input", "input in enabled fieldset" ); assert.isNotTabbable( "#disabledFieldset input", "input in disabled fieldset" ); assert.isTabbable( "#visibleAncestor-inputTypeNone", "input, no type" ); assert.isTabbable( "#visibleAncestor-inputTypeText", "input, type text" ); assert.isTabbable( "#visibleAncestor-inputTypeCheckbox", "input, type checkbox" ); assert.isTabbable( "#visibleAncestor-inputTypeRadio", "input, type radio" ); assert.isTabbable( "#visibleAncestor-inputTypeButton", "input, type button" ); assert.isNotTabbable( "#visibleAncestor-inputTypeHidden", "input, type hidden" ); assert.isTabbable( "#visibleAncestor-button", "button" ); assert.isTabbable( "#visibleAncestor-select", "select" ); assert.isTabbable( "#visibleAncestor-textarea", "textarea" ); assert.isTabbable( "#visibleAncestor-object", "object" ); assert.isTabbable( "#visibleAncestor-anchorWithHref", "anchor with href" ); assert.isNotTabbable( "#visibleAncestor-anchorWithoutHref", "anchor without href" ); assert.isNotTabbable( "#visibleAncestor-span", "span" ); assert.isNotTabbable( "#visibleAncestor-div", "div" ); assert.isTabbable( "#visibleAncestor-spanWithTabindex", "span with tabindex" ); assert.isNotTabbable( "#visibleAncestor-divWithNegativeTabindex", "div with tabindex" ); } ); QUnit.test( "tabbable - disabled elements", function( assert ) { assert.expect( 9 ); assert.isNotTabbable( "#disabledElement-inputTypeNone", "input, no type" ); assert.isNotTabbable( "#disabledElement-inputTypeText", "input, type text" ); assert.isNotTabbable( "#disabledElement-inputTypeCheckbox", "input, type checkbox" ); assert.isNotTabbable( "#disabledElement-inputTypeRadio", "input, type radio" ); assert.isNotTabbable( "#disabledElement-inputTypeButton", "input, type button" ); assert.isNotTabbable( "#disabledElement-inputTypeHidden", "input, type hidden" ); assert.isNotTabbable( "#disabledElement-button", "button" ); assert.isNotTabbable( "#disabledElement-select", "select" ); assert.isNotTabbable( "#disabledElement-textarea", "textarea" ); } ); QUnit.test( "tabbable - hidden styles", function( assert ) { assert.expect( 10 ); assert.isNotTabbable( "#displayNoneAncestor-input", "input, display: none parent" ); assert.isNotTabbable( "#displayNoneAncestor-span", "span with tabindex, display: none parent" ); assert.isNotTabbable( "#visibilityHiddenAncestor-input", "input, visibility: hidden parent" ); assert.isNotTabbable( "#visibilityHiddenAncestor-span", "span with tabindex, visibility: hidden parent" ); assert.isTabbable( "#nestedVisibilityOverrideAncestor-input", "input, visibility: visible parent but visibility: hidden grandparent" ); assert.isTabbable( "#nestedVisibilityOverrideAncestor-span", "span with tabindex, visibility: visible parent but visibility: hidden grandparent " ); assert.isNotTabbable( "#displayNone-input", "input, display: none" ); assert.isNotTabbable( "#visibilityHidden-input", "input, visibility: hidden" ); assert.isNotTabbable( "#displayNone-span", "span with tabindex, display: none" ); assert.isNotTabbable( "#visibilityHidden-span", "span with tabindex, visibility: hidden" ); } ); QUnit.test( "tabbable - natively tabbable with various tabindex", function( assert ) { assert.expect( 4 ); assert.isTabbable( "#inputTabindex0", "input, tabindex 0" ); assert.isTabbable( "#inputTabindex10", "input, tabindex 10" ); assert.isNotTabbable( "#inputTabindex-1", "input, tabindex -1" ); assert.isNotTabbable( "#inputTabindex-50", "input, tabindex -50" ); } ); QUnit.test( "tabbable - not natively tabbable with various tabindex", function( assert ) { assert.expect( 4 ); assert.isTabbable( "#spanTabindex0", "span, tabindex 0" ); assert.isTabbable( "#spanTabindex10", "span, tabindex 10" ); assert.isNotTabbable( "#spanTabindex-1", "span, tabindex -1" ); assert.isNotTabbable( "#spanTabindex-50", "span, tabindex -50" ); } ); QUnit.test( "tabbable - area elements", function( assert ) { assert.expect( 3 ); assert.isTabbable( "#areaCoordsHref", "coords and href" ); assert.isTabbable( "#areaNoCoordsHref", "href but no coords" ); assert.isNotTabbable( "#areaNoImg", "not associated with an image" ); } ); QUnit.test( "tabbable - dimensionless parent with overflow", function( assert ) { assert.expect( 1 ); assert.isTabbable( "#dimensionlessParent", "input" ); } ); } ); ================================================ FILE: tests/unit/datepicker/all.html ================================================ jQuery UI Datepicker Test Suite
    ================================================ FILE: tests/unit/datepicker/common.js ================================================ /* TestHelpers.commonWidgetTests( "datepicker", { defaults: { disabled: false } }); */ ================================================ FILE: tests/unit/datepicker/core.js ================================================ define( [ "qunit", "jquery", "lib/common", "lib/helper", "./helper", "ui/widgets/datepicker", "ui/i18n/datepicker-he" ], function( QUnit, $, common, helper, testHelper ) { "use strict"; QUnit.module( "datepicker: core", { beforeEach: function() { $( "body" ).trigger( "focus" ); }, afterEach: helper.moduleAfterEach } ); QUnit.test( "initialization - Reinitialization after body had been emptied.", function( assert ) { assert.expect( 1 ); var bodyContent = $( "body" ).children(), inp = $( "#inp" ); $( "#inp" ).datepicker(); $( "body" ).empty().append( inp ); $( "#inp" ).datepicker(); assert.ok( $( "#" + $.datepicker._mainDivId ).length === 1, "Datepicker container added" ); $( "body" ).empty().append( bodyContent ); // Returning to initial state for later tests } ); QUnit.test( "widget method - empty collection", function( assert ) { assert.expect( 1 ); $( "#nonExist" ).datepicker(); // Should create nothing assert.strictEqual( $( "#ui-datepicker-div" ).length, 0, "Non init on empty collection" ); } ); QUnit.test( "widget method", function( assert ) { assert.expect( 1 ); var actual = $( "#inp" ).datepicker().datepicker( "widget" )[ 0 ]; assert.deepEqual( $( "body > #ui-datepicker-div:last-child" )[ 0 ], actual ); } ); QUnit.test( "baseStructure", function( assert ) { var ready = assert.async(); assert.expect( 58 ); var header, title, table, thead, week, panel, inl, child, inp = testHelper.initNewInput(), dp = $( "#ui-datepicker-div" ); function step1() { testHelper.onFocus( inp, function() { assert.ok( dp.is( ":visible" ), "Structure - datepicker visible" ); assert.ok( !dp.is( ".ui-datepicker-rtl" ), "Structure - not right-to-left" ); assert.ok( !dp.is( ".ui-datepicker-multi" ), "Structure - not multi-month" ); assert.equal( dp.children().length, 2, "Structure - child count" ); header = dp.children().first(); assert.ok( header.is( "div.ui-datepicker-header" ), "Structure - header division" ); assert.equal( header.children().length, 3, "Structure - header child count" ); assert.ok( header.children().first().is( "a.ui-datepicker-prev" ) && header.children().first().html() !== "", "Structure - prev link" ); assert.ok( header.children().eq( 1 ).is( "a.ui-datepicker-next" ) && header.children().eq( 1 ).html() !== "", "Structure - next link" ); title = header.children().last(); assert.ok( title.is( "div.ui-datepicker-title" ) && title.html() !== "", "Structure - title division" ); assert.equal( title.children().length, 2, "Structure - title child count" ); assert.ok( title.children().first().is( "span.ui-datepicker-month" ) && title.children().first().text() !== "", "Structure - month text" ); assert.ok( title.children().last().is( "span.ui-datepicker-year" ) && title.children().last().text() !== "", "Structure - year text" ); table = dp.children().eq( 1 ); assert.ok( table.is( "table.ui-datepicker-calendar" ), "Structure - month table" ); assert.ok( table.children().first().is( "thead" ), "Structure - month table thead" ); thead = table.children().first().children().first(); assert.ok( thead.is( "tr" ), "Structure - month table title row" ); assert.equal( thead.find( "th" ).length, 7, "Structure - month table title cells" ); assert.ok( table.children().eq( 1 ).is( "tbody" ), "Structure - month table body" ); assert.ok( table.children().eq( 1 ).children( "tr" ).length >= 4, "Structure - month table week count" ); week = table.children().eq( 1 ).children().first(); assert.ok( week.is( "tr" ), "Structure - month table week row" ); assert.equal( week.children().length, 7, "Structure - week child count" ); assert.ok( week.children().first().is( "td.ui-datepicker-week-end" ), "Structure - month table first day cell" ); assert.ok( week.children().last().is( "td.ui-datepicker-week-end" ), "Structure - month table second day cell" ); inp.datepicker( "hide" ).datepicker( "destroy" ); step2(); } ); } function step2() { // Editable month/year and button panel inp = testHelper.initNewInput( { changeMonth: true, changeYear: true, showButtonPanel: true } ); testHelper.onFocus( inp, function() { title = dp.find( "div.ui-datepicker-title" ); assert.ok( title.children().first().is( "select.ui-datepicker-month" ), "Structure - month selector" ); assert.ok( title.children().last().is( "select.ui-datepicker-year" ), "Structure - year selector" ); panel = dp.children().last(); assert.ok( panel.is( "div.ui-datepicker-buttonpane" ), "Structure - button panel division" ); assert.equal( panel.children().length, 2, "Structure - button panel child count" ); assert.ok( panel.children().first().is( "button.ui-datepicker-current" ), "Structure - today button" ); assert.ok( panel.children().last().is( "button.ui-datepicker-close" ), "Structure - close button" ); inp.datepicker( "hide" ).datepicker( "destroy" ); step3(); } ); } function step3() { // Multi-month 2 inp = testHelper.initNewInput( { numberOfMonths: 2 } ); testHelper.onFocus( inp, function() { assert.ok( dp.is( ".ui-datepicker-multi" ), "Structure multi [2] - multi-month" ); assert.equal( dp.children().length, 3, "Structure multi [2] - child count" ); child = dp.children().first(); assert.ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-first" ), "Structure multi [2] - first month division" ); child = dp.children().eq( 1 ); assert.ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-last" ), "Structure multi [2] - second month division" ); child = dp.children().eq( 2 ); assert.ok( child.is( "div.ui-datepicker-row-break" ), "Structure multi [2] - row break" ); assert.ok( dp.is( ".ui-datepicker-multi-2" ), "Structure multi [2] - multi-2" ); inp.datepicker( "hide" ).datepicker( "destroy" ); step4(); } ); } function step4() { // Multi-month 3 inp = testHelper.initNewInput( { numberOfMonths: 3 } ); testHelper.onFocus( inp, function() { assert.ok( dp.is( ".ui-datepicker-multi-3" ), "Structure multi [3] - multi-3" ); assert.ok( !dp.is( ".ui-datepicker-multi-2" ), "Structure multi [3] - Trac #6704" ); inp.datepicker( "hide" ).datepicker( "destroy" ); step5(); } ); } function step5() { // Multi-month [2, 2] inp = testHelper.initNewInput( { numberOfMonths: [ 2, 2 ] } ); testHelper.onFocus( inp, function() { assert.ok( dp.is( ".ui-datepicker-multi" ), "Structure multi - multi-month" ); assert.equal( dp.children().length, 6, "Structure multi [2,2] - child count" ); child = dp.children().first(); assert.ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-first" ), "Structure multi [2,2] - first month division" ); child = dp.children().eq( 1 ); assert.ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-last" ), "Structure multi [2,2] - second month division" ); child = dp.children().eq( 2 ); assert.ok( child.is( "div.ui-datepicker-row-break" ), "Structure multi [2,2] - row break" ); child = dp.children().eq( 3 ); assert.ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-first" ), "Structure multi [2,2] - third month division" ); child = dp.children().eq( 4 ); assert.ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-last" ), "Structure multi [2,2] - fourth month division" ); child = dp.children().eq( 5 ); assert.ok( child.is( "div.ui-datepicker-row-break" ), "Structure multi [2,2] - row break" ); inp.datepicker( "hide" ).datepicker( "destroy" ); // Inline inl = testHelper.init( "#inl" ); dp = inl.children(); assert.ok( dp.is( ".ui-datepicker-inline" ), "Structure inline - main div" ); assert.ok( !dp.is( ".ui-datepicker-rtl" ), "Structure inline - not right-to-left" ); assert.ok( !dp.is( ".ui-datepicker-multi" ), "Structure inline - not multi-month" ); assert.equal( dp.children().length, 2, "Structure inline - child count" ); header = dp.children().first(); assert.ok( header.is( "div.ui-datepicker-header" ), "Structure inline - header division" ); assert.equal( header.children().length, 3, "Structure inline - header child count" ); table = dp.children().eq( 1 ); assert.ok( table.is( "table.ui-datepicker-calendar" ), "Structure inline - month table" ); assert.ok( table.children().first().is( "thead" ), "Structure inline - month table thead" ); assert.ok( table.children().eq( 1 ).is( "tbody" ), "Structure inline - month table body" ); inl.datepicker( "destroy" ); // Inline multi-month inl = testHelper.init( "#inl", { numberOfMonths: 2 } ); dp = inl.children(); assert.ok( dp.is( ".ui-datepicker-inline" ) && dp.is( ".ui-datepicker-multi" ), "Structure inline multi - main div" ); assert.equal( dp.children().length, 3, "Structure inline multi - child count" ); child = dp.children().first(); assert.ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-first" ), "Structure inline multi - first month division" ); child = dp.children().eq( 1 ); assert.ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-last" ), "Structure inline multi - second month division" ); child = dp.children().eq( 2 ); assert.ok( child.is( "div.ui-datepicker-row-break" ), "Structure inline multi - row break" ); inl.datepicker( "destroy" ); ready(); } ); } step1(); } ); QUnit.test( "customStructure", function( assert ) { var ready = assert.async(); assert.expect( 20 ); var header, panel, title, thead, inp = testHelper.initNewInput( $.datepicker.regional.he ), dp = $( "#ui-datepicker-div" ); function step1() { inp.datepicker( "option", "showButtonPanel", true ); testHelper.onFocus( inp, function() { assert.ok( dp.is( ".ui-datepicker-rtl" ), "Structure RTL - right-to-left" ); header = dp.children().first(); assert.ok( header.is( "div.ui-datepicker-header" ), "Structure RTL - header division" ); assert.equal( header.children().length, 3, "Structure RTL - header child count" ); assert.ok( header.children().first().is( "a.ui-datepicker-next" ), "Structure RTL - prev link" ); assert.ok( header.children().eq( 1 ).is( "a.ui-datepicker-prev" ), "Structure RTL - next link" ); panel = dp.children().last(); assert.ok( panel.is( "div.ui-datepicker-buttonpane" ), "Structure RTL - button division" ); assert.equal( panel.children().length, 2, "Structure RTL - button panel child count" ); assert.ok( panel.children().first().is( "button.ui-datepicker-close" ), "Structure RTL - close button" ); assert.ok( panel.children().last().is( "button.ui-datepicker-current" ), "Structure RTL - today button" ); inp.datepicker( "hide" ).datepicker( "destroy" ); step2(); } ); } // Hide prev/next function step2() { inp = testHelper.initNewInput( { hideIfNoPrevNext: true, minDate: new Date( 2008, 2 - 1, 4 ), maxDate: new Date( 2008, 2 - 1, 14 ) } ); inp.val( "02/10/2008" ); testHelper.onFocus( inp, function() { header = dp.children().first(); assert.ok( header.is( "div.ui-datepicker-header" ), "Structure hide prev/next - header division" ); assert.equal( header.children().length, 1, "Structure hide prev/next - links child count" ); assert.ok( header.children().first().is( "div.ui-datepicker-title" ), "Structure hide prev/next - title division" ); inp.datepicker( "hide" ).datepicker( "destroy" ); step3(); } ); } // Changeable Month with read-only year function step3() { inp = testHelper.initNewInput( { changeMonth: true } ); testHelper.onFocus( inp, function() { title = dp.children().first().children().last(); assert.equal( title.children().length, 2, "Structure changeable month - title child count" ); assert.ok( title.children().first().is( "select.ui-datepicker-month" ), "Structure changeable month - month selector" ); assert.ok( title.children().last().is( "span.ui-datepicker-year" ), "Structure changeable month - read-only year" ); inp.datepicker( "hide" ).datepicker( "destroy" ); step4(); } ); } // Changeable year with read-only month function step4() { inp = testHelper.initNewInput( { changeYear: true } ); testHelper.onFocus( inp, function() { title = dp.children().first().children().last(); assert.equal( title.children().length, 2, "Structure changeable year - title child count" ); assert.ok( title.children().first().is( "span.ui-datepicker-month" ), "Structure changeable year - read-only month" ); assert.ok( title.children().last().is( "select.ui-datepicker-year" ), "Structure changeable year - year selector" ); inp.datepicker( "hide" ).datepicker( "destroy" ); step5(); } ); } // Read-only first day of week function step5() { inp = testHelper.initNewInput( { changeFirstDay: false } ); testHelper.onFocus( inp, function() { thead = dp.find( ".ui-datepicker-calendar thead tr" ); assert.equal( thead.children().length, 7, "Structure read-only first day - thead child count" ); assert.equal( thead.find( "a" ).length, 0, "Structure read-only first day - thead links count" ); inp.datepicker( "hide" ).datepicker( "destroy" ); ready(); } ); } setTimeout( step1 ); } ); QUnit.test( "keystrokes", function( assert ) { assert.expect( 26 ); var inp = testHelper.init( "#inp" ), date = new Date(); inp.val( "" ).datepicker( "show" ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Keystroke enter" ); inp.val( "02/04/2008" ).datepicker( "show" ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 4 ), "Keystroke enter - preset" ); inp.val( "02/04/2008" ).datepicker( "show" ). simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.HOME } ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Keystroke ctrl+home" ); inp.val( "02/04/2008" ).datepicker( "show" ). simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.END } ); assert.ok( inp.datepicker( "getDate" ) == null, "Keystroke ctrl+end" ); inp.val( "" ).datepicker( "show" ). simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); assert.ok( inp.datepicker( "getDate" ) == null, "Keystroke esc" ); inp.val( "02/04/2008" ).datepicker( "show" ). simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 4 ), "Keystroke esc - preset" ); inp.val( "02/04/2008" ).datepicker( "show" ). simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } ). simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 4 ), "Keystroke esc - abandoned" ); // Moving by day or week inp.val( "" ).datepicker( "show" ). simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.LEFT } ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); date.setDate( date.getDate() - 1 ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Keystroke ctrl+left" ); inp.val( "" ).datepicker( "show" ). simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); date.setDate( date.getDate() + 1 ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Keystroke left" ); inp.val( "" ).datepicker( "show" ). simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.RIGHT } ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); date.setDate( date.getDate() + 1 ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Keystroke ctrl+right" ); inp.val( "" ).datepicker( "show" ). simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); date.setDate( date.getDate() - 1 ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Keystroke right" ); inp.val( "" ).datepicker( "show" ). simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.UP } ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); date.setDate( date.getDate() - 7 ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Keystroke ctrl+up" ); inp.val( "" ).datepicker( "show" ). simulate( "keydown", { keyCode: $.ui.keyCode.UP } ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); date.setDate( date.getDate() + 7 ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Keystroke up" ); inp.val( "" ).datepicker( "show" ). simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.DOWN } ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); date.setDate( date.getDate() + 7 ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Keystroke ctrl+down" ); inp.val( "" ).datepicker( "show" ). simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); date.setDate( date.getDate() - 7 ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Keystroke down" ); // Moving by month or year inp.val( "02/04/2008" ).datepicker( "show" ). simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2008, 1 - 1, 4 ), "Keystroke pgup" ); inp.val( "02/04/2008" ).datepicker( "show" ). simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2008, 3 - 1, 4 ), "Keystroke pgdn" ); inp.val( "02/04/2008" ).datepicker( "show" ). simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2007, 2 - 1, 4 ), "Keystroke ctrl+pgup" ); inp.val( "02/04/2008" ).datepicker( "show" ). simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN } ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2009, 2 - 1, 4 ), "Keystroke ctrl+pgdn" ); // Check for moving to short months inp.val( "03/31/2008" ).datepicker( "show" ). simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 29 ), "Keystroke pgup - Feb" ); inp.val( "01/30/2008" ).datepicker( "show" ). simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 29 ), "Keystroke pgdn - Feb" ); inp.val( "02/29/2008" ).datepicker( "show" ). simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2007, 2 - 1, 28 ), "Keystroke ctrl+pgup - Feb" ); inp.val( "02/29/2008" ).datepicker( "show" ). simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN } ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2009, 2 - 1, 28 ), "Keystroke ctrl+pgdn - Feb" ); // Goto current inp.datepicker( "option", { gotoCurrent: true } ). datepicker( "hide" ).val( "02/04/2008" ).datepicker( "show" ). simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ). simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.HOME } ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 4 ), "Keystroke ctrl+home" ); // Change steps inp.datepicker( "option", { stepMonths: 2, gotoCurrent: false } ). datepicker( "hide" ).val( "02/04/2008" ).datepicker( "show" ). simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2007, 12 - 1, 4 ), "Keystroke pgup step 2" ); inp.val( "02/04/2008" ).datepicker( "show" ). simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2008, 4 - 1, 4 ), "Keystroke pgdn step 2" ); } ); QUnit.test( "mouse", function( assert ) { assert.expect( 15 ); var inl, inp = testHelper.init( "#inp" ), dp = $( "#ui-datepicker-div" ), date = new Date(); inp.val( "" ).datepicker( "show" ); $( ".ui-datepicker-calendar tbody a:contains(10)", dp ).simulate( "click", {} ); date.setDate( 10 ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Mouse click" ); inp.val( "02/04/2008" ).datepicker( "show" ); $( ".ui-datepicker-calendar tbody a:contains(12)", dp ).simulate( "click", {} ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 12 ), "Mouse click - preset" ); inp.val( "02/04/2008" ).datepicker( "show" ); inp.val( "" ).datepicker( "show" ); $( "button.ui-datepicker-close", dp ).simulate( "click", {} ); assert.ok( inp.datepicker( "getDate" ) == null, "Mouse click - close" ); inp.val( "02/04/2008" ).datepicker( "show" ); $( "button.ui-datepicker-close", dp ).simulate( "click", {} ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 4 ), "Mouse click - close + preset" ); inp.val( "02/04/2008" ).datepicker( "show" ); $( "a.ui-datepicker-prev", dp ).simulate( "click", {} ); $( "button.ui-datepicker-close", dp ).simulate( "click", {} ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 4 ), "Mouse click - abandoned" ); // Current/previous/next inp.val( "02/04/2008" ).datepicker( "option", { showButtonPanel: true } ).datepicker( "show" ); $( ".ui-datepicker-current", dp ).simulate( "click", {} ); $( ".ui-datepicker-calendar tbody a:contains(14)", dp ).simulate( "click", {} ); date.setDate( 14 ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Mouse click - current" ); inp.val( "02/04/2008" ).datepicker( "show" ); $( ".ui-datepicker-prev", dp ).simulate( "click" ); $( ".ui-datepicker-calendar tbody a:contains(16)", dp ).simulate( "click" ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2008, 1 - 1, 16 ), "Mouse click - previous" ); inp.val( "02/04/2008" ).datepicker( "show" ); $( ".ui-datepicker-next", dp ).simulate( "click" ); $( ".ui-datepicker-calendar tbody a:contains(18)", dp ).simulate( "click" ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2008, 3 - 1, 18 ), "Mouse click - next" ); // Previous/next with minimum/maximum inp.datepicker( "option", { minDate: new Date( 2008, 2 - 1, 2 ), maxDate: new Date( 2008, 2 - 1, 26 ) } ).val( "02/04/2008" ).datepicker( "show" ); $( ".ui-datepicker-prev", dp ).simulate( "click" ); $( ".ui-datepicker-calendar tbody a:contains(16)", dp ).simulate( "click" ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 16 ), "Mouse click - previous + min/max" ); inp.val( "02/04/2008" ).datepicker( "show" ); $( ".ui-datepicker-next", dp ).simulate( "click" ); $( ".ui-datepicker-calendar tbody a:contains(18)", dp ).simulate( "click" ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 18 ), "Mouse click - next + min/max" ); // Inline inl = testHelper.init( "#inl" ); dp = $( ".ui-datepicker-inline", inl ); date = new Date(); inl.datepicker( "setDate", date ); $( ".ui-datepicker-calendar tbody a:contains(10)", dp ).simulate( "click", {} ); date.setDate( 10 ); testHelper.equalsDate( assert, inl.datepicker( "getDate" ), date, "Mouse click inline" ); inl.datepicker( "option", { showButtonPanel: true } ).datepicker( "setDate", new Date( 2008, 2 - 1, 4 ) ); $( ".ui-datepicker-calendar tbody a:contains(12)", dp ).simulate( "click", {} ); testHelper.equalsDate( assert, inl.datepicker( "getDate" ), new Date( 2008, 2 - 1, 12 ), "Mouse click inline - preset" ); inl.datepicker( "option", { showButtonPanel: true } ); $( ".ui-datepicker-current", dp ).simulate( "click", {} ); $( ".ui-datepicker-calendar tbody a:contains(14)", dp ).simulate( "click", {} ); date.setDate( 14 ); testHelper.equalsDate( assert, inl.datepicker( "getDate" ), date, "Mouse click inline - current" ); inl.datepicker( "setDate", new Date( 2008, 2 - 1, 4 ) ); $( ".ui-datepicker-prev", dp ).simulate( "click" ); $( ".ui-datepicker-calendar tbody a:contains(16)", dp ).simulate( "click" ); testHelper.equalsDate( assert, inl.datepicker( "getDate" ), new Date( 2008, 1 - 1, 16 ), "Mouse click inline - previous" ); inl.datepicker( "setDate", new Date( 2008, 2 - 1, 4 ) ); $( ".ui-datepicker-next", dp ).simulate( "click" ); $( ".ui-datepicker-calendar tbody a:contains(18)", dp ).simulate( "click" ); testHelper.equalsDate( assert, inl.datepicker( "getDate" ), new Date( 2008, 3 - 1, 18 ), "Mouse click inline - next" ); } ); QUnit.test( "initialized on focus is immediately shown (gh-2385)", function( assert ) { assert.expect( 2 ); var dp, dp2, inp, inp2, parent; try { inp = $( "#inp" ); parent = inp.parent(); parent.on( "focus", "#inp:not(.hasDatepicker)", function() { testHelper.init( "#inp" ); dp = $( "#ui-datepicker-div" ); } ); inp.trigger( "focus" ); assert.equal( dp.css( "display" ), "block", "Datepicker - visible (delegated focus)" ); } finally { inp.datepicker( "destroy" ); } try { inp2 = $( "#inp2" ); inp2.on( "focus", function() { if ( $( this ).hasClass( "hasDatepicker" ) ) { return; } testHelper.init( "#inp2" ); dp2 = $( "#ui-datepicker-div" ); } ); inp2.trigger( "focus" ); assert.equal( dp2.css( "display" ), "block", "Datepicker - visible (regular focus)" ); } finally { inp2.datepicker( "destroy" ); } } ); } ); ================================================ FILE: tests/unit/datepicker/datepicker.html ================================================ jQuery UI Datepicker Test Suite

    ================================================ FILE: tests/unit/datepicker/events.js ================================================ define( [ "qunit", "jquery", "./helper", "ui/widgets/datepicker" ], function( QUnit, $, testHelper ) { "use strict"; var beforeAfterEach = testHelper.beforeAfterEach; QUnit.module( "datepicker: events", beforeAfterEach() ); var selectedThis = null, selectedDate = null, selectedInst = null; function callback( date, inst ) { selectedThis = this; selectedDate = date; selectedInst = inst; } function callback2( year, month, inst ) { selectedThis = this; selectedDate = year + "/" + month; selectedInst = inst; } QUnit.test( "events", function( assert ) { assert.expect( 26 ); var dateStr, newMonthYear, inp2, inp = testHelper.init( "#inp", { onSelect: callback } ), date = new Date(); // OnSelect inp.val( "" ).datepicker( "show" ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); assert.equal( selectedThis, inp[ 0 ], "Callback selected this" ); assert.equal( selectedInst, $.data( inp[ 0 ], testHelper.PROP_NAME ), "Callback selected inst" ); assert.equal( selectedDate, $.datepicker.formatDate( "mm/dd/yy", date ), "Callback selected date" ); inp.val( "" ).datepicker( "show" ). simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.DOWN } ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); date.setDate( date.getDate() + 7 ); assert.equal( selectedDate, $.datepicker.formatDate( "mm/dd/yy", date ), "Callback selected date - ctrl+down" ); inp.val( "" ).datepicker( "show" ). simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); assert.equal( selectedDate, $.datepicker.formatDate( "mm/dd/yy", date ), "Callback selected date - esc" ); dateStr = "02/04/2008"; inp.val( dateStr ).datepicker( "show" ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); assert.equal( dateStr, selectedDate, "onSelect is called after enter keydown" ); // OnChangeMonthYear inp.datepicker( "option", { onChangeMonthYear: callback2, onSelect: null } ). val( "" ).datepicker( "show" ); newMonthYear = function( date ) { return date.getFullYear() + "/" + ( date.getMonth() + 1 ); }; date = new Date(); date.setDate( 1 ); inp.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ); date.setMonth( date.getMonth() - 1 ); assert.equal( selectedThis, inp[ 0 ], "Callback change month/year this" ); assert.equal( selectedInst, $.data( inp[ 0 ], testHelper.PROP_NAME ), "Callback change month/year inst" ); assert.equal( selectedDate, newMonthYear( date ), "Callback change month/year date - pgup" ); inp.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ); date.setMonth( date.getMonth() + 1 ); assert.equal( selectedDate, newMonthYear( date ), "Callback change month/year date - pgdn" ); inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } ); date.setFullYear( date.getFullYear() - 1 ); assert.equal( selectedDate, newMonthYear( date ), "Callback change month/year date - ctrl+pgup" ); inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.HOME } ); date.setFullYear( date.getFullYear() + 1 ); assert.equal( selectedDate, newMonthYear( date ), "Callback change month/year date - ctrl+home" ); inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN } ); date.setFullYear( date.getFullYear() + 1 ); assert.equal( selectedDate, newMonthYear( date ), "Callback change month/year date - ctrl+pgdn" ); inp.datepicker( "setDate", new Date( 2007, 1 - 1, 26 ) ); assert.equal( selectedDate, "2007/1", "Callback change month/year date - setDate" ); selectedDate = null; inp.datepicker( "setDate", new Date( 2007, 1 - 1, 12 ) ); assert.ok( selectedDate == null, "Callback change month/year date - setDate no change" ); // OnChangeMonthYear step by 2 inp.datepicker( "option", { stepMonths: 2 } ). datepicker( "hide" ).val( "" ).datepicker( "show" ). simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ); date.setMonth( date.getMonth() - 14 ); assert.equal( selectedDate, newMonthYear( date ), "Callback change month/year by 2 date - pgup" ); inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } ); date.setMonth( date.getMonth() - 12 ); assert.equal( selectedDate, newMonthYear( date ), "Callback change month/year by 2 date - ctrl+pgup" ); inp.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ); date.setMonth( date.getMonth() + 2 ); assert.equal( selectedDate, newMonthYear( date ), "Callback change month/year by 2 date - pgdn" ); inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN } ); date.setMonth( date.getMonth() + 12 ); assert.equal( selectedDate, newMonthYear( date ), "Callback change month/year by 2 date - ctrl+pgdn" ); // OnClose inp.datepicker( "option", { onClose: callback, onChangeMonthYear: null, stepMonths: 1 } ). val( "" ).datepicker( "show" ). simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); assert.equal( selectedThis, inp[ 0 ], "Callback close this" ); assert.equal( selectedInst, $.data( inp[ 0 ], testHelper.PROP_NAME ), "Callback close inst" ); assert.equal( selectedDate, "", "Callback close date - esc" ); inp.val( "" ).datepicker( "show" ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); assert.equal( selectedDate, $.datepicker.formatDate( "mm/dd/yy", new Date() ), "Callback close date - enter" ); inp.val( "02/04/2008" ).datepicker( "show" ). simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); assert.equal( selectedDate, "02/04/2008", "Callback close date - preset" ); inp.val( "02/04/2008" ).datepicker( "show" ). simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.END } ); assert.equal( selectedDate, "", "Callback close date - ctrl+end" ); inp2 = testHelper.init( "#inp2" ); inp2.datepicker().datepicker( "option", { onClose: callback } ).datepicker( "show" ); inp.datepicker( "show" ); assert.equal( selectedThis, inp2[ 0 ], "Callback close this" ); } ); QUnit.test( "beforeShowDay-getDate", function( assert ) { assert.expect( 3 ); var inp = testHelper.init( "#inp", { beforeShowDay: function() { inp.datepicker( "getDate" ); return [ true, "" ]; } } ); var dp = $( "#ui-datepicker-div" ); inp.val( "01/01/2010" ).datepicker( "show" ); // Contains non-breaking space assert.equal( $( "div.ui-datepicker-title" ).text(), // In IE7/8 with jQuery <1.8, encoded spaces behave in strange ways $( "January 2010" ).text(), "Initial month" ); $( "a.ui-datepicker-next", dp ).trigger( "click" ); $( "a.ui-datepicker-next", dp ).trigger( "click" ); // Contains non-breaking space assert.equal( $( "div.ui-datepicker-title" ).text(), $( "March 2010" ).text(), "After next clicks" ); inp.datepicker( "hide" ).datepicker( "show" ); $( "a.ui-datepicker-prev", dp ).trigger( "click" ); $( "a.ui-datepicker-prev", dp ).trigger( "click" ); // Contains non-breaking space assert.equal( $( "div.ui-datepicker-title" ).text(), $( "November 2009" ).text(), "After prev clicks" ); inp.datepicker( "hide" ); } ); } ); ================================================ FILE: tests/unit/datepicker/helper.js ================================================ define( [ "qunit", "jquery", "lib/helper", "ui/widgets/datepicker" ], function( QUnit, $, helper ) { "use strict"; return $.extend( helper, { addMonths: function( date, offset ) { var maxDay = 32 - new Date( date.getFullYear(), date.getMonth() + offset, 32 ).getDate(); date.setDate( Math.min( date.getDate(), maxDay ) ); date.setMonth( date.getMonth() + offset ); return date; }, equalsDate: function( assert, d1, d2, message ) { if ( !d1 || !d2 ) { assert.ok( false, message + " - missing date" ); return; } d1 = new Date( d1.getFullYear(), d1.getMonth(), d1.getDate() ); d2 = new Date( d2.getFullYear(), d2.getMonth(), d2.getDate() ); assert.equal( d1.toString(), d2.toString(), message ); }, beforeAfterEach: function() { return { afterEach: helper.moduleAfterEach }; }, init: function( id, options ) { $.datepicker.setDefaults( $.datepicker.regional[ "" ] ); return $( id ).datepicker( $.extend( { showAnim: "" }, options || {} ) ); }, initNewInput: function( options ) { var id = $( "" ).appendTo( "#qunit-fixture" ); return this.init( id, options ); }, PROP_NAME: "datepicker" } ); } ); ================================================ FILE: tests/unit/datepicker/methods.js ================================================ define( [ "qunit", "jquery", "./helper", "ui/widgets/datepicker" ], function( QUnit, $, testHelper ) { "use strict"; var beforeAfterEach = testHelper.beforeAfterEach; QUnit.module( "datepicker: methods", beforeAfterEach() ); QUnit.test( "destroy", function( assert ) { assert.expect( 39 ); var inl, inp = testHelper.init( "#inp" ), dp = $( "#ui-datepicker-div" ); // Destroy and clear active reference inp.datepicker( "show" ); assert.equal( dp.css( "display" ), "block", "Datepicker - visible" ); inp.datepicker( "hide" ).datepicker( "destroy" ); assert.ok( $.datepicker._curInst == null, "Datepicker - destroyed and cleared reference" ); assert.equal( dp.css( "display" ), "none", "Datepicker - absent" ); // Destroy without manual hiding (ensure datepicker is hidden after calling destroy) inp = testHelper.init( "#inp" ); inp.datepicker( "show" ); assert.equal( dp.css( "display" ), "block", "Datepicker - visible" ); inp.datepicker( "destroy" ); assert.ok( $.datepicker._curInst == null, "Datepicker - destroyed and cleared reference" ); assert.equal( dp.css( "display" ), "none", "Datepicker - absent" ); inp = testHelper.init( "#inp" ); assert.ok( inp.is( ".hasDatepicker" ), "Default - marker class set" ); assert.ok( $.data( inp[ 0 ], testHelper.PROP_NAME ), "Default - instance present" ); assert.ok( inp.next().is( "#alt" ), "Default - button absent" ); inp.datepicker( "destroy" ); inp = $( "#inp" ); assert.ok( !inp.is( ".hasDatepicker" ), "Default - marker class cleared" ); assert.ok( !$.data( inp[ 0 ], testHelper.PROP_NAME ), "Default - instance absent" ); assert.ok( inp.next().is( "#alt" ), "Default - button absent" ); // With button inp = testHelper.init( "#inp", { showOn: "both" } ); assert.ok( inp.is( ".hasDatepicker" ), "Button - marker class set" ); assert.ok( $.data( inp[ 0 ], testHelper.PROP_NAME ), "Button - instance present" ); assert.ok( inp.next().text() === "...", "Button - button added" ); inp.datepicker( "destroy" ); inp = $( "#inp" ); assert.ok( !inp.is( ".hasDatepicker" ), "Button - marker class cleared" ); assert.ok( !$.data( inp[ 0 ], testHelper.PROP_NAME ), "Button - instance absent" ); assert.ok( inp.next().is( "#alt" ), "Button - button removed" ); // With append text inp = testHelper.init( "#inp", { appendText: "Testing" } ); assert.ok( inp.is( ".hasDatepicker" ), "Append - marker class set" ); assert.ok( $.data( inp[ 0 ], testHelper.PROP_NAME ), "Append - instance present" ); assert.ok( inp.next().text() === "Testing", "Append - append text added" ); inp.datepicker( "destroy" ); inp = $( "#inp" ); assert.ok( !inp.is( ".hasDatepicker" ), "Append - marker class cleared" ); assert.ok( !$.data( inp[ 0 ], testHelper.PROP_NAME ), "Append - instance absent" ); assert.ok( inp.next().is( "#alt" ), "Append - append text removed" ); // With both inp = testHelper.init( "#inp", { showOn: "both", buttonImageOnly: true, buttonImage: "images/calendar.gif", appendText: "Testing" } ); assert.ok( inp.is( ".hasDatepicker" ), "Both - marker class set" ); assert.ok( $.data( inp[ 0 ], testHelper.PROP_NAME ), "Both - instance present" ); assert.ok( inp.next()[ 0 ].nodeName.toLowerCase() === "img", "Both - button added" ); assert.ok( inp.next().next().text() === "Testing", "Both - append text added" ); inp.datepicker( "destroy" ); inp = $( "#inp" ); assert.ok( !inp.is( ".hasDatepicker" ), "Both - marker class cleared" ); assert.ok( !$.data( inp[ 0 ], testHelper.PROP_NAME ), "Both - instance absent" ); assert.ok( inp.next().is( "#alt" ), "Both - button and append text absent" ); // Inline inl = testHelper.init( "#inl" ); assert.ok( inl.is( ".hasDatepicker" ), "Inline - marker class set" ); assert.ok( inl.html() !== "", "Inline - datepicker present" ); assert.ok( $.data( inl[ 0 ], testHelper.PROP_NAME ), "Inline - instance present" ); assert.ok( inl.next().length === 0 || inl.next().is( "p" ), "Inline - button absent" ); inl.datepicker( "destroy" ); inl = $( "#inl" ); assert.ok( !inl.is( ".hasDatepicker" ), "Inline - marker class cleared" ); assert.ok( inl.html() === "", "Inline - datepicker absent" ); assert.ok( !$.data( inl[ 0 ], testHelper.PROP_NAME ), "Inline - instance absent" ); assert.ok( inl.next().length === 0 || inl.next().is( "p" ), "Inline - button absent" ); } ); QUnit.test( "enableDisable", function( assert ) { assert.expect( 33 ); var inl, dp, inp = testHelper.init( "#inp" ); assert.ok( !inp.datepicker( "isDisabled" ), "Enable/disable - initially marked as enabled" ); assert.ok( !inp[ 0 ].disabled, "Enable/disable - field initially enabled" ); inp.datepicker( "disable" ); assert.ok( inp.datepicker( "isDisabled" ), "Enable/disable - now marked as disabled" ); assert.ok( inp[ 0 ].disabled, "Enable/disable - field now disabled" ); inp.datepicker( "enable" ); assert.ok( !inp.datepicker( "isDisabled" ), "Enable/disable - now marked as enabled" ); assert.ok( !inp[ 0 ].disabled, "Enable/disable - field now enabled" ); inp.datepicker( "destroy" ); // With a button inp = testHelper.init( "#inp", { showOn: "button" } ); assert.ok( !inp.datepicker( "isDisabled" ), "Enable/disable button - initially marked as enabled" ); assert.ok( !inp[ 0 ].disabled, "Enable/disable button - field initially enabled" ); assert.ok( !inp.next( "button" )[ 0 ].disabled, "Enable/disable button - button initially enabled" ); inp.datepicker( "disable" ); assert.ok( inp.datepicker( "isDisabled" ), "Enable/disable button - now marked as disabled" ); assert.ok( inp[ 0 ].disabled, "Enable/disable button - field now disabled" ); assert.ok( inp.next( "button" )[ 0 ].disabled, "Enable/disable button - button now disabled" ); inp.datepicker( "enable" ); assert.ok( !inp.datepicker( "isDisabled" ), "Enable/disable button - now marked as enabled" ); assert.ok( !inp[ 0 ].disabled, "Enable/disable button - field now enabled" ); assert.ok( !inp.next( "button" )[ 0 ].disabled, "Enable/disable button - button now enabled" ); inp.datepicker( "destroy" ); // With an image button inp = testHelper.init( "#inp", { showOn: "button", buttonImageOnly: true, buttonImage: "images/calendar.gif" } ); assert.ok( !inp.datepicker( "isDisabled" ), "Enable/disable image - initially marked as enabled" ); assert.ok( !inp[ 0 ].disabled, "Enable/disable image - field initially enabled" ); assert.ok( parseFloat( inp.next( "img" ).css( "opacity" ) ) === 1, "Enable/disable image - image initially enabled" ); inp.datepicker( "disable" ); assert.ok( inp.datepicker( "isDisabled" ), "Enable/disable image - now marked as disabled" ); assert.ok( inp[ 0 ].disabled, "Enable/disable image - field now disabled" ); assert.ok( parseFloat( inp.next( "img" ).css( "opacity" ) ) !== 1, "Enable/disable image - image now disabled" ); inp.datepicker( "enable" ); assert.ok( !inp.datepicker( "isDisabled" ), "Enable/disable image - now marked as enabled" ); assert.ok( !inp[ 0 ].disabled, "Enable/disable image - field now enabled" ); assert.ok( parseFloat( inp.next( "img" ).css( "opacity" ) ) === 1, "Enable/disable image - image now enabled" ); inp.datepicker( "destroy" ); // Inline inl = testHelper.init( "#inl", { changeYear: true } ); dp = $( ".ui-datepicker-inline", inl ); assert.ok( !inl.datepicker( "isDisabled" ), "Enable/disable inline - initially marked as enabled" ); assert.ok( !dp.children().is( ".ui-state-disabled" ), "Enable/disable inline - not visually disabled initially" ); assert.ok( !dp.find( "select" ).prop( "disabled" ), "Enable/disable inline - form element enabled initially" ); inl.datepicker( "disable" ); assert.ok( inl.datepicker( "isDisabled" ), "Enable/disable inline - now marked as disabled" ); assert.ok( dp.children().is( ".ui-state-disabled" ), "Enable/disable inline - visually disabled" ); assert.ok( dp.find( "select" ).prop( "disabled" ), "Enable/disable inline - form element disabled" ); inl.datepicker( "enable" ); assert.ok( !inl.datepicker( "isDisabled" ), "Enable/disable inline - now marked as enabled" ); assert.ok( !dp.children().is( ".ui-state-disabled" ), "Enable/disable inline - not visiually disabled" ); assert.ok( !dp.find( "select" ).prop( "disabled" ), "Enable/disable inline - form element enabled" ); inl.datepicker( "destroy" ); } ); } ); ================================================ FILE: tests/unit/datepicker/options.js ================================================ define( [ "qunit", "jquery", "./helper", "ui/widgets/datepicker", "ui/i18n/datepicker-fr", "ui/i18n/datepicker-he", "ui/i18n/datepicker-zh-CN" ], function( QUnit, $, testHelper ) { "use strict"; var beforeAfterEach = testHelper.beforeAfterEach; QUnit.module( "datepicker: options", beforeAfterEach() ); QUnit.test( "setDefaults", function( assert ) { assert.expect( 3 ); testHelper.init( "#inp" ); assert.equal( $.datepicker._defaults.showOn, "focus", "Initial showOn" ); $.datepicker.setDefaults( { showOn: "button" } ); assert.equal( $.datepicker._defaults.showOn, "button", "Change default showOn" ); $.datepicker.setDefaults( { showOn: "focus" } ); assert.equal( $.datepicker._defaults.showOn, "focus", "Restore showOn" ); } ); QUnit.test( "option", function( assert ) { assert.expect( 17 ); var inp = testHelper.init( "#inp" ), inst = $.data( inp[ 0 ], testHelper.PROP_NAME ); // Set option assert.equal( inst.settings.showOn, null, "Initial setting showOn" ); assert.equal( $.datepicker._get( inst, "showOn" ), "focus", "Initial instance showOn" ); assert.equal( $.datepicker._defaults.showOn, "focus", "Initial default showOn" ); inp.datepicker( "option", "showOn", "button" ); assert.equal( inst.settings.showOn, "button", "Change setting showOn" ); assert.equal( $.datepicker._get( inst, "showOn" ), "button", "Change instance showOn" ); assert.equal( $.datepicker._defaults.showOn, "focus", "Retain default showOn" ); inp.datepicker( "option", { showOn: "both" } ); assert.equal( inst.settings.showOn, "both", "Change setting showOn" ); assert.equal( $.datepicker._get( inst, "showOn" ), "both", "Change instance showOn" ); assert.equal( $.datepicker._defaults.showOn, "focus", "Retain default showOn" ); inp.datepicker( "option", "showOn", undefined ); assert.equal( inst.settings.showOn, null, "Clear setting showOn" ); assert.equal( $.datepicker._get( inst, "showOn" ), "focus", "Restore instance showOn" ); assert.equal( $.datepicker._defaults.showOn, "focus", "Retain default showOn" ); // Get option inp = testHelper.init( "#inp" ); assert.equal( inp.datepicker( "option", "showOn" ), "focus", "Initial setting showOn" ); inp.datepicker( "option", "showOn", "button" ); assert.equal( inp.datepicker( "option", "showOn" ), "button", "Change instance showOn" ); inp.datepicker( "option", "showOn", undefined ); assert.equal( inp.datepicker( "option", "showOn" ), "focus", "Reset instance showOn" ); assert.deepEqual( inp.datepicker( "option", "all" ), { showAnim: "" }, "Get instance settings" ); assert.deepEqual( inp.datepicker( "option", "defaults" ), $.datepicker._defaults, "Get default settings" ); } ); QUnit.test( "disabled", function( assert ) { assert.expect( 8 ); var inp = testHelper.init( "#inp" ); assert.ok( !inp.datepicker( "isDisabled" ), "Initially marked as enabled" ); assert.ok( !inp[ 0 ].disabled, "Field initially enabled" ); inp.datepicker( "option", "disabled", true ); assert.ok( inp.datepicker( "isDisabled" ), "Marked as disabled" ); assert.ok( inp[ 0 ].disabled, "Field now disabled" ); inp.datepicker( "option", "disabled", false ); assert.ok( !inp.datepicker( "isDisabled" ), "Marked as enabled" ); assert.ok( !inp[ 0 ].disabled, "Field now enabled" ); inp.datepicker( "destroy" ); inp = testHelper.init( "#inp", { disabled: true } ); assert.ok( inp.datepicker( "isDisabled" ), "Initially marked as disabled" ); assert.ok( inp[ 0 ].disabled, "Field initially disabled" ); } ); QUnit.test( "change", function( assert ) { assert.expect( 12 ); var inp = testHelper.init( "#inp" ), inst = $.data( inp[ 0 ], testHelper.PROP_NAME ); assert.equal( inst.settings.showOn, null, "Initial setting showOn" ); assert.equal( $.datepicker._get( inst, "showOn" ), "focus", "Initial instance showOn" ); assert.equal( $.datepicker._defaults.showOn, "focus", "Initial default showOn" ); inp.datepicker( "change", "showOn", "button" ); assert.equal( inst.settings.showOn, "button", "Change setting showOn" ); assert.equal( $.datepicker._get( inst, "showOn" ), "button", "Change instance showOn" ); assert.equal( $.datepicker._defaults.showOn, "focus", "Retain default showOn" ); inp.datepicker( "change", { showOn: "both" } ); assert.equal( inst.settings.showOn, "both", "Change setting showOn" ); assert.equal( $.datepicker._get( inst, "showOn" ), "both", "Change instance showOn" ); assert.equal( $.datepicker._defaults.showOn, "focus", "Retain default showOn" ); inp.datepicker( "change", "showOn", undefined ); assert.equal( inst.settings.showOn, null, "Clear setting showOn" ); assert.equal( $.datepicker._get( inst, "showOn" ), "focus", "Restore instance showOn" ); assert.equal( $.datepicker._defaults.showOn, "focus", "Retain default showOn" ); } ); QUnit.test( "invocation", function( assert ) { var ready = assert.async(); var button, image, body = $( "body" ); assert.expect( 29 ); function step0() { var inp = testHelper.initNewInput(), dp = $( "#ui-datepicker-div" ); button = inp.siblings( "button" ); assert.ok( button.length === 0, "Focus - button absent" ); image = inp.siblings( "img" ); assert.ok( image.length === 0, "Focus - image absent" ); testHelper.onFocus( inp, function() { assert.ok( dp.is( ":visible" ), "Focus - rendered on focus" ); inp.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); assert.ok( !dp.is( ":visible" ), "Focus - hidden on exit" ); step1(); } ); } function step1() { var inp = testHelper.initNewInput(), dp = $( "#ui-datepicker-div" ); testHelper.onFocus( inp, function() { assert.ok( dp.is( ":visible" ), "Focus - rendered on focus" ); body.simulate( "mousedown", {} ); assert.ok( !dp.is( ":visible" ), "Focus - hidden on external click" ); inp.datepicker( "hide" ).datepicker( "destroy" ); step2(); } ); } function step2() { var inp = testHelper.initNewInput( { showOn: "button", buttonText: "Popup" } ), dp = $( "#ui-datepicker-div" ); assert.ok( !dp.is( ":visible" ), "Button - initially hidden" ); button = inp.siblings( "button" ); image = inp.siblings( "img" ); assert.ok( button.length === 1, "Button - button present" ); assert.ok( image.length === 0, "Button - image absent" ); assert.equal( button.text(), "Popup", "Button - button text" ); testHelper.onFocus( inp, function() { assert.ok( !dp.is( ":visible" ), "Button - not rendered on focus" ); button.trigger( "click" ); assert.ok( dp.is( ":visible" ), "Button - rendered on button click" ); button.trigger( "click" ); assert.ok( !dp.is( ":visible" ), "Button - hidden on second button click" ); inp.datepicker( "hide" ).datepicker( "destroy" ); step3(); } ); } function step3() { var inp = testHelper.initNewInput( { showOn: "button", buttonImageOnly: true, buttonImage: "images/calendar.gif", buttonText: "Cal" } ), dp = $( "#ui-datepicker-div" ); assert.ok( !dp.is( ":visible" ), "Image button - initially hidden" ); button = inp.siblings( "button" ); assert.ok( button.length === 0, "Image button - button absent" ); image = inp.siblings( "img" ); assert.ok( image.length === 1, "Image button - image present" ); assert.ok( /images\/calendar\.gif$/.test( image.attr( "src" ) ), "Image button - image source" ); assert.equal( image.attr( "title" ), "Cal", "Image button - image text" ); testHelper.onFocus( inp, function() { assert.ok( !dp.is( ":visible" ), "Image button - not rendered on focus" ); image.trigger( "click" ); assert.ok( dp.is( ":visible" ), "Image button - rendered on image click" ); image.trigger( "click" ); assert.ok( !dp.is( ":visible" ), "Image button - hidden on second image click" ); inp.datepicker( "hide" ).datepicker( "destroy" ); step4(); } ); } function step4() { var inp = testHelper.initNewInput( { showOn: "both", buttonImage: "images/calendar.gif" } ), dp = $( "#ui-datepicker-div" ); assert.ok( !dp.is( ":visible" ), "Both - initially hidden" ); button = inp.siblings( "button" ); assert.ok( button.length === 1, "Both - button present" ); image = inp.siblings( "img" ); assert.ok( image.length === 0, "Both - image absent" ); image = button.children( "img" ); assert.ok( image.length === 1, "Both - button image present" ); testHelper.onFocus( inp, function() { assert.ok( dp.is( ":visible" ), "Both - rendered on focus" ); body.simulate( "mousedown", {} ); assert.ok( !dp.is( ":visible" ), "Both - hidden on external click" ); button.trigger( "click" ); assert.ok( dp.is( ":visible" ), "Both - rendered on button click" ); button.trigger( "click" ); assert.ok( !dp.is( ":visible" ), "Both - hidden on second button click" ); inp.datepicker( "hide" ).datepicker( "destroy" ); ready(); } ); } step0(); } ); QUnit.test( "otherMonths", function( assert ) { assert.expect( 8 ); var inp = testHelper.init( "#inp" ), pop = $( "#ui-datepicker-div" ); inp.val( "06/01/2009" ).datepicker( "show" ); assert.equal( pop.find( "tbody" ).text(), // In IE7/8 with jQuery <1.8, encoded spaces behave in strange ways $( "\u00a0123456789101112131415161718192021222324252627282930\u00a0\u00a0\u00a0\u00a0" ).text(), "Other months - none" ); assert.ok( pop.find( "td" ).last().find( "*" ).length === 0, "Other months - no content" ); inp.datepicker( "hide" ).datepicker( "option", "showOtherMonths", true ).datepicker( "show" ); assert.equal( pop.find( "tbody" ).text(), "311234567891011121314151617181920212223242526272829301234", "Other months - show" ); assert.ok( pop.find( "td" ).last().find( "span" ).length === 1, "Other months - span content" ); inp.datepicker( "hide" ).datepicker( "option", "selectOtherMonths", true ).datepicker( "show" ); assert.equal( pop.find( "tbody" ).text(), "311234567891011121314151617181920212223242526272829301234", "Other months - select" ); assert.ok( pop.find( "td" ).last().find( "a" ).length === 1, "Other months - link content" ); inp.datepicker( "hide" ).datepicker( "option", "showOtherMonths", false ).datepicker( "show" ); assert.equal( pop.find( "tbody" ).text(), // In IE7/8 with jQuery <1.8, encoded spaces behave in strange ways $( "\u00a0123456789101112131415161718192021222324252627282930\u00a0\u00a0\u00a0\u00a0" ).text(), "Other months - none" ); assert.ok( pop.find( "td" ).last().find( "*" ).length === 0, "Other months - no content" ); } ); QUnit.test( "defaultDate", function( assert ) { assert.expect( 16 ); var inp = testHelper.init( "#inp" ), date = new Date(); inp.val( "" ).datepicker( "show" ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Default date null" ); // Numeric values inp.datepicker( "option", { defaultDate: -2 } ). datepicker( "hide" ).val( "" ).datepicker( "show" ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); date.setDate( date.getDate() - 2 ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Default date -2" ); date = new Date(); inp.datepicker( "option", { defaultDate: 3 } ). datepicker( "hide" ).val( "" ).datepicker( "show" ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); date.setDate( date.getDate() + 3 ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Default date 3" ); date = new Date(); inp.datepicker( "option", { defaultDate: 1 / "a" } ). datepicker( "hide" ).val( "" ).datepicker( "show" ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Default date NaN" ); // String offset values inp.datepicker( "option", { defaultDate: "-1d" } ). datepicker( "hide" ).val( "" ).datepicker( "show" ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); date.setDate( date.getDate() - 1 ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Default date -1d" ); inp.datepicker( "option", { defaultDate: "+3d" } ). datepicker( "hide" ).val( "" ).datepicker( "show" ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); date.setDate( date.getDate() + 4 ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Default date +3d" ); inp.datepicker( "option", { defaultDate: " -2 w " } ). datepicker( "hide" ).val( "" ).datepicker( "show" ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); date = new Date(); date.setDate( date.getDate() - 14 ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Default date -2 w" ); inp.datepicker( "option", { defaultDate: "+1 w" } ). datepicker( "hide" ).val( "" ).datepicker( "show" ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); date.setDate( date.getDate() + 21 ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Default date +1 w" ); inp.datepicker( "option", { defaultDate: " -1 m " } ). datepicker( "hide" ).val( "" ).datepicker( "show" ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); date = testHelper.addMonths( new Date(), -1 ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Default date -1 m" ); inp.datepicker( "option", { defaultDate: "+2m" } ). datepicker( "hide" ).val( "" ).datepicker( "show" ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); date = testHelper.addMonths( new Date(), 2 ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Default date +2m" ); inp.datepicker( "option", { defaultDate: "-2y" } ). datepicker( "hide" ).val( "" ).datepicker( "show" ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); date = new Date(); date.setFullYear( date.getFullYear() - 2 ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Default date -2y" ); inp.datepicker( "option", { defaultDate: "+1 y " } ). datepicker( "hide" ).val( "" ).datepicker( "show" ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); date.setFullYear( date.getFullYear() + 3 ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Default date +1 y" ); inp.datepicker( "option", { defaultDate: "+1m +10d" } ). datepicker( "hide" ).val( "" ).datepicker( "show" ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); date = testHelper.addMonths( new Date(), 1 ); date.setDate( date.getDate() + 10 ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Default date +1m +10d" ); // String date values inp.datepicker( "option", { defaultDate: "07/04/2007" } ). datepicker( "hide" ).val( "" ).datepicker( "show" ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); date = new Date( 2007, 7 - 1, 4 ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Default date 07/04/2007" ); inp.datepicker( "option", { dateFormat: "yy-mm-dd", defaultDate: "2007-04-02" } ). datepicker( "hide" ).val( "" ).datepicker( "show" ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); date = new Date( 2007, 4 - 1, 2 ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Default date 2007-04-02" ); // Date value date = new Date( 2007, 1 - 1, 26 ); inp.datepicker( "option", { dateFormat: "mm/dd/yy", defaultDate: date } ). datepicker( "hide" ).val( "" ).datepicker( "show" ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Default date 01/26/2007" ); } ); QUnit.test( "miscellaneous", function( assert ) { assert.expect( 19 ); var curYear, longNames, shortNames, date, dp = $( "#ui-datepicker-div" ), inp = testHelper.init( "#inp" ); // Year range function genRange( start, offset ) { var i = start, range = ""; for ( ; i < start + offset; i++ ) { range += i; } return range; } curYear = new Date().getFullYear(); inp.val( "02/04/2008" ).datepicker( "show" ); assert.equal( dp.find( ".ui-datepicker-year" ).text(), "2008", "Year range - read-only default" ); inp.datepicker( "hide" ).datepicker( "option", { changeYear: true } ).datepicker( "show" ); assert.equal( dp.find( ".ui-datepicker-year" ).text(), genRange( 2008 - 10, 21 ), "Year range - changeable default" ); inp.datepicker( "hide" ).datepicker( "option", { yearRange: "c-6:c+2", changeYear: true } ).datepicker( "show" ); assert.equal( dp.find( ".ui-datepicker-year" ).text(), genRange( 2008 - 6, 9 ), "Year range - c-6:c+2" ); inp.datepicker( "hide" ).datepicker( "option", { yearRange: "2000:2010", changeYear: true } ).datepicker( "show" ); assert.equal( dp.find( ".ui-datepicker-year" ).text(), genRange( 2000, 11 ), "Year range - 2000:2010" ); inp.datepicker( "hide" ).datepicker( "option", { yearRange: "-5:+3", changeYear: true } ).datepicker( "show" ); assert.equal( dp.find( ".ui-datepicker-year" ).text(), genRange( curYear - 5, 9 ), "Year range - -5:+3" ); inp.datepicker( "hide" ).datepicker( "option", { yearRange: "2000:-5", changeYear: true } ).datepicker( "show" ); assert.equal( dp.find( ".ui-datepicker-year" ).text(), genRange( 2000, curYear - 2004 ), "Year range - 2000:-5" ); inp.datepicker( "hide" ).datepicker( "option", { yearRange: "", changeYear: true } ).datepicker( "show" ); assert.equal( dp.find( ".ui-datepicker-year" ).text(), genRange( curYear, 1 ), "Year range - -6:+2" ); // Navigation as date format inp.datepicker( "option", { showButtonPanel: true } ); assert.equal( dp.find( ".ui-datepicker-prev" ).text(), "Prev", "Navigation prev - default" ); assert.equal( dp.find( ".ui-datepicker-current" ).text(), "Today", "Navigation current - default" ); assert.equal( dp.find( ".ui-datepicker-next" ).text(), "Next", "Navigation next - default" ); inp.datepicker( "hide" ).datepicker( "option", { navigationAsDateFormat: true, prevText: "< M", currentText: "MM", nextText: "M >" } ). val( "02/04/2008" ).datepicker( "show" ); longNames = $.datepicker.regional[ "" ].monthNames; shortNames = $.datepicker.regional[ "" ].monthNamesShort; date = new Date(); assert.equal( dp.find( ".ui-datepicker-prev" ).text(), "< " + shortNames[ 0 ], "Navigation prev - as date format" ); assert.equal( dp.find( ".ui-datepicker-current" ).text(), longNames[ date.getMonth() ], "Navigation current - as date format" ); assert.equal( dp.find( ".ui-datepicker-next" ).text(), shortNames[ 2 ] + " >", "Navigation next - as date format" ); inp.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ); assert.equal( dp.find( ".ui-datepicker-prev" ).text(), "< " + shortNames[ 1 ], "Navigation prev - as date format + pgdn" ); assert.equal( dp.find( ".ui-datepicker-current" ).text(), longNames[ date.getMonth() ], "Navigation current - as date format + pgdn" ); assert.equal( dp.find( ".ui-datepicker-next" ).text(), shortNames[ 3 ] + " >", "Navigation next - as date format + pgdn" ); inp.datepicker( "hide" ).datepicker( "option", { gotoCurrent: true } ). val( "02/04/2008" ).datepicker( "show" ); assert.equal( dp.find( ".ui-datepicker-prev" ).text(), "< " + shortNames[ 0 ], "Navigation prev - as date format + goto current" ); assert.equal( dp.find( ".ui-datepicker-current" ).text(), longNames[ 1 ], "Navigation current - as date format + goto current" ); assert.equal( dp.find( ".ui-datepicker-next" ).text(), shortNames[ 2 ] + " >", "Navigation next - as date format + goto current" ); } ); QUnit.test( "minMax", function( assert ) { assert.expect( 23 ); var date, inp = testHelper.init( "#inp" ), dp = $( "#ui-datepicker-div" ), lastYear = new Date( 2007, 6 - 1, 4 ), nextYear = new Date( 2009, 6 - 1, 4 ), minDate = new Date( 2008, 2 - 1, 29 ), maxDate = new Date( 2008, 12 - 1, 7 ); inp.val( "06/04/2008" ).datepicker( "show" ); inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), lastYear, "Min/max - null, null - ctrl+pgup" ); inp.val( "06/04/2008" ).datepicker( "show" ); inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN } ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), nextYear, "Min/max - null, null - ctrl+pgdn" ); inp.datepicker( "option", { minDate: minDate } ). datepicker( "hide" ).val( "06/04/2008" ).datepicker( "show" ); inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), minDate, "Min/max - 02/29/2008, null - ctrl+pgup" ); inp.val( "06/04/2008" ).datepicker( "show" ); inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN } ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), nextYear, "Min/max - 02/29/2008, null - ctrl+pgdn" ); inp.datepicker( "option", { maxDate: maxDate } ). datepicker( "hide" ).val( "06/04/2008" ).datepicker( "show" ); inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), minDate, "Min/max - 02/29/2008, 12/07/2008 - ctrl+pgup" ); inp.val( "06/04/2008" ).datepicker( "show" ); inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN } ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), maxDate, "Min/max - 02/29/2008, 12/07/2008 - ctrl+pgdn" ); inp.datepicker( "option", { minDate: null } ). datepicker( "hide" ).val( "06/04/2008" ).datepicker( "show" ); inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), lastYear, "Min/max - null, 12/07/2008 - ctrl+pgup" ); inp.val( "06/04/2008" ).datepicker( "show" ); inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN } ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), maxDate, "Min/max - null, 12/07/2008 - ctrl+pgdn" ); // Relative dates date = new Date(); date.setDate( date.getDate() - 7 ); inp.datepicker( "option", { minDate: "-1w", maxDate: "+1 m +10 d " } ). datepicker( "hide" ).val( "" ).datepicker( "show" ); inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Min/max - -1w, +1 m +10 d - ctrl+pgup" ); date = testHelper.addMonths( new Date(), 1 ); date.setDate( date.getDate() + 10 ); inp.val( "" ).datepicker( "show" ); inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN } ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Min/max - -1w, +1 m +10 d - ctrl+pgdn" ); // With existing date inp = testHelper.init( "#inp" ); inp.val( "06/04/2008" ).datepicker( "option", { minDate: minDate } ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - setDate > min" ); inp.datepicker( "option", { minDate: null } ).val( "01/04/2008" ).datepicker( "option", { minDate: minDate } ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), minDate, "Min/max - setDate < min" ); inp.datepicker( "option", { minDate: null } ).val( "06/04/2008" ).datepicker( "option", { maxDate: maxDate } ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - setDate < max" ); inp.datepicker( "option", { maxDate: null } ).val( "01/04/2009" ).datepicker( "option", { maxDate: maxDate } ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), maxDate, "Min/max - setDate > max" ); inp.datepicker( "option", { maxDate: null } ).val( "01/04/2008" ).datepicker( "option", { minDate: minDate, maxDate: maxDate } ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), minDate, "Min/max - setDate < min" ); inp.datepicker( "option", { maxDate: null } ).val( "06/04/2008" ).datepicker( "option", { minDate: minDate, maxDate: maxDate } ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - setDate > min, < max" ); inp.datepicker( "option", { maxDate: null } ).val( "01/04/2009" ).datepicker( "option", { minDate: minDate, maxDate: maxDate } ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), maxDate, "Min/max - setDate > max" ); inp.datepicker( "option", { yearRange: "-0:+1" } ).val( "01/01/" + new Date().getFullYear() ); assert.ok( dp.find( ".ui-datepicker-prev" ).hasClass( "ui-state-disabled" ), "Year Range Test - previous button disabled at 1/1/minYear" ); inp.datepicker( "setDate", "12/30/" + new Date().getFullYear() ); assert.ok( dp.find( ".ui-datepicker-next" ).hasClass( "ui-state-disabled" ), "Year Range Test - next button disabled at 12/30/maxYear" ); inp.val( "" ).datepicker( "option", { minDate: new Date( 1900, 0, 1 ), maxDate: "-7y", yearRange: "1900:-7" } ); assert.ok( dp.find( ".ui-datepicker-next" ).hasClass( "ui-state-disabled" ), "Year Range Test - relative - next button disabled" ); assert.ok( !dp.find( ".ui-datepicker-prev" ).hasClass( "ui-state-disabled" ), "Year Range Test - relative - prev button enabled" ); inp.val( "" ).datepicker( "option", { minDate: new Date( 1900, 0, 1 ), maxDate: "1/25/2007", yearRange: "1900:2007" } ); assert.ok( dp.find( ".ui-datepicker-next" ).hasClass( "ui-state-disabled" ), "Year Range Test - absolute - next button disabled" ); assert.ok( !dp.find( ".ui-datepicker-prev" ).hasClass( "ui-state-disabled" ), "Year Range Test - absolute - prev button enabled" ); } ); QUnit.test( "setDate", function( assert ) { assert.expect( 24 ); var inl, alt, minDate, maxDate, dateAndTimeToSet, dateAndTimeClone, inp = testHelper.init( "#inp" ), date1 = new Date( 2008, 6 - 1, 4 ), date2 = new Date(); assert.ok( inp.datepicker( "getDate" ) == null, "Set date - default" ); inp.datepicker( "setDate", date1 ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date1, "Set date - 2008-06-04" ); date1 = new Date(); date1.setDate( date1.getDate() + 7 ); inp.datepicker( "setDate", +7 ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date1, "Set date - +7" ); date2.setFullYear( date2.getFullYear() + 2 ); inp.datepicker( "setDate", "+2y" ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date2, "Set date - +2y" ); inp.datepicker( "setDate", date1, date2 ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date1, "Set date - two dates" ); inp.datepicker( "setDate" ); assert.ok( inp.datepicker( "getDate" ) == null, "Set date - null" ); // Relative to current date date1 = new Date(); date1.setDate( date1.getDate() + 7 ); inp.datepicker( "setDate", "c +7" ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date1, "Set date - c +7" ); date1.setDate( date1.getDate() + 7 ); inp.datepicker( "setDate", "c+7" ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date1, "Set date - c+7" ); date1.setDate( date1.getDate() - 21 ); inp.datepicker( "setDate", "c -3 w" ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date1, "Set date - c -3 w" ); // Inline inl = testHelper.init( "#inl" ); date1 = new Date( 2008, 6 - 1, 4 ); date2 = new Date(); testHelper.equalsDate( assert, inl.datepicker( "getDate" ), date2, "Set date inline - default" ); inl.datepicker( "setDate", date1 ); testHelper.equalsDate( assert, inl.datepicker( "getDate" ), date1, "Set date inline - 2008-06-04" ); date1 = new Date(); date1.setDate( date1.getDate() + 7 ); inl.datepicker( "setDate", +7 ); testHelper.equalsDate( assert, inl.datepicker( "getDate" ), date1, "Set date inline - +7" ); date2.setFullYear( date2.getFullYear() + 2 ); inl.datepicker( "setDate", "+2y" ); testHelper.equalsDate( assert, inl.datepicker( "getDate" ), date2, "Set date inline - +2y" ); inl.datepicker( "setDate", date1, date2 ); testHelper.equalsDate( assert, inl.datepicker( "getDate" ), date1, "Set date inline - two dates" ); inl.datepicker( "setDate" ); assert.ok( inl.datepicker( "getDate" ) == null, "Set date inline - null" ); // Alternate field alt = $( "#alt" ); inp.datepicker( "option", { altField: "#alt", altFormat: "yy-mm-dd" } ); date1 = new Date( 2008, 6 - 1, 4 ); inp.datepicker( "setDate", date1 ); assert.equal( inp.val(), "06/04/2008", "Set date alternate - 06/04/2008" ); assert.equal( alt.val(), "2008-06-04", "Set date alternate - 2008-06-04" ); // With minimum/maximum inp = testHelper.init( "#inp" ); date1 = new Date( 2008, 1 - 1, 4 ); date2 = new Date( 2008, 6 - 1, 4 ); minDate = new Date( 2008, 2 - 1, 29 ); maxDate = new Date( 2008, 3 - 1, 28 ); inp.val( "" ).datepicker( "option", { minDate: minDate } ).datepicker( "setDate", date2 ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date2, "Set date min/max - setDate > min" ); inp.datepicker( "setDate", date1 ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), minDate, "Set date min/max - setDate < min" ); inp.val( "" ).datepicker( "option", { maxDate: maxDate, minDate: null } ).datepicker( "setDate", date1 ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date1, "Set date min/max - setDate < max" ); inp.datepicker( "setDate", date2 ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), maxDate, "Set date min/max - setDate > max" ); inp.val( "" ).datepicker( "option", { minDate: minDate } ).datepicker( "setDate", date1 ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), minDate, "Set date min/max - setDate < min" ); inp.datepicker( "setDate", date2 ); testHelper.equalsDate( assert, inp.datepicker( "getDate" ), maxDate, "Set date min/max - setDate > max" ); dateAndTimeToSet = new Date( 2008, 3 - 1, 28, 1, 11, 0 ); dateAndTimeClone = new Date( 2008, 3 - 1, 28, 1, 11, 0 ); inp.datepicker( "setDate", dateAndTimeToSet ); assert.equal( dateAndTimeToSet.getTime(), dateAndTimeClone.getTime(), "Date object passed should not be changed by setDate" ); } ); QUnit.test( "altField", function( assert ) { assert.expect( 11 ); var done = assert.async(), inp = testHelper.init( "#inp" ), alt = $( "#alt" ); // No alternate field set alt.val( "" ); inp.val( "06/04/2008" ).datepicker( "show" ); inp.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); assert.equal( inp.val(), "06/04/2008", "Alt field - dp - enter" ); assert.equal( alt.val(), "", "Alt field - alt not set" ); // Alternate field set alt.val( "" ); inp.datepicker( "option", { altField: "#alt", altFormat: "yy-mm-dd" } ). val( "06/04/2008" ).datepicker( "show" ); inp.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); assert.equal( inp.val(), "06/04/2008", "Alt field - dp - enter" ); assert.equal( alt.val(), "2008-06-04", "Alt field - alt - enter" ); // Move from initial date alt.val( "" ); inp.val( "06/04/2008" ).datepicker( "show" ); inp.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ). simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); assert.equal( inp.val(), "07/04/2008", "Alt field - dp - pgdn" ); assert.equal( alt.val(), "2008-07-04", "Alt field - alt - pgdn" ); // Alternate field set - closed alt.val( "" ); inp.val( "06/04/2008" ).datepicker( "show" ); inp.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ). simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); assert.equal( inp.val(), "06/04/2008", "Alt field - dp - pgdn/esc" ); assert.equal( alt.val(), "", "Alt field - alt - pgdn/esc" ); // Clear date and alternate alt.val( "" ); inp.val( "06/04/2008" ).datepicker( "show" ); inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.END } ); assert.equal( inp.val(), "", "Alt field - dp - ctrl+end" ); assert.equal( alt.val(), "", "Alt field - alt - ctrl+end" ); // HTML instead of selector alt.val( "" ); try { inp.datepicker( "option", { altField: "", altFormat: "yy-mm-dd" } ).val( "06/04/2008" ).datepicker( "show" ); inp.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); } catch ( e ) {} setTimeout( function() { assert.equal( window.globalAltField, undefined, "altField treated as a selector" ); delete window.globalAltField; done(); }, 500 ); } ); QUnit.test( "autoSize", function( assert ) { assert.expect( 15 ); var inp = testHelper.init( "#inp" ); assert.equal( inp.prop( "size" ), 20, "Auto size - default" ); inp.datepicker( "option", "autoSize", true ); assert.equal( inp.prop( "size" ), 10, "Auto size - mm/dd/yy" ); inp.datepicker( "option", "dateFormat", "m/d/yy" ); assert.equal( inp.prop( "size" ), 10, "Auto size - m/d/yy" ); inp.datepicker( "option", "dateFormat", "D M d yy" ); assert.equal( inp.prop( "size" ), 15, "Auto size - D M d yy" ); inp.datepicker( "option", "dateFormat", "DD, MM dd, yy" ); assert.equal( inp.prop( "size" ), 29, "Auto size - DD, MM dd, yy" ); // French inp.datepicker( "option", $.extend( { autoSize: false }, $.datepicker.regional.fr ) ); assert.equal( inp.prop( "size" ), 29, "Auto size - fr - default" ); inp.datepicker( "option", "autoSize", true ); assert.equal( inp.prop( "size" ), 10, "Auto size - fr - dd/mm/yy" ); inp.datepicker( "option", "dateFormat", "m/d/yy" ); assert.equal( inp.prop( "size" ), 10, "Auto size - fr - m/d/yy" ); inp.datepicker( "option", "dateFormat", "D M d yy" ); assert.equal( inp.prop( "size" ), 18, "Auto size - fr - D M d yy" ); inp.datepicker( "option", "dateFormat", "DD, MM dd, yy" ); assert.equal( inp.prop( "size" ), 28, "Auto size - fr - DD, MM dd, yy" ); // Hebrew inp.datepicker( "option", $.extend( { autoSize: false }, $.datepicker.regional.he ) ); assert.equal( inp.prop( "size" ), 28, "Auto size - he - default" ); inp.datepicker( "option", "autoSize", true ); assert.equal( inp.prop( "size" ), 10, "Auto size - he - dd/mm/yy" ); inp.datepicker( "option", "dateFormat", "m/d/yy" ); assert.equal( inp.prop( "size" ), 10, "Auto size - he - m/d/yy" ); inp.datepicker( "option", "dateFormat", "D M d yy" ); assert.equal( inp.prop( "size" ), 16, "Auto size - he - D M d yy" ); inp.datepicker( "option", "dateFormat", "DD, MM dd, yy" ); assert.equal( inp.prop( "size" ), 23, "Auto size - he - DD, MM dd, yy" ); } ); QUnit.test( "daylightSaving", function( assert ) { assert.expect( 25 ); var inp = testHelper.init( "#inp" ), dp = $( "#ui-datepicker-div" ); assert.ok( true, "Daylight saving - " + new Date() ); // Australia, Sydney - AM change, southern hemisphere inp.val( "04/01/2008" ).datepicker( "show" ); $( ".ui-datepicker-calendar td", dp ).eq( 6 ).find( "a" ).simulate( "click" ); assert.equal( inp.val(), "04/05/2008", "Daylight saving - Australia 04/05/2008" ); inp.val( "04/01/2008" ).datepicker( "show" ); $( ".ui-datepicker-calendar td", dp ).eq( 7 ).find( "a" ).simulate( "click" ); assert.equal( inp.val(), "04/06/2008", "Daylight saving - Australia 04/06/2008" ); inp.val( "04/01/2008" ).datepicker( "show" ); $( ".ui-datepicker-calendar td", dp ).eq( 8 ).find( "a" ).simulate( "click" ); assert.equal( inp.val(), "04/07/2008", "Daylight saving - Australia 04/07/2008" ); inp.val( "10/01/2008" ).datepicker( "show" ); $( ".ui-datepicker-calendar td", dp ).eq( 6 ).find( "a" ).simulate( "click" ); assert.equal( inp.val(), "10/04/2008", "Daylight saving - Australia 10/04/2008" ); inp.val( "10/01/2008" ).datepicker( "show" ); $( ".ui-datepicker-calendar td", dp ).eq( 7 ).find( "a" ).simulate( "click" ); assert.equal( inp.val(), "10/05/2008", "Daylight saving - Australia 10/05/2008" ); inp.val( "10/01/2008" ).datepicker( "show" ); $( ".ui-datepicker-calendar td", dp ).eq( 8 ).find( "a" ).simulate( "click" ); assert.equal( inp.val(), "10/06/2008", "Daylight saving - Australia 10/06/2008" ); // Brasil, Brasilia - midnight change, southern hemisphere inp.val( "02/01/2008" ).datepicker( "show" ); $( ".ui-datepicker-calendar td", dp ).eq( 20 ).find( "a" ).simulate( "click" ); assert.equal( inp.val(), "02/16/2008", "Daylight saving - Brasil 02/16/2008" ); inp.val( "02/01/2008" ).datepicker( "show" ); $( ".ui-datepicker-calendar td", dp ).eq( 21 ).find( "a" ).simulate( "click" ); assert.equal( inp.val(), "02/17/2008", "Daylight saving - Brasil 02/17/2008" ); inp.val( "02/01/2008" ).datepicker( "show" ); $( ".ui-datepicker-calendar td", dp ).eq( 22 ).find( "a" ).simulate( "click" ); assert.equal( inp.val(), "02/18/2008", "Daylight saving - Brasil 02/18/2008" ); inp.val( "10/01/2008" ).datepicker( "show" ); $( ".ui-datepicker-calendar td", dp ).eq( 13 ).find( "a" ).simulate( "click" ); assert.equal( inp.val(), "10/11/2008", "Daylight saving - Brasil 10/11/2008" ); inp.val( "10/01/2008" ).datepicker( "show" ); $( ".ui-datepicker-calendar td", dp ).eq( 14 ).find( "a" ).simulate( "click" ); assert.equal( inp.val(), "10/12/2008", "Daylight saving - Brasil 10/12/2008" ); inp.val( "10/01/2008" ).datepicker( "show" ); $( ".ui-datepicker-calendar td", dp ).eq( 15 ).find( "a" ).simulate( "click" ); assert.equal( inp.val(), "10/13/2008", "Daylight saving - Brasil 10/13/2008" ); // Lebanon, Beirut - midnight change, northern hemisphere inp.val( "03/01/2008" ).datepicker( "show" ); $( ".ui-datepicker-calendar td", dp ).eq( 34 ).find( "a" ).simulate( "click" ); assert.equal( inp.val(), "03/29/2008", "Daylight saving - Lebanon 03/29/2008" ); inp.val( "03/01/2008" ).datepicker( "show" ); $( ".ui-datepicker-calendar td", dp ).eq( 35 ).find( "a" ).simulate( "click" ); assert.equal( inp.val(), "03/30/2008", "Daylight saving - Lebanon 03/30/2008" ); inp.val( "03/01/2008" ).datepicker( "show" ); $( ".ui-datepicker-calendar td", dp ).eq( 36 ).find( "a" ).simulate( "click" ); assert.equal( inp.val(), "03/31/2008", "Daylight saving - Lebanon 03/31/2008" ); inp.val( "10/01/2008" ).datepicker( "show" ); $( ".ui-datepicker-calendar td", dp ).eq( 27 ).find( "a" ).simulate( "click" ); assert.equal( inp.val(), "10/25/2008", "Daylight saving - Lebanon 10/25/2008" ); inp.val( "10/01/2008" ).datepicker( "show" ); $( ".ui-datepicker-calendar td", dp ).eq( 28 ).find( "a" ).simulate( "click" ); assert.equal( inp.val(), "10/26/2008", "Daylight saving - Lebanon 10/26/2008" ); inp.val( "10/01/2008" ).datepicker( "show" ); $( ".ui-datepicker-calendar td", dp ).eq( 29 ).find( "a" ).simulate( "click" ); assert.equal( inp.val(), "10/27/2008", "Daylight saving - Lebanon 10/27/2008" ); // US, Eastern - AM change, northern hemisphere inp.val( "03/01/2008" ).datepicker( "show" ); $( ".ui-datepicker-calendar td", dp ).eq( 13 ).find( "a" ).simulate( "click" ); assert.equal( inp.val(), "03/08/2008", "Daylight saving - US 03/08/2008" ); inp.val( "03/01/2008" ).datepicker( "show" ); $( ".ui-datepicker-calendar td", dp ).eq( 14 ).find( "a" ).simulate( "click" ); assert.equal( inp.val(), "03/09/2008", "Daylight saving - US 03/09/2008" ); inp.val( "03/01/2008" ).datepicker( "show" ); $( ".ui-datepicker-calendar td", dp ).eq( 15 ).find( "a" ).simulate( "click" ); assert.equal( inp.val(), "03/10/2008", "Daylight saving - US 03/10/2008" ); inp.val( "11/01/2008" ).datepicker( "show" ); $( ".ui-datepicker-calendar td", dp ).eq( 6 ).find( "a" ).simulate( "click" ); assert.equal( inp.val(), "11/01/2008", "Daylight saving - US 11/01/2008" ); inp.val( "11/01/2008" ).datepicker( "show" ); $( ".ui-datepicker-calendar td", dp ).eq( 7 ).find( "a" ).simulate( "click" ); assert.equal( inp.val(), "11/02/2008", "Daylight saving - US 11/02/2008" ); inp.val( "11/01/2008" ).datepicker( "show" ); $( ".ui-datepicker-calendar td", dp ).eq( 8 ).find( "a" ).simulate( "click" ); assert.equal( inp.val(), "11/03/2008", "Daylight saving - US 11/03/2008" ); } ); var beforeShowThis = null, beforeShowInput = null, beforeShowInst = null, beforeShowDayThis = null, beforeShowDayOK = true, onUpdateDatepickerThis = null, onUpdateDatepickerInst = null; function beforeAll( input, inst ) { beforeShowThis = this; beforeShowInput = input; beforeShowInst = inst; return { currentText: "Current" }; } function beforeDay( date ) { beforeShowDayThis = this; beforeShowDayOK &= ( date > new Date( 2008, 1 - 1, 26 ) && date < new Date( 2008, 3 - 1, 6 ) ); return [ ( date.getDate() % 2 === 0 ), ( date.getDate() % 10 === 0 ? "day10" : "" ), ( date.getDate() % 3 === 0 ? "Divisble by 3" : "" ) ]; } function onUpdateDatepicker( inst ) { onUpdateDatepickerThis = this; onUpdateDatepickerInst = inst; inst.dpDiv.append( $( "
    " ).addClass( "on-update-datepicker-test" ) ); } QUnit.test( "callbacks", function( assert ) { assert.expect( 18 ); // Before show var dp, day20, day21, inp = testHelper.init( "#inp", { beforeShow: beforeAll } ), inst = $.data( inp[ 0 ], "datepicker" ); assert.equal( $.datepicker._get( inst, "currentText" ), "Today", "Before show - initial" ); inp.val( "02/04/2008" ).datepicker( "show" ); assert.equal( $.datepicker._get( inst, "currentText" ), "Current", "Before show - changed" ); assert.ok( beforeShowThis.id === inp[ 0 ].id, "Before show - this OK" ); assert.ok( beforeShowInput.id === inp[ 0 ].id, "Before show - input OK" ); assert.deepEqual( beforeShowInst, inst, "Before show - inst OK" ); inp.datepicker( "hide" ).datepicker( "destroy" ); // Before show day inp = testHelper.init( "#inp", { beforeShowDay: beforeDay } ); dp = $( "#ui-datepicker-div" ); inp.val( "02/04/2008" ).datepicker( "show" ); assert.ok( beforeShowDayThis.id === inp[ 0 ].id, "Before show day - this OK" ); assert.ok( beforeShowDayOK, "Before show day - dates OK" ); day20 = dp.find( ".ui-datepicker-calendar td:contains('20')" ); day21 = dp.find( ".ui-datepicker-calendar td:contains('21')" ); assert.ok( !day20.is( ".ui-datepicker-unselectable" ), "Before show day - unselectable 20" ); assert.ok( day21.is( ".ui-datepicker-unselectable" ), "Before show day - unselectable 21" ); assert.ok( day20.is( ".day10" ), "Before show day - CSS 20" ); assert.ok( !day21.is( ".day10" ), "Before show day - CSS 21" ); assert.ok( !day20.attr( "title" ), "Before show day - title 20" ); assert.ok( day21.attr( "title" ) === "Divisble by 3", "Before show day - title 21" ); inp.datepicker( "hide" ).datepicker( "destroy" ); inp = testHelper.init( "#inp", { onUpdateDatepicker: onUpdateDatepicker } ); inst = $.data( inp[ 0 ], "datepicker" ); dp = $( "#ui-datepicker-div" ); inp.val( "02/04/2008" ).datepicker( "show" ); assert.ok( onUpdateDatepickerThis.id === inp[ 0 ].id, "On update datepicker - this OK" ); assert.deepEqual( onUpdateDatepickerInst, inst, "On update datepicker - inst OK" ); assert.ok( dp.find( "div.on-update-datepicker-test" ).length === 1, "On update datepicker - custom element" ); inp.datepicker( "setDate", "02/05/2008" ); assert.ok( dp.find( "div.on-update-datepicker-test" ).length === 1, "On update datepicker - custom element after setDate" ); inp.datepicker( "refresh" ); assert.ok( dp.find( "div.on-update-datepicker-test" ).length === 1, "On update datepicker - custom element after refresh" ); inp.datepicker( "hide" ).datepicker( "destroy" ); } ); QUnit.test( "beforeShowDay - tooltips with quotes", function( assert ) { assert.expect( 1 ); var inp, dp; inp = testHelper.init( "#inp", { beforeShowDay: function() { return [ true, "", "'" ]; } } ); dp = $( "#ui-datepicker-div" ); inp.datepicker( "show" ); assert.equal( dp.find( ".ui-datepicker-calendar td:contains('9')" ).attr( "title" ), "'" ); inp.datepicker( "hide" ).datepicker( "destroy" ); } ); QUnit.test( "localisation", function( assert ) { assert.expect( 24 ); var dp, month, day, date, inp = testHelper.init( "#inp", $.datepicker.regional.fr ); inp.datepicker( "option", { dateFormat: "DD, d MM yy", showButtonPanel: true, changeMonth: true, changeYear: true } ).val( "" ).datepicker( "show" ); dp = $( "#ui-datepicker-div" ); assert.equal( $( ".ui-datepicker-close", dp ).text(), "Fermer", "Localisation - close" ); $( ".ui-datepicker-close", dp ).simulate( "mouseover" ); assert.equal( $( ".ui-datepicker-prev", dp ).text(), "Précédent", "Localisation - previous" ); assert.equal( $( ".ui-datepicker-current", dp ).text(), "Aujourd'hui", "Localisation - current" ); assert.equal( $( ".ui-datepicker-next", dp ).text(), "Suivant", "Localisation - next" ); month = 0; $( ".ui-datepicker-month option", dp ).each( function() { assert.equal( $( this ).text(), $.datepicker.regional.fr.monthNamesShort[ month ], "Localisation - month " + month ); month++; } ); day = 1; $( ".ui-datepicker-calendar th", dp ).each( function() { assert.equal( $( this ).text(), $.datepicker.regional.fr.dayNamesMin[ day ], "Localisation - day " + day ); day = ( day + 1 ) % 7; } ); inp.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); date = new Date(); assert.equal( inp.val(), $.datepicker.regional.fr.dayNames[ date.getDay() ] + ", " + date.getDate() + " " + $.datepicker.regional.fr.monthNames[ date.getMonth() ] + " " + date.getFullYear(), "Localisation - formatting" ); } ); QUnit.test( "noWeekends", function( assert ) { assert.expect( 31 ); var i, date; for ( i = 1; i <= 31; i++ ) { date = new Date( 2001, 1 - 1, i ); assert.deepEqual( $.datepicker.noWeekends( date ), [ ( i + 1 ) % 7 >= 2, "" ], "No weekends " + date ); } } ); QUnit.test( "iso8601Week", function( assert ) { assert.expect( 12 ); var date = new Date( 2000, 12 - 1, 31 ); assert.equal( $.datepicker.iso8601Week( date ), 52, "ISO 8601 week " + date ); date = new Date( 2001, 1 - 1, 1 ); assert.equal( $.datepicker.iso8601Week( date ), 1, "ISO 8601 week " + date ); date = new Date( 2001, 1 - 1, 7 ); assert.equal( $.datepicker.iso8601Week( date ), 1, "ISO 8601 week " + date ); date = new Date( 2001, 1 - 1, 8 ); assert.equal( $.datepicker.iso8601Week( date ), 2, "ISO 8601 week " + date ); date = new Date( 2003, 12 - 1, 28 ); assert.equal( $.datepicker.iso8601Week( date ), 52, "ISO 8601 week " + date ); date = new Date( 2003, 12 - 1, 29 ); assert.equal( $.datepicker.iso8601Week( date ), 1, "ISO 8601 week " + date ); date = new Date( 2004, 1 - 1, 4 ); assert.equal( $.datepicker.iso8601Week( date ), 1, "ISO 8601 week " + date ); date = new Date( 2004, 1 - 1, 5 ); assert.equal( $.datepicker.iso8601Week( date ), 2, "ISO 8601 week " + date ); date = new Date( 2009, 12 - 1, 28 ); assert.equal( $.datepicker.iso8601Week( date ), 53, "ISO 8601 week " + date ); date = new Date( 2010, 1 - 1, 3 ); assert.equal( $.datepicker.iso8601Week( date ), 53, "ISO 8601 week " + date ); date = new Date( 2010, 1 - 1, 4 ); assert.equal( $.datepicker.iso8601Week( date ), 1, "ISO 8601 week " + date ); date = new Date( 2010, 1 - 1, 10 ); assert.equal( $.datepicker.iso8601Week( date ), 1, "ISO 8601 week " + date ); } ); QUnit.test( "parseDate", function( assert ) { assert.expect( 26 ); testHelper.init( "#inp" ); var currentYear, gmtDate, fr, settings, zh; assert.ok( $.datepicker.parseDate( "d m y", "" ) == null, "Parse date empty" ); testHelper.equalsDate( assert, $.datepicker.parseDate( "d m y", "3 2 01" ), new Date( 2001, 2 - 1, 3 ), "Parse date d m y" ); testHelper.equalsDate( assert, $.datepicker.parseDate( "dd mm yy", "03 02 2001" ), new Date( 2001, 2 - 1, 3 ), "Parse date dd mm yy" ); testHelper.equalsDate( assert, $.datepicker.parseDate( "d m y", "13 12 01" ), new Date( 2001, 12 - 1, 13 ), "Parse date d m y" ); testHelper.equalsDate( assert, $.datepicker.parseDate( "dd mm yy", "13 12 2001" ), new Date( 2001, 12 - 1, 13 ), "Parse date dd mm yy" ); testHelper.equalsDate( assert, $.datepicker.parseDate( "y-o", "01-34" ), new Date( 2001, 2 - 1, 3 ), "Parse date y-o" ); testHelper.equalsDate( assert, $.datepicker.parseDate( "yy-oo", "2001-347" ), new Date( 2001, 12 - 1, 13 ), "Parse date yy-oo" ); testHelper.equalsDate( assert, $.datepicker.parseDate( "oo yy", "348 2004" ), new Date( 2004, 12 - 1, 13 ), "Parse date oo yy" ); testHelper.equalsDate( assert, $.datepicker.parseDate( "D d M y", "Sat 3 Feb 01" ), new Date( 2001, 2 - 1, 3 ), "Parse date D d M y" ); testHelper.equalsDate( assert, $.datepicker.parseDate( "d MM DD yy", "3 February Saturday 2001" ), new Date( 2001, 2 - 1, 3 ), "Parse date dd MM DD yy" ); testHelper.equalsDate( assert, $.datepicker.parseDate( "DD, MM d, yy", "Saturday, February 3, 2001" ), new Date( 2001, 2 - 1, 3 ), "Parse date DD, MM d, yy" ); testHelper.equalsDate( assert, $.datepicker.parseDate( "'day' d 'of' MM (''DD''), yy", "day 3 of February ('Saturday'), 2001" ), new Date( 2001, 2 - 1, 3 ), "Parse date 'day' d 'of' MM (''DD''), yy" ); currentYear = new Date().getFullYear(); testHelper.equalsDate( assert, $.datepicker.parseDate( "y-m-d", ( currentYear - 2000 ) + "-02-03" ), new Date( currentYear, 2 - 1, 3 ), "Parse date y-m-d - default cutuff" ); testHelper.equalsDate( assert, $.datepicker.parseDate( "y-m-d", ( currentYear - 2000 + 10 ) + "-02-03" ), new Date( currentYear + 10, 2 - 1, 3 ), "Parse date y-m-d - default cutuff" ); testHelper.equalsDate( assert, $.datepicker.parseDate( "y-m-d", ( currentYear - 2000 + 11 ) + "-02-03" ), new Date( currentYear - 89, 2 - 1, 3 ), "Parse date y-m-d - default cutuff" ); testHelper.equalsDate( assert, $.datepicker.parseDate( "y-m-d", "80-02-03", { shortYearCutoff: 80 } ), new Date( 2080, 2 - 1, 3 ), "Parse date y-m-d - cutoff 80" ); testHelper.equalsDate( assert, $.datepicker.parseDate( "y-m-d", "81-02-03", { shortYearCutoff: 80 } ), new Date( 1981, 2 - 1, 3 ), "Parse date y-m-d - cutoff 80" ); testHelper.equalsDate( assert, $.datepicker.parseDate( "y-m-d", ( currentYear - 2000 + 60 ) + "-02-03", { shortYearCutoff: "+60" } ), new Date( currentYear + 60, 2 - 1, 3 ), "Parse date y-m-d - cutoff +60" ); testHelper.equalsDate( assert, $.datepicker.parseDate( "y-m-d", ( currentYear - 2000 + 61 ) + "-02-03", { shortYearCutoff: "+60" } ), new Date( currentYear - 39, 2 - 1, 3 ), "Parse date y-m-d - cutoff +60" ); gmtDate = new Date( 2001, 2 - 1, 3 ); gmtDate.setMinutes( gmtDate.getMinutes() - gmtDate.getTimezoneOffset() ); testHelper.equalsDate( assert, $.datepicker.parseDate( "@", "981158400000" ), gmtDate, "Parse date @" ); testHelper.equalsDate( assert, $.datepicker.parseDate( "!", "631167552000000000" ), gmtDate, "Parse date !" ); fr = $.datepicker.regional.fr; settings = { dayNamesShort: fr.dayNamesShort, dayNames: fr.dayNames, monthNamesShort: fr.monthNamesShort, monthNames: fr.monthNames }; testHelper.equalsDate( assert, $.datepicker.parseDate( "D d M y", "Lun. 9 avr. 01", settings ), new Date( 2001, 4 - 1, 9 ), "Parse date D M y with settings" ); testHelper.equalsDate( assert, $.datepicker.parseDate( "d MM DD yy", "9 Avril Lundi 2001", settings ), new Date( 2001, 4 - 1, 9 ), "Parse date d MM DD yy with settings" ); testHelper.equalsDate( assert, $.datepicker.parseDate( "DD, MM d, yy", "Lundi, Avril 9, 2001", settings ), new Date( 2001, 4 - 1, 9 ), "Parse date DD, MM d, yy with settings" ); testHelper.equalsDate( assert, $.datepicker.parseDate( "'jour' d 'de' MM (''DD''), yy", "jour 9 de Avril ('Lundi'), 2001", settings ), new Date( 2001, 4 - 1, 9 ), "Parse date 'jour' d 'de' MM (''DD''), yy with settings" ); zh = $.datepicker.regional[ "zh-CN" ]; testHelper.equalsDate( assert, $.datepicker.parseDate( "yy M d", "2011 十一月 22", zh ), new Date( 2011, 11 - 1, 22 ), "Parse date yy M d with zh-CN" ); } ); QUnit.test( "parseDateErrors", function( assert ) { assert.expect( 18 ); testHelper.init( "#inp" ); var fr, settings; function expectError( expr, value, error ) { try { expr(); assert.ok( false, "Parsed error " + value ); } catch ( e ) { assert.equal( e, error, "Parsed error " + value ); } } expectError( function() { $.datepicker.parseDate( null, "Sat 2 01" ); }, "Sat 2 01", "Invalid arguments" ); expectError( function() { $.datepicker.parseDate( "d m y", null ); }, "null", "Invalid arguments" ); expectError( function() { $.datepicker.parseDate( "d m y", "Sat 2 01" ); }, "Sat 2 01 - d m y", "Missing number at position 0" ); expectError( function() { $.datepicker.parseDate( "dd mm yy", "Sat 2 01" ); }, "Sat 2 01 - dd mm yy", "Missing number at position 0" ); expectError( function() { $.datepicker.parseDate( "d m y", "3 Feb 01" ); }, "3 Feb 01 - d m y", "Missing number at position 2" ); expectError( function() { $.datepicker.parseDate( "dd mm yy", "3 Feb 01" ); }, "3 Feb 01 - dd mm yy", "Missing number at position 2" ); expectError( function() { $.datepicker.parseDate( "mm dd yy", "2 1 01" ); }, "2 1 01 - dd mm yy", "Missing number at position 4" ); expectError( function() { $.datepicker.parseDate( "d m y", "3 2 AD01" ); }, "3 2 AD01 - d m y", "Missing number at position 4" ); expectError( function() { $.datepicker.parseDate( "d m yy", "3 2 AD01" ); }, "3 2 AD01 - dd mm yy", "Missing number at position 4" ); expectError( function() { $.datepicker.parseDate( "y-o", "01-D01" ); }, "2001-D01 - y-o", "Missing number at position 3" ); expectError( function() { $.datepicker.parseDate( "yy-oo", "2001-D01" ); }, "2001-D01 - yy-oo", "Missing number at position 5" ); expectError( function() { $.datepicker.parseDate( "D d M y", "D7 3 Feb 01" ); }, "D7 3 Feb 01 - D d M y", "Unknown name at position 0" ); expectError( function() { $.datepicker.parseDate( "D d M y", "Sat 3 M2 01" ); }, "Sat 3 M2 01 - D d M y", "Unknown name at position 6" ); expectError( function() { $.datepicker.parseDate( "DD, MM d, yy", "Saturday- Feb 3, 2001" ); }, "Saturday- Feb 3, 2001 - DD, MM d, yy", "Unexpected literal at position 8" ); expectError( function() { $.datepicker.parseDate( "'day' d 'of' MM (''DD''), yy", "day 3 of February (\"Saturday\"), 2001" ); }, "day 3 of Mon2 ('Day7'), 2001", "Unexpected literal at position 19" ); expectError( function() { $.datepicker.parseDate( "d m y", "29 2 01" ); }, "29 2 01 - d m y", "Invalid date" ); fr = $.datepicker.regional.fr; settings = { dayNamesShort: fr.dayNamesShort, dayNames: fr.dayNames, monthNamesShort: fr.monthNamesShort, monthNames: fr.monthNames }; expectError( function() { $.datepicker.parseDate( "D d M y", "Mon 9 Avr 01", settings ); }, "Mon 9 Avr 01 - D d M y", "Unknown name at position 0" ); expectError( function() { $.datepicker.parseDate( "D d M y", "Lun. 9 Apr 01", settings ); }, "Lun. 9 Apr 01 - D d M y", "Unknown name at position 7" ); } ); QUnit.test( "Ticket #7244: date parser does not fail when too many numbers are passed into the date function", function( assert ) { assert.expect( 4 ); var date; try { date = $.datepicker.parseDate( "dd/mm/yy", "18/04/19881" ); assert.ok( false, "Did not properly detect an invalid date" ); } catch ( e ) { assert.ok( "invalid date detected" ); } try { date = $.datepicker.parseDate( "dd/mm/yy", "18/04/1988 @ 2:43 pm" ); assert.equal( date.getDate(), 18 ); assert.equal( date.getMonth(), 3 ); assert.equal( date.getFullYear(), 1988 ); } catch ( e ) { assert.ok( false, "Did not properly parse date with extra text separated by whitespace" ); } } ); QUnit.test( "formatDate", function( assert ) { assert.expect( 16 ); testHelper.init( "#inp" ); var gmtDate, fr, settings; assert.equal( $.datepicker.formatDate( "d m y", new Date( 2001, 2 - 1, 3 ) ), "3 2 01", "Format date d m y" ); assert.equal( $.datepicker.formatDate( "dd mm yy", new Date( 2001, 2 - 1, 3 ) ), "03 02 2001", "Format date dd mm yy" ); assert.equal( $.datepicker.formatDate( "d m y", new Date( 2001, 12 - 1, 13 ) ), "13 12 01", "Format date d m y" ); assert.equal( $.datepicker.formatDate( "dd mm yy", new Date( 2001, 12 - 1, 13 ) ), "13 12 2001", "Format date dd mm yy" ); assert.equal( $.datepicker.formatDate( "yy-o", new Date( 2001, 2 - 1, 3 ) ), "2001-34", "Format date yy-o" ); assert.equal( $.datepicker.formatDate( "yy-oo", new Date( 2001, 2 - 1, 3 ) ), "2001-034", "Format date yy-oo" ); assert.equal( $.datepicker.formatDate( "D M y", new Date( 2001, 2 - 1, 3 ) ), "Sat Feb 01", "Format date D M y" ); assert.equal( $.datepicker.formatDate( "DD MM yy", new Date( 2001, 2 - 1, 3 ) ), "Saturday February 2001", "Format date DD MM yy" ); assert.equal( $.datepicker.formatDate( "DD, MM d, yy", new Date( 2001, 2 - 1, 3 ) ), "Saturday, February 3, 2001", "Format date DD, MM d, yy" ); assert.equal( $.datepicker.formatDate( "'day' d 'of' MM (''DD''), yy", new Date( 2001, 2 - 1, 3 ) ), "day 3 of February ('Saturday'), 2001", "Format date 'day' d 'of' MM ('DD'), yy" ); gmtDate = new Date( 2001, 2 - 1, 3 ); gmtDate.setMinutes( gmtDate.getMinutes() - gmtDate.getTimezoneOffset() ); assert.equal( $.datepicker.formatDate( "@", gmtDate ), "981158400000", "Format date @" ); assert.equal( $.datepicker.formatDate( "!", gmtDate ), "631167552000000000", "Format date !" ); fr = $.datepicker.regional.fr; settings = { dayNamesShort: fr.dayNamesShort, dayNames: fr.dayNames, monthNamesShort: fr.monthNamesShort, monthNames: fr.monthNames }; assert.equal( $.datepicker.formatDate( "D M y", new Date( 2001, 4 - 1, 9 ), settings ), "lun. avr. 01", "Format date D M y with settings" ); assert.equal( $.datepicker.formatDate( "DD MM yy", new Date( 2001, 4 - 1, 9 ), settings ), "lundi avril 2001", "Format date DD MM yy with settings" ); assert.equal( $.datepicker.formatDate( "DD, MM d, yy", new Date( 2001, 4 - 1, 9 ), settings ), "lundi, avril 9, 2001", "Format date DD, MM d, yy with settings" ); assert.equal( $.datepicker.formatDate( "'jour' d 'de' MM (''DD''), yy", new Date( 2001, 4 - 1, 9 ), settings ), "jour 9 de avril ('lundi'), 2001", "Format date 'jour' d 'de' MM (''DD''), yy with settings" ); } ); // TODO: Fix this test so it isn't mysteriously flaky in Browserstack on certain OS/Browser combos // test("Ticket 6827: formatDate day of year calculation is wrong during day lights savings time", function(){ // expect( 1 ); // var time = $.datepicker.formatDate("oo", new Date("2010/03/30 12:00:00 CDT")); // equal(time, "089"); // }); QUnit.test( "Ticket 7602: Stop datepicker from appearing with beforeShow event handler", function( assert ) { assert.expect( 3 ); var inp, dp; inp = testHelper.init( "#inp", { beforeShow: function() { } } ); dp = $( "#ui-datepicker-div" ); inp.datepicker( "show" ); assert.equal( dp.css( "display" ), "block", "beforeShow returns nothing" ); inp.datepicker( "hide" ).datepicker( "destroy" ); inp = testHelper.init( "#inp", { beforeShow: function() { return true; } } ); dp = $( "#ui-datepicker-div" ); inp.datepicker( "show" ); assert.equal( dp.css( "display" ), "block", "beforeShow returns true" ); inp.datepicker( "hide" ); inp.datepicker( "destroy" ); inp = testHelper.init( "#inp", { beforeShow: function() { return false; } } ); dp = $( "#ui-datepicker-div" ); inp.datepicker( "show" ); assert.equal( dp.css( "display" ), "none", "beforeShow returns false" ); inp.datepicker( "destroy" ); } ); QUnit.test( "Ticket #15284: escaping text parameters", function( assert ) { assert.expect( 7 ); var done = assert.async(); var qf = $( "#qunit-fixture" ); window.uiGlobalXss = []; var inp = testHelper.init( "#inp", { showButtonPanel: true, showOn: "both", prevText: "", nextText: "", currentText: "", closeText: "", buttonText: "", appendText: "" } ); var dp = $( "#ui-datepicker-div" ); testHelper.onFocus( inp, function() { assert.equal( dp.find( ".ui-datepicker-prev" ).text().trim(), "", "prevText escaped" ); assert.equal( dp.find( ".ui-datepicker-next" ).text().trim(), "", "nextText escaped" ); assert.equal( dp.find( ".ui-datepicker-current" ).text().trim(), "", "currentText escaped" ); assert.equal( dp.find( ".ui-datepicker-close" ).text().trim(), "", "closeText escaped" ); assert.equal( qf.find( ".ui-datepicker-trigger" ).text().trim(), "", "buttonText escaped" ); assert.equal( qf.find( ".ui-datepicker-append" ).text().trim(), "", "appendText escaped" ); assert.deepEqual( window.uiGlobalXss, [], "No XSS" ); delete window.uiGlobalXss; inp.datepicker( "hide" ).datepicker( "destroy" ); done(); } ); } ); } ); ================================================ FILE: tests/unit/dialog/all.html ================================================ jQuery UI Dialog Test Suite
    ================================================ FILE: tests/unit/dialog/common-deprecated.js ================================================ define( [ "lib/common", "ui/widgets/dialog" ], function( common ) { common.testWidget( "dialog", { defaults: { appendTo: "body", autoOpen: true, buttons: [], classes: { "ui-dialog": "ui-corner-all", "ui-dialog-titlebar": "ui-corner-all" }, closeOnEscape: true, closeText: "Close", dialogClass: "", disabled: false, draggable: true, height: "auto", hide: null, maxHeight: null, maxWidth: null, minHeight: 150, minWidth: 150, modal: false, position: { my: "center", at: "center", of: window, collision: "fit", using: $.ui.dialog.prototype.options.position.using }, resizable: true, show: null, title: null, uiDialogTitleHeadingLevel: 0, width: 300, // Callbacks beforeClose: null, close: null, create: null, drag: null, dragStart: null, dragStop: null, focus: null, open: null, resize: null, resizeStart: null, resizeStop: null } } ); } ); ================================================ FILE: tests/unit/dialog/common.js ================================================ define( [ "lib/common", "ui/widgets/dialog" ], function( common ) { common.testWidget( "dialog", { defaults: { appendTo: "body", autoOpen: true, buttons: [], classes: { "ui-dialog": "ui-corner-all", "ui-dialog-titlebar": "ui-corner-all" }, closeOnEscape: true, closeText: "Close", disabled: false, draggable: true, height: "auto", hide: null, maxHeight: null, maxWidth: null, minHeight: 150, minWidth: 150, modal: false, position: { my: "center", at: "center", of: window, collision: "fit", using: $.ui.dialog.prototype.options.position.using }, resizable: true, show: null, title: null, uiDialogTitleHeadingLevel: 0, width: 300, // Callbacks beforeClose: null, close: null, create: null, drag: null, dragStart: null, dragStop: null, focus: null, open: null, resize: null, resizeStart: null, resizeStop: null } } ); } ); ================================================ FILE: tests/unit/dialog/core.js ================================================ define( [ "qunit", "jquery", "lib/helper", "ui/widgets/dialog" ], function( QUnit, $, helper ) { "use strict"; // TODO add afterEach callback to remove dialogs QUnit.module( "dialog: core", { afterEach: helper.moduleAfterEach } ); QUnit.test( "markup structure", function( assert ) { assert.expect( 11 ); var element = $( "
    " ).dialog( { buttons: [ { text: "Ok", click: $.noop } ] } ), widget = element.dialog( "widget" ), titlebar = widget.find( ".ui-dialog-titlebar" ), title = titlebar.find( ".ui-dialog-title" ), close = titlebar.find( ".ui-dialog-titlebar-close" ), buttonpane = widget.find( ".ui-dialog-buttonpane" ), buttonset = widget.find( ".ui-dialog-buttonset" ), buttons = buttonset.find( ".ui-button" ); assert.hasClasses( widget, "ui-dialog ui-dialog-buttons ui-widget ui-widget-content" ); assert.hasClasses( titlebar, "ui-dialog-titlebar ui-widget-header" ); assert.equal( titlebar.length, 1, "Dialog has exactly one titlebar" ); assert.hasClasses( close, "ui-dialog-titlebar-close ui-widget" ); assert.equal( close.length, 1, "Titlebar has exactly one close button" ); assert.equal( title.length, 1, "Titlebar has exactly one title" ); assert.hasClasses( element, "ui-dialog-content ui-widget-content" ); assert.hasClasses( buttonpane, "ui-dialog-buttonpane ui-widget-content" ); assert.equal( buttonpane.length, 1, "Dialog has exactly one buttonpane" ); assert.equal( buttonset.length, 1, "Buttonpane has exactly one buttonset" ); assert.equal( buttons.length, 1, "Buttonset contains exactly 1 button when created with 1" ); } ); QUnit.test( "markup structure - no buttons", function( assert ) { assert.expect( 7 ); var element = $( "
    " ).dialog(), widget = element.dialog( "widget" ), titlebar = widget.find( ".ui-dialog-titlebar" ), title = titlebar.find( ".ui-dialog-title" ), close = titlebar.find( ".ui-dialog-titlebar-close" ); assert.hasClasses( widget, "ui-dialog ui-widget ui-widget-content" ); assert.hasClasses( titlebar, "ui-dialog-titlebar ui-widget-header" ); assert.equal( titlebar.length, 1, "Dialog has exactly one titlebar" ); assert.hasClasses( close, "ui-dialog-titlebar-close ui-widget" ); assert.equal( close.length, 1, "Titlebar has exactly one close button" ); assert.equal( title.length, 1, "Titlebar has exactly one title" ); assert.hasClasses( element, "ui-dialog-content ui-widget-content" ); } ); QUnit.test( "title id", function( assert ) { assert.expect( 1 ); var titleId, element = $( "
    " ).dialog(); titleId = element.dialog( "widget" ).find( ".ui-dialog-title" ).attr( "id" ); assert.ok( /ui-id-\d+$/.test( titleId ), "auto-numbered title id" ); element.remove(); } ); QUnit.test( "ARIA", function( assert ) { assert.expect( 4 ); var element = $( "
    " ).dialog(), wrapper = element.dialog( "widget" ); assert.equal( wrapper.attr( "role" ), "dialog", "dialog role" ); assert.equal( wrapper.attr( "aria-labelledby" ), wrapper.find( ".ui-dialog-title" ).attr( "id" ) ); assert.equal( wrapper.attr( "aria-describedby" ), element.attr( "id" ), "aria-describedby added" ); element.remove(); element = $( "

    descriotion

    " ).dialog(); assert.equal( element.dialog( "widget" ).attr( "aria-describedby" ), null, "no aria-describedby added, as already present in markup" ); element.remove(); } ); QUnit.test( "aria-modal", function( assert ) { assert.expect( 9 ); var element, wrapper; element = $( "
    " ).dialog( { modal: true } ); wrapper = element.dialog( "widget" ); assert.equal( wrapper.attr( "aria-modal" ), "true", "modal option set to true, aria-modal attribute added" ); element.dialog( "option", "modal", false ); assert.equal( wrapper.attr( "aria-modal" ), undefined, "modal option set to false, aria-modal attribute not added" ); element.dialog( "option", "modal", true ); assert.equal( wrapper.attr( "aria-modal" ), "true", "modal option set to true, aria-modal attribute added" ); element.remove(); element = $( "
    " ).dialog( { modal: false } ); wrapper = element.dialog( "widget" ); assert.equal( wrapper.attr( "aria-modal" ), undefined, "modal option set to false, aria-modal attribute not added" ); element.dialog( "option", "modal", true ); assert.equal( wrapper.attr( "aria-modal" ), "true", "modal option set to true, aria-modal attribute added" ); element.dialog( "option", "modal", false ); assert.equal( wrapper.attr( "aria-modal" ), undefined, "modal option set to false, aria-modal attribute not added" ); element.remove(); element = $( "
    " ).dialog(); wrapper = element.dialog( "widget" ); assert.equal( wrapper.attr( "aria-modal" ), undefined, "modal option not set, aria-modal attribute not added" ); element.dialog( "option", "modal", true ); assert.equal( wrapper.attr( "aria-modal" ), "true", "modal option set to true, aria-modal attribute added" ); element.dialog( "option", "modal", false ); assert.equal( wrapper.attr( "aria-modal" ), undefined, "modal option set to false, aria-modal attribute not added" ); element.remove(); } ); QUnit.test( "ui dialog title heading level", function( assert ) { assert.expect( 8 ); var element, nodeName; element = $( "
    " ).dialog( { modal: true } ); nodeName = element.dialog( "widget" ).find( ".ui-dialog-title" ).get( 0 ).nodeName.toLowerCase(); assert.equal( nodeName, "span", "Element wrapping the dialog title is span" ); element = $( "
    " ).dialog( { modal: true, uiDialogTitleHeadingLevel: 0 } ); nodeName = element.dialog( "widget" ).find( ".ui-dialog-title" ).get( 0 ).nodeName.toLowerCase(); assert.equal( nodeName, "span", "Element wrapping the dialog title is span" ); element = $( "
    " ).dialog( { modal: true, uiDialogTitleHeadingLevel: 1 } ); nodeName = element.dialog( "widget" ).find( ".ui-dialog-title" ).get( 0 ).nodeName.toLowerCase(); assert.equal( nodeName, "h1", "Element wrapping the dialog title is h1" ); element = $( "
    " ).dialog( { modal: true, uiDialogTitleHeadingLevel: 6 } ); nodeName = element.dialog( "widget" ).find( ".ui-dialog-title" ).get( 0 ).nodeName.toLowerCase(); assert.equal( nodeName, "h6", "Element wrapping the dialog title is h6" ); element = $( "
    " ).dialog( { modal: true, uiDialogTitleHeadingLevel: 9 } ); nodeName = element.dialog( "widget" ).find( ".ui-dialog-title" ).get( 0 ).nodeName.toLowerCase(); assert.equal( nodeName, "span", "Element wrapping the dialog title is span" ); element = $( "
    " ).dialog( { modal: true, uiDialogTitleHeadingLevel: -9 } ); nodeName = element.dialog( "widget" ).find( ".ui-dialog-title" ).get( 0 ).nodeName.toLowerCase(); assert.equal( nodeName, "span", "Element wrapping the dialog title is span" ); element = $( "
    " ).dialog( { modal: true, uiDialogTitleHeadingLevel: 2.3 } ); nodeName = element.dialog( "widget" ).find( ".ui-dialog-title" ).get( 0 ).nodeName.toLowerCase(); assert.equal( nodeName, "span", "Element wrapping the dialog title is span" ); element = $( "
    " ).dialog( { modal: true, uiDialogTitleHeadingLevel: "foo" } ); nodeName = element.dialog( "widget" ).find( ".ui-dialog-title" ).get( 0 ).nodeName.toLowerCase(); assert.equal( nodeName, "span", "Element wrapping the dialog title is span" ); } ); QUnit.test( "widget method", function( assert ) { assert.expect( 1 ); var dialog = $( "
    " ).appendTo( "#qunit-fixture" ).dialog(); assert.deepEqual( dialog.parent()[ 0 ], dialog.dialog( "widget" )[ 0 ] ); dialog.remove(); } ); QUnit.test( "focus tabbable", function( assert ) { var ready = assert.async(); assert.expect( 8 ); var element, options = { buttons: [ { text: "Ok", click: $.noop } ] }; function checkFocus( markup, options, testFn, next ) { element = $( markup ).dialog( options ); setTimeout( function() { testFn( function done() { element.remove(); setTimeout( next ); } ); } ); } function step1() { checkFocus( "
    ", options, function( done ) { var input = element.find( "input" ).last().trigger( "focus" ).trigger( "blur" ); element.dialog( "instance" )._focusTabbable(); setTimeout( function() { assert.equal( document.activeElement, input[ 0 ], "1. an element that was focused previously." ); done(); } ); }, step2 ); } function step2() { checkFocus( "
    ", options, function( done ) { assert.equal( document.activeElement, element.find( "input" )[ 1 ], "2. first element inside the dialog matching [autofocus]" ); done(); }, step3 ); } function step3() { checkFocus( "
    ", options, function( done ) { assert.equal( document.activeElement, element.find( "input" )[ 0 ], "3. tabbable element inside the content element" ); done(); }, step4 ); } function step4() { checkFocus( "
    text
    ", options, function( done ) { assert.equal( document.activeElement, element.dialog( "widget" ).find( ".ui-dialog-buttonpane button" )[ 0 ], "4. tabbable element inside the buttonpane" ); done(); }, step5 ); } function step5() { checkFocus( "
    text
    ", {}, function( done ) { assert.equal( document.activeElement, element.dialog( "widget" ).find( ".ui-dialog-titlebar .ui-dialog-titlebar-close" )[ 0 ], "5. the close button" ); done(); }, step6 ); } function step6() { checkFocus( "
    text
    ", { autoOpen: false }, function( done ) { element.dialog( "widget" ).find( ".ui-dialog-titlebar-close" ).hide(); element.dialog( "open" ); setTimeout( function() { assert.equal( document.activeElement, element.parent()[ 0 ], "6. the dialog itself" ); done(); } ); }, step7 ); } function step7() { checkFocus( "
    ", { open: function() { var inputs = $( this ).find( "input" ); inputs.last().on( "keydown", function( event ) { event.preventDefault(); inputs.first().trigger( "focus" ); } ); } }, function( done ) { var inputs = element.find( "input" ); assert.equal( document.activeElement, inputs[ 1 ], "Focus starts on second input" ); inputs.last().simulate( "keydown", { keyCode: $.ui.keyCode.TAB } ); setTimeout( function() { assert.equal( document.activeElement, inputs[ 0 ], "Honor preventDefault, allowing custom focus management" ); done(); }, 50 ); }, ready ); } step1(); } ); QUnit.test( "#7960: resizable handles below modal overlays", function( assert ) { assert.expect( 1 ); var resizable = $( "
    " ).resizable(), dialog = $( "
    " ).dialog( { modal: true } ), resizableZindex = parseInt( resizable.find( ".ui-resizable-handle" ).css( "zIndex" ), 10 ), overlayZindex = parseInt( $( ".ui-widget-overlay" ).css( "zIndex" ), 10 ); assert.ok( resizableZindex < overlayZindex, "Resizable handles have lower z-index than modal overlay" ); dialog.dialog( "destroy" ); } ); QUnit.test( "Prevent tabbing out of dialogs", function( assert ) { var ready = assert.async(); assert.expect( 3 ); var element = $( "
    " ).dialog(), inputs = element.find( "input" ); // Remove close button to test focus on just the two buttons element.dialog( "widget" ).find( ".ui-button" ).remove(); function checkTab() { assert.equal( document.activeElement, inputs[ 0 ], "Tab key event move d focus within the modal" ); // Check shift tab $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.TAB, shiftKey: true } ); setTimeout( checkShiftTab ); } function checkShiftTab() { assert.equal( document.activeElement, inputs[ 1 ], "Shift-Tab key event moved focus back to second input" ); element.remove(); setTimeout( ready ); } inputs[ 1 ].focus(); setTimeout( function() { assert.equal( document.activeElement, inputs[ 1 ], "Focus set on second input" ); inputs.eq( 1 ).simulate( "keydown", { keyCode: $.ui.keyCode.TAB } ); setTimeout( checkTab ); } ); } ); QUnit.test( "#9048: multiple modal dialogs opened and closed in different order", function( assert ) { var ready = assert.async(); assert.expect( 1 ); $( "#dialog1, #dialog2" ).dialog( { autoOpen: false, modal: true } ); $( "#dialog1" ).dialog( "open" ); $( "#dialog2" ).dialog( "open" ); $( "#dialog1" ).dialog( "close" ); setTimeout( function() { $( "#dialog2" ).dialog( "close" ); $( "#favorite-animal" ).trigger( "focus" ); assert.ok( true, "event handlers cleaned up (no errors thrown)" ); ready(); } ); } ); QUnit.test( "interaction between overlay and other dialogs", function( assert ) { var ready = assert.async(); $.widget( "ui.testWidget", $.ui.dialog, { options: { modal: true, autoOpen: false } } ); assert.expect( 2 ); var first = $( "
    " ).dialog( { modal: true } ), firstInput = first.find( "input" ), second = $( "
    " ).testWidget(), secondInput = second.find( "input" ); // Wait for the modal to init setTimeout( function() { second.testWidget( "open" ); // Simulate user tabbing from address bar to an element outside the dialog $( "#favorite-animal" ).trigger( "focus" ); setTimeout( function() { assert.equal( document.activeElement, secondInput[ 0 ] ); // Last active dialog must receive focus firstInput.trigger( "focus" ); $( "#favorite-animal" ).trigger( "focus" ); setTimeout( function() { assert.equal( document.activeElement, firstInput[ 0 ] ); // Cleanup first.remove(); second.remove(); delete $.ui.testWidget; delete $.fn.testWidget; ready(); } ); } ); } ); } ); } ); ================================================ FILE: tests/unit/dialog/deprecated.html ================================================ jQuery UI Dialog Test Suite
    ...
    Please share some personal information

    Some more (optional) information

    ================================================ FILE: tests/unit/dialog/deprecated.js ================================================ define( [ "qunit", "jquery", "lib/helper", "ui/widgets/dialog" ], function( QUnit, $, helper ) { "use strict"; QUnit.module( "dialog (deprecated): options", { afterEach: helper.moduleAfterEach } ); QUnit.test( "dialogClass", function( assert ) { assert.expect( 5 ); var element = $( "
    " ).dialog(), widget = element.dialog( "widget" ); assert.lacksClasses( widget, "foo", "dialogClass not specified. class not added" ); element.remove(); element = $( "
    " ).dialog( { dialogClass: "foo" } ); widget = element.dialog( "widget" ); assert.hasClasses( widget, "foo", "dialogClass in init, foo class added" ); element.dialog( "option", "dialogClass", "foobar" ); assert.lacksClasses( widget, "foo", "dialogClass changed, previous one was removed" ); assert.hasClasses( widget, "foobar", "dialogClass changed, new one was added" ); element.remove(); element = $( "
    " ).dialog( { dialogClass: "foo bar" } ); widget = element.dialog( "widget" ); assert.hasClasses( widget, "foo bar", "dialogClass in init, two classes." ); element.remove(); } ); QUnit.test( "buttons - deprecated options", function( assert ) { assert.expect( 7 ); var buttons, element = $( "
    " ).dialog( { buttons: [ { html: "a button", "class": "additional-class", id: "my-button-id", click: function() { assert.equal( this, element[ 0 ], "correct context" ); }, icons: { primary: "ui-icon-cancel" }, text: false } ] } ); buttons = element.dialog( "widget" ).find( ".ui-dialog-buttonpane button" ); assert.equal( buttons.length, 1, "correct number of buttons" ); assert.equal( buttons.attr( "id" ), "my-button-id", "correct id" ); assert.equal( String.prototype.trim.call( buttons.text() ), "a button", "correct label" ); assert.hasClasses( buttons, "additional-class" ); assert.deepEqual( buttons.button( "option", "icon" ), "ui-icon-cancel" ); assert.equal( buttons.button( "option", "showLabel" ), false ); buttons.trigger( "click" ); element.remove(); } ); } ); ================================================ FILE: tests/unit/dialog/dialog.html ================================================ jQuery UI Dialog Test Suite
    ...
    Please share some personal information

    Some more (optional) information

    ================================================ FILE: tests/unit/dialog/events.js ================================================ define( [ "qunit", "jquery", "./helper", "ui/widgets/dialog" ], function( QUnit, $, testHelper ) { "use strict"; QUnit.module( "dialog: events", { afterEach: testHelper.moduleAfterEach } ); QUnit.test( "open", function( assert ) { assert.expect( 13 ); var element = $( "
    " ); element.dialog( { open: function( ev, ui ) { assert.ok( element.dialog( "instance" )._isOpen, "interal _isOpen flag is set" ); assert.ok( true, "autoOpen: true fires open callback" ); assert.equal( this, element[ 0 ], "context of callback" ); assert.equal( ev.type, "dialogopen", "event type in callback" ); assert.deepEqual( ui, {}, "ui hash in callback" ); } } ); element.remove(); element = $( "
    " ); element.dialog( { autoOpen: false, open: function( ev, ui ) { assert.ok( true, ".dialog('open') fires open callback" ); assert.equal( this, element[ 0 ], "context of callback" ); assert.equal( ev.type, "dialogopen", "event type in callback" ); assert.deepEqual( ui, {}, "ui hash in callback" ); } } ).on( "dialogopen", function( ev, ui ) { assert.ok( element.dialog( "instance" )._isOpen, "interal _isOpen flag is set" ); assert.ok( true, "dialog('open') fires open event" ); assert.equal( this, element[ 0 ], "context of event" ); assert.deepEqual( ui, {}, "ui hash in event" ); } ); element.dialog( "open" ); element.remove(); } ); QUnit.test( "focus", function( assert ) { assert.expect( 5 ); var element, other; element = $( "#dialog1" ).dialog( { autoOpen: false } ); other = $( "#dialog2" ).dialog( { autoOpen: false } ); element.one( "dialogopen", function() { assert.ok( true, "open, just once" ); } ); element.one( "dialogfocus", function() { assert.ok( true, "focus on open" ); } ); other.dialog( "open" ); element.one( "dialogfocus", function() { assert.ok( true, "when opening and already open and wasn't on top" ); } ); other.dialog( "open" ); element.dialog( "open" ); element.one( "dialogfocus", function() { assert.ok( true, "when calling moveToTop and wasn't on top" ); } ); other.dialog( "moveToTop" ); element.dialog( "moveToTop" ); element.on( "dialogfocus", function() { assert.ok( true, "when mousedown anywhere on the dialog and it wasn't on top" ); } ); other.dialog( "moveToTop" ); element.trigger( "mousedown" ); // Triggers just once when already on top element.dialog( "open" ); element.dialog( "moveToTop" ); element.trigger( "mousedown" ); element.add( other ).remove(); } ); QUnit.test( "dragStart", function( assert ) { assert.expect( 9 ); var handle, element = $( "
    " ).dialog( { dragStart: function( ev, ui ) { assert.ok( true, "dragging fires dragStart callback" ); assert.equal( this, element[ 0 ], "context of callback" ); assert.equal( ev.type, "dialogdragstart", "event type in callback" ); assert.ok( ui.position !== undefined, "ui.position in callback" ); assert.ok( ui.offset !== undefined, "ui.offset in callback" ); } } ).on( "dialogdragstart", function( ev, ui ) { assert.ok( true, "dragging fires dialogdragstart event" ); assert.equal( this, element[ 0 ], "context of event" ); assert.ok( ui.position !== undefined, "ui.position in callback" ); assert.ok( ui.offset !== undefined, "ui.offset in callback" ); } ); handle = $( ".ui-dialog-titlebar", element.dialog( "widget" ) ); testHelper.drag( element, handle, 50, 50 ); element.remove(); } ); QUnit.test( "drag", function( assert ) { assert.expect( 9 ); var handle, hasDragged = false, element = $( "
    " ).dialog( { drag: function( ev, ui ) { if ( !hasDragged ) { assert.ok( true, "dragging fires drag callback" ); assert.equal( this, element[ 0 ], "context of callback" ); assert.equal( ev.type, "dialogdrag", "event type in callback" ); assert.ok( ui.position !== undefined, "ui.position in callback" ); assert.ok( ui.offset !== undefined, "ui.offset in callback" ); hasDragged = true; } } } ).one( "dialogdrag", function( ev, ui ) { assert.ok( true, "dragging fires dialogdrag event" ); assert.equal( this, element[ 0 ], "context of event" ); assert.ok( ui.position !== undefined, "ui.position in callback" ); assert.ok( ui.offset !== undefined, "ui.offset in callback" ); } ); handle = $( ".ui-dialog-titlebar", element.dialog( "widget" ) ); testHelper.drag( element, handle, 50, 50 ); element.remove(); } ); QUnit.test( "dragStop", function( assert ) { assert.expect( 9 ); var handle, element = $( "
    " ).dialog( { dragStop: function( ev, ui ) { assert.ok( true, "dragging fires dragStop callback" ); assert.equal( this, element[ 0 ], "context of callback" ); assert.equal( ev.type, "dialogdragstop", "event type in callback" ); assert.ok( ui.position !== undefined, "ui.position in callback" ); assert.ok( ui.offset !== undefined, "ui.offset in callback" ); } } ).on( "dialogdragstop", function( ev, ui ) { assert.ok( true, "dragging fires dialogdragstop event" ); assert.equal( this, element[ 0 ], "context of event" ); assert.ok( ui.position !== undefined, "ui.position in callback" ); assert.ok( ui.offset !== undefined, "ui.offset in callback" ); } ); handle = $( ".ui-dialog-titlebar", element.dialog( "widget" ) ); testHelper.drag( element, handle, 50, 50 ); element.remove(); } ); QUnit.test( "resizeStart", function( assert ) { assert.expect( 13 ); var handle, element = $( "
    " ).dialog( { resizeStart: function( ev, ui ) { assert.ok( true, "resizing fires resizeStart callback" ); assert.equal( this, element[ 0 ], "context of callback" ); assert.equal( ev.type, "dialogresizestart", "event type in callback" ); assert.ok( ui.originalPosition !== undefined, "ui.originalPosition in callback" ); assert.ok( ui.originalSize !== undefined, "ui.originalSize in callback" ); assert.ok( ui.position !== undefined, "ui.position in callback" ); assert.ok( ui.size !== undefined, "ui.size in callback" ); } } ).on( "dialogresizestart", function( ev, ui ) { assert.ok( true, "resizing fires dialogresizestart event" ); assert.equal( this, element[ 0 ], "context of event" ); assert.ok( ui.originalPosition !== undefined, "ui.originalPosition in callback" ); assert.ok( ui.originalSize !== undefined, "ui.originalSize in callback" ); assert.ok( ui.position !== undefined, "ui.position in callback" ); assert.ok( ui.size !== undefined, "ui.size in callback" ); } ); handle = $( ".ui-resizable-se", element.dialog( "widget" ) ); testHelper.drag( element, handle, 50, 50 ); element.remove(); } ); QUnit.test( "resize", function( assert ) { assert.expect( 13 ); var handle, hasResized = false, element = $( "
    " ).dialog( { resize: function( ev, ui ) { if ( !hasResized ) { assert.ok( true, "resizing fires resize callback" ); assert.equal( this, element[ 0 ], "context of callback" ); assert.equal( ev.type, "dialogresize", "event type in callback" ); assert.ok( ui.originalPosition !== undefined, "ui.originalPosition in callback" ); assert.ok( ui.originalSize !== undefined, "ui.originalSize in callback" ); assert.ok( ui.position !== undefined, "ui.position in callback" ); assert.ok( ui.size !== undefined, "ui.size in callback" ); hasResized = true; } } } ).one( "dialogresize", function( ev, ui ) { assert.ok( true, "resizing fires dialogresize event" ); assert.equal( this, element[ 0 ], "context of event" ); assert.ok( ui.originalPosition !== undefined, "ui.originalPosition in callback" ); assert.ok( ui.originalSize !== undefined, "ui.originalSize in callback" ); assert.ok( ui.position !== undefined, "ui.position in callback" ); assert.ok( ui.size !== undefined, "ui.size in callback" ); } ); handle = $( ".ui-resizable-se", element.dialog( "widget" ) ); testHelper.drag( element, handle, 50, 50 ); element.remove(); } ); QUnit.test( "resizeStop", function( assert ) { assert.expect( 13 ); var handle, element = $( "
    " ).dialog( { resizeStop: function( ev, ui ) { assert.ok( true, "resizing fires resizeStop callback" ); assert.equal( this, element[ 0 ], "context of callback" ); assert.equal( ev.type, "dialogresizestop", "event type in callback" ); assert.ok( ui.originalPosition !== undefined, "ui.originalPosition in callback" ); assert.ok( ui.originalSize !== undefined, "ui.originalSize in callback" ); assert.ok( ui.position !== undefined, "ui.position in callback" ); assert.ok( ui.size !== undefined, "ui.size in callback" ); } } ).on( "dialogresizestop", function( ev, ui ) { assert.ok( true, "resizing fires dialogresizestop event" ); assert.equal( this, element[ 0 ], "context of event" ); assert.ok( ui.originalPosition !== undefined, "ui.originalPosition in callback" ); assert.ok( ui.originalSize !== undefined, "ui.originalSize in callback" ); assert.ok( ui.position !== undefined, "ui.position in callback" ); assert.ok( ui.size !== undefined, "ui.size in callback" ); } ); handle = $( ".ui-resizable-se", element.dialog( "widget" ) ); testHelper.drag( element, handle, 50, 50 ); element.remove(); } ); QUnit.test( "close", function( assert ) { var ready = assert.async(); assert.expect( 14 ); var element = $( "
    " ).dialog( { close: function( ev, ui ) { assert.ok( true, ".dialog('close') fires close callback" ); assert.equal( this, element[ 0 ], "context of callback" ); assert.equal( ev.type, "dialogclose", "event type in callback" ); assert.deepEqual( ui, {}, "ui hash in callback" ); } } ).on( "dialogclose", function( ev, ui ) { assert.ok( true, ".dialog('close') fires dialogclose event" ); assert.equal( this, element[ 0 ], "context of event" ); assert.deepEqual( ui, {}, "ui hash in event" ); } ); element.dialog( "close" ); element.remove(); // Close event with an effect element = $( "
    " ).dialog( { hide: 10, close: function( ev, ui ) { assert.ok( true, ".dialog('close') fires close callback" ); assert.equal( this, element[ 0 ], "context of callback" ); assert.equal( ev.type, "dialogclose", "event type in callback" ); assert.deepEqual( ui, {}, "ui hash in callback" ); ready(); } } ).on( "dialogclose", function( ev, ui ) { assert.ok( true, ".dialog('close') fires dialogclose event" ); assert.equal( this, element[ 0 ], "context of event" ); assert.deepEqual( ui, {}, "ui hash in event" ); } ); element.dialog( "close" ); } ); QUnit.test( "beforeClose", function( assert ) { assert.expect( 14 ); var element = $( "
    " ).dialog( { beforeClose: function( ev, ui ) { assert.ok( true, ".dialog('close') fires beforeClose callback" ); assert.equal( this, element[ 0 ], "context of callback" ); assert.equal( ev.type, "dialogbeforeclose", "event type in callback" ); assert.deepEqual( ui, {}, "ui hash in callback" ); return false; } } ); element.dialog( "close" ); assert.ok( element.dialog( "widget" ).is( ":visible" ), "beforeClose callback should prevent dialog from closing" ); element.remove(); element = $( "
    " ).dialog(); element.dialog( "option", "beforeClose", function( ev, ui ) { assert.ok( true, ".dialog('close') fires beforeClose callback" ); assert.equal( this, element[ 0 ], "context of callback" ); assert.equal( ev.type, "dialogbeforeclose", "event type in callback" ); assert.deepEqual( ui, {}, "ui hash in callback" ); return false; } ); element.dialog( "close" ); assert.ok( element.dialog( "widget" ).is( ":visible" ), "beforeClose callback should prevent dialog from closing" ); element.remove(); element = $( "
    " ).dialog().on( "dialogbeforeclose", function( ev, ui ) { assert.ok( true, ".dialog('close') triggers dialogbeforeclose event" ); assert.equal( this, element[ 0 ], "context of event" ); assert.deepEqual( ui, {}, "ui hash in event" ); return false; } ); element.dialog( "close" ); assert.ok( element.dialog( "widget" ).is( ":visible" ), "dialogbeforeclose event should prevent dialog from closing" ); element.remove(); } ); // #8789 and #8838 QUnit.test( "ensure dialog's container doesn't scroll on resize and focus", function( assert ) { var ready = assert.async(); assert.expect( 2 ); var element = $( "#dialog1" ).dialog(), initialScroll = $( window ).scrollTop(); element.dialog( "option", "height", 600 ); assert.equal( $( window ).scrollTop(), initialScroll, "scroll hasn't moved after height change" ); setTimeout( function() { $( ".ui-dialog-titlebar-close" ).simulate( "mousedown" ); assert.equal( $( window ).scrollTop(), initialScroll, "scroll hasn't moved after focus moved to dialog" ); element.dialog( "destroy" ); ready(); } ); } ); QUnit.test( "#5184: isOpen in dialogclose event is true", function( assert ) { assert.expect( 3 ); var element = $( "
    " ).dialog( { close: function() { assert.ok( !element.dialog( "isOpen" ), "dialog is not open during close" ); } } ); assert.ok( element.dialog( "isOpen" ), "dialog is open after init" ); element.dialog( "close" ); assert.ok( !element.dialog( "isOpen" ), "dialog is not open after close" ); element.remove(); } ); QUnit.test( "ensure dialog keeps focus when clicking modal overlay", function( assert ) { assert.expect( 2 ); var element = $( "
    " ).dialog( { modal: true } ); assert.equal( $( document.activeElement ).closest( ".ui-dialog" ).length, 1, "focus is in dialog" ); $( ".ui-widget-overlay" ).simulate( "mousedown" ); assert.equal( $( document.activeElement ).closest( ".ui-dialog" ).length, 1, "focus is still in dialog" ); element.remove(); } ); } ); ================================================ FILE: tests/unit/dialog/helper.js ================================================ define( [ "qunit", "jquery", "lib/helper", "ui/widgets/dialog" ], function( QUnit, $, helper ) { "use strict"; return $.extend( helper, { drag: function( element, handle, dx, dy ) { var d = element.dialog( "widget" ); //This mouseover is to work around a limitation in resizable //TODO: fix resizable so handle doesn't require mouseover in order to be used $( handle, d ).simulate( "mouseover" ).simulate( "drag", { dx: dx, dy: dy } ); }, testDrag: function( assert, element, dx, dy, expectedDX, expectedDY, msg ) { var actualDX, actualDY, offsetAfter, d = element.dialog( "widget" ), handle = $( ".ui-dialog-titlebar", d ), offsetBefore = d.offset(); this.drag( element, handle, dx, dy ); offsetAfter = d.offset(); msg = msg ? msg + "." : ""; actualDX = offsetAfter.left - offsetBefore.left; actualDY = offsetAfter.top - offsetBefore.top; assert.ok( expectedDX - actualDX <= 1 && expectedDY - actualDY <= 1, "dragged[" + expectedDX + ", " + expectedDY + "] " + msg ); }, shouldResize: function( assert, element, dw, dh, msg ) { var actualDH, actualDW, heightAfter, widthAfter, d = element.dialog( "widget" ), handle = $( ".ui-resizable-se", d ), heightBefore = element.height(), widthBefore = element.width(); this.drag( element, handle, 50, 50 ); heightAfter = element.height(); widthAfter = element.width(); msg = msg ? msg + "." : ""; actualDH = heightAfter - heightBefore; actualDW = widthAfter - widthBefore; // TODO: Switch to assert.close(). // Also change the testDrag() helper. assert.ok( Math.abs( actualDH - dh ) <= 1 && Math.abs( actualDW - dw ) <= 1, "resized[50, 50] " + msg ); } } ); } ); ================================================ FILE: tests/unit/dialog/methods.js ================================================ define( [ "qunit", "jquery", "lib/helper", "ui/widgets/dialog" ], function( QUnit, $, helper ) { "use strict"; QUnit.module( "dialog: methods", { afterEach: function() { $( "body>.ui-dialog" ).remove(); return helper.moduleAfterEach.apply( this, arguments ); } } ); QUnit.test( "init", function( assert ) { assert.expect( 6 ); $( "
    " ).appendTo( "body" ).dialog().remove(); assert.ok( true, ".dialog() called on element" ); $( [] ).dialog().remove(); assert.ok( true, ".dialog() called on empty collection" ); $( "
    " ).dialog().remove(); assert.ok( true, ".dialog() called on disconnected DOMElement - never connected" ); $( "
    " ).appendTo( "body" ).remove().dialog().remove(); assert.ok( true, ".dialog() called on disconnected DOMElement - removed" ); var element = $( "
    " ).dialog(); element.dialog( "option", "foo" ); element.remove(); assert.ok( true, "arbitrary option getter after init" ); $( "
    " ).dialog().dialog( "option", "foo", "bar" ).remove(); assert.ok( true, "arbitrary option setter after init" ); } ); QUnit.test( "destroy", function( assert ) { assert.expect( 17 ); var element, element2; $( "#dialog1, #form-dialog" ).hide(); assert.domEqual( "#dialog1", function() { var dialog = $( "#dialog1" ).dialog().dialog( "destroy" ); assert.equal( dialog.parent()[ 0 ], $( "#qunit-fixture" )[ 0 ] ); assert.equal( dialog.index(), 0 ); } ); assert.domEqual( "#form-dialog", function() { var dialog = $( "#form-dialog" ).dialog().dialog( "destroy" ); assert.equal( dialog.parent()[ 0 ], $( "#qunit-fixture" )[ 0 ] ); assert.equal( dialog.index(), 2 ); } ); // Ensure dimensions are restored (#8119) $( "#dialog1" ).show().css( { width: "400px", minHeight: "100px", height: "200px" } ); assert.domEqual( "#dialog1", function() { $( "#dialog1" ).dialog().dialog( "destroy" ); } ); // Don't throw errors when destroying a never opened modal dialog (#9004) $( "#dialog1" ).dialog( { autoOpen: false, modal: true } ).dialog( "destroy" ); assert.equal( $( ".ui-widget-overlay" ).length, 0, "overlay does not exist" ); assert.equal( $( document ).data( "ui-dialog-overlays" ), undefined, "ui-dialog-overlays equals the number of open overlays" ); element = $( "#dialog1" ).dialog( { modal: true } ); element2 = $( "#dialog2" ).dialog( { modal: true } ); assert.equal( $( ".ui-widget-overlay" ).length, 2, "overlays created when dialogs are open" ); assert.equal( $( document ).data( "ui-dialog-overlays" ), 2, "ui-dialog-overlays equals the number of open overlays" ); element.dialog( "close" ); assert.equal( $( ".ui-widget-overlay" ).length, 1, "overlay remains after closing one dialog" ); assert.equal( $( document ).data( "ui-dialog-overlays" ), 1, "ui-dialog-overlays equals the number of open overlays" ); element.dialog( "destroy" ); assert.equal( $( ".ui-widget-overlay" ).length, 1, "overlay remains after destroying one dialog" ); assert.equal( $( document ).data( "ui-dialog-overlays" ), 1, "ui-dialog-overlays equals the number of open overlays" ); element2.dialog( "destroy" ); assert.equal( $( ".ui-widget-overlay" ).length, 0, "overlays removed when all dialogs are destoryed" ); assert.equal( $( document ).data( "ui-dialog-overlays" ), undefined, "ui-dialog-overlays equals the number of open overlays" ); } ); QUnit.test( "#9000: Dialog leaves broken event handler after close/destroy in certain cases", function( assert ) { var ready = assert.async(); assert.expect( 1 ); $( "#dialog1" ).dialog( { modal: true } ).dialog( "close" ).dialog( "destroy" ); setTimeout( function() { $( "#favorite-animal" ).trigger( "focus" ); assert.ok( true, "close and destroy modal dialog before its really opened" ); ready(); } ); } ); QUnit.test( "#4980: Destroy should place element back in original DOM position", function( assert ) { assert.expect( 2 ); var container = $( "
    " ), modal = container.find( "#modal" ); modal.dialog(); assert.ok( !$.contains( container[ 0 ], modal[ 0 ] ), "dialog should move modal element to outside container element" ); modal.dialog( "destroy" ); assert.ok( $.contains( container[ 0 ], modal[ 0 ] ), "dialog(destroy) should place element back in original DOM position" ); } ); QUnit.test( "enable/disable disabled", function( assert ) { assert.expect( 3 ); var element = $( "
    " ).dialog(); element.dialog( "disable" ); assert.equal( element.dialog( "option", "disabled" ), false, "disable method doesn't do anything" ); assert.lacksClasses( element, "ui-dialog-disabled ui-state-disabled", "disable method doesn't add classes" ); assert.ok( !element.dialog( "widget" ).attr( "aria-disabled" ), "disable method doesn't add aria-disabled" ); } ); QUnit.test( "close", function( assert ) { assert.expect( 3 ); var element, expected = $( "
    " ).dialog(), actual = expected.dialog( "close" ); assert.equal( actual, expected, "close is chainable" ); element = $( "
    " ).dialog(); assert.ok( element.dialog( "widget" ).is( ":visible" ) && !element.dialog( "widget" ).is( ":hidden" ), "dialog visible before close method called" ); element.dialog( "close" ); assert.ok( element.dialog( "widget" ).is( ":hidden" ) && !element.dialog( "widget" ).is( ":visible" ), "dialog hidden after close method called" ); } ); QUnit.test( "isOpen", function( assert ) { assert.expect( 4 ); var element = $( "
    " ).dialog(); assert.equal( element.dialog( "isOpen" ), true, "dialog is open after init" ); element.dialog( "close" ); assert.equal( element.dialog( "isOpen" ), false, "dialog is closed" ); element.remove(); element = $( "
    " ).dialog( { autoOpen: false } ); assert.equal( element.dialog( "isOpen" ), false, "dialog is closed after init" ); element.dialog( "open" ); assert.equal( element.dialog( "isOpen" ), true, "dialog is open" ); element.remove(); } ); QUnit.test( "moveToTop", function( assert ) { assert.expect( 5 ); function order() { var actual = $( ".ui-dialog" ).map( function() { return +$( this ).css( "z-index" ); } ).get(); assert.deepEqual( actual, $.makeArray( arguments ) ); } var dialog1, dialog2, focusOn = "dialog1"; dialog1 = $( "#dialog1" ).dialog( { focus: function() { assert.equal( focusOn, "dialog1" ); } } ); focusOn = "dialog2"; dialog2 = $( "#dialog2" ).dialog( { focus: function() { assert.equal( focusOn, "dialog2" ); } } ); order( 100, 101 ); focusOn = "dialog1"; dialog1.dialog( "moveToTop" ); order( 102, 101 ); } ); QUnit.test( "moveToTop: content scroll stays intact", function( assert ) { assert.expect( 2 ); var otherDialog = $( "#dialog1" ).dialog(), scrollDialog = $( "#form-dialog" ).dialog( { height: 200 } ); scrollDialog.scrollTop( 50 ); assert.equal( scrollDialog.scrollTop(), 50 ); otherDialog.dialog( "moveToTop" ); assert.equal( scrollDialog.scrollTop(), 50 ); } ); QUnit.test( "open", function( assert ) { assert.expect( 3 ); var element, expected = $( "
    " ).dialog(), actual = expected.dialog( "open" ); assert.equal( actual, expected, "open is chainable" ); element = $( "
    " ).dialog( { autoOpen: false } ); assert.ok( element.dialog( "widget" ).is( ":hidden" ) && !element.dialog( "widget" ).is( ":visible" ), "dialog hidden before open method called" ); element.dialog( "open" ); assert.ok( element.dialog( "widget" ).is( ":visible" ) && !element.dialog( "widget" ).is( ":hidden" ), "dialog visible after open method called" ); } ); // https://bugs.jqueryui.com/ticket/6137 QUnit.test( "Ensure form elements don't reset when opening a dialog", function( assert ) { assert.expect( 2 ); var d1 = $( "
    " + "b
    " ).appendTo( "body" ).dialog( { autoOpen: false } ); d1.find( "#b" ).prop( "checked", true ); assert.equal( d1.find( "input:checked" ).val(), "b", "checkbox b is checked" ); d1.dialog( "open" ); assert.equal( d1.find( "input:checked" ).val(), "b", "checkbox b is checked" ); d1.remove(); } ); QUnit.test( "#8958: dialog can be opened while opening", function( assert ) { var ready = assert.async( 3 ); assert.expect( 1 ); var element = $( "
    " ).dialog( { autoOpen: false, modal: true, open: function() { assert.equal( $( ".ui-widget-overlay" ).length, 1 ); ready(); } } ); $( "#favorite-animal" ) // We focus the input to start the test. Once it receives focus, the // dialog will open. Opening the dialog, will cause an element inside // the dialog to gain focus, thus blurring the input. .on( "focus", function() { element.dialog( "open" ); ready(); } ) // When the input blurs, the dialog is in the process of opening. We // try to open the dialog again, to make sure that dialogs properly // handle a call to the open() method during the process of the dialog // being opened. .on( "blur", function() { element.dialog( "open" ); // Detach the handlers to avoid firing them outside of this // test logic; this may affect other tests. $( this ).off( "focus blur" ); ready(); } ) .trigger( "focus" ); } ); QUnit.test( "#5531: dialog width should be at least minWidth on creation", function( assert ) { assert.expect( 4 ); var element = $( "
    " ).dialog( { width: 200, minWidth: 300 } ); assert.equal( element.dialog( "option", "width" ), 300, "width is minWidth" ); element.dialog( "option", "width", 200 ); assert.equal( element.dialog( "option", "width" ), 300, "width unchanged when set to < minWidth" ); element.dialog( "option", "width", 320 ); assert.equal( element.dialog( "option", "width" ), 320, "width changed if set to > minWidth" ); element.remove(); element = $( "
    " ).dialog( { minWidth: 300 } ); assert.ok( element.dialog( "option", "width" ) >= 300, "width is at least 300" ); element.remove(); } ); } ); ================================================ FILE: tests/unit/dialog/options.js ================================================ define( [ "qunit", "jquery", "lib/helper", "./helper", "ui/widgets/dialog", "ui/effects/effect-blind", "ui/effects/effect-explode" ], function( QUnit, $, helper, testHelper ) { "use strict"; QUnit.module( "dialog: options", { afterEach: helper.moduleAfterEach } ); QUnit.test( "appendTo", function( assert ) { assert.expect( 16 ); var detached = $( "
    " ), element = $( "#dialog1" ).dialog( { modal: true } ); assert.equal( element.dialog( "widget" ).parent()[ 0 ], document.body, "defaults to body" ); assert.equal( $( ".ui-widget-overlay" ).parent()[ 0 ], document.body, "overlay defaults to body" ); element.dialog( "destroy" ); element.dialog( { appendTo: ".wrap", modal: true } ); assert.equal( element.dialog( "widget" ).parent()[ 0 ], $( "#wrap1" )[ 0 ], "first found element" ); assert.equal( $( ".ui-widget-overlay" ).parent()[ 0 ], $( "#wrap1" )[ 0 ], "overlay first found element" ); assert.equal( $( "#wrap2 .ui-dialog" ).length, 0, "only appends to one element" ); assert.equal( $( "#wrap2 .ui-widget-overlay" ).length, 0, "overlay only appends to one element" ); element.dialog( "destroy" ); element.dialog( { appendTo: null, modal: true } ); assert.equal( element.dialog( "widget" ).parent()[ 0 ], document.body, "null" ); assert.equal( $( ".ui-widget-overlay" ).parent()[ 0 ], document.body, "overlay null" ); element.dialog( "destroy" ); element.dialog( { autoOpen: false, modal: true } ).dialog( "option", "appendTo", "#wrap1" ).dialog( "open" ); assert.equal( element.dialog( "widget" ).parent()[ 0 ], $( "#wrap1" )[ 0 ], "modified after init" ); assert.equal( $( ".ui-widget-overlay" ).parent()[ 0 ], $( "#wrap1" )[ 0 ], "overlay modified after init" ); element.dialog( "destroy" ); element.dialog( { appendTo: detached, modal: true } ); assert.equal( element.dialog( "widget" ).parent()[ 0 ], detached[ 0 ], "detached jQuery object" ); assert.equal( detached.find( ".ui-widget-overlay" ).parent()[ 0 ], detached[ 0 ], "overlay detached jQuery object" ); element.dialog( "destroy" ); element.dialog( { appendTo: detached[ 0 ], modal: true } ); assert.equal( element.dialog( "widget" ).parent()[ 0 ], detached[ 0 ], "detached DOM element" ); assert.equal( detached.find( ".ui-widget-overlay" ).parent()[ 0 ], detached[ 0 ], "overlay detached DOM element" ); element.dialog( "destroy" ); element.dialog( { autoOpen: false, modal: true } ).dialog( "option", "appendTo", detached ); assert.equal( element.dialog( "widget" ).parent()[ 0 ], detached[ 0 ], "detached DOM element via option()" ); assert.equal( detached.find( ".ui-widget-overlay" ).length, 0, "overlay detached DOM element via option()" ); element.dialog( "destroy" ); } ); QUnit.test( "autoOpen", function( assert ) { assert.expect( 2 ); var element = $( "
    " ).dialog( { autoOpen: false } ); assert.ok( !element.dialog( "widget" ).is( ":visible" ), ".dialog({ autoOpen: false })" ); element.remove(); element = $( "
    " ).dialog( { autoOpen: true } ); assert.ok( element.dialog( "widget" ).is( ":visible" ), ".dialog({ autoOpen: true })" ); element.remove(); } ); QUnit.test( "buttons", function( assert ) { assert.expect( 21 ); var btn, i, newButtons, buttons = { "Ok": function( ev ) { assert.ok( true, "button click fires callback" ); assert.equal( this, element[ 0 ], "context of callback" ); assert.equal( ev.target, btn[ 0 ], "event target" ); }, "Cancel": function( ev ) { assert.ok( true, "button click fires callback" ); assert.equal( this, element[ 0 ], "context of callback" ); assert.equal( ev.target, btn[ 1 ], "event target" ); } }, element = $( "
    " ).dialog( { buttons: buttons } ); btn = element.dialog( "widget" ).find( ".ui-dialog-buttonpane button" ); assert.equal( btn.length, 2, "number of buttons" ); i = 0; $.each( buttons, function( key ) { assert.equal( btn.eq( i ).text(), key, "text of button " + ( i + 1 ) ); i++; } ); assert.hasClasses( btn.parent(), "ui-dialog-buttonset" ); assert.hasClasses( element.parent(), "ui-dialog-buttons" ); btn.trigger( "click" ); newButtons = { "Close": function( ev ) { assert.ok( true, "button click fires callback" ); assert.equal( this, element[ 0 ], "context of callback" ); assert.equal( ev.target, btn[ 0 ], "event target" ); } }; assert.deepEqual( element.dialog( "option", "buttons" ), buttons, ".dialog('option', 'buttons') getter" ); element.dialog( "option", "buttons", newButtons ); assert.deepEqual( element.dialog( "option", "buttons" ), newButtons, ".dialog('option', 'buttons', ...) setter" ); btn = element.dialog( "widget" ).find( ".ui-dialog-buttonpane button" ); assert.equal( btn.length, 1, "number of buttons after setter" ); btn.trigger( "click" ); i = 0; $.each( newButtons, function( key ) { assert.equal( btn.eq( i ).text(), key, "text of button " + ( i + 1 ) ); i += 1; } ); element.dialog( "option", "buttons", null ); btn = element.dialog( "widget" ).find( ".ui-dialog-buttonpane button" ); assert.equal( btn.length, 0, "all buttons have been removed" ); assert.equal( element.find( ".ui-dialog-buttonset" ).length, 0, "buttonset has been removed" ); assert.lacksClasses( element.parent(), "ui-dialog-buttons" ); element.remove(); } ); QUnit.test( "buttons - advanced", function( assert ) { assert.expect( 7 ); var buttons, element = $( "
    " ).dialog( { buttons: [ { text: "a button", "class": "additional-class", id: "my-button-id", click: function() { assert.equal( this, element[ 0 ], "correct context" ); }, icon: "ui-icon-cancel", showLabel: false } ] } ); buttons = element.dialog( "widget" ).find( ".ui-dialog-buttonpane button" ); assert.equal( buttons.length, 1, "correct number of buttons" ); assert.equal( buttons.attr( "id" ), "my-button-id", "correct id" ); assert.equal( String.prototype.trim.call( buttons.text() ), "a button", "correct label" ); assert.hasClasses( buttons, "additional-class" ); assert.deepEqual( buttons.button( "option", "icon" ), "ui-icon-cancel" ); assert.equal( buttons.button( "option", "showLabel" ), false ); buttons.trigger( "click" ); element.remove(); } ); QUnit.test( "#9043: buttons with Array.prototype modification", function( assert ) { assert.expect( 1 ); Array.prototype.test = $.noop; var element = $( "
    " ).dialog(); assert.equal( element.dialog( "widget" ).find( ".ui-dialog-buttonpane" ).length, 0, "no button pane" ); element.remove(); delete Array.prototype.test; } ); QUnit.test( "closeOnEscape", function( assert ) { assert.expect( 6 ); var element = $( "
    " ).dialog( { closeOnEscape: false } ); assert.ok( true, "closeOnEscape: false" ); assert.ok( element.dialog( "widget" ).is( ":visible" ) && !element.dialog( "widget" ).is( ":hidden" ), "dialog is open before ESC" ); element.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ) .simulate( "keypress", { keyCode: $.ui.keyCode.ESCAPE } ) .simulate( "keyup", { keyCode: $.ui.keyCode.ESCAPE } ); assert.ok( element.dialog( "widget" ).is( ":visible" ) && !element.dialog( "widget" ).is( ":hidden" ), "dialog is open after ESC" ); element.remove(); element = $( "
    " ).dialog( { closeOnEscape: true } ); assert.ok( true, "closeOnEscape: true" ); assert.ok( element.dialog( "widget" ).is( ":visible" ) && !element.dialog( "widget" ).is( ":hidden" ), "dialog is open before ESC" ); element.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ) .simulate( "keypress", { keyCode: $.ui.keyCode.ESCAPE } ) .simulate( "keyup", { keyCode: $.ui.keyCode.ESCAPE } ); assert.ok( element.dialog( "widget" ).is( ":hidden" ) && !element.dialog( "widget" ).is( ":visible" ), "dialog is closed after ESC" ); } ); QUnit.test( "closeText", function( assert ) { assert.expect( 4 ); var element = $( "
    " ).dialog(); assert.equal( String.prototype.trim.call( element.dialog( "widget" ).find( ".ui-dialog-titlebar-close" ).text() ), "Close", "default close text" ); element.remove(); element = $( "
    " ).dialog( { closeText: "foo" } ); assert.equal( String.prototype.trim.call( element.dialog( "widget" ).find( ".ui-dialog-titlebar-close" ).text() ), "foo", "closeText on init" ); element.remove(); element = $( "
    " ).dialog().dialog( "option", "closeText", "bar" ); assert.equal( String.prototype.trim.call( element.dialog( "widget" ).find( ".ui-dialog-titlebar-close" ).text() ), "bar", "closeText via option method" ); element.remove(); element = $( "
    " ).dialog( { closeText: "foo" } ); assert.equal( String.prototype.trim.call( element.dialog( "widget" ).find( ".ui-dialog-titlebar-close" ).text() ), "foo", "closeText is escaped" ); element.remove(); } ); QUnit.test( "draggable", function( assert ) { assert.expect( 4 ); var element = $( "
    " ).dialog( { draggable: false } ); testHelper.testDrag( assert, element, 50, -50, 0, 0 ); element.dialog( "option", "draggable", true ); testHelper.testDrag( assert, element, 50, -50, 50, -50 ); element.remove(); element = $( "
    " ).dialog( { draggable: true } ); testHelper.testDrag( assert, element, 50, -50, 50, -50 ); element.dialog( "option", "draggable", false ); testHelper.testDrag( assert, element, 50, -50, 0, 0 ); element.remove(); } ); QUnit.test( "height", function( assert ) { assert.expect( 4 ); var element = $( "
    " ).dialog(); assert.ok( Math.abs( element.dialog( "widget" ).outerHeight() - 150 ) < 0.25, "default height within 0.25 from expected" ); element.remove(); element = $( "
    " ).dialog( { height: 237 } ); assert.ok( Math.abs( element.dialog( "widget" ).outerHeight() - 237 ) < 0.25, "explicit height within 0.25 from expected" ); element.remove(); element = $( "
    " ).dialog(); element.dialog( "option", "height", 238 ); assert.ok( Math.abs( element.dialog( "widget" ).outerHeight() - 238 ) < 0.25, "explicit height set after init within 0.25 from expected" ); element.remove(); element = $( "
    " ).css( "padding", "20px" ) .dialog( { height: 240 } ); assert.ok( Math.abs( element.dialog( "widget" ).outerHeight() - 240 ) < 0.25, "explicit height with padding within 0.25 from expected" ); element.remove(); } ); QUnit.test( "maxHeight", function( assert ) { assert.expect( 3 ); var element = $( "
    " ).dialog( { maxHeight: 200 } ); testHelper.drag( element, ".ui-resizable-s", 1000, 1000 ); assert.close( element.dialog( "widget" ).height(), 200, 1, "maxHeight" ); element.remove(); element = $( "
    " ).dialog( { maxHeight: 200 } ); testHelper.drag( element, ".ui-resizable-n", -1000, -1000 ); assert.close( element.dialog( "widget" ).height(), 200, 1, "maxHeight" ); element.remove(); element = $( "
    " ).dialog( { maxHeight: 200 } ).dialog( "option", "maxHeight", 300 ); testHelper.drag( element, ".ui-resizable-s", 1000, 1000 ); assert.close( element.dialog( "widget" ).height(), 300, 1, "maxHeight" ); element.remove(); } ); QUnit.test( "maxWidth", function( assert ) { assert.expect( 3 ); var element = $( "
    " ).dialog( { maxWidth: 200 } ); testHelper.drag( element, ".ui-resizable-e", 1000, 1000 ); assert.close( element.dialog( "widget" ).width(), 200, 1, "maxWidth" ); element.remove(); element = $( "
    " ).dialog( { maxWidth: 200 } ); testHelper.drag( element, ".ui-resizable-w", -1000, -1000 ); assert.close( element.dialog( "widget" ).width(), 200, 1, "maxWidth" ); element.remove(); element = $( "
    " ).dialog( { maxWidth: 200 } ).dialog( "option", "maxWidth", 300 ); testHelper.drag( element, ".ui-resizable-w", -1000, -1000 ); assert.close( element.dialog( "widget" ).width(), 300, 1, "maxWidth" ); element.remove(); } ); QUnit.test( "minHeight", function( assert ) { assert.expect( 3 ); var element = $( "
    " ).dialog( { minHeight: 10 } ); testHelper.drag( element, ".ui-resizable-s", -1000, -1000 ); assert.close( element.dialog( "widget" ).height(), 10, 1, "minHeight" ); element.remove(); element = $( "
    " ).dialog( { minHeight: 10 } ); testHelper.drag( element, ".ui-resizable-n", 1000, 1000 ); assert.close( element.dialog( "widget" ).height(), 10, 1, "minHeight" ); element.remove(); element = $( "
    " ).dialog( { minHeight: 10 } ).dialog( "option", "minHeight", 30 ); testHelper.drag( element, ".ui-resizable-n", 1000, 1000 ); assert.close( element.dialog( "widget" ).height(), 30, 1, "minHeight" ); element.remove(); } ); QUnit.test( "minWidth", function( assert ) { assert.expect( 3 ); var element = $( "
    " ).dialog( { minWidth: 10 } ); testHelper.drag( element, ".ui-resizable-e", -1000, -1000 ); assert.close( element.dialog( "widget" ).width(), 10, 1, "minWidth" ); element.remove(); element = $( "
    " ).dialog( { minWidth: 10 } ); testHelper.drag( element, ".ui-resizable-w", 1000, 1000 ); assert.close( element.dialog( "widget" ).width(), 10, 1, "minWidth" ); element.remove(); element = $( "
    " ).dialog( { minWidth: 30 } ).dialog( "option", "minWidth", 30 ); testHelper.drag( element, ".ui-resizable-w", 1000, 1000 ); assert.close( element.dialog( "widget" ).width(), 30, 1, "minWidth" ); element.remove(); } ); QUnit.test( "position, default center on window", function( assert ) { assert.expect( 2 ); // Dialogs alter the window width and height in Firefox // so we collect that information before creating the dialog // Support: Firefox var winWidth = $( window ).width(), winHeight = $( window ).height(), element = $( "
    " ).dialog(), dialog = element.dialog( "widget" ), offset = dialog.offset(); assert.close( offset.left, Math.round( winWidth / 2 - dialog.outerWidth() / 2 ) + $( window ).scrollLeft(), 1, "dialog left position of center on window on initilization" ); assert.close( offset.top, Math.round( winHeight / 2 - dialog.outerHeight() / 2 ) + $( window ).scrollTop(), 1, "dialog top position of center on window on initilization" ); element.remove(); } ); QUnit.test( "position, right bottom at right bottom via ui.position args", function( assert ) { assert.expect( 2 ); // Dialogs alter the window width and height in Firefox // so we collect that information before creating the dialog // Support: Firefox var winWidth = $( window ).width(), winHeight = $( window ).height(), element = $( "
    " ).dialog( { position: { my: "right bottom", at: "right bottom" } } ), dialog = element.dialog( "widget" ), offset = dialog.offset(); assert.close( offset.left, winWidth - dialog.outerWidth() + $( window ).scrollLeft(), 1, "dialog left position of right bottom at right bottom on initilization" ); assert.close( offset.top, winHeight - dialog.outerHeight() + $( window ).scrollTop(), 1, "dialog top position of right bottom at right bottom on initilization" ); element.remove(); } ); QUnit.test( "position, at another element", function( assert ) { assert.expect( 4 ); var parent = $( "
    " ).css( { position: "absolute", top: 400, left: 600, height: 10, width: 10 } ).appendTo( "body" ), element = $( "
    " ).dialog( { position: { my: "left top", at: "left top", of: parent, collision: "none" } } ), dialog = element.dialog( "widget" ), offset = dialog.offset(); assert.close( offset.left, 600, 1, "dialog left position at another element on initilization" ); assert.close( offset.top, 400, 1, "dialog top position at another element on initilization" ); element.dialog( "option", "position", { my: "left top", at: "right bottom", of: parent, collision: "none" } ); offset = dialog.offset(); assert.close( offset.left, 610, 1, "dialog left position at another element via setting option" ); assert.close( offset.top, 410, 1, "dialog top position at another element via setting option" ); element.remove(); parent.remove(); } ); QUnit.test( "resizable", function( assert ) { assert.expect( 4 ); var element = $( "
    " ).dialog(); testHelper.shouldResize( assert, element, 50, 50, "[default]" ); element.dialog( "option", "resizable", false ); testHelper.shouldResize( assert, element, 0, 0, "disabled after init" ); element.remove(); element = $( "
    " ).dialog( { resizable: false } ); testHelper.shouldResize( assert, element, 0, 0, "disabled in init options" ); element.dialog( "option", "resizable", true ); testHelper.shouldResize( assert, element, 50, 50, "enabled after init" ); element.remove(); } ); QUnit.test( "title", function( assert ) { assert.expect( 11 ); function titleText() { return element.dialog( "widget" ).find( ".ui-dialog-title" ).html(); } var element = $( "
    " ).dialog(); // Some browsers return a non-breaking space and some return " " // so we generate a non-breaking space for comparison assert.equal( titleText(), $( " " ).html(), "[default]" ); assert.equal( element.dialog( "option", "title" ), null, "option not changed" ); element.remove(); element = $( "
    " ).dialog(); assert.equal( titleText(), "foo", "title in element attribute" ); assert.equal( element.dialog( "option", "title" ), "foo", "option updated from attribute" ); element.remove(); element = $( "
    " ).dialog( { title: "foo" } ); assert.equal( titleText(), "foo", "title in init options" ); assert.equal( element.dialog( "option", "title" ), "foo", "opiton set from options hash" ); element.remove(); element = $( "
    " ).dialog( { title: "bar" } ); assert.equal( titleText(), "bar", "title in init options should override title in element attribute" ); assert.equal( element.dialog( "option", "title" ), "bar", "opiton set from options hash" ); element.remove(); element = $( "
    " ).dialog().dialog( "option", "title", "foo" ); assert.equal( titleText(), "foo", "title after init" ); element.remove(); // Make sure attroperties are properly ignored - #5742 - .attr() might return a DOMElement element = $( "
    " ).dialog(); // Some browsers return a non-breaking space and some return " " // so we get the text to normalize to the actual non-breaking space assert.equal( titleText(), $( " " ).html(), "[default]" ); assert.equal( element.dialog( "option", "title" ), null, "option not changed" ); element.remove(); } ); QUnit.test( "width", function( assert ) { assert.expect( 3 ); var element = $( "
    " ).dialog(); assert.close( element.dialog( "widget" ).width(), 300, 1, "default width" ); element.remove(); element = $( "
    " ).dialog( { width: 437 } ); assert.close( element.dialog( "widget" ).width(), 437, 1, "explicit width" ); element.dialog( "option", "width", 438 ); assert.close( element.dialog( "widget" ).width(), 438, 1, "explicit width after init" ); element.remove(); } ); QUnit.test( "#4826: setting resizable false toggles resizable on dialog", function( assert ) { assert.expect( 6 ); var i, element = $( "
    " ).dialog( { resizable: false } ); testHelper.shouldResize( assert, element, 0, 0, "[default]" ); for ( i = 0; i < 2; i++ ) { element.dialog( "close" ).dialog( "open" ); testHelper.shouldResize( assert, element, 0, 0, "initialized with resizable false toggle (" + ( i + 1 ) + ")" ); } element.remove(); element = $( "
    " ).dialog( { resizable: true } ); testHelper.shouldResize( assert, element, 50, 50, "[default]" ); for ( i = 0; i < 2; i++ ) { element.dialog( "close" ).dialog( "option", "resizable", false ).dialog( "open" ); testHelper.shouldResize( assert, element, 0, 0, "set option resizable false toggle (" + ( i + 1 ) + ")" ); } element.remove(); } ); QUnit.test( "#8051 - 'Explode' dialog animation causes crash in IE 6, 7 and 8", function( assert ) { var ready = assert.async(); assert.expect( 1 ); var element = $( "
    " ).dialog( { show: "explode", focus: function() { assert.ok( true, "dialog opened with animation" ); element.remove(); ready(); } } ); } ); QUnit.test( "#4421 - Focus lost from dialog which uses show-effect", function( assert ) { var ready = assert.async(); assert.expect( 1 ); var element = $( "
    " ).dialog( { show: "blind", focus: function() { assert.equal( element.dialog( "widget" ).find( document.activeElement ).length, 1, "dialog maintains focus" ); element.remove(); ready(); } } ); } ); QUnit.test( "Open followed by close during show effect", function( assert ) { var ready = assert.async(); assert.expect( 1 ); var element = $( "
    " ).dialog( { show: "blind", close: function() { assert.ok( true, "dialog closed properly during animation" ); element.remove(); ready(); } } ); setTimeout( function() { element.dialog( "close" ); }, 100 ); } ); } ); ================================================ FILE: tests/unit/draggable/all.html ================================================ jQuery UI Draggable Test Suite
    ================================================ FILE: tests/unit/draggable/common.js ================================================ define( [ "lib/common", "ui/widgets/draggable" ], function( common ) { common.testWidget( "draggable", { defaults: { appendTo: "parent", axis: false, cancel: "input, textarea, button, select, option", classes: {}, connectToSortable: false, containment: false, cursor: "auto", cursorAt: false, disabled: false, grid: false, handle: false, helper: "original", opacity: false, refreshPositions: false, revert: false, revertDuration: 500, scroll: true, scrollSensitivity: 20, scrollSpeed: 20, scope: "default", snap: false, snapMode: "both", snapTolerance: 20, stack: false, zIndex: false, //Todo: remove the following option checks when interactions are rewritten: addClasses: true, delay: 0, distance: 1, iframeFix: false, // Callbacks create: null, drag: null, start: null, stop: null } } ); } ); ================================================ FILE: tests/unit/draggable/core.js ================================================ define( [ "qunit", "jquery", "lib/helper", "./helper", "ui/widgets/draggable", "ui/widgets/droppable", "ui/widgets/resizable" ], function( QUnit, $, helper, testHelper ) { "use strict"; QUnit.module( "draggable: core", { afterEach: helper.moduleAfterEach } ); QUnit.test( "element types", function( assert ) { var typeNames = ( "p,h1,h2,h3,h4,h5,h6,blockquote,ol,ul,dl,div,form" + ",table,fieldset,address,ins,del,em,strong,q,cite,dfn,abbr" + ",acronym,code,samp,kbd,var,img,hr" + ",input,button,label,select,iframe" ).split( "," ); assert.expect( typeNames.length * 2 ); $.each( typeNames, function( i ) { var offsetBefore, offsetAfter, typeName = typeNames[ i ], el = $( document.createElement( typeName ) ).appendTo( "#qunit-fixture" ); if ( typeName === "table" ) { el.append( "content" ); } el.draggable( { cancel: "" } ); offsetBefore = el.offset(); el.simulate( "drag", { dx: 50, dy: 50 } ); offsetAfter = el.offset(); // Support: Firefox, Chrome // There are some rounding errors, so we can't say equal, we have to settle for close enough assert.close( offsetBefore.left, offsetAfter.left - 50, 1, "dragged[50, 50] " + "<" + typeName + "> left" ); assert.close( offsetBefore.top, offsetAfter.top - 50, 1, "dragged[50, 50] " + "<" + typeName + "> top" ); el.draggable( "destroy" ); el.remove(); } ); } ); QUnit.test( "No options, relative", function( assert ) { assert.expect( 2 ); testHelper.shouldMove( assert, $( "#draggable1" ).draggable(), "no options, relative" ); } ); QUnit.test( "No options, absolute", function( assert ) { assert.expect( 2 ); testHelper.shouldMove( assert, $( "#draggable2" ).draggable(), "no options, absolute" ); } ); QUnit.test( "resizable handle with complex markup (#8756 / #8757)", function( assert ) { assert.expect( 2 ); $( "#draggable1" ) .append( $( "
    " ) .addClass( "ui-resizable-handle ui-resizable-w" ) .append( $( "
    " ) ) ); var handle = $( ".ui-resizable-w div" ), target = $( "#draggable1" ).draggable().resizable( { handles: "all" } ); // Todo: fix resizable so it doesn't require a mouseover handle.simulate( "mouseover" ).simulate( "drag", { dx: -50 } ); assert.equal( target.width(), 250, "compare width" ); // Todo: fix resizable so it doesn't require a mouseover handle.simulate( "mouseover" ).simulate( "drag", { dx: 50 } ); assert.equal( target.width(), 200, "compare width" ); } ); QUnit.test( "#8269: Removing draggable element on drop", function( assert ) { assert.expect( 2 ); var element = $( "#draggable1" ).wrap( "
    " ).draggable( { stop: function() { assert.ok( true, "stop still called despite element being removed from DOM on drop" ); } } ), dropOffset = $( "#droppable" ).offset(); $( "#droppable" ).droppable( { drop: function() { $( "#wrapper" ).remove(); assert.ok( true, "element removed from DOM on drop" ); } } ); element.simulate( "drag", { handle: "corner", x: dropOffset.left, y: dropOffset.top } ); } ); // https://bugs.jqueryui.com/ticket/7778 // drag element breaks in IE8 when its content is replaced onmousedown QUnit.test( "Stray mousemove after mousedown still drags", function( assert ) { assert.expect( 2 ); var element = $( "#draggable1" ).draggable( { scroll: false } ); // In IE8, when content is placed under the mouse (e.g. when draggable content is replaced // on mousedown), mousemove is triggered on those elements even though the mouse hasn't moved. element.on( "mousedown", function() { $( document ).simulate( "mousemove", { button: -1 } ); } ); testHelper.shouldMove( assert, element, "element is draggable" ); } ); QUnit.test( "#6258: not following mouse when scrolled and using overflow-y: scroll", function( assert ) { assert.expect( 2 ); var element = $( "#draggable1" ).draggable( { stop: function( event, ui ) { assert.equal( ui.position.left, 1, "left position is correct despite overflow on HTML" ); assert.equal( ui.position.top, 1, "top position is correct despite overflow on HTML" ); $( "html" ) .css( "overflow-y", oldOverflowY ) .css( "overflow-x", oldOverflowX ) .scrollTop( 0 ) .scrollLeft( 0 ); } } ), oldOverflowY = $( "html" ).css( "overflow-y" ), oldOverflowX = $( "html" ).css( "overflow-x" ); testHelper.forceScrollableWindow(); $( "html" ) .css( "overflow-y", "scroll" ) .css( "overflow-x", "scroll" ) .scrollTop( 300 ) .scrollLeft( 300 ); element.simulate( "drag", { dx: 1, dy: 1, moves: 1 } ); } ); QUnit.test( "#9315: jumps down with offset of scrollbar", function( assert ) { assert.expect( 2 ); var element = $( "#draggable2" ).draggable( { stop: function( event, ui ) { assert.equal( ui.position.left, 11, "left position is correct when position is absolute" ); assert.equal( ui.position.top, 11, "top position is correct when position is absolute" ); $( "html" ).scrollTop( 0 ).scrollLeft( 0 ); } } ); testHelper.forceScrollableWindow(); $( "html" ).scrollTop( 300 ).scrollLeft( 300 ); element.simulate( "drag", { dx: 1, dy: 1, moves: 1 } ); } ); QUnit.test( "scroll offset with fixed ancestors", function( assert ) { assert.expect( 2 ); var startValue = 300, element = $( "#draggable1" ) // https://bugs.jqueryui.com/ticket/5009 // scroll not working with parent's position fixed .wrap( "
    " ) // https://bugs.jqueryui.com/ticket/9612 // abspos elements inside of fixed elements moving away from the mouse when scrolling .wrap( "
    " ) .draggable( { drag: function() { startValue += 100; $( document ).scrollTop( startValue ).scrollLeft( startValue ); }, stop: function( event, ui ) { assert.equal( ui.position.left, 10, "left position is correct when parent position is fixed" ); assert.equal( ui.position.top, 10, "top position is correct when parent position is fixed" ); $( document ).scrollTop( 0 ).scrollLeft( 0 ); } } ); testHelper.forceScrollableWindow(); $( "#wrapper" ).css( "position", "fixed" ); $( "#wrapper2" ).css( "position", "absolute" ); element.simulate( "drag", { dx: 10, dy: 10, moves: 3 } ); } ); $( [ "hidden", "auto", "scroll" ] ).each( function() { var overflow = this; // https://bugs.jqueryui.com/ticket/9379 - position bug in scrollable div // https://bugs.jqueryui.com/ticket/10147 - Wrong position in a parent with "overflow: hidden" QUnit.test( "position in scrollable parent with overflow: " + overflow, function( assert ) { assert.expect( 2 ); $( "#qunit-fixture" ).html( "
    a
    " ); $( "#inner" ).css( { position: "absolute", width: "500px", height: "500px" } ); $( "#outer" ).css( { position: "absolute", width: "300px", height: "300px" } ); $( "#dragged" ).css( { width: "10px", height: "10px" } ); var moves = 3, startValue = 0, dragDelta = 20, delta = 100, // We scroll after each drag event, so subtract 1 from number of moves for expected expected = delta + ( ( moves - 1 ) * dragDelta ), element = $( "#dragged" ).draggable( { drag: function() { startValue += dragDelta; $( "#outer" ).scrollTop( startValue ).scrollLeft( startValue ); }, stop: function( event, ui ) { assert.equal( ui.position.left, expected, "left position is correct when grandparent is scrolled" ); assert.equal( ui.position.top, expected, "top position is correct when grandparent is scrolled" ); } } ); $( "#outer" ).css( "overflow", overflow ); element.simulate( "drag", { dy: delta, dx: delta, moves: moves } ); } ); } ); QUnit.test( "#5727: draggable from iframe", function( assert ) { assert.expect( 1 ); var iframeBody, draggable1, iframe = $( "" ) .append( "

    a bunch of content

    Just another dialog to test stacking
    ================================================ FILE: tests/visual/draggable/replaced.html ================================================ Draggable Visual Test

    WHAT: A draggable, whose content is replaced onmousedown.

    EXPECTED: In IE8, the draggable can actually be dragged.

    content
    ================================================ FILE: tests/visual/effects/all.html ================================================ jQuery UI Effects Test Suite
    • Blind up

    • Blind down

    • Blind left

    • Blind right

    • Bounce 3 times

    • Clip horizontally

    • Clip vertically

    • Drop up

    • Drop left

    • Drop right

    • Explode in 9 pieces

    • Explode in 36 pieces

    • Fade

    • Fold

    • Highlight

    • Pulsate 2 times

    • Puff

    • Scale

    • Shake

    • Size Default Show/Hide

    • Size Toggle

    • Slide down

    • Slide up

    • Slide left

    • Slide right

    • addClass

    • removeClass

    • toggleClass

    • hide/show (jQuery)

    ================================================ FILE: tests/visual/effects/clip.html ================================================ jQuery UI Effects Test Suite

    WHAT: A set of elements with various positions and clips, using the clip effect.

    EXPECTED: When clicking "Toggle" or "Effect Toggle", to observe the same behavior; All elements should not change position, aside from the expected clip animation. At the end of the animation, the animated elements should hide. Layout (i.e. the position of other elements) should not change until the animated elements are hidden.

    EXPECTED: Clicking "Toggle" or "Effect Toggle" a second time reverses the animation, first showing all elements at their original dimensions, and restoring them to their original state.

    EXPECTED: Clicking "Effect Default" should always perform a "hide" animation.

    EXPECTED: Clicking any of the buttons in quick succession should queue the relevant animations.

    EXPECTED CANTFIX: In IE8, the clip animation jumps due to a bug that causes .css('clip') to return undefined unless the clip property is an inline style.

    Bacon ipsum dolor sit amet chuck cow ground round, ham hock short loin tail jowl sausage flank. Venison andouille turducken sausage. Boudin filet mignon shoulder, prosciutto sirloin tail cow pastrami. Salami jerky flank rump, sirloin spare ribs pork belly. Biltong brisket boudin ground round, venison chicken shankle short ribs meatball corned beef. Swine short ribs shoulder, short loin turducken biltong prosciutto ball tip. Biltong beef bresaola sausage prosciutto spare ribs, short loin swine pork chop cow flank pork turkey shankle.

    jQuery Logo

    Jerky corned beef short loin fatback jowl tail. Rump spare ribs shoulder pork belly. Sausage cow ground round bacon. Bresaola kielbasa pastrami brisket ham hock. Andouille kielbasa ham, pork beef tenderloin ground round beef ribs flank turkey pancetta tri-tip.

    Shankle filet mignon ribeye chicken, bacon jowl drumstick frankfurter swine short loin capicola leberkas tenderloin pig. Shankle bacon shank pork loin, shoulder ham drumstick biltong. Shankle ham pastrami ball tip turkey leberkas pork loin ground round. Chicken strip steak venison shoulder biltong ham. Bacon pork loin tenderloin kielbasa, prosciutto sausage leberkas jowl ribeye turducken. Flank short loin venison tenderloin spare ribs boudin, tongue pork chop shank sirloin. Ground round ham pork belly, corned beef jowl strip steak short ribs prosciutto pig bresaola spare ribs.

    jQuery Logo

    Pork loin biltong ball tip tail jerky beef ribs prosciutto short loin turducken. Turkey chicken jowl pork loin shank tri-tip swine brisket. Doner prosciutto leberkas venison ground round, short loin capicola hamburger pork bacon. Spare ribs beef pork tenderloin rump shoulder pork belly turducken cow beef ribs pastrami tail flank. Spare ribs tri-tip shank, pork beef ribs ribeye chicken bacon boudin shoulder venison. Sirloin beef ribs boudin, andouille doner tail ball tip biltong prosciutto chicken beef turkey tongue hamburger tri-tip.

    Doner salami jowl beef ribs. Pork chop beef short loin pork, kielbasa tail andouille salami sausage meatball short ribs t-bone tri-tip ham. Meatball short ribs prosciutto flank chicken fatback frankfurter brisket turducken. Corned beef hamburger swine short ribs pancetta. Jerky bresaola pork chuck spare ribs pastrami shoulder flank chicken leberkas beef.

    Doner salami jowl beef ribs. Pork chop beef short loin pork, kielbasa tail andouille salami sausage meatball short ribs t-bone tri-tip ham. Meatball short ribs prosciutto flank chicken fatback frankfurter brisket turducken. Corned beef hamburger swine short ribs pancetta. Jerky bresaola pork chuck spare ribs pastrami shoulder flank chicken leberkas beef.

    Doner salami jowl beef ribs. Pork chop beef short loin pork, kielbasa tail andouille salami sausage meatball short ribs t-bone tri-tip ham. Meatball short ribs prosciutto flank chicken fatback frankfurter brisket turducken. Corned beef hamburger swine short ribs pancetta. Jerky bresaola pork chuck spare ribs pastrami shoulder flank chicken leberkas beef.

    ================================================ FILE: tests/visual/effects/effects.css ================================================ body { margin: 1em; padding: 0; background: #fff; color: #000; } ul.effects { list-style-type: none; margin: 0; padding: 0; } ul.effects li { padding: 0; width: 120px; height: 100px; float: left; margin-top: 20px; margin-left: 20px; } div.effect { width: 120px; height: 100px; background: #ccc; border: 5px outset #aaa; float: left; cursor: pointer; cursor: hand; } div.current { border: 5px outset #FF9C08; background: #FF9C08; } div.effect p { color: #191919; font-weight: bold; margin: 0; padding: 10px; } .ui-effects-transfer { border: 1px dotted #fff; background: #666; opacity: 0.5; } ================================================ FILE: tests/visual/effects/effects.js ================================================ var duration = 1000, wait = 500; function effect( elem, name, options ) { $.extend( options, { easing: "easeOutQuint" } ); $( elem ).on( "click", function() { $( this ) .addClass( "current" ) // delaying the initial animation makes sure that the queue stays in tact .delay( 10 ) .hide( name, options, duration ) .delay( wait ) .show( name, options, duration, function() { $( this ).removeClass( "current" ); } ); } ); } $( "#hide" ).on( "click", function() { $( this ) .addClass( "current" ) .hide( duration ) .delay( wait ) .show( duration, function() { $( this ).removeClass( "current" ); } ); } ); effect( "#blindLeft", "blind", { direction: "left" } ); effect( "#blindUp", "blind", { direction: "up" } ); effect( "#blindRight", "blind", { direction: "right" } ); effect( "#blindDown", "blind", { direction: "down" } ); effect( "#bounce3times", "bounce", { times: 3 } ); effect( "#clipHorizontally", "clip", { direction: "horizontal" } ); effect( "#clipVertically", "clip", { direction: "vertical" } ); effect( "#dropDown", "drop", { direction: "down" } ); effect( "#dropUp", "drop", { direction: "up" } ); effect( "#dropLeft", "drop", { direction: "left" } ); effect( "#dropRight", "drop", { direction: "right" } ); effect( "#explode9", "explode", {} ); effect( "#explode36", "explode", { pieces: 36 } ); effect( "#fade", "fade", {} ); effect( "#fold", "fold", { size: 50 } ); effect( "#highlight", "highlight", {} ); effect( "#pulsate", "pulsate", { times: 2 } ); effect( "#puff", "puff", {} ); effect( "#scale", "scale", {} ); effect( "#size", "size", {} ); $( "#sizeToggle" ).on( "click", function() { var options = { to: { width: 300, height: 300 } }; $( this ) .addClass( "current" ) .toggle( "size", options, duration ) .delay( wait ) .toggle( "size", options, duration, function() { $( this ).removeClass( "current" ); } ); } ); $( "#shake" ).on( "click", function() { $( this ) .addClass( "current" ) .effect( "shake", {}, 100, function() { $( this ).removeClass( "current" ); } ); } ); effect( "#slideDown", "slide", { direction: "down" } ); effect( "#slideUp", "slide", { direction: "up" } ); effect( "#slideLeft", "slide", { direction: "left" } ); effect( "#slideRight", "slide", { direction: "right" } ); $( "#addClass" ).on( "click", function() { $( this ).addClass( "current", duration, function() { $( this ).removeClass( "current" ); } ); } ); $( "#removeClass" ).on( "click", function() { $( this ).addClass( "current" ).removeClass( "current", duration ); } ); $( "#toggleClass" ).on( "click", function() { $( this ).toggleClass( "current", duration ); } ); ================================================ FILE: tests/visual/effects/scale.html ================================================ jQuery UI Effects Test Suite

    ================================================ FILE: tests/visual/effects/shake.html ================================================ jQuery UI Effects Test Suite

    WHAT: A set of elements with various box-model properties, using the shake effect to toggle.

    EXPECTED: When clicking "Toggle", all elements should not change dimension nor position, aside from the expected shake animation, which should take the number of milliseconds specified to complete. At the end of the animation, all elements should hide.

    EXPECTED: Clicking "Toggle" a second time reverses the animation, first showing all elements at their original dimensions, and restoring them to their original state.

    test
    test
    test
    test
    test
    test
    test
    test
    test
    test
    test
    test
    test
    test
    test
    ================================================ FILE: tests/visual/index.html ================================================ jQuery UI Visual Tests ================================================ FILE: tests/visual/menu/menu.html ================================================ Menu Visual Test: Default

    Default inline menu

    Inline with disabled items and submenus

    Menu with icons

    Long menu with scroll overflow, to test menu's scroll-on-keypress behaviour

    Menu with custom markup

    Menu with custom markup, multi-line items and a custom submenu icon

    Inline with dividers and group labels

    Log:
    ================================================ FILE: tests/visual/position/position.html ================================================ Position Visual Test

    This is the position target element.

    to position

    to position 2

    Position configuration:

    my:
    at:
    collision:
    ================================================ FILE: tests/visual/position/position_feedback.html ================================================ Position Visual Test: Feedback
    all around me
    ================================================ FILE: tests/visual/selectmenu/selectmenu.html ================================================ Selectmenu Visual Test: Default

    Event logging tests

    Disabled tests

    Empty tests

    Width tests

    Log:
    ================================================ FILE: tests/visual/slider/range_slider.html ================================================ jQuery UI Slider - Range slider

    Range Slider

    When set both values of range slider to the maximum, slider should not lock


    ================================================ FILE: tests/visual/tooltip/animations.html ================================================ Tooltip Visual Test: Animations
    {}
    {
    	"show": {
    		"effect": "slideDown"
    	},
    	"hide": {
    		"effect": "slideUp"
    	}
    }
    {
    	"show": {
    		"effect": "explode"
    	},
    	"hide": {
    		"effect": "explode"
    	}
    }
    {
    	"show": {
    		"effect": "bounce"
    	},
    	"hide": {
    		"effect": "blind"
    	}
    }
    {
    	"show": {
    		"effect": "drop",
    		"direction": "right"
    	},
    	"hide": {
    		"effect": "drop",
    		"direction": "right"
    	}
    }
    ================================================ FILE: tests/visual/tooltip/tooltip.html ================================================ Tooltip Visual Test: Default

    Lots of tooltipped elements close together.
    Mouse through them quickly and slowly.

    These elements are right aligned.
    One collides and one uses custom position.

    collision detection should kick in around here

    right aligned with custom position

    These footnotes pull content form the elements they link to.

    These elements load their content asynchronously.
    There should be a loading message while the content is retrieved.

    async
    async + cache

    Nested elements.

    tooltipped nested tooltipped third level
    Text in bold.

    Play around with focusing and hovering of form elements.

    Some inputs nested inside labels:

    Some button widgets:

    This is the footnote, including other elements
    This is the other footnote, including other elements
    ================================================ FILE: tests/visual/visual.css ================================================ #draggable, #resizable { width: 100px; height: 100px; background: #abc; } #droppable { width: 100px; height: 100px; background: #cde; } ================================================ FILE: themes/base/accordion.css ================================================ /*! * jQuery UI Accordion @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license * * https://api.jqueryui.com/accordion/#theming */ .ui-accordion .ui-accordion-header { display: block; cursor: pointer; position: relative; margin: 2px 0 0 0; padding: .5em .5em .5em .7em; font-size: 100%; } .ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; overflow: auto; } ================================================ FILE: themes/base/all.css ================================================ /*! * jQuery UI CSS Framework @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license * * https://api.jqueryui.com/category/theming/ */ @import "base.css"; @import "theme.css"; ================================================ FILE: themes/base/autocomplete.css ================================================ /*! * jQuery UI Autocomplete @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license * * https://api.jqueryui.com/autocomplete/#theming */ .ui-autocomplete { position: absolute; top: 0; left: 0; cursor: default; } ================================================ FILE: themes/base/base.css ================================================ /*! * jQuery UI CSS Framework @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license * * https://api.jqueryui.com/category/theming/ */ @import url("core.css"); @import url("accordion.css"); @import url("autocomplete.css"); @import url("button.css"); @import url("checkboxradio.css"); @import url("controlgroup.css"); @import url("datepicker.css"); @import url("dialog.css"); @import url("draggable.css"); @import url("menu.css"); @import url("progressbar.css"); @import url("resizable.css"); @import url("selectable.css"); @import url("selectmenu.css"); @import url("sortable.css"); @import url("slider.css"); @import url("spinner.css"); @import url("tabs.css"); @import url("tooltip.css"); ================================================ FILE: themes/base/button.css ================================================ /*! * jQuery UI Button @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license * * https://api.jqueryui.com/button/#theming */ .ui-button { padding: .4em 1em; display: inline-block; position: relative; line-height: normal; margin-right: .1em; cursor: pointer; vertical-align: middle; text-align: center; -webkit-user-select: none; user-select: none; } .ui-button, .ui-button:link, .ui-button:visited, .ui-button:hover, .ui-button:active { text-decoration: none; } /* to make room for the icon, a width needs to be set here */ .ui-button-icon-only { width: 2em; box-sizing: border-box; text-indent: -9999px; white-space: nowrap; } /* no icon support for input elements */ input.ui-button.ui-button-icon-only { text-indent: 0; } /* button icon element(s) */ .ui-button-icon-only .ui-icon { position: absolute; top: 50%; left: 50%; margin-top: -8px; margin-left: -8px; } .ui-button.ui-icon-notext .ui-icon { padding: 0; width: 2.1em; height: 2.1em; text-indent: -9999px; white-space: nowrap; } input.ui-button.ui-icon-notext .ui-icon { width: auto; height: auto; text-indent: 0; white-space: normal; padding: .4em 1em; } /* workarounds */ /* Support: Firefox 5 - 125+ */ input.ui-button::-moz-focus-inner, button.ui-button::-moz-focus-inner { border: 0; padding: 0; } ================================================ FILE: themes/base/checkboxradio.css ================================================ /*! * jQuery UI Checkboxradio @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license * * https://api.jqueryui.com/checkboxradio/#theming */ .ui-checkboxradio-label .ui-icon-background { box-shadow: inset 1px 1px 1px #ccc; border-radius: .12em; border: none; } .ui-checkboxradio-radio-label .ui-icon-background { width: 16px; height: 16px; border-radius: 1em; overflow: visible; border: none; } .ui-checkboxradio-radio-label.ui-checkboxradio-checked .ui-icon, .ui-checkboxradio-radio-label.ui-checkboxradio-checked:hover .ui-icon { background-image: none; width: 8px; height: 8px; border-width: 4px; border-style: solid; } .ui-checkboxradio-disabled { pointer-events: none; } ================================================ FILE: themes/base/controlgroup.css ================================================ /*! * jQuery UI Controlgroup @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license * * https://api.jqueryui.com/controlgroup/#theming */ .ui-controlgroup { vertical-align: middle; display: inline-block; } .ui-controlgroup > .ui-controlgroup-item { float: left; margin-left: 0; margin-right: 0; } .ui-controlgroup > .ui-controlgroup-item:focus, .ui-controlgroup > .ui-controlgroup-item.ui-visual-focus { z-index: 9999; } .ui-controlgroup-vertical > .ui-controlgroup-item { display: block; float: none; width: 100%; margin-top: 0; margin-bottom: 0; text-align: left; } .ui-controlgroup-vertical .ui-controlgroup-item { box-sizing: border-box; } .ui-controlgroup .ui-controlgroup-label { padding: .4em 1em; } .ui-controlgroup .ui-controlgroup-label span { font-size: 80%; } .ui-controlgroup-horizontal .ui-controlgroup-label + .ui-controlgroup-item { border-left: none; } .ui-controlgroup-vertical .ui-controlgroup-label + .ui-controlgroup-item { border-top: none; } .ui-controlgroup-horizontal .ui-controlgroup-label.ui-widget-content { border-right: none; } .ui-controlgroup-vertical .ui-controlgroup-label.ui-widget-content { border-bottom: none; } /* Spinner specific style fixes */ .ui-controlgroup-vertical .ui-spinner-input { width: calc( 100% - 2.4em ); } .ui-controlgroup-vertical .ui-spinner .ui-spinner-up { border-top-style: solid; } ================================================ FILE: themes/base/core.css ================================================ /*! * jQuery UI CSS Framework @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license * * https://api.jqueryui.com/category/theming/ */ /* Layout helpers ----------------------------------*/ .ui-helper-hidden { display: none; } .ui-helper-hidden-accessible { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; } .ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } .ui-helper-clearfix:before, .ui-helper-clearfix:after { content: ""; display: table; border-collapse: collapse; } .ui-helper-clearfix:after { clear: both; } .ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; } .ui-front { z-index: 100; } /* Interaction Cues ----------------------------------*/ .ui-state-disabled { cursor: default !important; pointer-events: none; } /* Icons ----------------------------------*/ .ui-icon { display: inline-block; vertical-align: middle; margin-top: -.25em; position: relative; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } .ui-widget-icon-block { left: 50%; margin-left: -8px; display: block; } /* Misc visuals ----------------------------------*/ /* Overlays */ .ui-widget-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; } ================================================ FILE: themes/base/datepicker.css ================================================ /*! * jQuery UI Datepicker @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license * * https://api.jqueryui.com/datepicker/#theming */ .ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; } .ui-datepicker .ui-datepicker-header { position: relative; padding: .2em 0; } .ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position: absolute; top: 2px; width: 1.8em; height: 1.8em; } .ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } .ui-datepicker .ui-datepicker-prev { left: 2px; } .ui-datepicker .ui-datepicker-next { right: 2px; } .ui-datepicker .ui-datepicker-prev-hover { left: 1px; } .ui-datepicker .ui-datepicker-next-hover { right: 1px; } .ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } .ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } .ui-datepicker .ui-datepicker-title select { font-size: 1em; margin: 1px 0; } .ui-datepicker select.ui-datepicker-month, .ui-datepicker select.ui-datepicker-year { width: 45%; } .ui-datepicker table { width: 100%; font-size: .9em; border-collapse: collapse; margin: 0 0 .4em; } .ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } .ui-datepicker td { border: 0; padding: 1px; } .ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } .ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding: 0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } .ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width: auto; overflow: visible; } .ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float: left; } /* with multiple calendars */ .ui-datepicker.ui-datepicker-multi { width: auto; } .ui-datepicker-multi .ui-datepicker-group { float: left; } .ui-datepicker-multi .ui-datepicker-group table { width: 95%; margin: 0 auto .4em; } .ui-datepicker-multi-2 .ui-datepicker-group { width: 50%; } .ui-datepicker-multi-3 .ui-datepicker-group { width: 33.3%; } .ui-datepicker-multi-4 .ui-datepicker-group { width: 25%; } .ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header, .ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width: 0; } .ui-datepicker-multi .ui-datepicker-buttonpane { clear: left; } .ui-datepicker-row-break { clear: both; width: 100%; font-size: 0; } /* RTL support */ .ui-datepicker-rtl { direction: rtl; } .ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } .ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } .ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } .ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } .ui-datepicker-rtl .ui-datepicker-buttonpane { clear: right; } .ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } .ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current, .ui-datepicker-rtl .ui-datepicker-group { float: right; } .ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header, .ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width: 0; border-left-width: 1px; } /* Icons */ .ui-datepicker .ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; left: .5em; top: .3em; } ================================================ FILE: themes/base/dialog.css ================================================ /*! * jQuery UI Dialog @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license * * https://api.jqueryui.com/dialog/#theming */ .ui-dialog { position: absolute; top: 0; left: 0; padding: .2em; outline: 0; } .ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; } .ui-dialog .ui-dialog-title { float: left; margin: .1em 0; white-space: nowrap; width: 90%; overflow: hidden; text-overflow: ellipsis; } .ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 20px; margin: -10px 0 0 0; padding: 1px; height: 20px; } .ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; } .ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin-top: .5em; padding: .3em 1em .5em .4em; } .ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; } .ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; } .ui-dialog .ui-resizable-n { height: 2px; top: 0; } .ui-dialog .ui-resizable-e { width: 2px; right: 0; } .ui-dialog .ui-resizable-s { height: 2px; bottom: 0; } .ui-dialog .ui-resizable-w { width: 2px; left: 0; } .ui-dialog .ui-resizable-se, .ui-dialog .ui-resizable-sw, .ui-dialog .ui-resizable-ne, .ui-dialog .ui-resizable-nw { width: 7px; height: 7px; } .ui-dialog .ui-resizable-se { right: 0; bottom: 0; } .ui-dialog .ui-resizable-sw { left: 0; bottom: 0; } .ui-dialog .ui-resizable-ne { right: 0; top: 0; } .ui-dialog .ui-resizable-nw { left: 0; top: 0; } .ui-draggable .ui-dialog-titlebar { cursor: move; } ================================================ FILE: themes/base/draggable.css ================================================ /*! * jQuery UI Draggable @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license */ .ui-draggable-handle { touch-action: none; } ================================================ FILE: themes/base/menu.css ================================================ /*! * jQuery UI Menu @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license * * https://api.jqueryui.com/menu/#theming */ .ui-menu { list-style: none; padding: 0; margin: 0; display: block; outline: 0; } .ui-menu .ui-menu { position: absolute; } .ui-menu .ui-menu-item { margin: 0; cursor: pointer; } .ui-menu .ui-menu-item-wrapper { position: relative; padding: 3px 1em 3px .4em; } .ui-menu .ui-menu-divider { margin: 5px 0; height: 0; font-size: 0; line-height: 0; border-width: 1px 0 0 0; } .ui-menu .ui-state-focus, .ui-menu .ui-state-active { margin: -1px; } /* icon support */ .ui-menu-icons { position: relative; } .ui-menu-icons .ui-menu-item-wrapper { padding-left: 2em; } /* left-aligned */ .ui-menu .ui-icon { position: absolute; top: 0; bottom: 0; left: .2em; margin: auto 0; } /* right-aligned */ .ui-menu .ui-menu-icon { left: auto; right: 0; } ================================================ FILE: themes/base/progressbar.css ================================================ /*! * jQuery UI Progressbar @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license * * https://api.jqueryui.com/progressbar/#theming */ .ui-progressbar { height: 2em; text-align: left; overflow: hidden; } .ui-progressbar .ui-progressbar-value { margin: -1px; height: 100%; } .ui-progressbar .ui-progressbar-overlay { background: url("data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw=="); height: 100%; opacity: 0.25; } .ui-progressbar-indeterminate .ui-progressbar-value { background-image: none; } ================================================ FILE: themes/base/resizable.css ================================================ /*! * jQuery UI Resizable @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license */ .ui-resizable { position: relative; } .ui-resizable-handle { position: absolute; font-size: 0.1px; display: block; touch-action: none; } .ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } .ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; } .ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; } .ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; } .ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; } .ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; } .ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; } .ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; } .ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px; } ================================================ FILE: themes/base/selectable.css ================================================ /*! * jQuery UI Selectable @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license */ .ui-selectable { touch-action: none; } .ui-selectable-helper { position: absolute; z-index: 100; border: 1px dotted black; } ================================================ FILE: themes/base/selectmenu.css ================================================ /*! * jQuery UI Selectmenu @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license * * https://api.jqueryui.com/selectmenu/#theming */ .ui-selectmenu-menu { padding: 0; margin: 0; position: absolute; top: 0; left: 0; display: none; } .ui-selectmenu-menu .ui-menu { overflow: auto; overflow-x: hidden; padding-bottom: 1px; } .ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup { font-size: 1em; font-weight: bold; line-height: 1.5; padding: 2px 0.4em; margin: 0.5em 0 0 0; height: auto; border: 0; } .ui-selectmenu-open { display: block; } .ui-selectmenu-text { display: block; margin-right: 20px; overflow: hidden; text-overflow: ellipsis; } .ui-selectmenu-button.ui-button { text-align: left; white-space: nowrap; width: 14em; } .ui-selectmenu-icon.ui-icon { float: right; margin-top: 0; } ================================================ FILE: themes/base/slider.css ================================================ /*! * jQuery UI Slider @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license * * https://api.jqueryui.com/slider/#theming */ .ui-slider { position: relative; text-align: left; } .ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: pointer; touch-action: none; } .ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; } .ui-slider-horizontal { height: .8em; } .ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; } .ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; } .ui-slider-horizontal .ui-slider-range-min { left: 0; } .ui-slider-horizontal .ui-slider-range-max { right: 0; } .ui-slider-vertical { width: .8em; height: 100px; } .ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; } .ui-slider-vertical .ui-slider-range { left: 0; width: 100%; } .ui-slider-vertical .ui-slider-range-min { bottom: 0; } .ui-slider-vertical .ui-slider-range-max { top: 0; } ================================================ FILE: themes/base/sortable.css ================================================ /*! * jQuery UI Sortable @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license */ .ui-sortable-handle { touch-action: none; } ================================================ FILE: themes/base/spinner.css ================================================ /*! * jQuery UI Spinner @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license * * https://api.jqueryui.com/spinner/#theming */ .ui-spinner { position: relative; display: inline-block; overflow: hidden; padding: 0; vertical-align: middle; } .ui-spinner-input { border: none; background: none; color: inherit; padding: .222em 0; margin: .2em 0; vertical-align: middle; margin-left: .4em; margin-right: 2em; } .ui-spinner-button { width: 1.6em; height: 50%; font-size: .5em; padding: 0; margin: 0; text-align: center; position: absolute; cursor: default; display: block; overflow: hidden; right: 0; } /* more specificity required here to override default borders */ .ui-spinner a.ui-spinner-button { border-top-style: none; border-bottom-style: none; border-right-style: none; } .ui-spinner-up { top: 0; } .ui-spinner-down { bottom: 0; } ================================================ FILE: themes/base/tabs.css ================================================ /*! * jQuery UI Tabs @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license * * https://api.jqueryui.com/tabs/#theming */ .ui-tabs { position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ padding: .2em; } .ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; } .ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 0; margin: 1px .2em 0 0; border-bottom-width: 0; padding: 0; white-space: nowrap; } .ui-tabs .ui-tabs-nav .ui-tabs-anchor { float: left; padding: .5em 1em; text-decoration: none; } .ui-tabs .ui-tabs-nav li.ui-tabs-active { margin-bottom: -1px; padding-bottom: 1px; } .ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor, .ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor, .ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor { cursor: text; } .ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor { cursor: pointer; } .ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; } ================================================ FILE: themes/base/theme.css ================================================ /*! * jQuery UI CSS Framework @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license * * https://api.jqueryui.com/category/theming/ * * To view and modify this theme, visit https://jqueryui.com/themeroller/ */ /* Component containers ----------------------------------*/ .ui-widget { font-family: Arial,Helvetica,sans-serif/*{ffDefault}*/; font-size: 1em/*{fsDefault}*/; } .ui-widget .ui-widget { font-size: 1em; } .ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Arial,Helvetica,sans-serif/*{ffDefault}*/; font-size: 1em; } .ui-widget.ui-widget-content { border: 1px solid #c5c5c5/*{borderColorDefault}*/; } .ui-widget-content { border: 1px solid #dddddd/*{borderColorContent}*/; background: #ffffff/*{bgColorContent}*/ /*{bgImgUrlContent}*/ /*{bgContentXPos}*/ /*{bgContentYPos}*/ /*{bgContentRepeat}*/; color: #333333/*{fcContent}*/; } .ui-widget-content a { color: #333333/*{fcContent}*/; } .ui-widget-header { border: 1px solid #dddddd/*{borderColorHeader}*/; background: #e9e9e9/*{bgColorHeader}*/ /*{bgImgUrlHeader}*/ /*{bgHeaderXPos}*/ /*{bgHeaderYPos}*/ /*{bgHeaderRepeat}*/; color: #333333/*{fcHeader}*/; font-weight: bold; } .ui-widget-header a { color: #333333/*{fcHeader}*/; } /* Interaction states ----------------------------------*/ .ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default, .ui-button, /* We use html here because we need a greater specificity to make sure disabled works properly when clicked or hovered */ html .ui-button.ui-state-disabled:hover, html .ui-button.ui-state-disabled:active { border: 1px solid #c5c5c5/*{borderColorDefault}*/; background: #f6f6f6/*{bgColorDefault}*/ /*{bgImgUrlDefault}*/ /*{bgDefaultXPos}*/ /*{bgDefaultYPos}*/ /*{bgDefaultRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #454545/*{fcDefault}*/; } .ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited, a.ui-button, a:link.ui-button, a:visited.ui-button, .ui-button { color: #454545/*{fcDefault}*/; text-decoration: none; } .ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus, .ui-button:hover, .ui-button:focus { border: 1px solid #cccccc/*{borderColorHover}*/; background: #ededed/*{bgColorHover}*/ /*{bgImgUrlHover}*/ /*{bgHoverXPos}*/ /*{bgHoverYPos}*/ /*{bgHoverRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #2b2b2b/*{fcHover}*/; } .ui-state-hover a, .ui-state-hover a:hover, .ui-state-hover a:link, .ui-state-hover a:visited, .ui-state-focus a, .ui-state-focus a:hover, .ui-state-focus a:link, .ui-state-focus a:visited, a.ui-button:hover, a.ui-button:focus { color: #2b2b2b/*{fcHover}*/; text-decoration: none; } .ui-visual-focus { box-shadow: 0 0 3px 1px rgb(94, 158, 214); } .ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active, a.ui-button:active, .ui-button:active, .ui-button.ui-state-active:hover { border: 1px solid #003eff/*{borderColorActive}*/; background: #007fff/*{bgColorActive}*/ /*{bgImgUrlActive}*/ /*{bgActiveXPos}*/ /*{bgActiveYPos}*/ /*{bgActiveRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #ffffff/*{fcActive}*/; } .ui-icon-background, .ui-state-active .ui-icon-background { border: #003eff/*{borderColorActive}*/; background-color: #ffffff/*{fcActive}*/; } .ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #ffffff/*{fcActive}*/; text-decoration: none; } /* Interaction Cues ----------------------------------*/ .ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight { border: 1px solid #dad55e/*{borderColorHighlight}*/; background: #fffa90/*{bgColorHighlight}*/ /*{bgImgUrlHighlight}*/ /*{bgHighlightXPos}*/ /*{bgHighlightYPos}*/ /*{bgHighlightRepeat}*/; color: #777620/*{fcHighlight}*/; } .ui-state-checked { border: 1px solid #dad55e/*{borderColorHighlight}*/; background: #fffa90/*{bgColorHighlight}*/; } .ui-state-highlight a, .ui-widget-content .ui-state-highlight a, .ui-widget-header .ui-state-highlight a { color: #777620/*{fcHighlight}*/; } .ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error { border: 1px solid #f1a899/*{borderColorError}*/; background: #fddfdf/*{bgColorError}*/ /*{bgImgUrlError}*/ /*{bgErrorXPos}*/ /*{bgErrorYPos}*/ /*{bgErrorRepeat}*/; color: #5f3f3f/*{fcError}*/; } .ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #5f3f3f/*{fcError}*/; } .ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #5f3f3f/*{fcError}*/; } .ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } .ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; font-weight: normal; } .ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; background-image: none; } /* Icons ----------------------------------*/ /* states and images */ .ui-icon { width: 16px; height: 16px; } .ui-icon, .ui-widget-content .ui-icon { background-image: url("images/ui-icons_444444_256x240.png")/*{iconsContent}*/; } .ui-widget-header .ui-icon { background-image: url("images/ui-icons_444444_256x240.png")/*{iconsHeader}*/; } .ui-state-hover .ui-icon, .ui-state-focus .ui-icon, .ui-button:hover .ui-icon, .ui-button:focus .ui-icon { background-image: url("images/ui-icons_555555_256x240.png")/*{iconsHover}*/; } .ui-state-active .ui-icon, .ui-button:active .ui-icon { background-image: url("images/ui-icons_ffffff_256x240.png")/*{iconsActive}*/; } .ui-state-highlight .ui-icon, .ui-button .ui-state-highlight.ui-icon { background-image: url("images/ui-icons_777620_256x240.png")/*{iconsHighlight}*/; } .ui-state-error .ui-icon, .ui-state-error-text .ui-icon { background-image: url("images/ui-icons_cc0000_256x240.png")/*{iconsError}*/; } .ui-button .ui-icon { background-image: url("images/ui-icons_777777_256x240.png")/*{iconsDefault}*/; } /* positioning */ /* Three classes needed to override `.ui-button:hover .ui-icon` */ .ui-icon-blank.ui-icon-blank.ui-icon-blank { background-image: none; } .ui-icon-caret-1-n { background-position: 0 0; } .ui-icon-caret-1-ne { background-position: -16px 0; } .ui-icon-caret-1-e { background-position: -32px 0; } .ui-icon-caret-1-se { background-position: -48px 0; } .ui-icon-caret-1-s { background-position: -65px 0; } .ui-icon-caret-1-sw { background-position: -80px 0; } .ui-icon-caret-1-w { background-position: -96px 0; } .ui-icon-caret-1-nw { background-position: -112px 0; } .ui-icon-caret-2-n-s { background-position: -128px 0; } .ui-icon-caret-2-e-w { background-position: -144px 0; } .ui-icon-triangle-1-n { background-position: 0 -16px; } .ui-icon-triangle-1-ne { background-position: -16px -16px; } .ui-icon-triangle-1-e { background-position: -32px -16px; } .ui-icon-triangle-1-se { background-position: -48px -16px; } .ui-icon-triangle-1-s { background-position: -65px -16px; } .ui-icon-triangle-1-sw { background-position: -80px -16px; } .ui-icon-triangle-1-w { background-position: -96px -16px; } .ui-icon-triangle-1-nw { background-position: -112px -16px; } .ui-icon-triangle-2-n-s { background-position: -128px -16px; } .ui-icon-triangle-2-e-w { background-position: -144px -16px; } .ui-icon-arrow-1-n { background-position: 0 -32px; } .ui-icon-arrow-1-ne { background-position: -16px -32px; } .ui-icon-arrow-1-e { background-position: -32px -32px; } .ui-icon-arrow-1-se { background-position: -48px -32px; } .ui-icon-arrow-1-s { background-position: -65px -32px; } .ui-icon-arrow-1-sw { background-position: -80px -32px; } .ui-icon-arrow-1-w { background-position: -96px -32px; } .ui-icon-arrow-1-nw { background-position: -112px -32px; } .ui-icon-arrow-2-n-s { background-position: -128px -32px; } .ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } .ui-icon-arrow-2-e-w { background-position: -160px -32px; } .ui-icon-arrow-2-se-nw { background-position: -176px -32px; } .ui-icon-arrowstop-1-n { background-position: -192px -32px; } .ui-icon-arrowstop-1-e { background-position: -208px -32px; } .ui-icon-arrowstop-1-s { background-position: -224px -32px; } .ui-icon-arrowstop-1-w { background-position: -240px -32px; } .ui-icon-arrowthick-1-n { background-position: 1px -48px; } .ui-icon-arrowthick-1-ne { background-position: -16px -48px; } .ui-icon-arrowthick-1-e { background-position: -32px -48px; } .ui-icon-arrowthick-1-se { background-position: -48px -48px; } .ui-icon-arrowthick-1-s { background-position: -64px -48px; } .ui-icon-arrowthick-1-sw { background-position: -80px -48px; } .ui-icon-arrowthick-1-w { background-position: -96px -48px; } .ui-icon-arrowthick-1-nw { background-position: -112px -48px; } .ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } .ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } .ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } .ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } .ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } .ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } .ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } .ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } .ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } .ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } .ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } .ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } .ui-icon-arrowreturn-1-w { background-position: -64px -64px; } .ui-icon-arrowreturn-1-n { background-position: -80px -64px; } .ui-icon-arrowreturn-1-e { background-position: -96px -64px; } .ui-icon-arrowreturn-1-s { background-position: -112px -64px; } .ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } .ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } .ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } .ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } .ui-icon-arrow-4 { background-position: 0 -80px; } .ui-icon-arrow-4-diag { background-position: -16px -80px; } .ui-icon-extlink { background-position: -32px -80px; } .ui-icon-newwin { background-position: -48px -80px; } .ui-icon-refresh { background-position: -64px -80px; } .ui-icon-shuffle { background-position: -80px -80px; } .ui-icon-transfer-e-w { background-position: -96px -80px; } .ui-icon-transferthick-e-w { background-position: -112px -80px; } .ui-icon-folder-collapsed { background-position: 0 -96px; } .ui-icon-folder-open { background-position: -16px -96px; } .ui-icon-document { background-position: -32px -96px; } .ui-icon-document-b { background-position: -48px -96px; } .ui-icon-note { background-position: -64px -96px; } .ui-icon-mail-closed { background-position: -80px -96px; } .ui-icon-mail-open { background-position: -96px -96px; } .ui-icon-suitcase { background-position: -112px -96px; } .ui-icon-comment { background-position: -128px -96px; } .ui-icon-person { background-position: -144px -96px; } .ui-icon-print { background-position: -160px -96px; } .ui-icon-trash { background-position: -176px -96px; } .ui-icon-locked { background-position: -192px -96px; } .ui-icon-unlocked { background-position: -208px -96px; } .ui-icon-bookmark { background-position: -224px -96px; } .ui-icon-tag { background-position: -240px -96px; } .ui-icon-home { background-position: 0 -112px; } .ui-icon-flag { background-position: -16px -112px; } .ui-icon-calendar { background-position: -32px -112px; } .ui-icon-cart { background-position: -48px -112px; } .ui-icon-pencil { background-position: -64px -112px; } .ui-icon-clock { background-position: -80px -112px; } .ui-icon-disk { background-position: -96px -112px; } .ui-icon-calculator { background-position: -112px -112px; } .ui-icon-zoomin { background-position: -128px -112px; } .ui-icon-zoomout { background-position: -144px -112px; } .ui-icon-search { background-position: -160px -112px; } .ui-icon-wrench { background-position: -176px -112px; } .ui-icon-gear { background-position: -192px -112px; } .ui-icon-heart { background-position: -208px -112px; } .ui-icon-star { background-position: -224px -112px; } .ui-icon-link { background-position: -240px -112px; } .ui-icon-cancel { background-position: 0 -128px; } .ui-icon-plus { background-position: -16px -128px; } .ui-icon-plusthick { background-position: -32px -128px; } .ui-icon-minus { background-position: -48px -128px; } .ui-icon-minusthick { background-position: -64px -128px; } .ui-icon-close { background-position: -80px -128px; } .ui-icon-closethick { background-position: -96px -128px; } .ui-icon-key { background-position: -112px -128px; } .ui-icon-lightbulb { background-position: -128px -128px; } .ui-icon-scissors { background-position: -144px -128px; } .ui-icon-clipboard { background-position: -160px -128px; } .ui-icon-copy { background-position: -176px -128px; } .ui-icon-contact { background-position: -192px -128px; } .ui-icon-image { background-position: -208px -128px; } .ui-icon-video { background-position: -224px -128px; } .ui-icon-script { background-position: -240px -128px; } .ui-icon-alert { background-position: 0 -144px; } .ui-icon-info { background-position: -16px -144px; } .ui-icon-notice { background-position: -32px -144px; } .ui-icon-help { background-position: -48px -144px; } .ui-icon-check { background-position: -64px -144px; } .ui-icon-bullet { background-position: -80px -144px; } .ui-icon-radio-on { background-position: -96px -144px; } .ui-icon-radio-off { background-position: -112px -144px; } .ui-icon-pin-w { background-position: -128px -144px; } .ui-icon-pin-s { background-position: -144px -144px; } .ui-icon-play { background-position: 0 -160px; } .ui-icon-pause { background-position: -16px -160px; } .ui-icon-seek-next { background-position: -32px -160px; } .ui-icon-seek-prev { background-position: -48px -160px; } .ui-icon-seek-end { background-position: -64px -160px; } .ui-icon-seek-start { background-position: -80px -160px; } /* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ .ui-icon-seek-first { background-position: -80px -160px; } .ui-icon-stop { background-position: -96px -160px; } .ui-icon-eject { background-position: -112px -160px; } .ui-icon-volume-off { background-position: -128px -160px; } .ui-icon-volume-on { background-position: -144px -160px; } .ui-icon-power { background-position: 0 -176px; } .ui-icon-signal-diag { background-position: -16px -176px; } .ui-icon-signal { background-position: -32px -176px; } .ui-icon-battery-0 { background-position: -48px -176px; } .ui-icon-battery-1 { background-position: -64px -176px; } .ui-icon-battery-2 { background-position: -80px -176px; } .ui-icon-battery-3 { background-position: -96px -176px; } .ui-icon-circle-plus { background-position: 0 -192px; } .ui-icon-circle-minus { background-position: -16px -192px; } .ui-icon-circle-close { background-position: -32px -192px; } .ui-icon-circle-triangle-e { background-position: -48px -192px; } .ui-icon-circle-triangle-s { background-position: -64px -192px; } .ui-icon-circle-triangle-w { background-position: -80px -192px; } .ui-icon-circle-triangle-n { background-position: -96px -192px; } .ui-icon-circle-arrow-e { background-position: -112px -192px; } .ui-icon-circle-arrow-s { background-position: -128px -192px; } .ui-icon-circle-arrow-w { background-position: -144px -192px; } .ui-icon-circle-arrow-n { background-position: -160px -192px; } .ui-icon-circle-zoomin { background-position: -176px -192px; } .ui-icon-circle-zoomout { background-position: -192px -192px; } .ui-icon-circle-check { background-position: -208px -192px; } .ui-icon-circlesmall-plus { background-position: 0 -208px; } .ui-icon-circlesmall-minus { background-position: -16px -208px; } .ui-icon-circlesmall-close { background-position: -32px -208px; } .ui-icon-squaresmall-plus { background-position: -48px -208px; } .ui-icon-squaresmall-minus { background-position: -64px -208px; } .ui-icon-squaresmall-close { background-position: -80px -208px; } .ui-icon-grip-dotted-vertical { background-position: 0 -224px; } .ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } .ui-icon-grip-solid-vertical { background-position: -32px -224px; } .ui-icon-grip-solid-horizontal { background-position: -48px -224px; } .ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } .ui-icon-grip-diagonal-se { background-position: -80px -224px; } /* Misc visuals ----------------------------------*/ /* Corner radius */ .ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { border-top-left-radius: 3px/*{cornerRadius}*/; } .ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { border-top-right-radius: 3px/*{cornerRadius}*/; } .ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { border-bottom-left-radius: 3px/*{cornerRadius}*/; } .ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { border-bottom-right-radius: 3px/*{cornerRadius}*/; } /* Overlays */ .ui-widget-overlay { background: #aaaaaa/*{bgColorOverlay}*/ /*{bgImgUrlOverlay}*/ /*{bgOverlayXPos}*/ /*{bgOverlayYPos}*/ /*{bgOverlayRepeat}*/; opacity: .3/*{opacityOverlay}*/; } .ui-widget-shadow { box-shadow: 0/*{offsetLeftShadow}*/ 0/*{offsetTopShadow}*/ 5px/*{thicknessShadow}*/ #666666/*{bgColorShadow}*/; } ================================================ FILE: themes/base/tooltip.css ================================================ /*! * jQuery UI Tooltip @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license * * https://api.jqueryui.com/tooltip/#theming */ .ui-tooltip { padding: 8px; position: absolute; z-index: 9999; max-width: 300px; } body .ui-tooltip { border-width: 2px; } ================================================ FILE: ui/data.js ================================================ /*! * jQuery UI :data @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license */ //>>label: :data Selector //>>group: Core //>>description: Selects elements which have data stored under the specified key. //>>docs: https://api.jqueryui.com/data-selector/ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "jquery", "./version" ], factory ); } else { // Browser globals factory( jQuery ); } } )( function( $ ) { "use strict"; return $.extend( $.expr.pseudos, { data: $.expr.createPseudo( function( dataName ) { return function( elem ) { return !!$.data( elem, dataName ); }; } ) } ); } ); ================================================ FILE: ui/disable-selection.js ================================================ /*! * jQuery UI Disable Selection @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license */ //>>label: disableSelection //>>group: Core //>>description: Disable selection of text content within the set of matched elements. //>>docs: https://api.jqueryui.com/disableSelection/ // This file is deprecated ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "jquery", "./version" ], factory ); } else { // Browser globals factory( jQuery ); } } )( function( $ ) { "use strict"; return $.fn.extend( { disableSelection: ( function() { var eventType = "onselectstart" in document.createElement( "div" ) ? "selectstart" : "mousedown"; return function() { return this.on( eventType + ".ui-disableSelection", function( event ) { event.preventDefault(); } ); }; } )(), enableSelection: function() { return this.off( ".ui-disableSelection" ); } } ); } ); ================================================ FILE: ui/effect.js ================================================ /*! * jQuery UI Effects @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license */ //>>label: Effects Core //>>group: Effects //>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects. //>>docs: https://api.jqueryui.com/category/effects-core/ //>>demos: https://jqueryui.com/effect/ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "jquery", "./jquery-var-for-color", "./vendor/jquery-color/jquery.color", "./version" ], factory ); } else { // Browser globals factory( jQuery ); } } )( function( $ ) { "use strict"; var dataSpace = "ui-effects-", dataSpaceStyle = "ui-effects-style", dataSpaceAnimated = "ui-effects-animated"; $.effects = { effect: {} }; /******************************************************************************/ /****************************** CLASS ANIMATIONS ******************************/ /******************************************************************************/ ( function() { var classAnimationActions = [ "add", "remove", "toggle" ], shorthandStyles = { border: 1, borderBottom: 1, borderColor: 1, borderLeft: 1, borderRight: 1, borderTop: 1, borderWidth: 1, margin: 1, padding: 1 }; $.each( [ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) { $.fx.step[ prop ] = function( fx ) { if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { jQuery.style( fx.elem, prop, fx.end ); fx.setAttr = true; } }; } ); function camelCase( string ) { return string.replace( /-([\da-z])/gi, function( all, letter ) { return letter.toUpperCase(); } ); } function getElementStyles( elem ) { var key, len, style = elem.ownerDocument.defaultView.getComputedStyle( elem ), styles = {}; len = style.length; while ( len-- ) { key = style[ len ]; if ( typeof style[ key ] === "string" ) { styles[ camelCase( key ) ] = style[ key ]; } } return styles; } function styleDifference( oldStyle, newStyle ) { var diff = {}, name, value; for ( name in newStyle ) { value = newStyle[ name ]; if ( oldStyle[ name ] !== value ) { if ( !shorthandStyles[ name ] ) { if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { diff[ name ] = value; } } } } return diff; } $.effects.animateClass = function( value, duration, easing, callback ) { var o = $.speed( duration, easing, callback ); return this.queue( function() { var animated = $( this ), baseClass = animated.attr( "class" ) || "", applyClassChange, allAnimations = o.children ? animated.find( "*" ).addBack() : animated; // Map the animated objects to store the original styles. allAnimations = allAnimations.map( function() { var el = $( this ); return { el: el, start: getElementStyles( this ) }; } ); // Apply class change applyClassChange = function() { $.each( classAnimationActions, function( i, action ) { if ( value[ action ] ) { animated[ action + "Class" ]( value[ action ] ); } } ); }; applyClassChange(); // Map all animated objects again - calculate new styles and diff allAnimations = allAnimations.map( function() { this.end = getElementStyles( this.el[ 0 ] ); this.diff = styleDifference( this.start, this.end ); return this; } ); // Apply original class animated.attr( "class", baseClass ); // Map all animated objects again - this time collecting a promise allAnimations = allAnimations.map( function() { var styleInfo = this, dfd = $.Deferred(), opts = $.extend( {}, o, { queue: false, complete: function() { dfd.resolve( styleInfo ); } } ); this.el.animate( this.diff, opts ); return dfd.promise(); } ); // Once all animations have completed: $.when.apply( $, allAnimations.get() ).done( function() { // Set the final class applyClassChange(); // For each animated element, // clear all css properties that were animated $.each( arguments, function() { var el = this.el; $.each( this.diff, function( key ) { el.css( key, "" ); } ); } ); // This is guarnteed to be there if you use jQuery.speed() // it also handles dequeuing the next anim... o.complete.call( animated[ 0 ] ); } ); } ); }; $.fn.extend( { addClass: ( function( orig ) { return function( classNames, speed, easing, callback ) { return speed ? $.effects.animateClass.call( this, { add: classNames }, speed, easing, callback ) : orig.apply( this, arguments ); }; } )( $.fn.addClass ), removeClass: ( function( orig ) { return function( classNames, speed, easing, callback ) { return arguments.length > 1 ? $.effects.animateClass.call( this, { remove: classNames }, speed, easing, callback ) : orig.apply( this, arguments ); }; } )( $.fn.removeClass ), toggleClass: ( function( orig ) { return function( classNames, force, speed, easing, callback ) { if ( typeof force === "boolean" || force === undefined ) { if ( !speed ) { // Without speed parameter return orig.apply( this, arguments ); } else { return $.effects.animateClass.call( this, ( force ? { add: classNames } : { remove: classNames } ), speed, easing, callback ); } } else { // Without force parameter return $.effects.animateClass.call( this, { toggle: classNames }, force, speed, easing ); } }; } )( $.fn.toggleClass ), switchClass: function( remove, add, speed, easing, callback ) { return $.effects.animateClass.call( this, { add: add, remove: remove }, speed, easing, callback ); } } ); } )(); /******************************************************************************/ /*********************************** EFFECTS **********************************/ /******************************************************************************/ ( function() { if ( $.expr && $.expr.pseudos && $.expr.pseudos.animated ) { $.expr.pseudos.animated = ( function( orig ) { return function( elem ) { return !!$( elem ).data( dataSpaceAnimated ) || orig( elem ); }; } )( $.expr.pseudos.animated ); } if ( $.uiBackCompat === true ) { $.extend( $.effects, { // Saves a set of properties in a data storage save: function( element, set ) { var i = 0, length = set.length; for ( ; i < length; i++ ) { if ( set[ i ] !== null ) { element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); } } }, // Restores a set of previously saved properties from a data storage restore: function( element, set ) { var val, i = 0, length = set.length; for ( ; i < length; i++ ) { if ( set[ i ] !== null ) { val = element.data( dataSpace + set[ i ] ); element.css( set[ i ], val ); } } }, setMode: function( el, mode ) { if ( mode === "toggle" ) { mode = el.is( ":hidden" ) ? "show" : "hide"; } return mode; }, // Wraps the element around a wrapper that copies position properties createWrapper: function( element ) { // If the element is already wrapped, return it if ( element.parent().is( ".ui-effects-wrapper" ) ) { return element.parent(); } // Wrap the element var props = { width: element.outerWidth( true ), height: element.outerHeight( true ), "float": element.css( "float" ) }, wrapper = $( "
    " ) .addClass( "ui-effects-wrapper" ) .css( { fontSize: "100%", background: "transparent", border: "none", margin: 0, padding: 0 } ), // Store the size in case width/height are defined in % - Fixes #5245 size = { width: element.width(), height: element.height() }, active = document.activeElement; // Support: Firefox // Firefox incorrectly exposes anonymous content // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 try { // eslint-disable-next-line no-unused-expressions active.id; } catch ( _e ) { active = document.body; } element.wrap( wrapper ); // Fixes #7595 - Elements lose focus when wrapped. if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { $( active ).trigger( "focus" ); } // Hotfix for jQuery 1.4 since some change in wrap() seems to actually // lose the reference to the wrapped element wrapper = element.parent(); // Transfer positioning properties to the wrapper if ( element.css( "position" ) === "static" ) { wrapper.css( { position: "relative" } ); element.css( { position: "relative" } ); } else { $.extend( props, { position: element.css( "position" ), zIndex: element.css( "z-index" ) } ); $.each( [ "top", "left", "bottom", "right" ], function( i, pos ) { props[ pos ] = element.css( pos ); if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { props[ pos ] = "auto"; } } ); element.css( { position: "relative", top: 0, left: 0, right: "auto", bottom: "auto" } ); } element.css( size ); return wrapper.css( props ).show(); }, removeWrapper: function( element ) { var active = document.activeElement; if ( element.parent().is( ".ui-effects-wrapper" ) ) { element.parent().replaceWith( element ); // Fixes #7595 - Elements lose focus when wrapped. if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { $( active ).trigger( "focus" ); } } return element; } } ); } $.extend( $.effects, { version: "@VERSION", define: function( name, mode, effect ) { if ( !effect ) { effect = mode; mode = "effect"; } $.effects.effect[ name ] = effect; $.effects.effect[ name ].mode = mode; return effect; }, scaledDimensions: function( element, percent, direction ) { if ( percent === 0 ) { return { height: 0, width: 0, outerHeight: 0, outerWidth: 0 }; } var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1, y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1; return { height: element.height() * y, width: element.width() * x, outerHeight: element.outerHeight() * y, outerWidth: element.outerWidth() * x }; }, clipToBox: function( animation ) { return { width: animation.clip.right - animation.clip.left, height: animation.clip.bottom - animation.clip.top, left: animation.clip.left, top: animation.clip.top }; }, // Injects recently queued functions to be first in line (after "inprogress") unshift: function( element, queueLength, count ) { var queue = element.queue(); if ( queueLength > 1 ) { queue.splice.apply( queue, [ 1, 0 ].concat( queue.splice( queueLength, count ) ) ); } element.dequeue(); }, saveStyle: function( element ) { element.data( dataSpaceStyle, element[ 0 ].style.cssText ); }, restoreStyle: function( element ) { element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || ""; element.removeData( dataSpaceStyle ); }, mode: function( element, mode ) { var hidden = element.is( ":hidden" ); if ( mode === "toggle" ) { mode = hidden ? "show" : "hide"; } if ( hidden ? mode === "hide" : mode === "show" ) { mode = "none"; } return mode; }, // Translates a [top,left] array into a baseline value getBaseline: function( origin, original ) { var y, x; switch ( origin[ 0 ] ) { case "top": y = 0; break; case "middle": y = 0.5; break; case "bottom": y = 1; break; default: y = origin[ 0 ] / original.height; } switch ( origin[ 1 ] ) { case "left": x = 0; break; case "center": x = 0.5; break; case "right": x = 1; break; default: x = origin[ 1 ] / original.width; } return { x: x, y: y }; }, // Creates a placeholder element so that the original element can be made absolute createPlaceholder: function( element ) { var placeholder, cssPosition = element.css( "position" ), position = element.position(); // Lock in margins first to account for form elements, which // will change margin if you explicitly set height // see: https://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380 // Support: Safari element.css( { marginTop: element.css( "marginTop" ), marginBottom: element.css( "marginBottom" ), marginLeft: element.css( "marginLeft" ), marginRight: element.css( "marginRight" ) } ) .outerWidth( element.outerWidth() ) .outerHeight( element.outerHeight() ); if ( /^(static|relative)/.test( cssPosition ) ) { cssPosition = "absolute"; placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( { // Convert inline to inline block to account for inline elements // that turn to inline block based on content (like img) display: /^(inline|ruby)/.test( element.css( "display" ) ) ? "inline-block" : "block", visibility: "hidden", // Margins need to be set to account for margin collapse marginTop: element.css( "marginTop" ), marginBottom: element.css( "marginBottom" ), marginLeft: element.css( "marginLeft" ), marginRight: element.css( "marginRight" ), "float": element.css( "float" ) } ) .outerWidth( element.outerWidth() ) .outerHeight( element.outerHeight() ) .addClass( "ui-effects-placeholder" ); element.data( dataSpace + "placeholder", placeholder ); } element.css( { position: cssPosition, left: position.left, top: position.top } ); return placeholder; }, removePlaceholder: function( element ) { var dataKey = dataSpace + "placeholder", placeholder = element.data( dataKey ); if ( placeholder ) { placeholder.remove(); element.removeData( dataKey ); } }, // Removes a placeholder if it exists and restores // properties that were modified during placeholder creation cleanUp: function( element ) { $.effects.restoreStyle( element ); $.effects.removePlaceholder( element ); }, setTransition: function( element, list, factor, value ) { value = value || {}; $.each( list, function( i, x ) { var unit = element.cssUnit( x ); if ( unit[ 0 ] > 0 ) { value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; } } ); return value; } } ); // Return an effect options object for the given parameters: function _normalizeArguments( effect, options, speed, callback ) { // Allow passing all options as the first parameter if ( $.isPlainObject( effect ) ) { options = effect; effect = effect.effect; } // Convert to an object effect = { effect: effect }; // Catch (effect, null, ...) if ( options == null ) { options = {}; } // Catch (effect, callback) if ( typeof options === "function" ) { callback = options; speed = null; options = {}; } // Catch (effect, speed, ?) if ( typeof options === "number" || $.fx.speeds[ options ] ) { callback = speed; speed = options; options = {}; } // Catch (effect, options, callback) if ( typeof speed === "function" ) { callback = speed; speed = null; } // Add options to effect if ( options ) { $.extend( effect, options ); } speed = speed || options.duration; effect.duration = $.fx.off ? 0 : typeof speed === "number" ? speed : speed in $.fx.speeds ? $.fx.speeds[ speed ] : $.fx.speeds._default; effect.complete = callback || options.complete; return effect; } function standardAnimationOption( option ) { // Valid standard speeds (nothing, number, named speed) if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) { return true; } // Invalid strings - treat as "normal" speed if ( typeof option === "string" && !$.effects.effect[ option ] ) { return true; } // Complete callback if ( typeof option === "function" ) { return true; } // Options hash (but not naming an effect) if ( typeof option === "object" && !option.effect ) { return true; } // Didn't match any standard API return false; } $.fn.extend( { effect: function( /* effect, options, speed, callback */ ) { var args = _normalizeArguments.apply( this, arguments ), effectMethod = $.effects.effect[ args.effect ], defaultMode = effectMethod.mode, queue = args.queue, queueName = queue || "fx", complete = args.complete, mode = args.mode, modes = [], prefilter = function( next ) { var el = $( this ), normalizedMode = $.effects.mode( el, mode ) || defaultMode; // Sentinel for duck-punching the :animated pseudo-selector el.data( dataSpaceAnimated, true ); // Save effect mode for later use, // we can't just call $.effects.mode again later, // as the .show() below destroys the initial state modes.push( normalizedMode ); // See $.uiBackCompat inside of run() for removal of defaultMode in 1.14 if ( defaultMode && ( normalizedMode === "show" || ( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) { el.show(); } if ( !defaultMode || normalizedMode !== "none" ) { $.effects.saveStyle( el ); } if ( typeof next === "function" ) { next(); } }; if ( $.fx.off || !effectMethod ) { // Delegate to the original method (e.g., .show()) if possible if ( mode ) { return this[ mode ]( args.duration, complete ); } else { return this.each( function() { if ( complete ) { complete.call( this ); } } ); } } function run( next ) { var elem = $( this ); function cleanup() { elem.removeData( dataSpaceAnimated ); $.effects.cleanUp( elem ); if ( args.mode === "hide" ) { elem.hide(); } done(); } function done() { if ( typeof complete === "function" ) { complete.call( elem[ 0 ] ); } if ( typeof next === "function" ) { next(); } } // Override mode option on a per element basis, // as toggle can be either show or hide depending on element state args.mode = modes.shift(); if ( $.uiBackCompat === true && !defaultMode ) { if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { // Call the core method to track "olddisplay" properly elem[ mode ](); done(); } else { effectMethod.call( elem[ 0 ], args, done ); } } else { if ( args.mode === "none" ) { // Call the core method to track "olddisplay" properly elem[ mode ](); done(); } else { effectMethod.call( elem[ 0 ], args, cleanup ); } } } // Run prefilter on all elements first to ensure that // any showing or hiding happens before placeholder creation, // which ensures that any layout changes are correctly captured. return queue === false ? this.each( prefilter ).each( run ) : this.queue( queueName, prefilter ).queue( queueName, run ); }, show: ( function( orig ) { return function( option ) { if ( standardAnimationOption( option ) ) { return orig.apply( this, arguments ); } else { var args = _normalizeArguments.apply( this, arguments ); args.mode = "show"; return this.effect.call( this, args ); } }; } )( $.fn.show ), hide: ( function( orig ) { return function( option ) { if ( standardAnimationOption( option ) ) { return orig.apply( this, arguments ); } else { var args = _normalizeArguments.apply( this, arguments ); args.mode = "hide"; return this.effect.call( this, args ); } }; } )( $.fn.hide ), toggle: ( function( orig ) { return function( option ) { if ( standardAnimationOption( option ) || typeof option === "boolean" ) { return orig.apply( this, arguments ); } else { var args = _normalizeArguments.apply( this, arguments ); args.mode = "toggle"; return this.effect.call( this, args ); } }; } )( $.fn.toggle ), cssUnit: function( key ) { var style = this.css( key ), val = []; $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { if ( style.indexOf( unit ) > 0 ) { val = [ parseFloat( style ), unit ]; } } ); return val; }, cssClip: function( clipObj ) { if ( clipObj ) { return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " + clipObj.bottom + "px " + clipObj.left + "px)" ); } return parseClip( this.css( "clip" ), this ); }, transfer: function( options, done ) { var element = $( this ), target = $( options.to ), targetFixed = target.css( "position" ) === "fixed", body = $( "body" ), fixTop = targetFixed ? body.scrollTop() : 0, fixLeft = targetFixed ? body.scrollLeft() : 0, endPosition = target.offset(), animation = { top: endPosition.top - fixTop, left: endPosition.left - fixLeft, height: target.innerHeight(), width: target.innerWidth() }, startPosition = element.offset(), transfer = $( "
    " ); transfer .appendTo( "body" ) .addClass( options.className ) .css( { top: startPosition.top - fixTop, left: startPosition.left - fixLeft, height: element.innerHeight(), width: element.innerWidth(), position: targetFixed ? "fixed" : "absolute" } ) .animate( animation, options.duration, options.easing, function() { transfer.remove(); if ( typeof done === "function" ) { done(); } } ); } } ); function parseClip( str, element ) { var outerWidth = element.outerWidth(), outerHeight = element.outerHeight(), clipRegex = /^rect\((-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto)\)$/, values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ]; return { top: parseFloat( values[ 1 ] ) || 0, right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ), bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ), left: parseFloat( values[ 4 ] ) || 0 }; } $.fx.step.clip = function( fx ) { if ( !fx.clipInit ) { fx.start = $( fx.elem ).cssClip(); if ( typeof fx.end === "string" ) { fx.end = parseClip( fx.end, fx.elem ); } fx.clipInit = true; } $( fx.elem ).cssClip( { top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top, right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right, bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom, left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left } ); }; } )(); /******************************************************************************/ /*********************************** EASING ***********************************/ /******************************************************************************/ ( function() { // Based on easing equations from Robert Penner (http://robertpenner.com/easing) var baseEasings = {}; $.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { baseEasings[ name ] = function( p ) { return Math.pow( p, i + 2 ); }; } ); $.extend( baseEasings, { Sine: function( p ) { return 1 - Math.cos( p * Math.PI / 2 ); }, Circ: function( p ) { return 1 - Math.sqrt( 1 - p * p ); }, Elastic: function( p ) { return p === 0 || p === 1 ? p : -Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 ); }, Back: function( p ) { return p * p * ( 3 * p - 2 ); }, Bounce: function( p ) { var pow2, bounce = 4; while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); } } ); $.each( baseEasings, function( name, easeIn ) { $.easing[ "easeIn" + name ] = easeIn; $.easing[ "easeOut" + name ] = function( p ) { return 1 - easeIn( 1 - p ); }; $.easing[ "easeInOut" + name ] = function( p ) { return p < 0.5 ? easeIn( p * 2 ) / 2 : 1 - easeIn( p * -2 + 2 ) / 2; }; } ); } )(); return $.effects; } ); ================================================ FILE: ui/effects/effect-blind.js ================================================ /*! * jQuery UI Effects Blind @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license */ //>>label: Blind Effect //>>group: Effects //>>description: Blinds the element. //>>docs: https://api.jqueryui.com/blind-effect/ //>>demos: https://jqueryui.com/effect/ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "jquery", "../version", "../effect" ], factory ); } else { // Browser globals factory( jQuery ); } } )( function( $ ) { "use strict"; return $.effects.define( "blind", "hide", function( options, done ) { var map = { up: [ "bottom", "top" ], vertical: [ "bottom", "top" ], down: [ "top", "bottom" ], left: [ "right", "left" ], horizontal: [ "right", "left" ], right: [ "left", "right" ] }, element = $( this ), direction = options.direction || "up", start = element.cssClip(), animate = { clip: $.extend( {}, start ) }, placeholder = $.effects.createPlaceholder( element ); animate.clip[ map[ direction ][ 0 ] ] = animate.clip[ map[ direction ][ 1 ] ]; if ( options.mode === "show" ) { element.cssClip( animate.clip ); if ( placeholder ) { placeholder.css( $.effects.clipToBox( animate ) ); } animate.clip = start; } if ( placeholder ) { placeholder.animate( $.effects.clipToBox( animate ), options.duration, options.easing ); } element.animate( animate, { queue: false, duration: options.duration, easing: options.easing, complete: done } ); } ); } ); ================================================ FILE: ui/effects/effect-bounce.js ================================================ /*! * jQuery UI Effects Bounce @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license */ //>>label: Bounce Effect //>>group: Effects //>>description: Bounces an element horizontally or vertically n times. //>>docs: https://api.jqueryui.com/bounce-effect/ //>>demos: https://jqueryui.com/effect/ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "jquery", "../version", "../effect" ], factory ); } else { // Browser globals factory( jQuery ); } } )( function( $ ) { "use strict"; return $.effects.define( "bounce", function( options, done ) { var upAnim, downAnim, refValue, element = $( this ), // Defaults: mode = options.mode, hide = mode === "hide", show = mode === "show", direction = options.direction || "up", distance = options.distance, times = options.times || 5, // Number of internal animations anims = times * 2 + ( show || hide ? 1 : 0 ), speed = options.duration / anims, easing = options.easing, // Utility: ref = ( direction === "up" || direction === "down" ) ? "top" : "left", motion = ( direction === "up" || direction === "left" ), i = 0, queuelen = element.queue().length; $.effects.createPlaceholder( element ); refValue = element.css( ref ); // Default distance for the BIGGEST bounce is the outer Distance / 3 if ( !distance ) { distance = element[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; } if ( show ) { downAnim = { opacity: 1 }; downAnim[ ref ] = refValue; // If we are showing, force opacity 0 and set the initial position // then do the "first" animation element .css( "opacity", 0 ) .css( ref, motion ? -distance * 2 : distance * 2 ) .animate( downAnim, speed, easing ); } // Start at the smallest distance if we are hiding if ( hide ) { distance = distance / Math.pow( 2, times - 1 ); } downAnim = {}; downAnim[ ref ] = refValue; // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here for ( ; i < times; i++ ) { upAnim = {}; upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; element .animate( upAnim, speed, easing ) .animate( downAnim, speed, easing ); distance = hide ? distance * 2 : distance / 2; } // Last Bounce when Hiding if ( hide ) { upAnim = { opacity: 0 }; upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; element.animate( upAnim, speed, easing ); } element.queue( done ); $.effects.unshift( element, queuelen, anims + 1 ); } ); } ); ================================================ FILE: ui/effects/effect-clip.js ================================================ /*! * jQuery UI Effects Clip @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license */ //>>label: Clip Effect //>>group: Effects //>>description: Clips the element on and off like an old TV. //>>docs: https://api.jqueryui.com/clip-effect/ //>>demos: https://jqueryui.com/effect/ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "jquery", "../version", "../effect" ], factory ); } else { // Browser globals factory( jQuery ); } } )( function( $ ) { "use strict"; return $.effects.define( "clip", "hide", function( options, done ) { var start, animate = {}, element = $( this ), direction = options.direction || "vertical", both = direction === "both", horizontal = both || direction === "horizontal", vertical = both || direction === "vertical"; start = element.cssClip(); animate.clip = { top: vertical ? ( start.bottom - start.top ) / 2 : start.top, right: horizontal ? ( start.right - start.left ) / 2 : start.right, bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom, left: horizontal ? ( start.right - start.left ) / 2 : start.left }; $.effects.createPlaceholder( element ); if ( options.mode === "show" ) { element.cssClip( animate.clip ); animate.clip = start; } element.animate( animate, { queue: false, duration: options.duration, easing: options.easing, complete: done } ); } ); } ); ================================================ FILE: ui/effects/effect-drop.js ================================================ /*! * jQuery UI Effects Drop @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license */ //>>label: Drop Effect //>>group: Effects //>>description: Moves an element in one direction and hides it at the same time. //>>docs: https://api.jqueryui.com/drop-effect/ //>>demos: https://jqueryui.com/effect/ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "jquery", "../version", "../effect" ], factory ); } else { // Browser globals factory( jQuery ); } } )( function( $ ) { "use strict"; return $.effects.define( "drop", "hide", function( options, done ) { var distance, element = $( this ), mode = options.mode, show = mode === "show", direction = options.direction || "left", ref = ( direction === "up" || direction === "down" ) ? "top" : "left", motion = ( direction === "up" || direction === "left" ) ? "-=" : "+=", oppositeMotion = ( motion === "+=" ) ? "-=" : "+=", animation = { opacity: 0 }; $.effects.createPlaceholder( element ); distance = options.distance || element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2; animation[ ref ] = motion + distance; if ( show ) { element.css( animation ); animation[ ref ] = oppositeMotion + distance; animation.opacity = 1; } // Animate element.animate( animation, { queue: false, duration: options.duration, easing: options.easing, complete: done } ); } ); } ); ================================================ FILE: ui/effects/effect-explode.js ================================================ /*! * jQuery UI Effects Explode @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license */ //>>label: Explode Effect //>>group: Effects //>>description: Explodes an element in all directions into n pieces. Implodes an element to its original wholeness. //>>docs: https://api.jqueryui.com/explode-effect/ //>>demos: https://jqueryui.com/effect/ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "jquery", "../version", "../effect" ], factory ); } else { // Browser globals factory( jQuery ); } } )( function( $ ) { "use strict"; return $.effects.define( "explode", "hide", function( options, done ) { var i, j, left, top, mx, my, rows = options.pieces ? Math.round( Math.sqrt( options.pieces ) ) : 3, cells = rows, element = $( this ), mode = options.mode, show = mode === "show", // Show and then visibility:hidden the element before calculating offset offset = element.show().css( "visibility", "hidden" ).offset(), // Width and height of a piece width = Math.ceil( element.outerWidth() / cells ), height = Math.ceil( element.outerHeight() / rows ), pieces = []; // Children animate complete: function childComplete() { pieces.push( this ); if ( pieces.length === rows * cells ) { animComplete(); } } // Clone the element for each row and cell. for ( i = 0; i < rows; i++ ) { // ===> top = offset.top + i * height; my = i - ( rows - 1 ) / 2; for ( j = 0; j < cells; j++ ) { // ||| left = offset.left + j * width; mx = j - ( cells - 1 ) / 2; // Create a clone of the now hidden main element that will be absolute positioned // within a wrapper div off the -left and -top equal to size of our pieces element .clone() .appendTo( "body" ) .wrap( "
    " ) .css( { position: "absolute", visibility: "visible", left: -j * width, top: -i * height } ) // Select the wrapper - make it overflow: hidden and absolute positioned based on // where the original was located +left and +top equal to the size of pieces .parent() .addClass( "ui-effects-explode" ) .css( { position: "absolute", overflow: "hidden", width: width, height: height, left: left + ( show ? mx * width : 0 ), top: top + ( show ? my * height : 0 ), opacity: show ? 0 : 1 } ) .animate( { left: left + ( show ? 0 : mx * width ), top: top + ( show ? 0 : my * height ), opacity: show ? 1 : 0 }, options.duration || 500, options.easing, childComplete ); } } function animComplete() { element.css( { visibility: "visible" } ); $( pieces ).remove(); done(); } } ); } ); ================================================ FILE: ui/effects/effect-fade.js ================================================ /*! * jQuery UI Effects Fade @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license */ //>>label: Fade Effect //>>group: Effects //>>description: Fades the element. //>>docs: https://api.jqueryui.com/fade-effect/ //>>demos: https://jqueryui.com/effect/ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "jquery", "../version", "../effect" ], factory ); } else { // Browser globals factory( jQuery ); } } )( function( $ ) { "use strict"; return $.effects.define( "fade", "toggle", function( options, done ) { var show = options.mode === "show"; $( this ) .css( "opacity", show ? 0 : 1 ) .animate( { opacity: show ? 1 : 0 }, { queue: false, duration: options.duration, easing: options.easing, complete: done } ); } ); } ); ================================================ FILE: ui/effects/effect-fold.js ================================================ /*! * jQuery UI Effects Fold @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license */ //>>label: Fold Effect //>>group: Effects //>>description: Folds an element first horizontally and then vertically. //>>docs: https://api.jqueryui.com/fold-effect/ //>>demos: https://jqueryui.com/effect/ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "jquery", "../version", "../effect" ], factory ); } else { // Browser globals factory( jQuery ); } } )( function( $ ) { "use strict"; return $.effects.define( "fold", "hide", function( options, done ) { // Create element var element = $( this ), mode = options.mode, show = mode === "show", hide = mode === "hide", size = options.size || 15, percent = /([0-9]+)%/.exec( size ), horizFirst = !!options.horizFirst, ref = horizFirst ? [ "right", "bottom" ] : [ "bottom", "right" ], duration = options.duration / 2, placeholder = $.effects.createPlaceholder( element ), start = element.cssClip(), animation1 = { clip: $.extend( {}, start ) }, animation2 = { clip: $.extend( {}, start ) }, distance = [ start[ ref[ 0 ] ], start[ ref[ 1 ] ] ], queuelen = element.queue().length; if ( percent ) { size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; } animation1.clip[ ref[ 0 ] ] = size; animation2.clip[ ref[ 0 ] ] = size; animation2.clip[ ref[ 1 ] ] = 0; if ( show ) { element.cssClip( animation2.clip ); if ( placeholder ) { placeholder.css( $.effects.clipToBox( animation2 ) ); } animation2.clip = start; } // Animate element .queue( function( next ) { if ( placeholder ) { placeholder .animate( $.effects.clipToBox( animation1 ), duration, options.easing ) .animate( $.effects.clipToBox( animation2 ), duration, options.easing ); } next(); } ) .animate( animation1, duration, options.easing ) .animate( animation2, duration, options.easing ) .queue( done ); $.effects.unshift( element, queuelen, 4 ); } ); } ); ================================================ FILE: ui/effects/effect-highlight.js ================================================ /*! * jQuery UI Effects Highlight @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license */ //>>label: Highlight Effect //>>group: Effects //>>description: Highlights the background of an element in a defined color for a custom duration. //>>docs: https://api.jqueryui.com/highlight-effect/ //>>demos: https://jqueryui.com/effect/ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "jquery", "../version", "../effect" ], factory ); } else { // Browser globals factory( jQuery ); } } )( function( $ ) { "use strict"; return $.effects.define( "highlight", "show", function( options, done ) { var element = $( this ), animation = { backgroundColor: element.css( "backgroundColor" ) }; if ( options.mode === "hide" ) { animation.opacity = 0; } $.effects.saveStyle( element ); element .css( { backgroundImage: "none", backgroundColor: options.color || "#ffff99" } ) .animate( animation, { queue: false, duration: options.duration, easing: options.easing, complete: done } ); } ); } ); ================================================ FILE: ui/effects/effect-puff.js ================================================ /*! * jQuery UI Effects Puff @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license */ //>>label: Puff Effect //>>group: Effects //>>description: Creates a puff effect by scaling the element up and hiding it at the same time. //>>docs: https://api.jqueryui.com/puff-effect/ //>>demos: https://jqueryui.com/effect/ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "jquery", "../version", "../effect", "./effect-scale" ], factory ); } else { // Browser globals factory( jQuery ); } } )( function( $ ) { "use strict"; return $.effects.define( "puff", "hide", function( options, done ) { var newOptions = $.extend( true, {}, options, { fade: true, percent: parseInt( options.percent, 10 ) || 150 } ); $.effects.effect.scale.call( this, newOptions, done ); } ); } ); ================================================ FILE: ui/effects/effect-pulsate.js ================================================ /*! * jQuery UI Effects Pulsate @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license */ //>>label: Pulsate Effect //>>group: Effects //>>description: Pulsates an element n times by changing the opacity to zero and back. //>>docs: https://api.jqueryui.com/pulsate-effect/ //>>demos: https://jqueryui.com/effect/ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "jquery", "../version", "../effect" ], factory ); } else { // Browser globals factory( jQuery ); } } )( function( $ ) { "use strict"; return $.effects.define( "pulsate", "show", function( options, done ) { var element = $( this ), mode = options.mode, show = mode === "show", hide = mode === "hide", showhide = show || hide, // Showing or hiding leaves off the "last" animation anims = ( ( options.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), duration = options.duration / anims, animateTo = 0, i = 1, queuelen = element.queue().length; if ( show || !element.is( ":visible" ) ) { element.css( "opacity", 0 ).show(); animateTo = 1; } // Anims - 1 opacity "toggles" for ( ; i < anims; i++ ) { element.animate( { opacity: animateTo }, duration, options.easing ); animateTo = 1 - animateTo; } element.animate( { opacity: animateTo }, duration, options.easing ); element.queue( done ); $.effects.unshift( element, queuelen, anims + 1 ); } ); } ); ================================================ FILE: ui/effects/effect-scale.js ================================================ /*! * jQuery UI Effects Scale @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license */ //>>label: Scale Effect //>>group: Effects //>>description: Grows or shrinks an element and its content. //>>docs: https://api.jqueryui.com/scale-effect/ //>>demos: https://jqueryui.com/effect/ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "jquery", "../version", "../effect", "./effect-size" ], factory ); } else { // Browser globals factory( jQuery ); } } )( function( $ ) { "use strict"; return $.effects.define( "scale", function( options, done ) { // Create element var el = $( this ), mode = options.mode, percent = parseInt( options.percent, 10 ) || ( parseInt( options.percent, 10 ) === 0 ? 0 : ( mode !== "effect" ? 0 : 100 ) ), newOptions = $.extend( true, { from: $.effects.scaledDimensions( el ), to: $.effects.scaledDimensions( el, percent, options.direction || "both" ), origin: options.origin || [ "middle", "center" ] }, options ); // Fade option to support puff if ( options.fade ) { newOptions.from.opacity = 1; newOptions.to.opacity = 0; } $.effects.effect.size.call( this, newOptions, done ); } ); } ); ================================================ FILE: ui/effects/effect-shake.js ================================================ /*! * jQuery UI Effects Shake @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license */ //>>label: Shake Effect //>>group: Effects //>>description: Shakes an element horizontally or vertically n times. //>>docs: https://api.jqueryui.com/shake-effect/ //>>demos: https://jqueryui.com/effect/ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "jquery", "../version", "../effect" ], factory ); } else { // Browser globals factory( jQuery ); } } )( function( $ ) { "use strict"; return $.effects.define( "shake", function( options, done ) { var i = 1, element = $( this ), direction = options.direction || "left", distance = options.distance || 20, times = options.times || 3, anims = times * 2 + 1, speed = Math.round( options.duration / anims ), ref = ( direction === "up" || direction === "down" ) ? "top" : "left", positiveMotion = ( direction === "up" || direction === "left" ), animation = {}, animation1 = {}, animation2 = {}, queuelen = element.queue().length; $.effects.createPlaceholder( element ); // Animation animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; // Animate element.animate( animation, speed, options.easing ); // Shakes for ( ; i < times; i++ ) { element .animate( animation1, speed, options.easing ) .animate( animation2, speed, options.easing ); } element .animate( animation1, speed, options.easing ) .animate( animation, speed / 2, options.easing ) .queue( done ); $.effects.unshift( element, queuelen, anims + 1 ); } ); } ); ================================================ FILE: ui/effects/effect-size.js ================================================ /*! * jQuery UI Effects Size @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license */ //>>label: Size Effect //>>group: Effects //>>description: Resize an element to a specified width and height. //>>docs: https://api.jqueryui.com/size-effect/ //>>demos: https://jqueryui.com/effect/ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "jquery", "../version", "../effect" ], factory ); } else { // Browser globals factory( jQuery ); } } )( function( $ ) { "use strict"; return $.effects.define( "size", function( options, done ) { // Create element var baseline, factor, temp, element = $( this ), // Copy for children cProps = [ "fontSize" ], vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], // Set options mode = options.mode, restore = mode !== "effect", scale = options.scale || "both", origin = options.origin || [ "middle", "center" ], position = element.css( "position" ), pos = element.position(), original = $.effects.scaledDimensions( element ), from = options.from || original, to = options.to || $.effects.scaledDimensions( element, 0 ); $.effects.createPlaceholder( element ); if ( mode === "show" ) { temp = from; from = to; to = temp; } // Set scaling factor factor = { from: { y: from.height / original.height, x: from.width / original.width }, to: { y: to.height / original.height, x: to.width / original.width } }; // Scale the css box if ( scale === "box" || scale === "both" ) { // Vertical props scaling if ( factor.from.y !== factor.to.y ) { from = $.effects.setTransition( element, vProps, factor.from.y, from ); to = $.effects.setTransition( element, vProps, factor.to.y, to ); } // Horizontal props scaling if ( factor.from.x !== factor.to.x ) { from = $.effects.setTransition( element, hProps, factor.from.x, from ); to = $.effects.setTransition( element, hProps, factor.to.x, to ); } } // Scale the content if ( scale === "content" || scale === "both" ) { // Vertical props scaling if ( factor.from.y !== factor.to.y ) { from = $.effects.setTransition( element, cProps, factor.from.y, from ); to = $.effects.setTransition( element, cProps, factor.to.y, to ); } } // Adjust the position properties based on the provided origin points if ( origin ) { baseline = $.effects.getBaseline( origin, original ); from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top; from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left; to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top; to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left; } delete from.outerHeight; delete from.outerWidth; element.css( from ); // Animate the children if desired if ( scale === "content" || scale === "both" ) { vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps ); hProps = hProps.concat( [ "marginLeft", "marginRight" ] ); // Only animate children with width attributes specified // TODO: is this right? should we include anything with css width specified as well element.find( "*[width]" ).each( function() { var child = $( this ), childOriginal = $.effects.scaledDimensions( child ), childFrom = { height: childOriginal.height * factor.from.y, width: childOriginal.width * factor.from.x, outerHeight: childOriginal.outerHeight * factor.from.y, outerWidth: childOriginal.outerWidth * factor.from.x }, childTo = { height: childOriginal.height * factor.to.y, width: childOriginal.width * factor.to.x, outerHeight: childOriginal.height * factor.to.y, outerWidth: childOriginal.width * factor.to.x }; // Vertical props scaling if ( factor.from.y !== factor.to.y ) { childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom ); childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo ); } // Horizontal props scaling if ( factor.from.x !== factor.to.x ) { childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom ); childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo ); } if ( restore ) { $.effects.saveStyle( child ); } // Animate children child.css( childFrom ); child.animate( childTo, options.duration, options.easing, function() { // Restore children if ( restore ) { $.effects.restoreStyle( child ); } } ); } ); } // Animate element.animate( to, { queue: false, duration: options.duration, easing: options.easing, complete: function() { var offset = element.offset(); if ( to.opacity === 0 ) { element.css( "opacity", from.opacity ); } if ( !restore ) { element .css( "position", position === "static" ? "relative" : position ) .offset( offset ); // Need to save style here so that automatic style restoration // doesn't restore to the original styles from before the animation. $.effects.saveStyle( element ); } done(); } } ); } ); } ); ================================================ FILE: ui/effects/effect-slide.js ================================================ /*! * jQuery UI Effects Slide @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license */ //>>label: Slide Effect //>>group: Effects //>>description: Slides an element in and out of the viewport. //>>docs: https://api.jqueryui.com/slide-effect/ //>>demos: https://jqueryui.com/effect/ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "jquery", "../version", "../effect" ], factory ); } else { // Browser globals factory( jQuery ); } } )( function( $ ) { "use strict"; return $.effects.define( "slide", "show", function( options, done ) { var startClip, startRef, element = $( this ), map = { up: [ "bottom", "top" ], down: [ "top", "bottom" ], left: [ "right", "left" ], right: [ "left", "right" ] }, mode = options.mode, direction = options.direction || "left", ref = ( direction === "up" || direction === "down" ) ? "top" : "left", positiveMotion = ( direction === "up" || direction === "left" ), distance = options.distance || element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ), animation = {}; $.effects.createPlaceholder( element ); startClip = element.cssClip(); startRef = element.position()[ ref ]; // Define hide animation animation[ ref ] = ( positiveMotion ? -1 : 1 ) * distance + startRef; animation.clip = element.cssClip(); animation.clip[ map[ direction ][ 1 ] ] = animation.clip[ map[ direction ][ 0 ] ]; // Reverse the animation if we're showing if ( mode === "show" ) { element.cssClip( animation.clip ); element.css( ref, animation[ ref ] ); animation.clip = startClip; animation[ ref ] = startRef; } // Actually animate element.animate( animation, { queue: false, duration: options.duration, easing: options.easing, complete: done } ); } ); } ); ================================================ FILE: ui/effects/effect-transfer.js ================================================ /*! * jQuery UI Effects Transfer @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license */ //>>label: Transfer Effect //>>group: Effects //>>description: Displays a transfer effect from one element to another. //>>docs: https://api.jqueryui.com/transfer-effect/ //>>demos: https://jqueryui.com/effect/ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "jquery", "../version", "../effect" ], factory ); } else { // Browser globals factory( jQuery ); } } )( function( $ ) { "use strict"; var effect; if ( $.uiBackCompat === true ) { effect = $.effects.define( "transfer", function( options, done ) { $( this ).transfer( options, done ); } ); } return effect; } ); ================================================ FILE: ui/focusable.js ================================================ /*! * jQuery UI Focusable @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license */ //>>label: :focusable Selector //>>group: Core //>>description: Selects elements which can be focused. //>>docs: https://api.jqueryui.com/focusable-selector/ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "jquery", "./version" ], factory ); } else { // Browser globals factory( jQuery ); } } )( function( $ ) { "use strict"; // Selectors $.ui.focusable = function( element, hasTabindex ) { var map, mapName, img, focusableIfVisible, fieldset, 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 + "']" ); return img.length > 0 && img.is( ":visible" ); } if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) { focusableIfVisible = !element.disabled; if ( focusableIfVisible ) { // Form controls within a disabled fieldset are disabled. // However, controls within the fieldset's legend do not get disabled. // Since controls generally aren't placed inside legends, we skip // this portion of the check. fieldset = $( element ).closest( "fieldset" )[ 0 ]; if ( fieldset ) { focusableIfVisible = !fieldset.disabled; } } } else if ( "a" === nodeName ) { focusableIfVisible = element.href || hasTabindex; } else { focusableIfVisible = hasTabindex; } return focusableIfVisible && $( element ).is( ":visible" ) && $( element ).css( "visibility" ) === "visible"; }; $.extend( $.expr.pseudos, { focusable: function( element ) { return $.ui.focusable( element, $.attr( element, "tabindex" ) != null ); } } ); return $.ui.focusable; } ); ================================================ FILE: ui/form-reset-mixin.js ================================================ /*! * jQuery UI Form Reset Mixin @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license */ //>>label: Form Reset Mixin //>>group: Core //>>description: Refresh input widgets when their form is reset //>>docs: https://api.jqueryui.com/form-reset-mixin/ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "jquery", "./version" ], factory ); } else { // Browser globals factory( jQuery ); } } )( function( $ ) { "use strict"; return $.ui.formResetMixin = { _formResetHandler: function() { var form = $( this ); // Wait for the form reset to actually happen before refreshing setTimeout( function() { var instances = form.data( "ui-form-reset-instances" ); $.each( instances, function() { this.refresh(); } ); } ); }, _bindFormResetHandler: function() { this.form = $( this.element.prop( "form" ) ); if ( !this.form.length ) { return; } var instances = this.form.data( "ui-form-reset-instances" ) || []; if ( !instances.length ) { // We don't use _on() here because we use a single event handler per form this.form.on( "reset.ui-form-reset", this._formResetHandler ); } instances.push( this ); this.form.data( "ui-form-reset-instances", instances ); }, _unbindFormResetHandler: function() { if ( !this.form.length ) { return; } var instances = this.form.data( "ui-form-reset-instances" ); instances.splice( $.inArray( this, instances ), 1 ); if ( instances.length ) { this.form.data( "ui-form-reset-instances", instances ); } else { this.form .removeData( "ui-form-reset-instances" ) .off( "reset.ui-form-reset" ); } } }; } ); ================================================ FILE: ui/i18n/datepicker-af.js ================================================ /* Afrikaans initialisation for the jQuery UI date picker plugin. */ /* Written by Renier Pretorius. */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.af = { closeText: "Selekteer", prevText: "Vorige", nextText: "Volgende", currentText: "Vandag", monthNames: [ "Januarie", "Februarie", "Maart", "April", "Mei", "Junie", "Julie", "Augustus", "September", "Oktober", "November", "Desember" ], monthNamesShort: [ "Jan", "Feb", "Mrt", "Apr", "Mei", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Des" ], dayNames: [ "Sondag", "Maandag", "Dinsdag", "Woensdag", "Donderdag", "Vrydag", "Saterdag" ], dayNamesShort: [ "Son", "Maa", "Din", "Woe", "Don", "Vry", "Sat" ], dayNamesMin: [ "So", "Ma", "Di", "Wo", "Do", "Vr", "Sa" ], weekHeader: "Wk", dateFormat: "dd/mm/yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.af ); return datepicker.regional.af; } ); ================================================ FILE: ui/i18n/datepicker-ar-DZ.js ================================================ /* Algerian Arabic Translation for jQuery UI date picker plugin. /* Used in most of Maghreb countries, primarily in Algeria, Tunisia, Morocco. /* Mohamed Cherif BOUCHELAGHEM -- cherifbouchelaghem@yahoo.fr */ /* Mohamed Amine HADDAD -- zatamine@gmail.com */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional[ "ar-DZ" ] = { closeText: "إغلاق", prevText: "السابق", nextText: "التالي", currentText: "اليوم", monthNames: [ "جانفي", "فيفري", "مارس", "أفريل", "ماي", "جوان", "جويلية", "أوت", "سبتمبر", "أكتوبر", "نوفمبر", "ديسمبر" ], monthNamesShort: [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12" ], dayNames: [ "الأحد", "الاثنين", "الثلاثاء", "الأربعاء", "الخميس", "الجمعة", "السبت" ], dayNamesShort: [ "الأحد", "الاثنين", "الثلاثاء", "الأربعاء", "الخميس", "الجمعة", "السبت" ], dayNamesMin: [ "ح", "ن", "ث", "ر", "خ", "ج", "س" ], weekHeader: "أسبوع", dateFormat: "dd/mm/yy", firstDay: 6, isRTL: true, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional[ "ar-DZ" ] ); return datepicker.regional[ "ar-DZ" ]; } ); ================================================ FILE: ui/i18n/datepicker-ar.js ================================================ /* Arabic Translation for jQuery UI date picker plugin. */ /* Used in most of Arab countries, primarily in Bahrain, */ /* Kuwait, Oman, Qatar, Saudi Arabia and the United Arab Emirates, Egypt, Sudan and Yemen. */ /* Written by Mohammed Alshehri -- m@dralshehri.com */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.ar = { closeText: "إغلاق", prevText: "السابق", nextText: "التالي", currentText: "اليوم", monthNames: [ "يناير", "فبراير", "مارس", "أبريل", "مايو", "يونيو", "يوليو", "أغسطس", "سبتمبر", "أكتوبر", "نوفمبر", "ديسمبر" ], monthNamesShort: [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12" ], dayNames: [ "الأحد", "الاثنين", "الثلاثاء", "الأربعاء", "الخميس", "الجمعة", "السبت" ], dayNamesShort: [ "أحد", "اثنين", "ثلاثاء", "أربعاء", "خميس", "جمعة", "سبت" ], dayNamesMin: [ "ح", "ن", "ث", "ر", "خ", "ج", "س" ], weekHeader: "أسبوع", dateFormat: "dd/mm/yy", firstDay: 0, isRTL: true, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.ar ); return datepicker.regional.ar; } ); ================================================ FILE: ui/i18n/datepicker-az.js ================================================ /* Azerbaijani (UTF-8) initialisation for the jQuery UI date picker plugin. */ /* Written by Jamil Najafov (necefov33@gmail.com). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.az = { closeText: "Bağla", prevText: "Geri", nextText: "İrəli", currentText: "Bugün", monthNames: [ "Yanvar", "Fevral", "Mart", "Aprel", "May", "İyun", "İyul", "Avqust", "Sentyabr", "Oktyabr", "Noyabr", "Dekabr" ], monthNamesShort: [ "Yan", "Fev", "Mar", "Apr", "May", "İyun", "İyul", "Avq", "Sen", "Okt", "Noy", "Dek" ], dayNames: [ "Bazar", "Bazar ertəsi", "Çərşənbə axşamı", "Çərşənbə", "Cümə axşamı", "Cümə", "Şənbə" ], dayNamesShort: [ "B", "Be", "Ça", "Ç", "Ca", "C", "Ş" ], dayNamesMin: [ "B", "B", "Ç", "С", "Ç", "C", "Ş" ], weekHeader: "Hf", dateFormat: "dd.mm.yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.az ); return datepicker.regional.az; } ); ================================================ FILE: ui/i18n/datepicker-be.js ================================================ /* Belarusian initialisation for the jQuery UI date picker plugin. */ /* Written by Pavel Selitskas */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.be = { closeText: "Зачыніць", prevText: "Папяр.", nextText: "Наст.", currentText: "Сёньня", monthNames: [ "Студзень", "Люты", "Сакавік", "Красавік", "Травень", "Чэрвень", "Ліпень", "Жнівень", "Верасень", "Кастрычнік", "Лістапад", "Сьнежань" ], monthNamesShort: [ "Сту", "Лют", "Сак", "Кра", "Тра", "Чэр", "Ліп", "Жні", "Вер", "Кас", "Ліс", "Сьн" ], dayNames: [ "нядзеля", "панядзелак", "аўторак", "серада", "чацьвер", "пятніца", "субота" ], dayNamesShort: [ "ндз", "пнд", "аўт", "срд", "чцв", "птн", "сбт" ], dayNamesMin: [ "Нд", "Пн", "Аў", "Ср", "Чц", "Пт", "Сб" ], weekHeader: "Тд", dateFormat: "dd.mm.yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.be ); return datepicker.regional.be; } ); ================================================ FILE: ui/i18n/datepicker-bg.js ================================================ /* Bulgarian initialisation for the jQuery UI date picker plugin. */ /* Written by Stoyan Kyosev. */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.bg = { closeText: "затвори", prevText: "назад", nextText: "напред", nextBigText: ">>", currentText: "днес", monthNames: [ "Януари", "Февруари", "Март", "Април", "Май", "Юни", "Юли", "Август", "Септември", "Октомври", "Ноември", "Декември" ], monthNamesShort: [ "Яну", "Фев", "Мар", "Апр", "Май", "Юни", "Юли", "Авг", "Сеп", "Окт", "Нов", "Дек" ], dayNames: [ "Неделя", "Понеделник", "Вторник", "Сряда", "Четвъртък", "Петък", "Събота" ], dayNamesShort: [ "Нед", "Пон", "Вто", "Сря", "Чет", "Пет", "Съб" ], dayNamesMin: [ "Не", "По", "Вт", "Ср", "Че", "Пе", "Съ" ], weekHeader: "Wk", dateFormat: "dd.mm.yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.bg ); return datepicker.regional.bg; } ); ================================================ FILE: ui/i18n/datepicker-bs.js ================================================ /* Bosnian i18n for the jQuery UI date picker plugin. */ /* Written by Kenan Konjo. */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.bs = { closeText: "Zatvori", prevText: "Prethodno", nextText: "Sljedeći", currentText: "Danas", monthNames: [ "Januar", "Februar", "Mart", "April", "Maj", "Juni", "Juli", "August", "Septembar", "Oktobar", "Novembar", "Decembar" ], monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "Maj", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec" ], dayNames: [ "Nedelja", "Ponedeljak", "Utorak", "Srijeda", "Četvrtak", "Petak", "Subota" ], dayNamesShort: [ "Ned", "Pon", "Uto", "Sri", "Čet", "Pet", "Sub" ], dayNamesMin: [ "Ne", "Po", "Ut", "Sr", "Če", "Pe", "Su" ], weekHeader: "Wk", dateFormat: "dd.mm.yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.bs ); return datepicker.regional.bs; } ); ================================================ FILE: ui/i18n/datepicker-ca.js ================================================ /* Inicialització en català per a l'extensió 'UI date picker' per jQuery. */ /* Writers: (joan.leon@gmail.com). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.ca = { closeText: "Tanca", prevText: "Anterior", nextText: "Següent", currentText: "Avui", monthNames: [ "gener", "febrer", "març", "abril", "maig", "juny", "juliol", "agost", "setembre", "octubre", "novembre", "desembre" ], monthNamesShort: [ "gen", "feb", "març", "abr", "maig", "juny", "jul", "ag", "set", "oct", "nov", "des" ], dayNames: [ "diumenge", "dilluns", "dimarts", "dimecres", "dijous", "divendres", "dissabte" ], dayNamesShort: [ "dg", "dl", "dt", "dc", "dj", "dv", "ds" ], dayNamesMin: [ "dg", "dl", "dt", "dc", "dj", "dv", "ds" ], weekHeader: "Set", dateFormat: "dd/mm/yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.ca ); return datepicker.regional.ca; } ); ================================================ FILE: ui/i18n/datepicker-cs.js ================================================ /* Czech initialisation for the jQuery UI date picker plugin. */ /* Written by Tomas Muller (tomas@tomas-muller.net). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.cs = { closeText: "Zavřít", prevText: "Dříve", nextText: "Později", currentText: "Nyní", monthNames: [ "leden", "únor", "březen", "duben", "květen", "červen", "červenec", "srpen", "září", "říjen", "listopad", "prosinec" ], monthNamesShort: [ "led", "úno", "bře", "dub", "kvě", "čer", "čvc", "srp", "zář", "říj", "lis", "pro" ], dayNames: [ "neděle", "pondělí", "úterý", "středa", "čtvrtek", "pátek", "sobota" ], dayNamesShort: [ "ne", "po", "út", "st", "čt", "pá", "so" ], dayNamesMin: [ "ne", "po", "út", "st", "čt", "pá", "so" ], weekHeader: "Týd", dateFormat: "dd.mm.yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.cs ); return datepicker.regional.cs; } ); ================================================ FILE: ui/i18n/datepicker-cy-GB.js ================================================ /* Welsh/UK initialisation for the jQuery UI date picker plugin. */ /* Written by William Griffiths. */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional[ "cy-GB" ] = { closeText: "Done", prevText: "Prev", nextText: "Next", currentText: "Today", monthNames: [ "Ionawr", "Chwefror", "Mawrth", "Ebrill", "Mai", "Mehefin", "Gorffennaf", "Awst", "Medi", "Hydref", "Tachwedd", "Rhagfyr" ], monthNamesShort: [ "Ion", "Chw", "Maw", "Ebr", "Mai", "Meh", "Gor", "Aws", "Med", "Hyd", "Tac", "Rha" ], dayNames: [ "Dydd Sul", "Dydd Llun", "Dydd Mawrth", "Dydd Mercher", "Dydd Iau", "Dydd Gwener", "Dydd Sadwrn" ], dayNamesShort: [ "Sul", "Llu", "Maw", "Mer", "Iau", "Gwe", "Sad" ], dayNamesMin: [ "Su", "Ll", "Ma", "Me", "Ia", "Gw", "Sa" ], weekHeader: "Wy", dateFormat: "dd/mm/yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional[ "cy-GB" ] ); return datepicker.regional[ "cy-GB" ]; } ); ================================================ FILE: ui/i18n/datepicker-da.js ================================================ /* Danish initialisation for the jQuery UI date picker plugin. */ /* Written by Jan Christensen ( deletestuff@gmail.com). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.da = { closeText: "Luk", prevText: "Forrige", nextText: "Næste", currentText: "I dag", monthNames: [ "Januar", "Februar", "Marts", "April", "Maj", "Juni", "Juli", "August", "September", "Oktober", "November", "December" ], monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "Maj", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec" ], dayNames: [ "Søndag", "Mandag", "Tirsdag", "Onsdag", "Torsdag", "Fredag", "Lørdag" ], dayNamesShort: [ "Søn", "Man", "Tir", "Ons", "Tor", "Fre", "Lør" ], dayNamesMin: [ "Sø", "Ma", "Ti", "On", "To", "Fr", "Lø" ], weekHeader: "Uge", dateFormat: "dd-mm-yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.da ); return datepicker.regional.da; } ); ================================================ FILE: ui/i18n/datepicker-de-AT.js ================================================ /* German/Austrian initialisation for the jQuery UI date picker plugin. */ /* Based on the de initialisation. */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional[ "de-AT" ] = { closeText: "Schließen", prevText: "Zurück", nextText: "Vor", currentText: "Heute", monthNames: [ "Jänner", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember" ], monthNamesShort: [ "Jän", "Feb", "Mär", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez" ], dayNames: [ "Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag" ], dayNamesShort: [ "So", "Mo", "Di", "Mi", "Do", "Fr", "Sa" ], dayNamesMin: [ "So", "Mo", "Di", "Mi", "Do", "Fr", "Sa" ], weekHeader: "KW", dateFormat: "dd.mm.yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional[ "de-AT" ] ); return datepicker.regional[ "de-AT" ]; } ); ================================================ FILE: ui/i18n/datepicker-de.js ================================================ /* German initialisation for the jQuery UI date picker plugin. */ /* Written by Milian Wolff (mail@milianw.de). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.de = { closeText: "Schließen", prevText: "Zurück", nextText: "Vor", currentText: "Heute", monthNames: [ "Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember" ], monthNamesShort: [ "Jan", "Feb", "Mär", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez" ], dayNames: [ "Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag" ], dayNamesShort: [ "So", "Mo", "Di", "Mi", "Do", "Fr", "Sa" ], dayNamesMin: [ "So", "Mo", "Di", "Mi", "Do", "Fr", "Sa" ], weekHeader: "KW", dateFormat: "dd.mm.yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.de ); return datepicker.regional.de; } ); ================================================ FILE: ui/i18n/datepicker-el.js ================================================ /* Greek (el) initialisation for the jQuery UI date picker plugin. */ /* Written by Alex Cicovic (https://alexcicovic.com) */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.el = { closeText: "Κλείσιμο", prevText: "Προηγούμενος", nextText: "Επόμενος", currentText: "Σήμερα", monthNames: [ "Ιανουάριος", "Φεβρουάριος", "Μάρτιος", "Απρίλιος", "Μάιος", "Ιούνιος", "Ιούλιος", "Αύγουστος", "Σεπτέμβριος", "Οκτώβριος", "Νοέμβριος", "Δεκέμβριος" ], monthNamesShort: [ "Ιαν", "Φεβ", "Μαρ", "Απρ", "Μαι", "Ιουν", "Ιουλ", "Αυγ", "Σεπ", "Οκτ", "Νοε", "Δεκ" ], dayNames: [ "Κυριακή", "Δευτέρα", "Τρίτη", "Τετάρτη", "Πέμπτη", "Παρασκευή", "Σάββατο" ], dayNamesShort: [ "Κυρ", "Δευ", "Τρι", "Τετ", "Πεμ", "Παρ", "Σαβ" ], dayNamesMin: [ "Κυ", "Δε", "Τρ", "Τε", "Πε", "Πα", "Σα" ], weekHeader: "Εβδ", dateFormat: "dd/mm/yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.el ); return datepicker.regional.el; } ); ================================================ FILE: ui/i18n/datepicker-en-AU.js ================================================ /* English/Australia initialisation for the jQuery UI date picker plugin. */ /* Based on the en-GB initialisation. */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional[ "en-AU" ] = { closeText: "Done", prevText: "Prev", nextText: "Next", currentText: "Today", monthNames: [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ], monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], dayNamesMin: [ "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" ], weekHeader: "Wk", dateFormat: "dd/mm/yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional[ "en-AU" ] ); return datepicker.regional[ "en-AU" ]; } ); ================================================ FILE: ui/i18n/datepicker-en-GB.js ================================================ /* English/UK initialisation for the jQuery UI date picker plugin. */ /* Written by Stuart. */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional[ "en-GB" ] = { closeText: "Done", prevText: "Prev", nextText: "Next", currentText: "Today", monthNames: [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ], monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], dayNamesMin: [ "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" ], weekHeader: "Wk", dateFormat: "dd/mm/yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional[ "en-GB" ] ); return datepicker.regional[ "en-GB" ]; } ); ================================================ FILE: ui/i18n/datepicker-en-NZ.js ================================================ /* English/New Zealand initialisation for the jQuery UI date picker plugin. */ /* Based on the en-GB initialisation. */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional[ "en-NZ" ] = { closeText: "Done", prevText: "Prev", nextText: "Next", currentText: "Today", monthNames: [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ], monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], dayNamesMin: [ "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" ], weekHeader: "Wk", dateFormat: "dd/mm/yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional[ "en-NZ" ] ); return datepicker.regional[ "en-NZ" ]; } ); ================================================ FILE: ui/i18n/datepicker-eo.js ================================================ /* Esperanto initialisation for the jQuery UI date picker plugin. */ /* Written by Olivier M. (olivierweb@ifrance.com). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.eo = { closeText: "Fermi", prevText: "Anta", nextText: "Sekv", currentText: "Nuna", monthNames: [ "Januaro", "Februaro", "Marto", "Aprilo", "Majo", "Junio", "Julio", "Aŭgusto", "Septembro", "Oktobro", "Novembro", "Decembro" ], monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "Maj", "Jun", "Jul", "Aŭg", "Sep", "Okt", "Nov", "Dec" ], dayNames: [ "Dimanĉo", "Lundo", "Mardo", "Merkredo", "Ĵaŭdo", "Vendredo", "Sabato" ], dayNamesShort: [ "Dim", "Lun", "Mar", "Mer", "Ĵaŭ", "Ven", "Sab" ], dayNamesMin: [ "Di", "Lu", "Ma", "Me", "Ĵa", "Ve", "Sa" ], weekHeader: "Sb", dateFormat: "dd/mm/yy", firstDay: 0, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.eo ); return datepicker.regional.eo; } ); ================================================ FILE: ui/i18n/datepicker-es.js ================================================ /* Inicialización en español para la extensión 'UI date picker' para jQuery. */ /* Traducido por Vester (xvester@gmail.com). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.es = { closeText: "Cerrar", prevText: "Ant", nextText: "Sig", currentText: "Hoy", monthNames: [ "enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre" ], monthNamesShort: [ "ene", "feb", "mar", "abr", "may", "jun", "jul", "ago", "sep", "oct", "nov", "dic" ], dayNames: [ "domingo", "lunes", "martes", "miércoles", "jueves", "viernes", "sábado" ], dayNamesShort: [ "dom", "lun", "mar", "mié", "jue", "vie", "sáb" ], dayNamesMin: [ "D", "L", "M", "X", "J", "V", "S" ], weekHeader: "Sm", dateFormat: "dd/mm/yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.es ); return datepicker.regional.es; } ); ================================================ FILE: ui/i18n/datepicker-et.js ================================================ /* Estonian initialisation for the jQuery UI date picker plugin. */ /* Written by Mart Sõmermaa (mrts.pydev at gmail com). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.et = { closeText: "Sulge", prevText: "Eelnev", nextText: "Järgnev", currentText: "Täna", monthNames: [ "Jaanuar", "Veebruar", "Märts", "Aprill", "Mai", "Juuni", "Juuli", "August", "September", "Oktoober", "November", "Detsember" ], monthNamesShort: [ "Jaan", "Veebr", "Märts", "Apr", "Mai", "Juuni", "Juuli", "Aug", "Sept", "Okt", "Nov", "Dets" ], dayNames: [ "Pühapäev", "Esmaspäev", "Teisipäev", "Kolmapäev", "Neljapäev", "Reede", "Laupäev" ], dayNamesShort: [ "Pühap", "Esmasp", "Teisip", "Kolmap", "Neljap", "Reede", "Laup" ], dayNamesMin: [ "P", "E", "T", "K", "N", "R", "L" ], weekHeader: "näd", dateFormat: "dd.mm.yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.et ); return datepicker.regional.et; } ); ================================================ FILE: ui/i18n/datepicker-eu.js ================================================ /* Karrikas-ek itzulia (karrikas@karrikas.com) */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.eu = { closeText: "Egina", prevText: "Aur", nextText: "Hur", currentText: "Gaur", monthNames: [ "urtarrila", "otsaila", "martxoa", "apirila", "maiatza", "ekaina", "uztaila", "abuztua", "iraila", "urria", "azaroa", "abendua" ], monthNamesShort: [ "urt.", "ots.", "mar.", "api.", "mai.", "eka.", "uzt.", "abu.", "ira.", "urr.", "aza.", "abe." ], dayNames: [ "igandea", "astelehena", "asteartea", "asteazkena", "osteguna", "ostirala", "larunbata" ], dayNamesShort: [ "ig.", "al.", "ar.", "az.", "og.", "ol.", "lr." ], dayNamesMin: [ "ig", "al", "ar", "az", "og", "ol", "lr" ], weekHeader: "As", dateFormat: "yy-mm-dd", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.eu ); return datepicker.regional.eu; } ); ================================================ FILE: ui/i18n/datepicker-fa.js ================================================ /* Persian (Farsi) Translation for the jQuery UI date picker plugin. */ /* Javad Mowlanezhad -- jmowla@gmail.com */ /* Jalali calendar should supported soon! (Its implemented but I have to test it) */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.fa = { closeText: "بستن", prevText: "قبلی", nextText: "بعدی", currentText: "امروز", monthNames: [ "ژانویه", "فوریه", "مارس", "آوریل", "مه", "ژوئن", "ژوئیه", "اوت", "سپتامبر", "اکتبر", "نوامبر", "دسامبر" ], monthNamesShort: [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12" ], dayNames: [ "يکشنبه", "دوشنبه", "سه‌شنبه", "چهارشنبه", "پنجشنبه", "جمعه", "شنبه" ], dayNamesShort: [ "ی", "د", "س", "چ", "پ", "ج", "ش" ], dayNamesMin: [ "ی", "د", "س", "چ", "پ", "ج", "ش" ], weekHeader: "هف", dateFormat: "yy/mm/dd", firstDay: 6, isRTL: true, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.fa ); return datepicker.regional.fa; } ); ================================================ FILE: ui/i18n/datepicker-fi.js ================================================ /* Finnish initialisation for the jQuery UI date picker plugin. */ /* Written by Harri Kilpiö (harrikilpio@gmail.com). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.fi = { closeText: "Sulje", prevText: "Edellinen", nextText: "Seuraava", currentText: "Tänään", monthNames: [ "Tammikuu", "Helmikuu", "Maaliskuu", "Huhtikuu", "Toukokuu", "Kesäkuu", "Heinäkuu", "Elokuu", "Syyskuu", "Lokakuu", "Marraskuu", "Joulukuu" ], monthNamesShort: [ "Tammi", "Helmi", "Maalis", "Huhti", "Touko", "Kesä", "Heinä", "Elo", "Syys", "Loka", "Marras", "Joulu" ], dayNamesShort: [ "Su", "Ma", "Ti", "Ke", "To", "Pe", "La" ], dayNames: [ "Sunnuntai", "Maanantai", "Tiistai", "Keskiviikko", "Torstai", "Perjantai", "Lauantai" ], dayNamesMin: [ "Su", "Ma", "Ti", "Ke", "To", "Pe", "La" ], weekHeader: "Vk", dateFormat: "d.m.yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.fi ); return datepicker.regional.fi; } ); ================================================ FILE: ui/i18n/datepicker-fo.js ================================================ /* Faroese initialisation for the jQuery UI date picker plugin */ /* Written by Sverri Mohr Olsen, sverrimo@gmail.com */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.fo = { closeText: "Lat aftur", prevText: "Fyrra", nextText: "Næsta", currentText: "Í dag", monthNames: [ "Januar", "Februar", "Mars", "Apríl", "Mei", "Juni", "Juli", "August", "September", "Oktober", "November", "Desember" ], monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "Mei", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Des" ], dayNames: [ "Sunnudagur", "Mánadagur", "Týsdagur", "Mikudagur", "Hósdagur", "Fríggjadagur", "Leyardagur" ], dayNamesShort: [ "Sun", "Mán", "Týs", "Mik", "Hós", "Frí", "Ley" ], dayNamesMin: [ "Su", "Má", "Tý", "Mi", "Hó", "Fr", "Le" ], weekHeader: "Vk", dateFormat: "dd-mm-yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.fo ); return datepicker.regional.fo; } ); ================================================ FILE: ui/i18n/datepicker-fr-CA.js ================================================ /* Canadian-French initialisation for the jQuery UI date picker plugin. */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional[ "fr-CA" ] = { closeText: "Fermer", prevText: "Précédent", nextText: "Suivant", currentText: "Aujourd'hui", monthNames: [ "janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre" ], monthNamesShort: [ "janv.", "févr.", "mars", "avril", "mai", "juin", "juil.", "août", "sept.", "oct.", "nov.", "déc." ], dayNames: [ "dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi" ], dayNamesShort: [ "dim.", "lun.", "mar.", "mer.", "jeu.", "ven.", "sam." ], dayNamesMin: [ "D", "L", "M", "M", "J", "V", "S" ], weekHeader: "Sem.", dateFormat: "yy-mm-dd", firstDay: 0, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional[ "fr-CA" ] ); return datepicker.regional[ "fr-CA" ]; } ); ================================================ FILE: ui/i18n/datepicker-fr-CH.js ================================================ /* Swiss-French initialisation for the jQuery UI date picker plugin. */ /* Written Martin Voelkle (martin.voelkle@e-tc.ch). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional[ "fr-CH" ] = { closeText: "Fermer", prevText: "Préc", nextText: "Suiv", currentText: "Courant", monthNames: [ "janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre" ], monthNamesShort: [ "janv.", "févr.", "mars", "avril", "mai", "juin", "juil.", "août", "sept.", "oct.", "nov.", "déc." ], dayNames: [ "dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi" ], dayNamesShort: [ "dim.", "lun.", "mar.", "mer.", "jeu.", "ven.", "sam." ], dayNamesMin: [ "D", "L", "M", "M", "J", "V", "S" ], weekHeader: "Sm", dateFormat: "dd.mm.yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional[ "fr-CH" ] ); return datepicker.regional[ "fr-CH" ]; } ); ================================================ FILE: ui/i18n/datepicker-fr.js ================================================ /* French initialisation for the jQuery UI date picker plugin. */ /* Written by Keith Wood (kbwood{at}iinet.com.au), Stéphane Nahmani (sholby@sholby.net), Stéphane Raimbault */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.fr = { closeText: "Fermer", prevText: "Précédent", nextText: "Suivant", currentText: "Aujourd'hui", monthNames: [ "janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre" ], monthNamesShort: [ "janv.", "févr.", "mars", "avr.", "mai", "juin", "juil.", "août", "sept.", "oct.", "nov.", "déc." ], dayNames: [ "dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi" ], dayNamesShort: [ "dim.", "lun.", "mar.", "mer.", "jeu.", "ven.", "sam." ], dayNamesMin: [ "D", "L", "M", "M", "J", "V", "S" ], weekHeader: "Sem.", dateFormat: "dd/mm/yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.fr ); return datepicker.regional.fr; } ); ================================================ FILE: ui/i18n/datepicker-gl.js ================================================ /* Galician localization for 'UI date picker' jQuery extension. */ /* Translated by Jorge Barreiro . */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.gl = { closeText: "Pechar", prevText: "Ant", nextText: "Seg", currentText: "Hoxe", monthNames: [ "Xaneiro", "Febreiro", "Marzo", "Abril", "Maio", "Xuño", "Xullo", "Agosto", "Setembro", "Outubro", "Novembro", "Decembro" ], monthNamesShort: [ "Xan", "Feb", "Mar", "Abr", "Mai", "Xuñ", "Xul", "Ago", "Set", "Out", "Nov", "Dec" ], dayNames: [ "Domingo", "Luns", "Martes", "Mércores", "Xoves", "Venres", "Sábado" ], dayNamesShort: [ "Dom", "Lun", "Mar", "Mér", "Xov", "Ven", "Sáb" ], dayNamesMin: [ "Do", "Lu", "Ma", "Mé", "Xo", "Ve", "Sá" ], weekHeader: "Sm", dateFormat: "dd/mm/yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.gl ); return datepicker.regional.gl; } ); ================================================ FILE: ui/i18n/datepicker-he.js ================================================ /* Hebrew initialisation for the UI Datepicker extension. */ /* Written by Amir Hardon (ahardon at gmail dot com). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.he = { closeText: "סגור", prevText: "הקודם", nextText: "הבא", currentText: "היום", monthNames: [ "ינואר", "פברואר", "מרץ", "אפריל", "מאי", "יוני", "יולי", "אוגוסט", "ספטמבר", "אוקטובר", "נובמבר", "דצמבר" ], monthNamesShort: [ "ינו", "פבר", "מרץ", "אפר", "מאי", "יוני", "יולי", "אוג", "ספט", "אוק", "נוב", "דצמ" ], dayNames: [ "ראשון", "שני", "שלישי", "רביעי", "חמישי", "שישי", "שבת" ], dayNamesShort: [ "א'", "ב'", "ג'", "ד'", "ה'", "ו'", "שבת" ], dayNamesMin: [ "א'", "ב'", "ג'", "ד'", "ה'", "ו'", "שבת" ], weekHeader: "Wk", dateFormat: "dd/mm/yy", firstDay: 0, isRTL: true, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.he ); return datepicker.regional.he; } ); ================================================ FILE: ui/i18n/datepicker-hi.js ================================================ /* Hindi initialisation for the jQuery UI date picker plugin. */ /* Written by Michael Dawart. */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.hi = { closeText: "बंद", prevText: "पिछला", nextText: "अगला", currentText: "आज", monthNames: [ "जनवरी ", "फरवरी", "मार्च", "अप्रेल", "मई", "जून", "जूलाई", "अगस्त ", "सितम्बर", "अक्टूबर", "नवम्बर", "दिसम्बर" ], monthNamesShort: [ "जन", "फर", "मार्च", "अप्रेल", "मई", "जून", "जूलाई", "अग", "सित", "अक्ट", "नव", "दि" ], dayNames: [ "रविवार", "सोमवार", "मंगलवार", "बुधवार", "गुरुवार", "शुक्रवार", "शनिवार" ], dayNamesShort: [ "रवि", "सोम", "मंगल", "बुध", "गुरु", "शुक्र", "शनि" ], dayNamesMin: [ "रवि", "सोम", "मंगल", "बुध", "गुरु", "शुक्र", "शनि" ], weekHeader: "हफ्ता", dateFormat: "dd/mm/yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.hi ); return datepicker.regional.hi; } ); ================================================ FILE: ui/i18n/datepicker-hr.js ================================================ /* Croatian i18n for the jQuery UI date picker plugin. */ /* Written by Vjekoslav Nesek. */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.hr = { closeText: "Zatvori", prevText: "Prethodno", nextText: "Sljedeći", currentText: "Danas", monthNames: [ "Siječanj", "Veljača", "Ožujak", "Travanj", "Svibanj", "Lipanj", "Srpanj", "Kolovoz", "Rujan", "Listopad", "Studeni", "Prosinac" ], monthNamesShort: [ "Sij", "Velj", "Ožu", "Tra", "Svi", "Lip", "Srp", "Kol", "Ruj", "Lis", "Stu", "Pro" ], dayNames: [ "Nedjelja", "Ponedjeljak", "Utorak", "Srijeda", "Četvrtak", "Petak", "Subota" ], dayNamesShort: [ "Ned", "Pon", "Uto", "Sri", "Čet", "Pet", "Sub" ], dayNamesMin: [ "Ne", "Po", "Ut", "Sr", "Če", "Pe", "Su" ], weekHeader: "Tje", dateFormat: "dd.mm.yy.", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.hr ); return datepicker.regional.hr; } ); ================================================ FILE: ui/i18n/datepicker-hu.js ================================================ /* Hungarian initialisation for the jQuery UI date picker plugin. */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.hu = { closeText: "Bezár", prevText: "Vissza", nextText: "Előre", currentText: "Ma", monthNames: [ "Január", "Február", "Március", "Április", "Május", "Június", "Július", "Augusztus", "Szeptember", "Október", "November", "December" ], monthNamesShort: [ "Jan", "Feb", "Már", "Ápr", "Máj", "Jún", "Júl", "Aug", "Szep", "Okt", "Nov", "Dec" ], dayNames: [ "Vasárnap", "Hétfő", "Kedd", "Szerda", "Csütörtök", "Péntek", "Szombat" ], dayNamesShort: [ "Vas", "Hét", "Ked", "Sze", "Csü", "Pén", "Szo" ], dayNamesMin: [ "V", "H", "K", "Sze", "Cs", "P", "Szo" ], weekHeader: "Hét", dateFormat: "yy.mm.dd.", firstDay: 1, isRTL: false, showMonthAfterYear: true, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.hu ); return datepicker.regional.hu; } ); ================================================ FILE: ui/i18n/datepicker-hy.js ================================================ /* Armenian(UTF-8) initialisation for the jQuery UI date picker plugin. */ /* Written by Levon Zakaryan (levon.zakaryan@gmail.com)*/ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.hy = { closeText: "Փակել", prevText: "Նախ.", nextText: "Հաջ.", currentText: "Այսօր", monthNames: [ "Հունվար", "Փետրվար", "Մարտ", "Ապրիլ", "Մայիս", "Հունիս", "Հուլիս", "Օգոստոս", "Սեպտեմբեր", "Հոկտեմբեր", "Նոյեմբեր", "Դեկտեմբեր" ], monthNamesShort: [ "Հունվ", "Փետր", "Մարտ", "Ապր", "Մայիս", "Հունիս", "Հուլ", "Օգս", "Սեպ", "Հոկ", "Նոյ", "Դեկ" ], dayNames: [ "կիրակի", "եկուշաբթի", "երեքշաբթի", "չորեքշաբթի", "հինգշաբթի", "ուրբաթ", "շաբաթ" ], dayNamesShort: [ "կիր", "երկ", "երք", "չրք", "հնգ", "ուրբ", "շբթ" ], dayNamesMin: [ "կիր", "երկ", "երք", "չրք", "հնգ", "ուրբ", "շբթ" ], weekHeader: "ՇԲՏ", dateFormat: "dd.mm.yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.hy ); return datepicker.regional.hy; } ); ================================================ FILE: ui/i18n/datepicker-id.js ================================================ /* Indonesian initialisation for the jQuery UI date picker plugin. */ /* Written by Deden Fathurahman (dedenf@gmail.com). */ /* Fixed by Denny Septian Panggabean (xamidimura@gmail.com) */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.id = { closeText: "Tutup", prevText: "Mundur", nextText: "Maju", currentText: "Hari ini", monthNames: [ "Januari", "Februari", "Maret", "April", "Mei", "Juni", "Juli", "Agustus", "September", "Oktober", "Nopember", "Desember" ], monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "Mei", "Jun", "Jul", "Agus", "Sep", "Okt", "Nop", "Des" ], dayNames: [ "Minggu", "Senin", "Selasa", "Rabu", "Kamis", "Jumat", "Sabtu" ], dayNamesShort: [ "Min", "Sen", "Sel", "Rab", "Kam", "Jum", "Sab" ], dayNamesMin: [ "Mg", "Sn", "Sl", "Rb", "Km", "Jm", "Sb" ], weekHeader: "Mg", dateFormat: "dd/mm/yy", firstDay: 0, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.id ); return datepicker.regional.id; } ); ================================================ FILE: ui/i18n/datepicker-is.js ================================================ /* Icelandic initialisation for the jQuery UI date picker plugin. */ /* Written by Haukur H. Thorsson (haukur@eskill.is). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.is = { closeText: "Loka", prevText: "Fyrri", nextText: "Næsti ", currentText: "Í dag", monthNames: [ "Janúar", "Febrúar", "Mars", "Apríl", "Maí", "Júní", "Júlí", "Ágúst", "September", "Október", "Nóvember", "Desember" ], monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "Maí", "Jún", "Júl", "Ágú", "Sep", "Okt", "Nóv", "Des" ], dayNames: [ "Sunnudagur", "Mánudagur", "Þriðjudagur", "Miðvikudagur", "Fimmtudagur", "Föstudagur", "Laugardagur" ], dayNamesShort: [ "Sun", "Mán", "Þri", "Mið", "Fim", "Fös", "Lau" ], dayNamesMin: [ "Su", "Má", "Þr", "Mi", "Fi", "Fö", "La" ], weekHeader: "Vika", dateFormat: "dd.mm.yy", firstDay: 0, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.is ); return datepicker.regional.is; } ); ================================================ FILE: ui/i18n/datepicker-it-CH.js ================================================ /* Italian initialisation for the jQuery UI date picker plugin. */ /* Written by Antonello Pasella (antonello.pasella@gmail.com). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional[ "it-CH" ] = { closeText: "Chiudi", prevText: "Prec", nextText: "Succ", currentText: "Oggi", monthNames: [ "Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre" ], monthNamesShort: [ "Gen", "Feb", "Mar", "Apr", "Mag", "Giu", "Lug", "Ago", "Set", "Ott", "Nov", "Dic" ], dayNames: [ "Domenica", "Lunedì", "Martedì", "Mercoledì", "Giovedì", "Venerdì", "Sabato" ], dayNamesShort: [ "Dom", "Lun", "Mar", "Mer", "Gio", "Ven", "Sab" ], dayNamesMin: [ "Do", "Lu", "Ma", "Me", "Gi", "Ve", "Sa" ], weekHeader: "Sm", dateFormat: "dd.mm.yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional[ "it-CH" ] ); return datepicker.regional[ "it-CH" ]; } ); ================================================ FILE: ui/i18n/datepicker-it.js ================================================ /* Italian initialisation for the jQuery UI date picker plugin. */ /* Written by Antonello Pasella (antonello.pasella@gmail.com). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.it = { closeText: "Chiudi", prevText: "Prec", nextText: "Succ", currentText: "Oggi", monthNames: [ "Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre" ], monthNamesShort: [ "Gen", "Feb", "Mar", "Apr", "Mag", "Giu", "Lug", "Ago", "Set", "Ott", "Nov", "Dic" ], dayNames: [ "Domenica", "Lunedì", "Martedì", "Mercoledì", "Giovedì", "Venerdì", "Sabato" ], dayNamesShort: [ "Dom", "Lun", "Mar", "Mer", "Gio", "Ven", "Sab" ], dayNamesMin: [ "Do", "Lu", "Ma", "Me", "Gi", "Ve", "Sa" ], weekHeader: "Sm", dateFormat: "dd/mm/yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.it ); return datepicker.regional.it; } ); ================================================ FILE: ui/i18n/datepicker-ja.js ================================================ /* Japanese initialisation for the jQuery UI date picker plugin. */ /* Written by Kentaro SATO (kentaro@ranvis.com). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.ja = { closeText: "閉じる", prevText: "前", nextText: "次", currentText: "今日", monthNames: [ "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月" ], monthNamesShort: [ "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月" ], dayNames: [ "日曜日", "月曜日", "火曜日", "水曜日", "木曜日", "金曜日", "土曜日" ], dayNamesShort: [ "日", "月", "火", "水", "木", "金", "土" ], dayNamesMin: [ "日", "月", "火", "水", "木", "金", "土" ], weekHeader: "週", dateFormat: "yy/mm/dd", firstDay: 0, isRTL: false, showMonthAfterYear: true, yearSuffix: "年" }; datepicker.setDefaults( datepicker.regional.ja ); return datepicker.regional.ja; } ); ================================================ FILE: ui/i18n/datepicker-ka.js ================================================ /* Georgian (UTF-8) initialisation for the jQuery UI date picker plugin. */ /* Written by Lado Lomidze (lado.lomidze@gmail.com). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.ka = { closeText: "დახურვა", prevText: "წინა", nextText: "შემდეგი ", currentText: "დღეს", monthNames: [ "იანვარი", "თებერვალი", "მარტი", "აპრილი", "მაისი", "ივნისი", "ივლისი", "აგვისტო", "სექტემბერი", "ოქტომბერი", "ნოემბერი", "დეკემბერი" ], monthNamesShort: [ "იან", "თებ", "მარ", "აპრ", "მაი", "ივნ", "ივლ", "აგვ", "სექ", "ოქტ", "ნოე", "დეკ" ], dayNames: [ "კვირა", "ორშაბათი", "სამშაბათი", "ოთხშაბათი", "ხუთშაბათი", "პარასკევი", "შაბათი" ], dayNamesShort: [ "კვ", "ორშ", "სამ", "ოთხ", "ხუთ", "პარ", "შაბ" ], dayNamesMin: [ "კვ", "ორშ", "სამ", "ოთხ", "ხუთ", "პარ", "შაბ" ], weekHeader: "კვირა", dateFormat: "dd-mm-yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.ka ); return datepicker.regional.ka; } ); ================================================ FILE: ui/i18n/datepicker-kk.js ================================================ /* Kazakh (UTF-8) initialisation for the jQuery UI date picker plugin. */ /* Written by Dmitriy Karasyov (dmitriy.karasyov@gmail.com). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.kk = { closeText: "Жабу", prevText: "Алдыңғы", nextText: "Келесі", currentText: "Бүгін", monthNames: [ "Қаңтар", "Ақпан", "Наурыз", "Сәуір", "Мамыр", "Маусым", "Шілде", "Тамыз", "Қыркүйек", "Қазан", "Қараша", "Желтоқсан" ], monthNamesShort: [ "Қаң", "Ақп", "Нау", "Сәу", "Мам", "Мау", "Шіл", "Там", "Қыр", "Қаз", "Қар", "Жел" ], dayNames: [ "Жексенбі", "Дүйсенбі", "Сейсенбі", "Сәрсенбі", "Бейсенбі", "Жұма", "Сенбі" ], dayNamesShort: [ "жкс", "дсн", "ссн", "срс", "бсн", "жма", "снб" ], dayNamesMin: [ "Жк", "Дс", "Сс", "Ср", "Бс", "Жм", "Сн" ], weekHeader: "Не", dateFormat: "dd.mm.yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.kk ); return datepicker.regional.kk; } ); ================================================ FILE: ui/i18n/datepicker-km.js ================================================ /* Khmer initialisation for the jQuery calendar extension. */ /* Written by Chandara Om (chandara.teacher@gmail.com). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.km = { closeText: "ធ្វើ​រួច", prevText: "មុន", nextText: "បន្ទាប់", currentText: "ថ្ងៃ​នេះ", monthNames: [ "មករា", "កុម្ភៈ", "មីនា", "មេសា", "ឧសភា", "មិថុនា", "កក្កដា", "សីហា", "កញ្ញា", "តុលា", "វិច្ឆិកា", "ធ្នូ" ], monthNamesShort: [ "មករា", "កុម្ភៈ", "មីនា", "មេសា", "ឧសភា", "មិថុនា", "កក្កដា", "សីហា", "កញ្ញា", "តុលា", "វិច្ឆិកា", "ធ្នូ" ], dayNames: [ "អាទិត្យ", "ចន្ទ", "អង្គារ", "ពុធ", "ព្រហស្បតិ៍", "សុក្រ", "សៅរ៍" ], dayNamesShort: [ "អា", "ច", "អ", "ពុ", "ព្រហ", "សុ", "សៅ" ], dayNamesMin: [ "អា", "ច", "អ", "ពុ", "ព្រហ", "សុ", "សៅ" ], weekHeader: "សប្ដាហ៍", dateFormat: "dd-mm-yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.km ); return datepicker.regional.km; } ); ================================================ FILE: ui/i18n/datepicker-ko.js ================================================ /* Korean initialisation for the jQuery calendar extension. */ /* Written by DaeKwon Kang (ncrash.dk@gmail.com), Edited by Genie and Myeongjin Lee. */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.ko = { closeText: "닫기", prevText: "이전달", nextText: "다음달", currentText: "오늘", monthNames: [ "1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월" ], monthNamesShort: [ "1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월" ], dayNames: [ "일요일", "월요일", "화요일", "수요일", "목요일", "금요일", "토요일" ], dayNamesShort: [ "일", "월", "화", "수", "목", "금", "토" ], dayNamesMin: [ "일", "월", "화", "수", "목", "금", "토" ], weekHeader: "주", dateFormat: "yy. m. d.", firstDay: 0, isRTL: false, showMonthAfterYear: true, yearSuffix: "년" }; datepicker.setDefaults( datepicker.regional.ko ); return datepicker.regional.ko; } ); ================================================ FILE: ui/i18n/datepicker-ky.js ================================================ /* Kyrgyz (UTF-8) initialisation for the jQuery UI date picker plugin. */ /* Written by Sergey Kartashov (ebishkek@yandex.ru). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.ky = { closeText: "Жабуу", prevText: "Мур", nextText: "Кий", currentText: "Бүгүн", monthNames: [ "Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь" ], monthNamesShort: [ "Янв", "Фев", "Мар", "Апр", "Май", "Июн", "Июл", "Авг", "Сен", "Окт", "Ноя", "Дек" ], dayNames: [ "жекшемби", "дүйшөмбү", "шейшемби", "шаршемби", "бейшемби", "жума", "ишемби" ], dayNamesShort: [ "жек", "дүй", "шей", "шар", "бей", "жум", "ише" ], dayNamesMin: [ "Жк", "Дш", "Шш", "Шр", "Бш", "Жм", "Иш" ], weekHeader: "Жум", dateFormat: "dd.mm.yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.ky ); return datepicker.regional.ky; } ); ================================================ FILE: ui/i18n/datepicker-lb.js ================================================ /* Luxembourgish initialisation for the jQuery UI date picker plugin. */ /* Written by Michel Weimerskirch */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.lb = { closeText: "Fäerdeg", prevText: "Zréck", nextText: "Weider", currentText: "Haut", monthNames: [ "Januar", "Februar", "Mäerz", "Abrëll", "Mee", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember" ], monthNamesShort: [ "Jan", "Feb", "Mäe", "Abr", "Mee", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez" ], dayNames: [ "Sonndeg", "Méindeg", "Dënschdeg", "Mëttwoch", "Donneschdeg", "Freideg", "Samschdeg" ], dayNamesShort: [ "Son", "Méi", "Dën", "Mët", "Don", "Fre", "Sam" ], dayNamesMin: [ "So", "Mé", "Dë", "Më", "Do", "Fr", "Sa" ], weekHeader: "W", dateFormat: "dd.mm.yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.lb ); return datepicker.regional.lb; } ); ================================================ FILE: ui/i18n/datepicker-lt.js ================================================ /* Lithuanian (UTF-8) initialisation for the jQuery UI date picker plugin. */ /* @author Arturas Paleicikas */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.lt = { closeText: "Uždaryti", prevText: "Atgal", nextText: "Pirmyn", currentText: "Šiandien", monthNames: [ "Sausis", "Vasaris", "Kovas", "Balandis", "Gegužė", "Birželis", "Liepa", "Rugpjūtis", "Rugsėjis", "Spalis", "Lapkritis", "Gruodis" ], monthNamesShort: [ "Sau", "Vas", "Kov", "Bal", "Geg", "Bir", "Lie", "Rugp", "Rugs", "Spa", "Lap", "Gru" ], dayNames: [ "sekmadienis", "pirmadienis", "antradienis", "trečiadienis", "ketvirtadienis", "penktadienis", "šeštadienis" ], dayNamesShort: [ "sek", "pir", "ant", "tre", "ket", "pen", "šeš" ], dayNamesMin: [ "Se", "Pr", "An", "Tr", "Ke", "Pe", "Še" ], weekHeader: "SAV", dateFormat: "yy-mm-dd", firstDay: 1, isRTL: false, showMonthAfterYear: true, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.lt ); return datepicker.regional.lt; } ); ================================================ FILE: ui/i18n/datepicker-lv.js ================================================ /* Latvian (UTF-8) initialisation for the jQuery UI date picker plugin. */ /* @author Arturas Paleicikas */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.lv = { closeText: "Aizvērt", prevText: "Iepr.", nextText: "Nāk.", currentText: "Šodien", monthNames: [ "Janvāris", "Februāris", "Marts", "Aprīlis", "Maijs", "Jūnijs", "Jūlijs", "Augusts", "Septembris", "Oktobris", "Novembris", "Decembris" ], monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "Mai", "Jūn", "Jūl", "Aug", "Sep", "Okt", "Nov", "Dec" ], dayNames: [ "svētdiena", "pirmdiena", "otrdiena", "trešdiena", "ceturtdiena", "piektdiena", "sestdiena" ], dayNamesShort: [ "svt", "prm", "otr", "tre", "ctr", "pkt", "sst" ], dayNamesMin: [ "Sv", "Pr", "Ot", "Tr", "Ct", "Pk", "Ss" ], weekHeader: "Ned.", dateFormat: "dd.mm.yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.lv ); return datepicker.regional.lv; } ); ================================================ FILE: ui/i18n/datepicker-mk.js ================================================ /* Macedonian i18n for the jQuery UI date picker plugin. */ /* Written by Stojce Slavkovski. */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.mk = { closeText: "Затвори", prevText: "Претходна", nextText: "Следно", currentText: "Денес", monthNames: [ "Јануари", "Февруари", "Март", "Април", "Мај", "Јуни", "Јули", "Август", "Септември", "Октомври", "Ноември", "Декември" ], monthNamesShort: [ "Јан", "Фев", "Мар", "Апр", "Мај", "Јун", "Јул", "Авг", "Сеп", "Окт", "Ное", "Дек" ], dayNames: [ "Недела", "Понеделник", "Вторник", "Среда", "Четврток", "Петок", "Сабота" ], dayNamesShort: [ "Нед", "Пон", "Вто", "Сре", "Чет", "Пет", "Саб" ], dayNamesMin: [ "Не", "По", "Вт", "Ср", "Че", "Пе", "Са" ], weekHeader: "Сед", dateFormat: "dd.mm.yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.mk ); return datepicker.regional.mk; } ); ================================================ FILE: ui/i18n/datepicker-ml.js ================================================ /* Malayalam (UTF-8) initialisation for the jQuery UI date picker plugin. */ /* Written by Saji Nediyanchath (saji89@gmail.com). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.ml = { closeText: "ശരി", prevText: "മുന്നത്തെ", nextText: "അടുത്തത് ", currentText: "ഇന്ന്", monthNames: [ "ജനുവരി", "ഫെബ്രുവരി", "മാര്‍ച്ച്", "ഏപ്രില്‍", "മേയ്", "ജൂണ്‍", "ജൂലൈ", "ആഗസ്റ്റ്", "സെപ്റ്റംബര്‍", "ഒക്ടോബര്‍", "നവംബര്‍", "ഡിസംബര്‍" ], monthNamesShort: [ "ജനു", "ഫെബ്", "മാര്‍", "ഏപ്രി", "മേയ്", "ജൂണ്‍", "ജൂലാ", "ആഗ", "സെപ്", "ഒക്ടോ", "നവം", "ഡിസ" ], dayNames: [ "ഞായര്‍", "തിങ്കള്‍", "ചൊവ്വ", "ബുധന്‍", "വ്യാഴം", "വെള്ളി", "ശനി" ], dayNamesShort: [ "ഞായ", "തിങ്ക", "ചൊവ്വ", "ബുധ", "വ്യാഴം", "വെള്ളി", "ശനി" ], dayNamesMin: [ "ഞാ", "തി", "ചൊ", "ബു", "വ്യാ", "വെ", "ശ" ], weekHeader: "ആ", dateFormat: "dd/mm/yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.ml ); return datepicker.regional.ml; } ); ================================================ FILE: ui/i18n/datepicker-ms.js ================================================ /* Malaysian initialisation for the jQuery UI date picker plugin. */ /* Written by Mohd Nawawi Mohamad Jamili (nawawi@ronggeng.net). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.ms = { closeText: "Tutup", prevText: "Sebelum", nextText: "Selepas", currentText: "hari ini", monthNames: [ "Januari", "Februari", "Mac", "April", "Mei", "Jun", "Julai", "Ogos", "September", "Oktober", "November", "Disember" ], monthNamesShort: [ "Jan", "Feb", "Mac", "Apr", "Mei", "Jun", "Jul", "Ogo", "Sep", "Okt", "Nov", "Dis" ], dayNames: [ "Ahad", "Isnin", "Selasa", "Rabu", "Khamis", "Jumaat", "Sabtu" ], dayNamesShort: [ "Aha", "Isn", "Sel", "Rab", "kha", "Jum", "Sab" ], dayNamesMin: [ "Ah", "Is", "Se", "Ra", "Kh", "Ju", "Sa" ], weekHeader: "Mg", dateFormat: "dd/mm/yy", firstDay: 0, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.ms ); return datepicker.regional.ms; } ); ================================================ FILE: ui/i18n/datepicker-nb.js ================================================ /* Norwegian Bokmål initialisation for the jQuery UI date picker plugin. */ /* Written by Bjørn Johansen (post@bjornjohansen.no). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.nb = { closeText: "Lukk", prevText: "Forrige", nextText: "Neste", currentText: "I dag", monthNames: [ "januar", "februar", "mars", "april", "mai", "juni", "juli", "august", "september", "oktober", "november", "desember" ], monthNamesShort: [ "jan", "feb", "mar", "apr", "mai", "jun", "jul", "aug", "sep", "okt", "nov", "des" ], dayNamesShort: [ "søn", "man", "tir", "ons", "tor", "fre", "lør" ], dayNames: [ "søndag", "mandag", "tirsdag", "onsdag", "torsdag", "fredag", "lørdag" ], dayNamesMin: [ "sø", "ma", "ti", "on", "to", "fr", "lø" ], weekHeader: "Uke", dateFormat: "dd.mm.yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.nb ); return datepicker.regional.nb; } ); ================================================ FILE: ui/i18n/datepicker-nl-BE.js ================================================ /* Dutch (Belgium) initialisation for the jQuery UI date picker plugin. */ /* David De Sloovere @DavidDeSloovere */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional[ "nl-BE" ] = { closeText: "Sluiten", prevText: "Vorig", nextText: "Volgende", currentText: "Vandaag", monthNames: [ "januari", "februari", "maart", "april", "mei", "juni", "juli", "augustus", "september", "oktober", "november", "december" ], monthNamesShort: [ "jan", "feb", "mrt", "apr", "mei", "jun", "jul", "aug", "sep", "okt", "nov", "dec" ], dayNames: [ "zondag", "maandag", "dinsdag", "woensdag", "donderdag", "vrijdag", "zaterdag" ], dayNamesShort: [ "zon", "maa", "din", "woe", "don", "vri", "zat" ], dayNamesMin: [ "zo", "ma", "di", "wo", "do", "vr", "za" ], weekHeader: "Wk", dateFormat: "dd/mm/yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional[ "nl-BE" ] ); return datepicker.regional[ "nl-BE" ]; } ); ================================================ FILE: ui/i18n/datepicker-nl.js ================================================ /* Dutch (UTF-8) initialisation for the jQuery UI date picker plugin. */ /* Written by Mathias Bynens */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.nl = { closeText: "Sluiten", prevText: "Vorig", nextText: "Volgende", currentText: "Vandaag", monthNames: [ "januari", "februari", "maart", "april", "mei", "juni", "juli", "augustus", "september", "oktober", "november", "december" ], monthNamesShort: [ "jan", "feb", "mrt", "apr", "mei", "jun", "jul", "aug", "sep", "okt", "nov", "dec" ], dayNames: [ "zondag", "maandag", "dinsdag", "woensdag", "donderdag", "vrijdag", "zaterdag" ], dayNamesShort: [ "zon", "maa", "din", "woe", "don", "vri", "zat" ], dayNamesMin: [ "zo", "ma", "di", "wo", "do", "vr", "za" ], weekHeader: "Wk", dateFormat: "dd-mm-yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.nl ); return datepicker.regional.nl; } ); ================================================ FILE: ui/i18n/datepicker-nn.js ================================================ /* Norwegian Nynorsk initialisation for the jQuery UI date picker plugin. */ /* Written by Bjørn Johansen (post@bjornjohansen.no). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.nn = { closeText: "Lukk", prevText: "Førre", nextText: "Neste", currentText: "I dag", monthNames: [ "januar", "februar", "mars", "april", "mai", "juni", "juli", "august", "september", "oktober", "november", "desember" ], monthNamesShort: [ "jan", "feb", "mar", "apr", "mai", "jun", "jul", "aug", "sep", "okt", "nov", "des" ], dayNamesShort: [ "sun", "mån", "tys", "ons", "tor", "fre", "lau" ], dayNames: [ "sundag", "måndag", "tysdag", "onsdag", "torsdag", "fredag", "laurdag" ], dayNamesMin: [ "su", "må", "ty", "on", "to", "fr", "la" ], weekHeader: "Veke", dateFormat: "dd.mm.yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.nn ); return datepicker.regional.nn; } ); ================================================ FILE: ui/i18n/datepicker-no.js ================================================ /* Norwegian initialisation for the jQuery UI date picker plugin. */ /* Written by Naimdjon Takhirov (naimdjon@gmail.com). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.no = { closeText: "Lukk", prevText: "Forrige", nextText: "Neste", currentText: "I dag", monthNames: [ "januar", "februar", "mars", "april", "mai", "juni", "juli", "august", "september", "oktober", "november", "desember" ], monthNamesShort: [ "jan", "feb", "mar", "apr", "mai", "jun", "jul", "aug", "sep", "okt", "nov", "des" ], dayNamesShort: [ "søn", "man", "tir", "ons", "tor", "fre", "lør" ], dayNames: [ "søndag", "mandag", "tirsdag", "onsdag", "torsdag", "fredag", "lørdag" ], dayNamesMin: [ "sø", "ma", "ti", "on", "to", "fr", "lø" ], weekHeader: "Uke", dateFormat: "dd.mm.yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.no ); return datepicker.regional.no; } ); ================================================ FILE: ui/i18n/datepicker-pl.js ================================================ /* Polish initialisation for the jQuery UI date picker plugin. */ /* Written by Jacek Wysocki (jacek.wysocki@gmail.com). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.pl = { closeText: "Zamknij", prevText: "Poprzedni", nextText: "Następny", currentText: "Dziś", monthNames: [ "Styczeń", "Luty", "Marzec", "Kwiecień", "Maj", "Czerwiec", "Lipiec", "Sierpień", "Wrzesień", "Październik", "Listopad", "Grudzień" ], monthNamesShort: [ "Sty", "Lu", "Mar", "Kw", "Maj", "Cze", "Lip", "Sie", "Wrz", "Pa", "Lis", "Gru" ], dayNames: [ "Niedziela", "Poniedziałek", "Wtorek", "Środa", "Czwartek", "Piątek", "Sobota" ], dayNamesShort: [ "Nie", "Pn", "Wt", "Śr", "Czw", "Pt", "So" ], dayNamesMin: [ "N", "Pn", "Wt", "Śr", "Cz", "Pt", "So" ], weekHeader: "Tydz", dateFormat: "dd.mm.yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.pl ); return datepicker.regional.pl; } ); ================================================ FILE: ui/i18n/datepicker-pt-BR.js ================================================ /* Brazilian initialisation for the jQuery UI date picker plugin. */ /* Written by Leonildo Costa Silva (leocsilva@gmail.com). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional[ "pt-BR" ] = { closeText: "Fechar", prevText: "Anterior", nextText: "Próximo", currentText: "Hoje", monthNames: [ "Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro" ], monthNamesShort: [ "Jan", "Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez" ], dayNames: [ "Domingo", "Segunda-feira", "Terça-feira", "Quarta-feira", "Quinta-feira", "Sexta-feira", "Sábado" ], dayNamesShort: [ "Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb" ], dayNamesMin: [ "Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb" ], weekHeader: "Sm", dateFormat: "dd/mm/yy", firstDay: 0, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional[ "pt-BR" ] ); return datepicker.regional[ "pt-BR" ]; } ); ================================================ FILE: ui/i18n/datepicker-pt.js ================================================ /* Portuguese initialisation for the jQuery UI date picker plugin. */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.pt = { closeText: "Fechar", prevText: "Anterior", nextText: "Seguinte", currentText: "Hoje", monthNames: [ "Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro" ], monthNamesShort: [ "Jan", "Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez" ], dayNames: [ "Domingo", "Segunda-feira", "Terça-feira", "Quarta-feira", "Quinta-feira", "Sexta-feira", "Sábado" ], dayNamesShort: [ "Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb" ], dayNamesMin: [ "Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb" ], weekHeader: "Sem", dateFormat: "dd/mm/yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.pt ); return datepicker.regional.pt; } ); ================================================ FILE: ui/i18n/datepicker-rm.js ================================================ /* Romansh initialisation for the jQuery UI date picker plugin. */ /* Written by Yvonne Gienal (yvonne.gienal@educa.ch). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.rm = { closeText: "Serrar", prevText: "Suandant", nextText: "Precedent", currentText: "Actual", monthNames: [ "Schaner", "Favrer", "Mars", "Avrigl", "Matg", "Zercladur", "Fanadur", "Avust", "Settember", "October", "November", "December" ], monthNamesShort: [ "Scha", "Fev", "Mar", "Avr", "Matg", "Zer", "Fan", "Avu", "Sett", "Oct", "Nov", "Dec" ], dayNames: [ "Dumengia", "Glindesdi", "Mardi", "Mesemna", "Gievgia", "Venderdi", "Sonda" ], dayNamesShort: [ "Dum", "Gli", "Mar", "Mes", "Gie", "Ven", "Som" ], dayNamesMin: [ "Du", "Gl", "Ma", "Me", "Gi", "Ve", "So" ], weekHeader: "emna", dateFormat: "dd/mm/yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.rm ); return datepicker.regional.rm; } ); ================================================ FILE: ui/i18n/datepicker-ro.js ================================================ /* Romanian initialisation for the jQuery UI date picker plugin. * * Written by Edmond L. (ll_edmond@walla.com) * and Ionut G. Stan (ionut.g.stan@gmail.com) */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.ro = { closeText: "Închide", prevText: "Luna precedentă", nextText: "Luna următoare ", currentText: "Azi", monthNames: [ "Ianuarie", "Februarie", "Martie", "Aprilie", "Mai", "Iunie", "Iulie", "August", "Septembrie", "Octombrie", "Noiembrie", "Decembrie" ], monthNamesShort: [ "Ian", "Feb", "Mar", "Apr", "Mai", "Iun", "Iul", "Aug", "Sep", "Oct", "Nov", "Dec" ], dayNames: [ "Duminică", "Luni", "Marţi", "Miercuri", "Joi", "Vineri", "Sâmbătă" ], dayNamesShort: [ "Dum", "Lun", "Mar", "Mie", "Joi", "Vin", "Sâm" ], dayNamesMin: [ "Du", "Lu", "Ma", "Mi", "Jo", "Vi", "Sâ" ], weekHeader: "Săpt", dateFormat: "dd.mm.yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.ro ); return datepicker.regional.ro; } ); ================================================ FILE: ui/i18n/datepicker-ru.js ================================================ /* Russian (UTF-8) initialisation for the jQuery UI date picker plugin. */ /* Written by Andrew Stromnov (stromnov@gmail.com). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.ru = { closeText: "Закрыть", prevText: "Пред", nextText: "След", currentText: "Сегодня", monthNames: [ "Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь" ], monthNamesShort: [ "Янв", "Фев", "Мар", "Апр", "Май", "Июн", "Июл", "Авг", "Сен", "Окт", "Ноя", "Дек" ], dayNames: [ "воскресенье", "понедельник", "вторник", "среда", "четверг", "пятница", "суббота" ], dayNamesShort: [ "вск", "пнд", "втр", "срд", "чтв", "птн", "сбт" ], dayNamesMin: [ "Вс", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб" ], weekHeader: "Нед", dateFormat: "dd.mm.yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.ru ); return datepicker.regional.ru; } ); ================================================ FILE: ui/i18n/datepicker-sk.js ================================================ /* Slovak initialisation for the jQuery UI date picker plugin. */ /* Written by Vojtech Rinik (vojto@hmm.sk). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.sk = { closeText: "Zavrieť", prevText: "Predchádzajúci", nextText: "Nasledujúci", currentText: "Dnes", monthNames: [ "január", "február", "marec", "apríl", "máj", "jún", "júl", "august", "september", "október", "november", "december" ], monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "Máj", "Jún", "Júl", "Aug", "Sep", "Okt", "Nov", "Dec" ], dayNames: [ "nedeľa", "pondelok", "utorok", "streda", "štvrtok", "piatok", "sobota" ], dayNamesShort: [ "Ned", "Pon", "Uto", "Str", "Štv", "Pia", "Sob" ], dayNamesMin: [ "Ne", "Po", "Ut", "St", "Št", "Pia", "So" ], weekHeader: "Ty", dateFormat: "dd.mm.yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.sk ); return datepicker.regional.sk; } ); ================================================ FILE: ui/i18n/datepicker-sl.js ================================================ /* Slovenian initialisation for the jQuery UI date picker plugin. */ /* Written by Jaka Jancar (jaka@kubje.org). */ /* c = č, s = š z = ž C = Č S = Š Z = Ž */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.sl = { closeText: "Zapri", prevText: "Prejšnji", nextText: "Naslednji", currentText: "Trenutni", monthNames: [ "Januar", "Februar", "Marec", "April", "Maj", "Junij", "Julij", "Avgust", "September", "Oktober", "November", "December" ], monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "Maj", "Jun", "Jul", "Avg", "Sep", "Okt", "Nov", "Dec" ], dayNames: [ "Nedelja", "Ponedeljek", "Torek", "Sreda", "Četrtek", "Petek", "Sobota" ], dayNamesShort: [ "Ned", "Pon", "Tor", "Sre", "Čet", "Pet", "Sob" ], dayNamesMin: [ "Ne", "Po", "To", "Sr", "Če", "Pe", "So" ], weekHeader: "Teden", dateFormat: "dd.mm.yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.sl ); return datepicker.regional.sl; } ); ================================================ FILE: ui/i18n/datepicker-sq.js ================================================ /* Albanian initialisation for the jQuery UI date picker plugin. */ /* Written by Flakron Bytyqi (flakron@gmail.com). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.sq = { closeText: "mbylle", prevText: "mbrapa", nextText: "Përpara", currentText: "sot", monthNames: [ "Janar", "Shkurt", "Mars", "Prill", "Maj", "Qershor", "Korrik", "Gusht", "Shtator", "Tetor", "Nëntor", "Dhjetor" ], monthNamesShort: [ "Jan", "Shk", "Mar", "Pri", "Maj", "Qer", "Kor", "Gus", "Sht", "Tet", "Nën", "Dhj" ], dayNames: [ "E Diel", "E Hënë", "E Martë", "E Mërkurë", "E Enjte", "E Premte", "E Shtune" ], dayNamesShort: [ "Di", "Hë", "Ma", "Më", "En", "Pr", "Sh" ], dayNamesMin: [ "Di", "Hë", "Ma", "Më", "En", "Pr", "Sh" ], weekHeader: "Ja", dateFormat: "dd.mm.yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.sq ); return datepicker.regional.sq; } ); ================================================ FILE: ui/i18n/datepicker-sr-SR.js ================================================ /* Serbian i18n for the jQuery UI date picker plugin. */ /* Written by Dejan Dimić. */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional[ "sr-SR" ] = { closeText: "Zatvori", prevText: "Prethodno", nextText: "Sljedeći", currentText: "Danas", monthNames: [ "Januar", "Februar", "Mart", "April", "Maj", "Jun", "Jul", "Avgust", "Septembar", "Oktobar", "Novembar", "Decembar" ], monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "Maj", "Jun", "Jul", "Avg", "Sep", "Okt", "Nov", "Dec" ], dayNames: [ "Nedelja", "Ponedeljak", "Utorak", "Sreda", "Četvrtak", "Petak", "Subota" ], dayNamesShort: [ "Ned", "Pon", "Uto", "Sre", "Čet", "Pet", "Sub" ], dayNamesMin: [ "Ne", "Po", "Ut", "Sr", "Če", "Pe", "Su" ], weekHeader: "Sed", dateFormat: "dd.mm.yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional[ "sr-SR" ] ); return datepicker.regional[ "sr-SR" ]; } ); ================================================ FILE: ui/i18n/datepicker-sr.js ================================================ /* Serbian i18n for the jQuery UI date picker plugin. */ /* Written by Dejan Dimić. */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.sr = { closeText: "Затвори", prevText: "Претходна", nextText: "Следећи", currentText: "Данас", monthNames: [ "Јануар", "Фебруар", "Март", "Април", "Мај", "Јун", "Јул", "Август", "Септембар", "Октобар", "Новембар", "Децембар" ], monthNamesShort: [ "Јан", "Феб", "Мар", "Апр", "Мај", "Јун", "Јул", "Авг", "Сеп", "Окт", "Нов", "Дец" ], dayNames: [ "Недеља", "Понедељак", "Уторак", "Среда", "Четвртак", "Петак", "Субота" ], dayNamesShort: [ "Нед", "Пон", "Уто", "Сре", "Чет", "Пет", "Суб" ], dayNamesMin: [ "Не", "По", "Ут", "Ср", "Че", "Пе", "Су" ], weekHeader: "Сед", dateFormat: "dd.mm.yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.sr ); return datepicker.regional.sr; } ); ================================================ FILE: ui/i18n/datepicker-sv.js ================================================ /* Swedish initialisation for the jQuery UI date picker plugin. */ /* Written by Anders Ekdahl ( anders@nomadiz.se). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.sv = { closeText: "Stäng", prevText: "Förra", nextText: "Nästa", currentText: "Idag", monthNames: [ "januari", "februari", "mars", "april", "maj", "juni", "juli", "augusti", "september", "oktober", "november", "december" ], monthNamesShort: [ "jan.", "feb.", "mars", "apr.", "maj", "juni", "juli", "aug.", "sep.", "okt.", "nov.", "dec." ], dayNamesShort: [ "sön", "mån", "tis", "ons", "tor", "fre", "lör" ], dayNames: [ "söndag", "måndag", "tisdag", "onsdag", "torsdag", "fredag", "lördag" ], dayNamesMin: [ "sö", "må", "ti", "on", "to", "fr", "lö" ], weekHeader: "Ve", dateFormat: "yy-mm-dd", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.sv ); return datepicker.regional.sv; } ); ================================================ FILE: ui/i18n/datepicker-ta.js ================================================ /* Tamil (UTF-8) initialisation for the jQuery UI date picker plugin. */ /* Written by S A Sureshkumar (saskumar@live.com). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.ta = { closeText: "மூடு", prevText: "முன்னையது", nextText: "அடுத்தது", currentText: "இன்று", monthNames: [ "தை", "மாசி", "பங்குனி", "சித்திரை", "வைகாசி", "ஆனி", "ஆடி", "ஆவணி", "புரட்டாசி", "ஐப்பசி", "கார்த்திகை", "மார்கழி" ], monthNamesShort: [ "தை", "மாசி", "பங்", "சித்", "வைகா", "ஆனி", "ஆடி", "ஆவ", "புர", "ஐப்", "கார்", "மார்" ], dayNames: [ "ஞாயிற்றுக்கிழமை", "திங்கட்கிழமை", "செவ்வாய்க்கிழமை", "புதன்கிழமை", "வியாழக்கிழமை", "வெள்ளிக்கிழமை", "சனிக்கிழமை" ], dayNamesShort: [ "ஞாயிறு", "திங்கள்", "செவ்வாய்", "புதன்", "வியாழன்", "வெள்ளி", "சனி" ], dayNamesMin: [ "ஞா", "தி", "செ", "பு", "வி", "வெ", "ச" ], weekHeader: "Не", dateFormat: "dd/mm/yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.ta ); return datepicker.regional.ta; } ); ================================================ FILE: ui/i18n/datepicker-th.js ================================================ /* Thai initialisation for the jQuery UI date picker plugin. */ /* Written by pipo (pipo@sixhead.com). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.th = { closeText: "ปิด", prevText: "ย้อน", nextText: "ถัดไป", currentText: "วันนี้", monthNames: [ "มกราคม", "กุมภาพันธ์", "มีนาคม", "เมษายน", "พฤษภาคม", "มิถุนายน", "กรกฎาคม", "สิงหาคม", "กันยายน", "ตุลาคม", "พฤศจิกายน", "ธันวาคม" ], monthNamesShort: [ "ม.ค.", "ก.พ.", "มี.ค.", "เม.ย.", "พ.ค.", "มิ.ย.", "ก.ค.", "ส.ค.", "ก.ย.", "ต.ค.", "พ.ย.", "ธ.ค." ], dayNames: [ "อาทิตย์", "จันทร์", "อังคาร", "พุธ", "พฤหัสบดี", "ศุกร์", "เสาร์" ], dayNamesShort: [ "อา.", "จ.", "อ.", "พ.", "พฤ.", "ศ.", "ส." ], dayNamesMin: [ "อา.", "จ.", "อ.", "พ.", "พฤ.", "ศ.", "ส." ], weekHeader: "Wk", dateFormat: "dd/mm/yy", firstDay: 0, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.th ); return datepicker.regional.th; } ); ================================================ FILE: ui/i18n/datepicker-tj.js ================================================ /* Tajiki (UTF-8) initialisation for the jQuery UI date picker plugin. */ /* Written by Abdurahmon Saidov (saidovab@gmail.com). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.tj = { closeText: "Идома", prevText: "Қафо", nextText: "Пеш", currentText: "Имрӯз", monthNames: [ "Январ", "Феврал", "Март", "Апрел", "Май", "Июн", "Июл", "Август", "Сентябр", "Октябр", "Ноябр", "Декабр" ], monthNamesShort: [ "Янв", "Фев", "Мар", "Апр", "Май", "Июн", "Июл", "Авг", "Сен", "Окт", "Ноя", "Дек" ], dayNames: [ "якшанбе", "душанбе", "сешанбе", "чоршанбе", "панҷшанбе", "ҷумъа", "шанбе" ], dayNamesShort: [ "якш", "душ", "сеш", "чор", "пан", "ҷум", "шан" ], dayNamesMin: [ "Як", "Дш", "Сш", "Чш", "Пш", "Ҷм", "Шн" ], weekHeader: "Хф", dateFormat: "dd.mm.yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.tj ); return datepicker.regional.tj; } ); ================================================ FILE: ui/i18n/datepicker-tr.js ================================================ /* Turkish initialisation for the jQuery UI date picker plugin. */ /* Written by Izzet Emre Erkan (kara@karalamalar.net). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.tr = { closeText: "kapat", prevText: "geri", nextText: "ileri", currentText: "bugün", monthNames: [ "Ocak", "Şubat", "Mart", "Nisan", "Mayıs", "Haziran", "Temmuz", "Ağustos", "Eylül", "Ekim", "Kasım", "Aralık" ], monthNamesShort: [ "Oca", "Şub", "Mar", "Nis", "May", "Haz", "Tem", "Ağu", "Eyl", "Eki", "Kas", "Ara" ], dayNames: [ "Pazar", "Pazartesi", "Salı", "Çarşamba", "Perşembe", "Cuma", "Cumartesi" ], dayNamesShort: [ "Pz", "Pt", "Sa", "Ça", "Pe", "Cu", "Ct" ], dayNamesMin: [ "Pz", "Pt", "Sa", "Ça", "Pe", "Cu", "Ct" ], weekHeader: "Hf", dateFormat: "dd.mm.yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.tr ); return datepicker.regional.tr; } ); ================================================ FILE: ui/i18n/datepicker-uk.js ================================================ /* Ukrainian (UTF-8) initialisation for the jQuery UI date picker plugin. */ /* Written by Maxim Drogobitskiy (maxdao@gmail.com). */ /* Corrected by Igor Milla (igor.fsp.milla@gmail.com). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.uk = { closeText: "Закрити", prevText: "Попередній", nextText: "найближчий", currentText: "Сьогодні", monthNames: [ "Січень", "Лютий", "Березень", "Квітень", "Травень", "Червень", "Липень", "Серпень", "Вересень", "Жовтень", "Листопад", "Грудень" ], monthNamesShort: [ "Січ", "Лют", "Бер", "Кві", "Тра", "Чер", "Лип", "Сер", "Вер", "Жов", "Лис", "Гру" ], dayNames: [ "неділя", "понеділок", "вівторок", "середа", "четвер", "п’ятниця", "субота" ], dayNamesShort: [ "нед", "пнд", "вів", "срд", "чтв", "птн", "сбт" ], dayNamesMin: [ "Нд", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб" ], weekHeader: "Тиж", dateFormat: "dd.mm.yy", firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.uk ); return datepicker.regional.uk; } ); ================================================ FILE: ui/i18n/datepicker-vi.js ================================================ /* Vietnamese initialisation for the jQuery UI date picker plugin. */ /* Translated by Le Thanh Huy (lthanhhuy@cit.ctu.edu.vn). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional.vi = { closeText: "Đóng", prevText: "Trước", nextText: "Tiếp", currentText: "Hôm nay", monthNames: [ "Tháng Một", "Tháng Hai", "Tháng Ba", "Tháng Tư", "Tháng Năm", "Tháng Sáu", "Tháng Bảy", "Tháng Tám", "Tháng Chín", "Tháng Mười", "Tháng Mười Một", "Tháng Mười Hai" ], monthNamesShort: [ "Tháng 1", "Tháng 2", "Tháng 3", "Tháng 4", "Tháng 5", "Tháng 6", "Tháng 7", "Tháng 8", "Tháng 9", "Tháng 10", "Tháng 11", "Tháng 12" ], dayNames: [ "Chủ Nhật", "Thứ Hai", "Thứ Ba", "Thứ Tư", "Thứ Năm", "Thứ Sáu", "Thứ Bảy" ], dayNamesShort: [ "CN", "T2", "T3", "T4", "T5", "T6", "T7" ], dayNamesMin: [ "CN", "T2", "T3", "T4", "T5", "T6", "T7" ], weekHeader: "Tu", dateFormat: "dd/mm/yy", firstDay: 0, isRTL: false, showMonthAfterYear: false, yearSuffix: "" }; datepicker.setDefaults( datepicker.regional.vi ); return datepicker.regional.vi; } ); ================================================ FILE: ui/i18n/datepicker-zh-CN.js ================================================ /* Chinese initialisation for the jQuery UI date picker plugin. */ /* Written by Cloudream (cloudream@gmail.com). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional[ "zh-CN" ] = { closeText: "关闭", prevText: "上月", nextText: "下月", currentText: "今天", monthNames: [ "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月" ], monthNamesShort: [ "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月" ], dayNames: [ "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" ], dayNamesShort: [ "周日", "周一", "周二", "周三", "周四", "周五", "周六" ], dayNamesMin: [ "日", "一", "二", "三", "四", "五", "六" ], weekHeader: "周", dateFormat: "yy-mm-dd", firstDay: 1, isRTL: false, showMonthAfterYear: true, yearSuffix: "年" }; datepicker.setDefaults( datepicker.regional[ "zh-CN" ] ); return datepicker.regional[ "zh-CN" ]; } ); ================================================ FILE: ui/i18n/datepicker-zh-HK.js ================================================ /* Chinese initialisation for the jQuery UI date picker plugin. */ /* Written by SCCY (samuelcychan@gmail.com). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional[ "zh-HK" ] = { closeText: "關閉", prevText: "上月", nextText: "下月", currentText: "今天", monthNames: [ "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月" ], monthNamesShort: [ "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月" ], dayNames: [ "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" ], dayNamesShort: [ "周日", "周一", "周二", "周三", "周四", "周五", "周六" ], dayNamesMin: [ "日", "一", "二", "三", "四", "五", "六" ], weekHeader: "周", dateFormat: "dd-mm-yy", firstDay: 0, isRTL: false, showMonthAfterYear: true, yearSuffix: "年" }; datepicker.setDefaults( datepicker.regional[ "zh-HK" ] ); return datepicker.regional[ "zh-HK" ]; } ); ================================================ FILE: ui/i18n/datepicker-zh-TW.js ================================================ /* Chinese initialisation for the jQuery UI date picker plugin. */ /* Written by Ressol (ressol@gmail.com). */ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "../widgets/datepicker" ], factory ); } else { // Browser globals factory( jQuery.datepicker ); } } )( function( datepicker ) { "use strict"; datepicker.regional[ "zh-TW" ] = { closeText: "關閉", prevText: "上個月", nextText: "下個月", currentText: "今天", monthNames: [ "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月" ], monthNamesShort: [ "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月" ], dayNames: [ "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" ], dayNamesShort: [ "週日", "週一", "週二", "週三", "週四", "週五", "週六" ], dayNamesMin: [ "日", "一", "二", "三", "四", "五", "六" ], weekHeader: "週", dateFormat: "yy/mm/dd", firstDay: 1, isRTL: false, showMonthAfterYear: true, yearSuffix: "年" }; datepicker.setDefaults( datepicker.regional[ "zh-TW" ] ); return datepicker.regional[ "zh-TW" ]; } ); ================================================ FILE: ui/jquery-patch.js ================================================ /*! * jQuery UI Legacy jQuery Core patches @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license * */ //>>label: Legacy jQuery Core patches //>>group: Core //>>description: Backport `.even()`, `.odd()` and `$.escapeSelector` to older jQuery Core versions (deprecated) ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "jquery", "./version" ], factory ); } else { // Browser globals factory( jQuery ); } } )( function( $ ) { "use strict"; // Support: jQuery 2.2.x or older. // This method has been defined in jQuery 3.0.0. // Code from https://github.com/jquery/jquery/blob/e539bac79e666bba95bba86d690b4e609dca2286/src/selector/escapeSelector.js if ( !$.escapeSelector ) { $.escapeSelector = function( id ) { return CSS.escape( id + "" ); }; } // Support: jQuery 3.4.x or older // These methods have been defined in jQuery 3.5.0. if ( !$.fn.even || !$.fn.odd ) { $.fn.extend( { even: function() { return this.filter( function( i ) { return i % 2 === 0; } ); }, odd: function() { return this.filter( function( i ) { return i % 2 === 1; } ); } } ); } } ); ================================================ FILE: ui/jquery-var-for-color.js ================================================ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "jquery", "./version" ], factory ); } else { // Browser globals factory( jQuery ); } } )( function( $ ) { "use strict"; // Create a local jQuery because jQuery Color relies on it and the // global may not exist with AMD and a custom build (#10199). // This module is a noop if used as a regular AMD module. // eslint-disable-next-line no-unused-vars var jQuery = $; } ); ================================================ FILE: ui/keycode.js ================================================ /*! * jQuery UI Keycode @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license */ //>>label: Keycode //>>group: Core //>>description: Provide keycodes as keynames //>>docs: https://api.jqueryui.com/jQuery.ui.keyCode/ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "jquery", "./version" ], factory ); } else { // Browser globals factory( jQuery ); } } )( function( $ ) { "use strict"; return $.ui.keyCode = { BACKSPACE: 8, COMMA: 188, DELETE: 46, DOWN: 40, END: 35, ENTER: 13, ESCAPE: 27, HOME: 36, LEFT: 37, PAGE_DOWN: 34, PAGE_UP: 33, PERIOD: 190, RIGHT: 39, SPACE: 32, TAB: 9, UP: 38 }; } ); ================================================ FILE: ui/labels.js ================================================ /*! * jQuery UI Labels @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license */ //>>label: labels //>>group: Core //>>description: Find all the labels associated with a given input //>>docs: https://api.jqueryui.com/labels/ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "jquery", "./version" ], factory ); } else { // Browser globals factory( jQuery ); } } )( function( $ ) { "use strict"; return $.fn.labels = function() { var ancestor, selector, id, labels, ancestors; if ( !this.length ) { return this.pushStack( [] ); } // Check control.labels first if ( this[ 0 ].labels && this[ 0 ].labels.length ) { return this.pushStack( this[ 0 ].labels ); } // If `control.labels` is empty - e.g. inside of document fragments - find // the labels manually labels = this.eq( 0 ).parents( "label" ); // Look for the label based on the id id = this.attr( "id" ); if ( id ) { // We don't search against the document in case the element // is disconnected from the DOM ancestor = this.eq( 0 ).parents().last(); // Get a full set of top level ancestors ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() ); // Create a selector for the label based on the id selector = "label[for='" + CSS.escape( id ) + "']"; labels = labels.add( ancestors.find( selector ).addBack( selector ) ); } // Return whatever we have found for labels return this.pushStack( labels ); }; } ); ================================================ FILE: ui/plugin.js ================================================ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "jquery", "./version" ], factory ); } else { // Browser globals factory( jQuery ); } } )( function( $ ) { "use strict"; // $.ui.plugin is deprecated. Use $.widget() extensions instead. return $.ui.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, allowDisconnected ) { var i, set = instance.plugins[ name ]; if ( !set ) { return; } if ( !allowDisconnected && ( !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 ); } } } }; } ); ================================================ FILE: ui/position.js ================================================ /*! * jQuery UI Position @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license * * https://api.jqueryui.com/position/ */ //>>label: Position //>>group: Core //>>description: Positions elements relative to other elements. //>>docs: https://api.jqueryui.com/position/ //>>demos: https://jqueryui.com/position/ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "jquery", "./version" ], factory ); } else { // Browser globals factory( jQuery ); } } )( function( $ ) { "use strict"; ( function() { var cachedScrollbarWidth, max = Math.max, abs = Math.abs, rhorizontal = /left|center|right/, rvertical = /top|center|bottom/, roffset = /[\+\-]\d+(\.[\d]+)?%?/, rposition = /^\w+/, rpercent = /%$/, _position = $.fn.position; function getOffsets( offsets, width, height ) { return [ parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) ]; } function parseCss( element, property ) { return parseInt( $.css( element, property ), 10 ) || 0; } function isWindow( obj ) { return obj != null && obj === obj.window; } function getDimensions( elem ) { var raw = elem[ 0 ]; if ( raw.nodeType === 9 ) { return { width: elem.width(), height: elem.height(), offset: { top: 0, left: 0 } }; } if ( isWindow( raw ) ) { return { width: elem.width(), height: elem.height(), offset: { top: elem.scrollTop(), left: elem.scrollLeft() } }; } if ( raw.preventDefault ) { return { width: 0, height: 0, offset: { top: raw.pageY, left: raw.pageX } }; } return { width: elem.outerWidth(), height: elem.outerHeight(), offset: elem.offset() }; } $.position = { scrollbarWidth: function() { if ( cachedScrollbarWidth !== undefined ) { return cachedScrollbarWidth; } var w1, w2, div = $( "
    " + "
    " ), innerDiv = div.children()[ 0 ]; $( "body" ).append( div ); w1 = innerDiv.offsetWidth; div.css( "overflow", "scroll" ); w2 = innerDiv.offsetWidth; if ( w1 === w2 ) { w2 = div[ 0 ].clientWidth; } div.remove(); return ( cachedScrollbarWidth = w1 - w2 ); }, getScrollInfo: function( within ) { var overflowX = within.isWindow || within.isDocument ? "" : within.element.css( "overflow-x" ), overflowY = within.isWindow || within.isDocument ? "" : within.element.css( "overflow-y" ), hasOverflowX = overflowX === "scroll" || ( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ), hasOverflowY = overflowY === "scroll" || ( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight ); return { width: hasOverflowY ? $.position.scrollbarWidth() : 0, height: hasOverflowX ? $.position.scrollbarWidth() : 0 }; }, getWithinInfo: function( element ) { var withinElement = $( element || window ), isElemWindow = isWindow( withinElement[ 0 ] ), isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9, hasOffset = !isElemWindow && !isDocument; return { element: withinElement, isWindow: isElemWindow, isDocument: isDocument, offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 }, scrollLeft: withinElement.scrollLeft(), scrollTop: withinElement.scrollTop(), width: withinElement.outerWidth(), height: withinElement.outerHeight() }; } }; $.fn.position = function( options ) { if ( !options || !options.of ) { return _position.apply( this, arguments ); } // Make a copy, we don't want to modify arguments options = $.extend( {}, options ); var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, // Make sure string options are treated as CSS selectors target = typeof options.of === "string" ? $( document ).find( options.of ) : $( options.of ), within = $.position.getWithinInfo( options.within ), scrollInfo = $.position.getScrollInfo( within ), collision = ( options.collision || "flip" ).split( " " ), offsets = {}; dimensions = getDimensions( target ); if ( target[ 0 ].preventDefault ) { // Force left top to allow flipping options.at = "left top"; } targetWidth = dimensions.width; targetHeight = dimensions.height; targetOffset = dimensions.offset; // Clone to reuse original targetOffset later basePosition = $.extend( {}, targetOffset ); // Force my and at to have valid horizontal and vertical positions // if a value is missing or invalid, it will be converted to center $.each( [ "my", "at" ], function() { var pos = ( options[ this ] || "" ).split( " " ), horizontalOffset, verticalOffset; if ( pos.length === 1 ) { pos = rhorizontal.test( pos[ 0 ] ) ? pos.concat( [ "center" ] ) : rvertical.test( pos[ 0 ] ) ? [ "center" ].concat( pos ) : [ "center", "center" ]; } pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; // Calculate offsets horizontalOffset = roffset.exec( pos[ 0 ] ); verticalOffset = roffset.exec( pos[ 1 ] ); offsets[ this ] = [ horizontalOffset ? horizontalOffset[ 0 ] : 0, verticalOffset ? verticalOffset[ 0 ] : 0 ]; // Reduce to just the positions without the offsets options[ this ] = [ rposition.exec( pos[ 0 ] )[ 0 ], rposition.exec( pos[ 1 ] )[ 0 ] ]; } ); // Normalize collision option if ( collision.length === 1 ) { collision[ 1 ] = collision[ 0 ]; } if ( options.at[ 0 ] === "right" ) { basePosition.left += targetWidth; } else if ( options.at[ 0 ] === "center" ) { basePosition.left += targetWidth / 2; } if ( options.at[ 1 ] === "bottom" ) { basePosition.top += targetHeight; } else if ( options.at[ 1 ] === "center" ) { basePosition.top += targetHeight / 2; } atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); basePosition.left += atOffset[ 0 ]; basePosition.top += atOffset[ 1 ]; return this.each( function() { var collisionPosition, using, elem = $( this ), elemWidth = elem.outerWidth(), elemHeight = elem.outerHeight(), marginLeft = parseCss( this, "marginLeft" ), marginTop = parseCss( this, "marginTop" ), collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width, collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height, position = $.extend( {}, basePosition ), myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); if ( options.my[ 0 ] === "right" ) { position.left -= elemWidth; } else if ( options.my[ 0 ] === "center" ) { position.left -= elemWidth / 2; } if ( options.my[ 1 ] === "bottom" ) { position.top -= elemHeight; } else if ( options.my[ 1 ] === "center" ) { position.top -= elemHeight / 2; } position.left += myOffset[ 0 ]; position.top += myOffset[ 1 ]; collisionPosition = { marginLeft: marginLeft, marginTop: marginTop }; $.each( [ "left", "top" ], function( i, dir ) { if ( $.ui.position[ collision[ i ] ] ) { $.ui.position[ collision[ i ] ][ dir ]( position, { targetWidth: targetWidth, targetHeight: targetHeight, elemWidth: elemWidth, elemHeight: elemHeight, collisionPosition: collisionPosition, collisionWidth: collisionWidth, collisionHeight: collisionHeight, offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], my: options.my, at: options.at, within: within, elem: elem } ); } } ); if ( options.using ) { // Adds feedback as second argument to using callback, if present using = function( props ) { var left = targetOffset.left - position.left, right = left + targetWidth - elemWidth, top = targetOffset.top - position.top, bottom = top + targetHeight - elemHeight, feedback = { target: { element: target, left: targetOffset.left, top: targetOffset.top, width: targetWidth, height: targetHeight }, element: { element: elem, left: position.left, top: position.top, width: elemWidth, height: elemHeight }, horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" }; if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { feedback.horizontal = "center"; } if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { feedback.vertical = "middle"; } if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { feedback.important = "horizontal"; } else { feedback.important = "vertical"; } options.using.call( this, props, feedback ); }; } elem.offset( $.extend( position, { using: using } ) ); } ); }; $.ui.position = { fit: { left: function( position, data ) { var within = data.within, withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, outerWidth = within.width, collisionPosLeft = position.left - data.collisionPosition.marginLeft, overLeft = withinOffset - collisionPosLeft, overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, newOverRight; // Element is wider than within if ( data.collisionWidth > outerWidth ) { // Element is initially over the left side of within if ( overLeft > 0 && overRight <= 0 ) { newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset; position.left += overLeft - newOverRight; // Element is initially over right side of within } else if ( overRight > 0 && overLeft <= 0 ) { position.left = withinOffset; // Element is initially over both left and right sides of within } else { if ( overLeft > overRight ) { position.left = withinOffset + outerWidth - data.collisionWidth; } else { position.left = withinOffset; } } // Too far left -> align with left edge } else if ( overLeft > 0 ) { position.left += overLeft; // Too far right -> align with right edge } else if ( overRight > 0 ) { position.left -= overRight; // Adjust based on position and margin } else { position.left = max( position.left - collisionPosLeft, position.left ); } }, top: function( position, data ) { var within = data.within, withinOffset = within.isWindow ? within.scrollTop : within.offset.top, outerHeight = data.within.height, collisionPosTop = position.top - data.collisionPosition.marginTop, overTop = withinOffset - collisionPosTop, overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, newOverBottom; // Element is taller than within if ( data.collisionHeight > outerHeight ) { // Element is initially over the top of within if ( overTop > 0 && overBottom <= 0 ) { newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset; position.top += overTop - newOverBottom; // Element is initially over bottom of within } else if ( overBottom > 0 && overTop <= 0 ) { position.top = withinOffset; // Element is initially over both top and bottom of within } else { if ( overTop > overBottom ) { position.top = withinOffset + outerHeight - data.collisionHeight; } else { position.top = withinOffset; } } // Too far up -> align with top } else if ( overTop > 0 ) { position.top += overTop; // Too far down -> align with bottom edge } else if ( overBottom > 0 ) { position.top -= overBottom; // Adjust based on position and margin } else { position.top = max( position.top - collisionPosTop, position.top ); } } }, flip: { left: function( position, data ) { var within = data.within, withinOffset = within.offset.left + within.scrollLeft, outerWidth = within.width, offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, collisionPosLeft = position.left - data.collisionPosition.marginLeft, overLeft = collisionPosLeft - offsetLeft, overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, myOffset = data.my[ 0 ] === "left" ? -data.elemWidth : data.my[ 0 ] === "right" ? data.elemWidth : 0, atOffset = data.at[ 0 ] === "left" ? data.targetWidth : data.at[ 0 ] === "right" ? -data.targetWidth : 0, offset = -2 * data.offset[ 0 ], newOverRight, newOverLeft; if ( overLeft < 0 ) { newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset; if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { position.left += myOffset + atOffset + offset; } } else if ( overRight > 0 ) { newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft; if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { position.left += myOffset + atOffset + offset; } } }, top: function( position, data ) { var within = data.within, withinOffset = within.offset.top + within.scrollTop, outerHeight = within.height, offsetTop = within.isWindow ? within.scrollTop : within.offset.top, collisionPosTop = position.top - data.collisionPosition.marginTop, overTop = collisionPosTop - offsetTop, overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, top = data.my[ 1 ] === "top", myOffset = top ? -data.elemHeight : data.my[ 1 ] === "bottom" ? data.elemHeight : 0, atOffset = data.at[ 1 ] === "top" ? data.targetHeight : data.at[ 1 ] === "bottom" ? -data.targetHeight : 0, offset = -2 * data.offset[ 1 ], newOverTop, newOverBottom; if ( overTop < 0 ) { newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset; if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) { position.top += myOffset + atOffset + offset; } } else if ( overBottom > 0 ) { newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop; if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) { position.top += myOffset + atOffset + offset; } } } }, flipfit: { left: function() { $.ui.position.flip.left.apply( this, arguments ); $.ui.position.fit.left.apply( this, arguments ); }, top: function() { $.ui.position.flip.top.apply( this, arguments ); $.ui.position.fit.top.apply( this, arguments ); } } }; } )(); return $.ui.position; } ); ================================================ FILE: ui/scroll-parent.js ================================================ /*! * jQuery UI Scroll Parent @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license */ //>>label: scrollParent //>>group: Core //>>description: Get the closest ancestor element that is scrollable. //>>docs: https://api.jqueryui.com/scrollParent/ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "jquery", "./version" ], factory ); } else { // Browser globals factory( jQuery ); } } )( function( $ ) { "use strict"; return $.fn.scrollParent = function( includeHidden ) { var position = this.css( "position" ), excludeStaticParent = position === "absolute", overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/, scrollParent = this.parents().filter( function() { var parent = $( this ); if ( excludeStaticParent && parent.css( "position" ) === "static" ) { return false; } return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + parent.css( "overflow-x" ) ); } ).eq( 0 ); return position === "fixed" || !scrollParent.length ? $( this[ 0 ].ownerDocument || document ) : scrollParent; }; } ); ================================================ FILE: ui/tabbable.js ================================================ /*! * jQuery UI Tabbable @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license */ //>>label: :tabbable Selector //>>group: Core //>>description: Selects elements which can be tabbed to. //>>docs: https://api.jqueryui.com/tabbable-selector/ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "jquery", "./version", "./focusable" ], factory ); } else { // Browser globals factory( jQuery ); } } )( function( $ ) { "use strict"; return $.extend( $.expr.pseudos, { tabbable: function( element ) { var tabIndex = $.attr( element, "tabindex" ), hasTabindex = tabIndex != null; return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex ); } } ); } ); ================================================ FILE: ui/unique-id.js ================================================ /*! * jQuery UI Unique ID @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license */ //>>label: uniqueId //>>group: Core //>>description: Functions to generate and remove uniqueId's //>>docs: https://api.jqueryui.com/uniqueId/ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "jquery", "./version" ], factory ); } else { // Browser globals factory( jQuery ); } } )( function( $ ) { "use strict"; return $.fn.extend( { uniqueId: ( function() { var uuid = 0; return function() { return this.each( function() { if ( !this.id ) { this.id = "ui-id-" + ( ++uuid ); } } ); }; } )(), removeUniqueId: function() { return this.each( function() { if ( /^ui-id-\d+$/.test( this.id ) ) { $( this ).removeAttr( "id" ); } } ); } } ); } ); ================================================ FILE: ui/vendor/jquery-color/LICENSE.txt ================================================ Copyright OpenJS Foundation and other contributors, https://openjsf.org/ This software consists of voluntary contributions made by many individuals. For exact contribution history, see the revision history available at https://github.com/jquery/jquery-color The following license applies to all parts of jQuery Color except as documented below: ==== 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. ==== Copyright and related rights for sample code are waived via CC0. Sample code is defined as all source code displayed within the README. CC0: http://creativecommons.org/publicdomain/zero/1.0/ ==== All files located in the node_modules and external directories are externally maintained libraries used by this software which have their own licenses; we recommend you read them, as their terms may differ from the terms above. ================================================ FILE: ui/vendor/jquery-color/jquery.color.js ================================================ /*! * jQuery Color Animations v3.0.0 * https://github.com/jquery/jquery-color * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license * * Date: Wed May 15 16:49:44 2024 +0200 */ ( function( root, factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "jquery" ], factory ); } else if ( typeof exports === "object" ) { module.exports = factory( require( "jquery" ) ); } else { factory( root.jQuery ); } } )( this, function( jQuery, undefined ) { "use strict"; var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor " + "borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", class2type = {}, toString = class2type.toString, // plusequals test for += 100 -= 100 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, // a set of RE's that can match strings and generate color tuples. stringParsers = [ { re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, parse: function( execResult ) { return [ execResult[ 1 ], execResult[ 2 ], execResult[ 3 ], execResult[ 4 ] ]; } }, { re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, parse: function( execResult ) { return [ execResult[ 1 ] * 2.55, execResult[ 2 ] * 2.55, execResult[ 3 ] * 2.55, execResult[ 4 ] ]; } }, { // this regex ignores A-F because it's compared against an already lowercased string re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})?/, parse: function( execResult ) { return [ parseInt( execResult[ 1 ], 16 ), parseInt( execResult[ 2 ], 16 ), parseInt( execResult[ 3 ], 16 ), execResult[ 4 ] ? ( parseInt( execResult[ 4 ], 16 ) / 255 ).toFixed( 2 ) : 1 ]; } }, { // this regex ignores A-F because it's compared against an already lowercased string re: /#([a-f0-9])([a-f0-9])([a-f0-9])([a-f0-9])?/, parse: function( execResult ) { return [ parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ), execResult[ 4 ] ? ( parseInt( execResult[ 4 ] + execResult[ 4 ], 16 ) / 255 ) .toFixed( 2 ) : 1 ]; } }, { re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, space: "hsla", parse: function( execResult ) { return [ execResult[ 1 ], execResult[ 2 ] / 100, execResult[ 3 ] / 100, execResult[ 4 ] ]; } } ], // jQuery.Color( ) color = jQuery.Color = function( color, green, blue, alpha ) { return new jQuery.Color.fn.parse( color, green, blue, alpha ); }, spaces = { rgba: { props: { red: { idx: 0, type: "byte" }, green: { idx: 1, type: "byte" }, blue: { idx: 2, type: "byte" } } }, hsla: { props: { hue: { idx: 0, type: "degrees" }, saturation: { idx: 1, type: "percent" }, lightness: { idx: 2, type: "percent" } } } }, propTypes = { "byte": { floor: true, max: 255 }, "percent": { max: 1 }, "degrees": { mod: 360, floor: true } }, // colors = jQuery.Color.names colors, // local aliases of functions called often each = jQuery.each; // define cache name and alpha properties // for rgba and hsla spaces each( spaces, function( spaceName, space ) { space.cache = "_" + spaceName; space.props.alpha = { idx: 3, type: "percent", def: 1 }; } ); // Populate the class2type map jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), function( _i, name ) { class2type[ "[object " + name + "]" ] = name.toLowerCase(); } ); function getType( obj ) { if ( obj == null ) { return obj + ""; } return typeof obj === "object" ? class2type[ toString.call( obj ) ] || "object" : typeof obj; } function clamp( value, prop, allowEmpty ) { var type = propTypes[ prop.type ] || {}; if ( value == null ) { return ( allowEmpty || !prop.def ) ? null : prop.def; } // ~~ is an short way of doing floor for positive numbers value = type.floor ? ~~value : parseFloat( value ); if ( type.mod ) { // we add mod before modding to make sure that negatives values // get converted properly: -10 -> 350 return ( value + type.mod ) % type.mod; } // for now all property types without mod have min and max return Math.min( type.max, Math.max( 0, value ) ); } function stringParse( string ) { var inst = color(), rgba = inst._rgba = []; string = string.toLowerCase(); each( stringParsers, function( _i, parser ) { var parsed, match = parser.re.exec( string ), values = match && parser.parse( match ), spaceName = parser.space || "rgba"; if ( values ) { parsed = inst[ spaceName ]( values ); // if this was an rgba parse the assignment might happen twice // oh well.... inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; rgba = inst._rgba = parsed._rgba; // exit each( stringParsers ) here because we matched return false; } } ); // Found a stringParser that handled it if ( rgba.length ) { // if this came from a parsed string, force "transparent" when alpha is 0 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) if ( rgba.join() === "0,0,0,0" ) { jQuery.extend( rgba, colors.transparent ); } return inst; } // named colors return colors[ string ]; } color.fn = jQuery.extend( color.prototype, { parse: function( red, green, blue, alpha ) { if ( red === undefined ) { this._rgba = [ null, null, null, null ]; return this; } if ( red.jquery || red.nodeType ) { red = jQuery( red ).css( green ); green = undefined; } var inst = this, type = getType( red ), rgba = this._rgba = []; // more than 1 argument specified - assume ( red, green, blue, alpha ) if ( green !== undefined ) { red = [ red, green, blue, alpha ]; type = "array"; } if ( type === "string" ) { return this.parse( stringParse( red ) || colors._default ); } if ( type === "array" ) { each( spaces.rgba.props, function( _key, prop ) { rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); } ); return this; } if ( type === "object" ) { if ( red instanceof color ) { each( spaces, function( _spaceName, space ) { if ( red[ space.cache ] ) { inst[ space.cache ] = red[ space.cache ].slice(); } } ); } else { each( spaces, function( _spaceName, space ) { var cache = space.cache; each( space.props, function( key, prop ) { // if the cache doesn't exist, and we know how to convert if ( !inst[ cache ] && space.to ) { // if the value was null, we don't need to copy it // if the key was alpha, we don't need to copy it either if ( key === "alpha" || red[ key ] == null ) { return; } inst[ cache ] = space.to( inst._rgba ); } // this is the only case where we allow nulls for ALL properties. // call clamp with alwaysAllowEmpty inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); } ); // everything defined but alpha? if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { // use the default of 1 if ( inst[ cache ][ 3 ] == null ) { inst[ cache ][ 3 ] = 1; } if ( space.from ) { inst._rgba = space.from( inst[ cache ] ); } } } ); } return this; } }, is: function( compare ) { var is = color( compare ), same = true, inst = this; each( spaces, function( _, space ) { var localCache, isCache = is[ space.cache ]; if ( isCache ) { localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; each( space.props, function( _, prop ) { if ( isCache[ prop.idx ] != null ) { same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); return same; } } ); } return same; } ); return same; }, _space: function() { var used = [], inst = this; each( spaces, function( spaceName, space ) { if ( inst[ space.cache ] ) { used.push( spaceName ); } } ); return used.pop(); }, transition: function( other, distance ) { var end = color( other ), spaceName = end._space(), space = spaces[ spaceName ], startColor = this.alpha() === 0 ? color( "transparent" ) : this, start = startColor[ space.cache ] || space.to( startColor._rgba ), result = start.slice(); end = end[ space.cache ]; each( space.props, function( _key, prop ) { var index = prop.idx, startValue = start[ index ], endValue = end[ index ], type = propTypes[ prop.type ] || {}; // if null, don't override start value if ( endValue === null ) { return; } // if null - use end if ( startValue === null ) { result[ index ] = endValue; } else { if ( type.mod ) { if ( endValue - startValue > type.mod / 2 ) { startValue += type.mod; } else if ( startValue - endValue > type.mod / 2 ) { startValue -= type.mod; } } result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); } } ); return this[ spaceName ]( result ); }, blend: function( opaque ) { // if we are already opaque - return ourself if ( this._rgba[ 3 ] === 1 ) { return this; } var rgb = this._rgba.slice(), a = rgb.pop(), blend = color( opaque )._rgba; return color( jQuery.map( rgb, function( v, i ) { return ( 1 - a ) * blend[ i ] + a * v; } ) ); }, toRgbaString: function() { var prefix = "rgba(", rgba = jQuery.map( this._rgba, function( v, i ) { if ( v != null ) { return v; } return i > 2 ? 1 : 0; } ); if ( rgba[ 3 ] === 1 ) { rgba.pop(); prefix = "rgb("; } return prefix + rgba.join( ", " ) + ")"; }, toHslaString: function() { var prefix = "hsla(", hsla = jQuery.map( this.hsla(), function( v, i ) { if ( v == null ) { v = i > 2 ? 1 : 0; } // catch 1 and 2 if ( i && i < 3 ) { v = Math.round( v * 100 ) + "%"; } return v; } ); if ( hsla[ 3 ] === 1 ) { hsla.pop(); prefix = "hsl("; } return prefix + hsla.join( ", " ) + ")"; }, toHexString: function( includeAlpha ) { var rgba = this._rgba.slice(), alpha = rgba.pop(); if ( includeAlpha ) { rgba.push( ~~( alpha * 255 ) ); } return "#" + jQuery.map( rgba, function( v ) { // default to 0 when nulls exist return ( "0" + ( v || 0 ).toString( 16 ) ).substr( -2 ); } ).join( "" ); }, toString: function() { return this.toRgbaString(); } } ); color.fn.parse.prototype = color.fn; // hsla conversions adapted from: // https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 function hue2rgb( p, q, h ) { h = ( h + 1 ) % 1; if ( h * 6 < 1 ) { return p + ( q - p ) * h * 6; } if ( h * 2 < 1 ) { return q; } if ( h * 3 < 2 ) { return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6; } return p; } spaces.hsla.to = function( rgba ) { if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { return [ null, null, null, rgba[ 3 ] ]; } var r = rgba[ 0 ] / 255, g = rgba[ 1 ] / 255, b = rgba[ 2 ] / 255, a = rgba[ 3 ], max = Math.max( r, g, b ), min = Math.min( r, g, b ), diff = max - min, add = max + min, l = add * 0.5, h, s; if ( min === max ) { h = 0; } else if ( r === max ) { h = ( 60 * ( g - b ) / diff ) + 360; } else if ( g === max ) { h = ( 60 * ( b - r ) / diff ) + 120; } else { h = ( 60 * ( r - g ) / diff ) + 240; } // chroma (diff) == 0 means greyscale which, by definition, saturation = 0% // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) if ( diff === 0 ) { s = 0; } else if ( l <= 0.5 ) { s = diff / add; } else { s = diff / ( 2 - add ); } return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ]; }; spaces.hsla.from = function( hsla ) { if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { return [ null, null, null, hsla[ 3 ] ]; } var h = hsla[ 0 ] / 360, s = hsla[ 1 ], l = hsla[ 2 ], a = hsla[ 3 ], q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, p = 2 * l - q; return [ Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), Math.round( hue2rgb( p, q, h ) * 255 ), Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), a ]; }; each( spaces, function( spaceName, space ) { var props = space.props, cache = space.cache, to = space.to, from = space.from; // makes rgba() and hsla() color.fn[ spaceName ] = function( value ) { // generate a cache for this space if it doesn't exist if ( to && !this[ cache ] ) { this[ cache ] = to( this._rgba ); } if ( value === undefined ) { return this[ cache ].slice(); } var ret, type = getType( value ), arr = ( type === "array" || type === "object" ) ? value : arguments, local = this[ cache ].slice(); each( props, function( key, prop ) { var val = arr[ type === "object" ? key : prop.idx ]; if ( val == null ) { val = local[ prop.idx ]; } local[ prop.idx ] = clamp( val, prop ); } ); if ( from ) { ret = color( from( local ) ); ret[ cache ] = local; return ret; } else { return color( local ); } }; // makes red() green() blue() alpha() hue() saturation() lightness() each( props, function( key, prop ) { // alpha is included in more than one space if ( color.fn[ key ] ) { return; } color.fn[ key ] = function( value ) { var local, cur, match, fn, vtype = getType( value ); if ( key === "alpha" ) { fn = this._hsla ? "hsla" : "rgba"; } else { fn = spaceName; } local = this[ fn ](); cur = local[ prop.idx ]; if ( vtype === "undefined" ) { return cur; } if ( vtype === "function" ) { value = value.call( this, cur ); vtype = getType( value ); } if ( value == null && prop.empty ) { return this; } if ( vtype === "string" ) { match = rplusequals.exec( value ); if ( match ) { value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); } } local[ prop.idx ] = value; return this[ fn ]( local ); }; } ); } ); // add cssHook and .fx.step function for each named hook. // accept a space separated string of properties color.hook = function( hook ) { var hooks = hook.split( " " ); each( hooks, function( _i, hook ) { jQuery.cssHooks[ hook ] = { set: function( elem, value ) { var parsed; if ( value !== "transparent" && ( getType( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) { value = color( parsed || value ); value = value.toRgbaString(); } elem.style[ hook ] = value; } }; jQuery.fx.step[ hook ] = function( fx ) { if ( !fx.colorInit ) { fx.start = color( fx.elem, hook ); fx.end = color( fx.end ); fx.colorInit = true; } jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); }; } ); }; color.hook( stepHooks ); jQuery.cssHooks.borderColor = { expand: function( value ) { var expanded = {}; each( [ "Top", "Right", "Bottom", "Left" ], function( _i, part ) { expanded[ "border" + part + "Color" ] = value; } ); return expanded; } }; // Basic color names only. // Usage of any of the other color names requires adding yourself or including // jquery.color.svg-names.js. colors = jQuery.Color.names = { // 4.1. Basic color keywords aqua: "#00ffff", black: "#000000", blue: "#0000ff", fuchsia: "#ff00ff", gray: "#808080", green: "#008000", lime: "#00ff00", maroon: "#800000", navy: "#000080", olive: "#808000", purple: "#800080", red: "#ff0000", silver: "#c0c0c0", teal: "#008080", white: "#ffffff", yellow: "#ffff00", // 4.2.3. "transparent" color keyword transparent: [ null, null, null, 0 ], _default: "#ffffff" }; } ); ================================================ FILE: ui/version.js ================================================ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "jquery" ], factory ); } else { // Browser globals factory( jQuery ); } } )( function( $ ) { "use strict"; $.ui = $.ui || {}; return $.ui.version = "@VERSION"; } ); ================================================ FILE: ui/widget.js ================================================ /*! * jQuery UI Widget @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license */ //>>label: Widget //>>group: Core //>>description: Provides a factory for creating stateful widgets with a common API. //>>docs: https://api.jqueryui.com/jQuery.widget/ //>>demos: https://jqueryui.com/widget/ ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "jquery", "./version" ], factory ); } else { // Browser globals factory( jQuery ); } } )( function( $ ) { "use strict"; var widgetUuid = 0; var widgetHasOwnProperty = Array.prototype.hasOwnProperty; var widgetSlice = Array.prototype.slice; $.cleanData = ( function( orig ) { return function( elems ) { var events, elem, i; for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) { // Only trigger remove when necessary to save time events = $._data( elem, "events" ); if ( events && events.remove ) { $( elem ).triggerHandler( "remove" ); } } orig( elems ); }; } )( $.cleanData ); $.widget = function( name, base, prototype ) { var existingConstructor, constructor, basePrototype; // ProxiedPrototype allows the provided prototype to remain unmodified // so that it can be used as a mixin for multiple widgets (#8876) var proxiedPrototype = {}; var namespace = name.split( "." )[ 0 ]; name = name.split( "." )[ 1 ]; if ( name === "__proto__" || name === "constructor" ) { return $.error( "Invalid widget name: " + name ); } var fullName = namespace + "-" + name; if ( !prototype ) { prototype = base; base = $.Widget; } if ( Array.isArray( prototype ) ) { prototype = $.extend.apply( null, [ {} ].concat( prototype ) ); } // Create selector for plugin $.expr.pseudos[ 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 || !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 ( typeof value !== "function" ) { proxiedPrototype[ prop ] = value; return; } proxiedPrototype[ prop ] = ( function() { function _super() { return base.prototype[ prop ].apply( this, arguments ); } function _superApply( args ) { return base.prototype[ prop ].apply( this, args ); } return function() { var __super = this._super; var __superApply = this._superApply; var 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 ) : 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 ); return constructor; }; $.widget.extend = function( target ) { var input = widgetSlice.call( arguments, 1 ); var inputIndex = 0; var inputLength = input.length; var key; var value; for ( ; inputIndex < inputLength; inputIndex++ ) { for ( key in input[ inputIndex ] ) { value = input[ inputIndex ][ key ]; if ( widgetHasOwnProperty.call( input[ inputIndex ], 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"; var args = widgetSlice.call( arguments, 1 ); var returnValue = this; if ( isMethodCall ) { // If this is an empty collection, we need to have the instance method // return undefined instead of the jQuery instance if ( !this.length && options === "instance" ) { returnValue = undefined; } else { this.each( function() { var methodValue; var instance = $.data( this, fullName ); if ( options === "instance" ) { returnValue = instance; return false; } if ( !instance ) { return $.error( "cannot call methods on " + name + " prior to initialization; " + "attempted to call method '" + options + "'" ); } if ( typeof instance[ options ] !== "function" || 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 { // Allow multiple hashes to be passed on init if ( args.length ) { options = $.widget.extend.apply( null, [ options ].concat( args ) ); } this.each( function() { var instance = $.data( this, fullName ); if ( instance ) { instance.option( options || {} ); if ( instance._init ) { instance._init(); } } else { $.data( this, fullName, new object( options, this ) ); } } ); } return returnValue; }; }; $.Widget = function( /* options, element */ ) {}; $.Widget._childConstructors = []; $.Widget.prototype = { widgetName: "widget", widgetEventPrefix: "", defaultElement: "
    ", options: { classes: {}, disabled: false, // Callbacks create: null }, _createWidget: function( options, element ) { element = $( element || this.defaultElement || this )[ 0 ]; this.element = $( element ); this.uuid = widgetUuid++; this.eventNamespace = "." + this.widgetName + this.uuid; this.bindings = $(); this.hoverable = $(); this.focusable = $(); this.classesElementLookup = {}; 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.options = $.widget.extend( {}, this.options, this._getCreateOptions(), options ); this._create(); if ( this.options.disabled ) { this._setOptionDisabled( this.options.disabled ); } this._trigger( "create", null, this._getCreateEventData() ); this._init(); }, _getCreateOptions: function() { return {}; }, _getCreateEventData: $.noop, _create: $.noop, _init: $.noop, destroy: function() { var that = this; this._destroy(); $.each( this.classesElementLookup, function( key, value ) { that._removeClass( value, key ); } ); // We can probably remove the unbind calls in 2.0 // all event bindings should go through this._on() this.element .off( this.eventNamespace ) .removeData( this.widgetFullName ); this.widget() .off( this.eventNamespace ) .removeAttr( "aria-disabled" ); // Clean up events and states this.bindings.off( this.eventNamespace ); }, _destroy: $.noop, widget: function() { return this.element; }, option: function( key, value ) { var options = key; var parts; var curOption; var 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 ( arguments.length === 1 ) { return curOption[ key ] === undefined ? null : curOption[ key ]; } curOption[ key ] = value; } else { if ( arguments.length === 1 ) { 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 ) { if ( key === "classes" ) { this._setOptionClasses( value ); } this.options[ key ] = value; if ( key === "disabled" ) { this._setOptionDisabled( value ); } return this; }, _setOptionClasses: function( value ) { var classKey, elements, currentElements; for ( classKey in value ) { currentElements = this.classesElementLookup[ classKey ]; if ( value[ classKey ] === this.options.classes[ classKey ] || !currentElements || !currentElements.length ) { continue; } // We are doing this to create a new jQuery object because the _removeClass() call // on the next line is going to destroy the reference to the current elements being // tracked. We need to save a copy of this collection so that we can add the new classes // below. elements = $( currentElements.get() ); this._removeClass( currentElements, classKey ); // We don't use _addClass() here, because that uses this.options.classes // for generating the string of classes. We want to use the value passed in from // _setOption(), this is the new value of the classes option which was passed to // _setOption(). We pass this value directly to _classes(). elements.addClass( this._classes( { element: elements, keys: classKey, classes: value, add: true } ) ); } }, _setOptionDisabled: function( value ) { this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value ); // If the widget is becoming disabled, then nothing is interactive if ( value ) { this._removeClass( this.hoverable, null, "ui-state-hover" ); this._removeClass( this.focusable, null, "ui-state-focus" ); } }, enable: function() { return this._setOptions( { disabled: false } ); }, disable: function() { return this._setOptions( { disabled: true } ); }, _classes: function( options ) { var full = []; var that = this; options = $.extend( { element: this.element, classes: this.options.classes || {} }, options ); function bindRemoveEvent() { var nodesToBind = []; options.element.each( function( _, element ) { var isTracked = $.map( that.classesElementLookup, function( elements ) { return elements; } ) .some( function( elements ) { return elements.is( element ); } ); if ( !isTracked ) { nodesToBind.push( element ); } } ); that._on( $( nodesToBind ), { remove: "_untrackClassesElement" } ); } function processClassString( classes, checkOption ) { var current, i; for ( i = 0; i < classes.length; i++ ) { current = that.classesElementLookup[ classes[ i ] ] || $(); if ( options.add ) { bindRemoveEvent(); current = $( $.uniqueSort( current.get().concat( options.element.get() ) ) ); } else { current = $( current.not( options.element ).get() ); } that.classesElementLookup[ classes[ i ] ] = current; full.push( classes[ i ] ); if ( checkOption && options.classes[ classes[ i ] ] ) { full.push( options.classes[ classes[ i ] ] ); } } } if ( options.keys ) { processClassString( options.keys.match( /\S+/g ) || [], true ); } if ( options.extra ) { processClassString( options.extra.match( /\S+/g ) || [] ); } return full.join( " " ); }, _untrackClassesElement: function( event ) { var that = this; $.each( that.classesElementLookup, function( key, value ) { if ( $.inArray( event.target, value ) !== -1 ) { that.classesElementLookup[ key ] = $( value.not( event.target ).get() ); } } ); this._off( $( event.target ) ); }, _removeClass: function( element, keys, extra ) { return this._toggleClass( element, keys, extra, false ); }, _addClass: function( element, keys, extra ) { return this._toggleClass( element, keys, extra, true ); }, _toggleClass: function( element, keys, extra, add ) { add = ( typeof add === "boolean" ) ? add : extra; var shift = ( typeof element === "string" || element === null ), options = { extra: shift ? keys : extra, keys: shift ? element : keys, element: shift ? this.element : element, add: add }; options.element.toggleClass( this._classes( options ), add ); return this; }, _on: function( suppressDisabledCheck, element, handlers ) { var delegateElement; var 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 { 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*(.*)$/ ); var eventName = match[ 1 ] + instance.eventNamespace; var selector = match[ 2 ]; if ( selector ) { delegateElement.on( eventName, selector, handlerProxy ); } else { element.on( eventName, handlerProxy ); } } ); }, _off: function( element, eventName ) { eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; element.off( eventName ); // Clear the stack to avoid memory leaks (#10056) this.bindings = $( this.bindings.not( element ).get() ); this.focusable = $( this.focusable.not( element ).get() ); this.hoverable = $( this.hoverable.not( element ).get() ); }, _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 ) { this._addClass( $( event.currentTarget ), null, "ui-state-hover" ); }, mouseleave: function( event ) { this._removeClass( $( event.currentTarget ), null, "ui-state-hover" ); } } ); }, _focusable: function( element ) { this.focusable = this.focusable.add( element ); this._on( element, { focusin: function( event ) { this._addClass( $( event.currentTarget ), null, "ui-state-focus" ); }, focusout: function( event ) { this._removeClass( $( event.currentTarget ), null, "ui-state-focus" ); } } ); }, _trigger: function( type, event, data ) { var prop, orig; var 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 !( typeof callback === "function" && 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; var effectName = !options ? method : options === true || typeof options === "number" ? defaultEffect : options.effect || defaultEffect; options = options || {}; if ( typeof options === "number" ) { options = { duration: options }; } else if ( options === true ) { 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(); } ); } }; } ); return $.widget; } ); ================================================ FILE: ui/widgets/accordion.js ================================================ /*! * jQuery UI Accordion @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license */ //>>label: Accordion //>>group: Widgets //>>description: Displays collapsible content panels for presenting information in a limited amount of space. //>>docs: https://api.jqueryui.com/accordion/ //>>demos: https://jqueryui.com/accordion/ //>>css.structure: ../../themes/base/core.css //>>css.structure: ../../themes/base/accordion.css //>>css.theme: ../../themes/base/theme.css ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "jquery", "../version", "../keycode", "../unique-id", "../widget" ], factory ); } else { // Browser globals factory( jQuery ); } } )( function( $ ) { "use strict"; return $.widget( "ui.accordion", { version: "@VERSION", options: { active: 0, animate: {}, classes: { "ui-accordion-header": "ui-corner-top", "ui-accordion-header-collapsed": "ui-corner-all", "ui-accordion-content": "ui-corner-bottom" }, collapsible: false, event: "click", header: function( elem ) { return elem .find( "> li > :first-child" ) .add( elem.find( "> :not(li)" ) // Support: jQuery <3.5 only // We could use `.even()` but that's unavailable in older jQuery. .filter( function( i ) { return i % 2 === 0; } ) ); }, heightStyle: "auto", icons: { activeHeader: "ui-icon-triangle-1-s", header: "ui-icon-triangle-1-e" }, // Callbacks activate: null, beforeActivate: null }, hideProps: { borderTopWidth: "hide", borderBottomWidth: "hide", paddingTop: "hide", paddingBottom: "hide", height: "hide" }, showProps: { borderTopWidth: "show", borderBottomWidth: "show", paddingTop: "show", paddingBottom: "show", height: "show" }, _create: function() { var options = this.options; this.prevShow = this.prevHide = $(); this._addClass( "ui-accordion", "ui-widget ui-helper-reset" ); this.element.attr( "role", "tablist" ); // Don't allow collapsible: false and active: false / null if ( !options.collapsible && ( options.active === false || options.active == null ) ) { options.active = 0; } this._processPanels(); // handle negative values if ( options.active < 0 ) { options.active += this.headers.length; } this._refresh(); }, _getCreateEventData: function() { return { header: this.active, panel: !this.active.length ? $() : this.active.next() }; }, _createIcons: function() { var icon, children, icons = this.options.icons; if ( icons ) { icon = $( "" ); this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header ); icon.prependTo( this.headers ); children = this.active.children( ".ui-accordion-header-icon" ); this._removeClass( children, icons.header ) ._addClass( children, null, icons.activeHeader ) ._addClass( this.headers, "ui-accordion-icons" ); } }, _destroyIcons: function() { this._removeClass( this.headers, "ui-accordion-icons" ); this.headers.children( ".ui-accordion-header-icon" ).remove(); }, _destroy: function() { var contents; // Clean up main element this.element.removeAttr( "role" ); // Clean up headers this.headers .removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" ) .removeUniqueId(); this._destroyIcons(); // Clean up content panels contents = this.headers.next() .css( "display", "" ) .removeAttr( "role aria-hidden aria-labelledby" ) .removeUniqueId(); if ( this.options.heightStyle !== "content" ) { contents.css( "height", "" ); } }, _setOption: function( key, value ) { if ( key === "active" ) { // _activate() will handle invalid values and update this.options this._activate( value ); return; } if ( key === "event" ) { if ( this.options.event ) { this._off( this.headers, this.options.event ); } this._setupEvents( value ); } this._super( key, value ); // Setting collapsible: false while collapsed; open first panel if ( key === "collapsible" && !value && this.options.active === false ) { this._activate( 0 ); } if ( key === "icons" ) { this._destroyIcons(); if ( value ) { this._createIcons(); } } }, _setOptionDisabled: function( value ) { this._super( value ); this.element.attr( "aria-disabled", value ); this._toggleClass( null, "ui-state-disabled", !!value ); }, _keydown: function( event ) { if ( event.altKey || event.ctrlKey ) { return; } var keyCode = $.ui.keyCode, length = this.headers.length, currentIndex = this.headers.index( event.target ), toFocus = false; switch ( event.keyCode ) { case keyCode.RIGHT: case keyCode.DOWN: toFocus = this.headers[ ( currentIndex + 1 ) % length ]; break; case keyCode.LEFT: case keyCode.UP: toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; break; case keyCode.SPACE: case keyCode.ENTER: this._eventHandler( event ); break; case keyCode.HOME: toFocus = this.headers[ 0 ]; break; case keyCode.END: toFocus = this.headers[ length - 1 ]; break; } if ( toFocus ) { $( event.target ).attr( "tabIndex", -1 ); $( toFocus ).attr( "tabIndex", 0 ); $( toFocus ).trigger( "focus" ); event.preventDefault(); } }, _panelKeyDown: function( event ) { if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { $( event.currentTarget ).prev().trigger( "focus" ); } }, refresh: function() { var options = this.options; this._processPanels(); // Was collapsed or no panel if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) { options.active = false; this.active = $(); // active false only when collapsible is true } else if ( options.active === false ) { this._activate( 0 ); // was active, but active panel is gone } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { // all remaining panel are disabled if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) { options.active = false; this.active = $(); // activate previous panel } else { this._activate( Math.max( 0, options.active - 1 ) ); } // was active, active panel still exists } else { // make sure active index is correct options.active = this.headers.index( this.active ); } this._destroyIcons(); this._refresh(); }, _processPanels: function() { var prevHeaders = this.headers, prevPanels = this.panels; if ( typeof this.options.header === "function" ) { this.headers = this.options.header( this.element ); } else { this.headers = this.element.find( this.options.header ); } this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed", "ui-state-default" ); this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide(); this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" ); // Avoid memory leaks (#10056) if ( prevPanels ) { this._off( prevHeaders.not( this.headers ) ); this._off( prevPanels.not( this.panels ) ); } }, _refresh: function() { var maxHeight, options = this.options, heightStyle = options.heightStyle, parent = this.element.parent(); this.active = this._findActive( options.active ); this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" ) ._removeClass( this.active, "ui-accordion-header-collapsed" ); this._addClass( this.active.next(), "ui-accordion-content-active" ); this.active.next().show(); this.headers .attr( "role", "tab" ) .each( function() { var header = $( this ), headerId = header.uniqueId().attr( "id" ), panel = header.next(), panelId = panel.uniqueId().attr( "id" ); header.attr( "aria-controls", panelId ); panel.attr( "aria-labelledby", headerId ); } ) .next() .attr( "role", "tabpanel" ); this.headers .not( this.active ) .attr( { "aria-selected": "false", "aria-expanded": "false", tabIndex: -1 } ) .next() .attr( { "aria-hidden": "true" } ) .hide(); // Make sure at least one header is in the tab order if ( !this.active.length ) { this.headers.eq( 0 ).attr( "tabIndex", 0 ); } else { this.active.attr( { "aria-selected": "true", "aria-expanded": "true", tabIndex: 0 } ) .next() .attr( { "aria-hidden": "false" } ); } this._createIcons(); this._setupEvents( options.event ); if ( heightStyle === "fill" ) { maxHeight = parent.height(); this.element.siblings( ":visible" ).each( function() { var elem = $( this ), position = elem.css( "position" ); if ( position === "absolute" || position === "fixed" ) { return; } maxHeight -= elem.outerHeight( true ); } ); this.headers.each( function() { maxHeight -= $( this ).outerHeight( true ); } ); this.headers.next() .each( function() { $( this ).height( Math.max( 0, maxHeight - $( this ).innerHeight() + $( this ).height() ) ); } ) .css( "overflow", "auto" ); } else if ( heightStyle === "auto" ) { maxHeight = 0; this.headers.next() .each( function() { var isVisible = $( this ).is( ":visible" ); if ( !isVisible ) { $( this ).show(); } maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); if ( !isVisible ) { $( this ).hide(); } } ) .height( maxHeight ); } }, _activate: function( index ) { var active = this._findActive( index )[ 0 ]; // Trying to activate the already active panel if ( active === this.active[ 0 ] ) { return; } // Trying to collapse, simulate a click on the currently active header active = active || this.active[ 0 ]; this._eventHandler( { target: active, currentTarget: active, preventDefault: $.noop } ); }, _findActive: function( selector ) { return typeof selector === "number" ? this.headers.eq( selector ) : $(); }, _setupEvents: function( event ) { var events = { keydown: "_keydown" }; if ( event ) { $.each( event.split( " " ), function( index, eventName ) { events[ eventName ] = "_eventHandler"; } ); } this._off( this.headers.add( this.headers.next() ) ); this._on( this.headers, events ); this._on( this.headers.next(), { keydown: "_panelKeyDown" } ); this._hoverable( this.headers ); this._focusable( this.headers ); }, _eventHandler: function( event ) { var activeChildren, clickedChildren, options = this.options, active = this.active, clicked = $( event.currentTarget ), clickedIsActive = clicked[ 0 ] === active[ 0 ], collapsing = clickedIsActive && options.collapsible, toShow = collapsing ? $() : clicked.next(), toHide = active.next(), eventData = { oldHeader: active, oldPanel: toHide, newHeader: collapsing ? $() : clicked, newPanel: toShow }; event.preventDefault(); if ( // click on active header, but not collapsible ( clickedIsActive && !options.collapsible ) || // allow canceling activation ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { return; } options.active = collapsing ? false : this.headers.index( clicked ); // When the call to ._toggle() comes after the class changes // it causes a very odd bug in IE 8 (see #6720) this.active = clickedIsActive ? $() : clicked; this._toggle( eventData ); // Switch classes // corner classes on the previously active header stay after the animation this._removeClass( active, "ui-accordion-header-active", "ui-state-active" ); if ( options.icons ) { activeChildren = active.children( ".ui-accordion-header-icon" ); this._removeClass( activeChildren, null, options.icons.activeHeader ) ._addClass( activeChildren, null, options.icons.header ); } if ( !clickedIsActive ) { this._removeClass( clicked, "ui-accordion-header-collapsed" ) ._addClass( clicked, "ui-accordion-header-active", "ui-state-active" ); if ( options.icons ) { clickedChildren = clicked.children( ".ui-accordion-header-icon" ); this._removeClass( clickedChildren, null, options.icons.header ) ._addClass( clickedChildren, null, options.icons.activeHeader ); } this._addClass( clicked.next(), "ui-accordion-content-active" ); } }, _toggle: function( data ) { var toShow = data.newPanel, toHide = this.prevShow.length ? this.prevShow : data.oldPanel; // Handle activating a panel during the animation for another activation this.prevShow.add( this.prevHide ).stop( true, true ); this.prevShow = toShow; this.prevHide = toHide; if ( this.options.animate ) { this._animate( toShow, toHide, data ); } else { toHide.hide(); toShow.show(); this._toggleComplete( data ); } toHide.attr( { "aria-hidden": "true" } ); toHide.prev().attr( { "aria-selected": "false", "aria-expanded": "false" } ); // if we're switching panels, remove the old header from the tab order // if we're opening from collapsed state, remove the previous header from the tab order // if we're collapsing, then keep the collapsing header in the tab order if ( toShow.length && toHide.length ) { toHide.prev().attr( { "tabIndex": -1, "aria-expanded": "false" } ); } else if ( toShow.length ) { this.headers.filter( function() { return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0; } ) .attr( "tabIndex", -1 ); } toShow .attr( "aria-hidden", "false" ) .prev() .attr( { "aria-selected": "true", "aria-expanded": "true", tabIndex: 0 } ); }, _animate: function( toShow, toHide, data ) { var total, easing, duration, that = this, adjust = 0, boxSizing = toShow.css( "box-sizing" ), down = toShow.length && ( !toHide.length || ( toShow.index() < toHide.index() ) ), animate = this.options.animate || {}, options = down && animate.down || animate, complete = function() { that._toggleComplete( data ); }; if ( typeof options === "number" ) { duration = options; } if ( typeof options === "string" ) { easing = options; } // fall back from options to animation in case of partial down settings easing = easing || options.easing || animate.easing; duration = duration || options.duration || animate.duration; if ( !toHide.length ) { return toShow.animate( this.showProps, duration, easing, complete ); } if ( !toShow.length ) { return toHide.animate( this.hideProps, duration, easing, complete ); } total = toShow.show().outerHeight(); toHide.animate( this.hideProps, { duration: duration, easing: easing, step: function( now, fx ) { fx.now = Math.round( now ); } } ); toShow .hide() .animate( this.showProps, { duration: duration, easing: easing, complete: complete, step: function( now, fx ) { fx.now = Math.round( now ); if ( fx.prop !== "height" ) { if ( boxSizing === "content-box" ) { adjust += fx.now; } } else if ( that.options.heightStyle !== "content" ) { fx.now = Math.round( total - toHide.outerHeight() - adjust ); adjust = 0; } } } ); }, _toggleComplete: function( data ) { var toHide = data.oldPanel, prev = toHide.prev(); this._removeClass( toHide, "ui-accordion-content-active" ); this._removeClass( prev, "ui-accordion-header-active" ) ._addClass( prev, "ui-accordion-header-collapsed" ); this._trigger( "activate", null, data ); } } ); } ); ================================================ FILE: ui/widgets/autocomplete.js ================================================ /*! * jQuery UI Autocomplete @VERSION * https://jqueryui.com * * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * https://jquery.org/license */ //>>label: Autocomplete //>>group: Widgets //>>description: Lists suggested words as the user is typing. //>>docs: https://api.jqueryui.com/autocomplete/ //>>demos: https://jqueryui.com/autocomplete/ //>>css.structure: ../../themes/base/core.css //>>css.structure: ../../themes/base/autocomplete.css //>>css.theme: ../../themes/base/theme.css ( function( factory ) { "use strict"; if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "jquery", "./menu", "../keycode", "../position", "../version", "../widget" ], factory ); } else { // Browser globals factory( jQuery ); } } )( function( $ ) { "use strict"; $.widget( "ui.autocomplete", { version: "@VERSION", defaultElement: "", options: { appendTo: null, autoFocus: false, delay: 300, minLength: 1, position: { my: "left top", at: "left bottom", collision: "none" }, source: null, // Callbacks change: null, close: null, focus: null, open: null, response: null, search: null, select: null }, requestIndex: 0, pending: 0, liveRegionTimer: null, _create: function() { // Some browsers only repeat keydown events, not keypress events, // so we use the suppressKeyPress flag to determine if we've already // handled the keydown event. #7269 // Unfortunately the code for & in keypress is the same as the up arrow, // so we use the suppressKeyPressRepeat flag to avoid handling keypress // events when we know the keydown event was used to modify the // search term. #7799 var suppressKeyPress, suppressKeyPressRepeat, suppressInput, nodeName = this.element[ 0 ].nodeName.toLowerCase(), isTextarea = nodeName === "textarea", isInput = nodeName === "input"; // Textareas are always multi-line // Inputs are always single-line, even if inside a contentEditable element // All other element types are determined by whether they're contentEditable this.isMultiLine = isTextarea || !isInput && this.element.prop( "contentEditable" ) === "true"; this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ]; this.isNewMenu = true; this._addClass( "ui-autocomplete-input" ); this.element.attr( "autocomplete", "off" ); this._on( this.element, { keydown: function( event ) { if ( this.element.prop( "readOnly" ) ) { suppressKeyPress = true; suppressInput = true; suppressKeyPressRepeat = true; return; } suppressKeyPress = false; suppressInput = false; suppressKeyPressRepeat = false; var keyCode = $.ui.keyCode; switch ( event.keyCode ) { case keyCode.PAGE_UP: suppressKeyPress = true; this._move( "previousPage", event ); break; case keyCode.PAGE_DOWN: suppressKeyPress = true; this._move( "nextPage", event ); break; case keyCode.UP: suppressKeyPress = true; this._keyEvent( "previous", event ); break; case keyCode.DOWN: suppressKeyPress = true; this._keyEvent( "next", event ); break; case keyCode.ENTER: // when menu is open and has focus if ( this.menu.active ) { // #6055 - Opera still allows the keypress to occur // which causes forms to submit suppressKeyPress = true; event.preventDefault(); this.menu.select( event ); } break; case keyCode.TAB: if ( this.menu.active ) { this.menu.select( event ); } break; case keyCode.ESCAPE: if ( this.menu.element.is( ":visible" ) ) { if ( !this.isMultiLine ) { this._value( this.term ); } this.close( event ); // Different browsers have different default behavior for escape // Single press can mean undo or clear event.preventDefault(); } break; default: suppressKeyPressRepeat = true; // search timeout should be triggered before the input value is changed this._searchTimeout( event ); break; } }, keypress: function( event ) { if ( suppressKeyPress ) { suppressKeyPress = false; if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { event.preventDefault(); } return; } if ( suppressKeyPressRepeat ) { return; } // Replicate some key handlers to allow them to repeat in Firefox and Opera var keyCode = $.ui.keyCode; switch ( event.keyCode ) { case keyCode.PAGE_UP: this._move( "previousPage", event ); break; case keyCode.PAGE_DOWN: this._move( "nextPage", event ); break; case keyCode.UP: this._keyEvent( "previous", event ); break; case keyCode.DOWN: this._keyEvent( "next", event ); break; } }, input: function( event ) { if ( suppressInput ) { suppressInput = false; event.preventDefault(); return; } this._searchTimeout( event ); }, focus: function() { this.selectedItem = null; this.previous = this._value(); }, blur: function( event ) { clearTimeout( this.searching ); this.close( event ); this._change( event ); } } ); this._initSource(); this.menu = $( "