jquery-ui-rails-dox-fork 7.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (180) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +2 -0
  3. data/.gitmodules +3 -0
  4. data/.travis.yml +2 -0
  5. data/CONTRIBUTING.txt +30 -0
  6. data/Gemfile +3 -0
  7. data/History.md +172 -0
  8. data/License.txt +2 -0
  9. data/README.md +311 -0
  10. data/Rakefile +263 -0
  11. data/VERSIONS.md +41 -0
  12. data/app/assets/images/jquery-ui/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  13. data/app/assets/images/jquery-ui/ui-icons_444444_256x240.png +0 -0
  14. data/app/assets/images/jquery-ui/ui-icons_555555_256x240.png +0 -0
  15. data/app/assets/images/jquery-ui/ui-icons_777620_256x240.png +0 -0
  16. data/app/assets/images/jquery-ui/ui-icons_777777_256x240.png +0 -0
  17. data/app/assets/images/jquery-ui/ui-icons_cc0000_256x240.png +0 -0
  18. data/app/assets/images/jquery-ui/ui-icons_ffffff_256x240.png +0 -0
  19. data/app/assets/javascripts/jquery-ui/core.js +15 -0
  20. data/app/assets/javascripts/jquery-ui/data.js +45 -0
  21. data/app/assets/javascripts/jquery-ui/disable-selection.js +51 -0
  22. data/app/assets/javascripts/jquery-ui/effect.all.js +15 -0
  23. data/app/assets/javascripts/jquery-ui/effect.js +975 -0
  24. data/app/assets/javascripts/jquery-ui/effects/effect-blind.js +76 -0
  25. data/app/assets/javascripts/jquery-ui/effects/effect-bounce.js +116 -0
  26. data/app/assets/javascripts/jquery-ui/effects/effect-clip.js +71 -0
  27. data/app/assets/javascripts/jquery-ui/effects/effect-drop.js +75 -0
  28. data/app/assets/javascripts/jquery-ui/effects/effect-explode.js +117 -0
  29. data/app/assets/javascripts/jquery-ui/effects/effect-fade.js +53 -0
  30. data/app/assets/javascripts/jquery-ui/effects/effect-fold.js +95 -0
  31. data/app/assets/javascripts/jquery-ui/effects/effect-highlight.js +63 -0
  32. data/app/assets/javascripts/jquery-ui/effects/effect-puff.js +49 -0
  33. data/app/assets/javascripts/jquery-ui/effects/effect-pulsate.js +70 -0
  34. data/app/assets/javascripts/jquery-ui/effects/effect-scale.js +63 -0
  35. data/app/assets/javascripts/jquery-ui/effects/effect-shake.js +80 -0
  36. data/app/assets/javascripts/jquery-ui/effects/effect-size.js +199 -0
  37. data/app/assets/javascripts/jquery-ui/effects/effect-slide.js +82 -0
  38. data/app/assets/javascripts/jquery-ui/effects/effect-transfer.js +46 -0
  39. data/app/assets/javascripts/jquery-ui/focusable.js +89 -0
  40. data/app/assets/javascripts/jquery-ui/form-reset-mixin.js +83 -0
  41. data/app/assets/javascripts/jquery-ui/form.js +25 -0
  42. data/app/assets/javascripts/jquery-ui/i18n/datepicker-af.js +40 -0
  43. data/app/assets/javascripts/jquery-ui/i18n/datepicker-ar-DZ.js +42 -0
  44. data/app/assets/javascripts/jquery-ui/i18n/datepicker-ar.js +42 -0
  45. data/app/assets/javascripts/jquery-ui/i18n/datepicker-az.js +40 -0
  46. data/app/assets/javascripts/jquery-ui/i18n/datepicker-be.js +40 -0
  47. data/app/assets/javascripts/jquery-ui/i18n/datepicker-bg.js +41 -0
  48. data/app/assets/javascripts/jquery-ui/i18n/datepicker-bs.js +40 -0
  49. data/app/assets/javascripts/jquery-ui/i18n/datepicker-ca.js +40 -0
  50. data/app/assets/javascripts/jquery-ui/i18n/datepicker-cs.js +40 -0
  51. data/app/assets/javascripts/jquery-ui/i18n/datepicker-cy-GB.js +48 -0
  52. data/app/assets/javascripts/jquery-ui/i18n/datepicker-da.js +40 -0
  53. data/app/assets/javascripts/jquery-ui/i18n/datepicker-de-AT.js +41 -0
  54. data/app/assets/javascripts/jquery-ui/i18n/datepicker-de.js +40 -0
  55. data/app/assets/javascripts/jquery-ui/i18n/datepicker-el.js +40 -0
  56. data/app/assets/javascripts/jquery-ui/i18n/datepicker-en-AU.js +40 -0
  57. data/app/assets/javascripts/jquery-ui/i18n/datepicker-en-GB.js +40 -0
  58. data/app/assets/javascripts/jquery-ui/i18n/datepicker-en-NZ.js +40 -0
  59. data/app/assets/javascripts/jquery-ui/i18n/datepicker-eo.js +40 -0
  60. data/app/assets/javascripts/jquery-ui/i18n/datepicker-es.js +40 -0
  61. data/app/assets/javascripts/jquery-ui/i18n/datepicker-et.js +48 -0
  62. data/app/assets/javascripts/jquery-ui/i18n/datepicker-eu.js +39 -0
  63. data/app/assets/javascripts/jquery-ui/i18n/datepicker-fa.js +76 -0
  64. data/app/assets/javascripts/jquery-ui/i18n/datepicker-fi.js +40 -0
  65. data/app/assets/javascripts/jquery-ui/i18n/datepicker-fo.js +48 -0
  66. data/app/assets/javascripts/jquery-ui/i18n/datepicker-fr-CA.js +40 -0
  67. data/app/assets/javascripts/jquery-ui/i18n/datepicker-fr-CH.js +40 -0
  68. data/app/assets/javascripts/jquery-ui/i18n/datepicker-fr.js +42 -0
  69. data/app/assets/javascripts/jquery-ui/i18n/datepicker-gl.js +40 -0
  70. data/app/assets/javascripts/jquery-ui/i18n/datepicker-he.js +40 -0
  71. data/app/assets/javascripts/jquery-ui/i18n/datepicker-hi.js +40 -0
  72. data/app/assets/javascripts/jquery-ui/i18n/datepicker-hr.js +40 -0
  73. data/app/assets/javascripts/jquery-ui/i18n/datepicker-hu.js +39 -0
  74. data/app/assets/javascripts/jquery-ui/i18n/datepicker-hy.js +40 -0
  75. data/app/assets/javascripts/jquery-ui/i18n/datepicker-id.js +41 -0
  76. data/app/assets/javascripts/jquery-ui/i18n/datepicker-is.js +48 -0
  77. data/app/assets/javascripts/jquery-ui/i18n/datepicker-it-CH.js +40 -0
  78. data/app/assets/javascripts/jquery-ui/i18n/datepicker-it.js +40 -0
  79. data/app/assets/javascripts/jquery-ui/i18n/datepicker-ja.js +40 -0
  80. data/app/assets/javascripts/jquery-ui/i18n/datepicker-ka.js +51 -0
  81. data/app/assets/javascripts/jquery-ui/i18n/datepicker-kk.js +40 -0
  82. data/app/assets/javascripts/jquery-ui/i18n/datepicker-km.js +40 -0
  83. data/app/assets/javascripts/jquery-ui/i18n/datepicker-ko.js +40 -0
  84. data/app/assets/javascripts/jquery-ui/i18n/datepicker-ky.js +41 -0
  85. data/app/assets/javascripts/jquery-ui/i18n/datepicker-lb.js +48 -0
  86. data/app/assets/javascripts/jquery-ui/i18n/datepicker-lt.js +48 -0
  87. data/app/assets/javascripts/jquery-ui/i18n/datepicker-lv.js +48 -0
  88. data/app/assets/javascripts/jquery-ui/i18n/datepicker-mk.js +40 -0
  89. data/app/assets/javascripts/jquery-ui/i18n/datepicker-ml.js +40 -0
  90. data/app/assets/javascripts/jquery-ui/i18n/datepicker-ms.js +40 -0
  91. data/app/assets/javascripts/jquery-ui/i18n/datepicker-nb.js +52 -0
  92. data/app/assets/javascripts/jquery-ui/i18n/datepicker-nl-BE.js +40 -0
  93. data/app/assets/javascripts/jquery-ui/i18n/datepicker-nl.js +40 -0
  94. data/app/assets/javascripts/jquery-ui/i18n/datepicker-nn.js +52 -0
  95. data/app/assets/javascripts/jquery-ui/i18n/datepicker-no.js +53 -0
  96. data/app/assets/javascripts/jquery-ui/i18n/datepicker-pl.js +40 -0
  97. data/app/assets/javascripts/jquery-ui/i18n/datepicker-pt-BR.js +48 -0
  98. data/app/assets/javascripts/jquery-ui/i18n/datepicker-pt.js +47 -0
  99. data/app/assets/javascripts/jquery-ui/i18n/datepicker-rm.js +64 -0
  100. data/app/assets/javascripts/jquery-ui/i18n/datepicker-ro.js +43 -0
  101. data/app/assets/javascripts/jquery-ui/i18n/datepicker-ru.js +40 -0
  102. data/app/assets/javascripts/jquery-ui/i18n/datepicker-sk.js +40 -0
  103. data/app/assets/javascripts/jquery-ui/i18n/datepicker-sl.js +41 -0
  104. data/app/assets/javascripts/jquery-ui/i18n/datepicker-sq.js +40 -0
  105. data/app/assets/javascripts/jquery-ui/i18n/datepicker-sr-SR.js +40 -0
  106. data/app/assets/javascripts/jquery-ui/i18n/datepicker-sr.js +40 -0
  107. data/app/assets/javascripts/jquery-ui/i18n/datepicker-sv.js +40 -0
  108. data/app/assets/javascripts/jquery-ui/i18n/datepicker-ta.js +56 -0
  109. data/app/assets/javascripts/jquery-ui/i18n/datepicker-th.js +40 -0
  110. data/app/assets/javascripts/jquery-ui/i18n/datepicker-tj.js +40 -0
  111. data/app/assets/javascripts/jquery-ui/i18n/datepicker-tr.js +40 -0
  112. data/app/assets/javascripts/jquery-ui/i18n/datepicker-uk.js +41 -0
  113. data/app/assets/javascripts/jquery-ui/i18n/datepicker-vi.js +40 -0
  114. data/app/assets/javascripts/jquery-ui/i18n/datepicker-zh-CN.js +40 -0
  115. data/app/assets/javascripts/jquery-ui/i18n/datepicker-zh-HK.js +40 -0
  116. data/app/assets/javascripts/jquery-ui/i18n/datepicker-zh-TW.js +40 -0
  117. data/app/assets/javascripts/jquery-ui/ie.js +20 -0
  118. data/app/assets/javascripts/jquery-ui/jquery-patch.js +91 -0
  119. data/app/assets/javascripts/jquery-ui/jquery-var-for-color.js +24 -0
  120. data/app/assets/javascripts/jquery-ui/keycode.js +51 -0
  121. data/app/assets/javascripts/jquery-ui/labels.js +71 -0
  122. data/app/assets/javascripts/jquery-ui/plugin.js +49 -0
  123. data/app/assets/javascripts/jquery-ui/position.js +513 -0
  124. data/app/assets/javascripts/jquery-ui/safe-active-element.js +46 -0
  125. data/app/assets/javascripts/jquery-ui/safe-blur.js +27 -0
  126. data/app/assets/javascripts/jquery-ui/scroll-parent.js +50 -0
  127. data/app/assets/javascripts/jquery-ui/tabbable.js +41 -0
  128. data/app/assets/javascripts/jquery-ui/unique-id.js +54 -0
  129. data/app/assets/javascripts/jquery-ui/vendor/jquery-color/jquery.color.js +722 -0
  130. data/app/assets/javascripts/jquery-ui/version.js +20 -0
  131. data/app/assets/javascripts/jquery-ui/widget.js +758 -0
  132. data/app/assets/javascripts/jquery-ui/widgets/accordion.js +627 -0
  133. data/app/assets/javascripts/jquery-ui/widgets/autocomplete.js +685 -0
  134. data/app/assets/javascripts/jquery-ui/widgets/button.js +454 -0
  135. data/app/assets/javascripts/jquery-ui/widgets/checkboxradio.js +294 -0
  136. data/app/assets/javascripts/jquery-ui/widgets/controlgroup.js +304 -0
  137. data/app/assets/javascripts/jquery-ui/widgets/datepicker.js +2243 -0
  138. data/app/assets/javascripts/jquery-ui/widgets/dialog.js +968 -0
  139. data/app/assets/javascripts/jquery-ui/widgets/draggable.js +1268 -0
  140. data/app/assets/javascripts/jquery-ui/widgets/droppable.js +508 -0
  141. data/app/assets/javascripts/jquery-ui/widgets/menu.js +720 -0
  142. data/app/assets/javascripts/jquery-ui/widgets/mouse.js +241 -0
  143. data/app/assets/javascripts/jquery-ui/widgets/progressbar.js +184 -0
  144. data/app/assets/javascripts/jquery-ui/widgets/resizable.js +1225 -0
  145. data/app/assets/javascripts/jquery-ui/widgets/selectable.js +321 -0
  146. data/app/assets/javascripts/jquery-ui/widgets/selectmenu.js +702 -0
  147. data/app/assets/javascripts/jquery-ui/widgets/slider.js +760 -0
  148. data/app/assets/javascripts/jquery-ui/widgets/sortable.js +1622 -0
  149. data/app/assets/javascripts/jquery-ui/widgets/spinner.js +588 -0
  150. data/app/assets/javascripts/jquery-ui/widgets/tabs.js +931 -0
  151. data/app/assets/javascripts/jquery-ui/widgets/tooltip.js +533 -0
  152. data/app/assets/javascripts/jquery-ui.js +57 -0
  153. data/app/assets/stylesheets/jquery-ui/accordion.css +26 -0
  154. data/app/assets/stylesheets/jquery-ui/all.css +14 -0
  155. data/app/assets/stylesheets/jquery-ui/autocomplete.css +19 -0
  156. data/app/assets/stylesheets/jquery-ui/base.css +32 -0
  157. data/app/assets/stylesheets/jquery-ui/button.css +85 -0
  158. data/app/assets/stylesheets/jquery-ui/checkboxradio.css +37 -0
  159. data/app/assets/stylesheets/jquery-ui/controlgroup.css +68 -0
  160. data/app/assets/stylesheets/jquery-ui/core.css +100 -0
  161. data/app/assets/stylesheets/jquery-ui/datepicker.css +188 -0
  162. data/app/assets/stylesheets/jquery-ui/dialog.css +104 -0
  163. data/app/assets/stylesheets/jquery-ui/draggable.css +15 -0
  164. data/app/assets/stylesheets/jquery-ui/menu.css +67 -0
  165. data/app/assets/stylesheets/jquery-ui/progressbar.css +31 -0
  166. data/app/assets/stylesheets/jquery-ui/resizable.css +81 -0
  167. data/app/assets/stylesheets/jquery-ui/selectable.css +20 -0
  168. data/app/assets/stylesheets/jquery-ui/selectmenu.css +53 -0
  169. data/app/assets/stylesheets/jquery-ui/slider.css +78 -0
  170. data/app/assets/stylesheets/jquery-ui/sortable.css +15 -0
  171. data/app/assets/stylesheets/jquery-ui/spinner.css +55 -0
  172. data/app/assets/stylesheets/jquery-ui/tabs.css +54 -0
  173. data/app/assets/stylesheets/jquery-ui/theme.css.erb +456 -0
  174. data/app/assets/stylesheets/jquery-ui/tooltip.css +22 -0
  175. data/app/assets/stylesheets/jquery-ui.css +1 -0
  176. data/lib/jquery/ui/rails/engine.rb +8 -0
  177. data/lib/jquery/ui/rails/version.rb +8 -0
  178. data/lib/jquery/ui/rails.rb +2 -0
  179. data/lib/jquery-ui-rails.rb +1 -0
  180. metadata +250 -0
@@ -0,0 +1,720 @@
1
+ //= require jquery-ui/keycode
2
+ //= require jquery-ui/position
3
+ //= require jquery-ui/safe-active-element
4
+ //= require jquery-ui/unique-id
5
+ //= require jquery-ui/version
6
+ //= require jquery-ui/widget
7
+
8
+ /*!
9
+ * jQuery UI Menu 1.13.2
10
+ * http://jqueryui.com
11
+ *
12
+ * Copyright jQuery Foundation and other contributors
13
+ * Released under the MIT license.
14
+ * http://jquery.org/license
15
+ */
16
+
17
+ //>>label: Menu
18
+ //>>group: Widgets
19
+ //>>description: Creates nestable menus.
20
+ //>>docs: http://api.jqueryui.com/menu/
21
+ //>>demos: http://jqueryui.com/menu/
22
+ //>>css.structure: ../../themes/base/core.css
23
+ //>>css.structure: ../../themes/base/menu.css
24
+ //>>css.theme: ../../themes/base/theme.css
25
+
26
+ ( function( factory ) {
27
+ "use strict";
28
+
29
+ if ( typeof define === "function" && define.amd ) {
30
+
31
+ // AMD. Register as an anonymous module.
32
+ define( [
33
+ "jquery",
34
+ "../keycode",
35
+ "../position",
36
+ "../safe-active-element",
37
+ "../unique-id",
38
+ "../version",
39
+ "../widget"
40
+ ], factory );
41
+ } else {
42
+
43
+ // Browser globals
44
+ factory( jQuery );
45
+ }
46
+ } )( function( $ ) {
47
+ "use strict";
48
+
49
+ return $.widget( "ui.menu", {
50
+ version: "1.13.2",
51
+ defaultElement: "<ul>",
52
+ delay: 300,
53
+ options: {
54
+ icons: {
55
+ submenu: "ui-icon-caret-1-e"
56
+ },
57
+ items: "> *",
58
+ menus: "ul",
59
+ position: {
60
+ my: "left top",
61
+ at: "right top"
62
+ },
63
+ role: "menu",
64
+
65
+ // Callbacks
66
+ blur: null,
67
+ focus: null,
68
+ select: null
69
+ },
70
+
71
+ _create: function() {
72
+ this.activeMenu = this.element;
73
+
74
+ // Flag used to prevent firing of the click handler
75
+ // as the event bubbles up through nested menus
76
+ this.mouseHandled = false;
77
+ this.lastMousePosition = { x: null, y: null };
78
+ this.element
79
+ .uniqueId()
80
+ .attr( {
81
+ role: this.options.role,
82
+ tabIndex: 0
83
+ } );
84
+
85
+ this._addClass( "ui-menu", "ui-widget ui-widget-content" );
86
+ this._on( {
87
+
88
+ // Prevent focus from sticking to links inside menu after clicking
89
+ // them (focus should always stay on UL during navigation).
90
+ "mousedown .ui-menu-item": function( event ) {
91
+ event.preventDefault();
92
+
93
+ this._activateItem( event );
94
+ },
95
+ "click .ui-menu-item": function( event ) {
96
+ var target = $( event.target );
97
+ var active = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
98
+ if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
99
+ this.select( event );
100
+
101
+ // Only set the mouseHandled flag if the event will bubble, see #9469.
102
+ if ( !event.isPropagationStopped() ) {
103
+ this.mouseHandled = true;
104
+ }
105
+
106
+ // Open submenu on click
107
+ if ( target.has( ".ui-menu" ).length ) {
108
+ this.expand( event );
109
+ } else if ( !this.element.is( ":focus" ) &&
110
+ active.closest( ".ui-menu" ).length ) {
111
+
112
+ // Redirect focus to the menu
113
+ this.element.trigger( "focus", [ true ] );
114
+
115
+ // If the active item is on the top level, let it stay active.
116
+ // Otherwise, blur the active item since it is no longer visible.
117
+ if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
118
+ clearTimeout( this.timer );
119
+ }
120
+ }
121
+ }
122
+ },
123
+ "mouseenter .ui-menu-item": "_activateItem",
124
+ "mousemove .ui-menu-item": "_activateItem",
125
+ mouseleave: "collapseAll",
126
+ "mouseleave .ui-menu": "collapseAll",
127
+ focus: function( event, keepActiveItem ) {
128
+
129
+ // If there's already an active item, keep it active
130
+ // If not, activate the first item
131
+ var item = this.active || this._menuItems().first();
132
+
133
+ if ( !keepActiveItem ) {
134
+ this.focus( event, item );
135
+ }
136
+ },
137
+ blur: function( event ) {
138
+ this._delay( function() {
139
+ var notContained = !$.contains(
140
+ this.element[ 0 ],
141
+ $.ui.safeActiveElement( this.document[ 0 ] )
142
+ );
143
+ if ( notContained ) {
144
+ this.collapseAll( event );
145
+ }
146
+ } );
147
+ },
148
+ keydown: "_keydown"
149
+ } );
150
+
151
+ this.refresh();
152
+
153
+ // Clicks outside of a menu collapse any open menus
154
+ this._on( this.document, {
155
+ click: function( event ) {
156
+ if ( this._closeOnDocumentClick( event ) ) {
157
+ this.collapseAll( event, true );
158
+ }
159
+
160
+ // Reset the mouseHandled flag
161
+ this.mouseHandled = false;
162
+ }
163
+ } );
164
+ },
165
+
166
+ _activateItem: function( event ) {
167
+
168
+ // Ignore mouse events while typeahead is active, see #10458.
169
+ // Prevents focusing the wrong item when typeahead causes a scroll while the mouse
170
+ // is over an item in the menu
171
+ if ( this.previousFilter ) {
172
+ return;
173
+ }
174
+
175
+ // If the mouse didn't actually move, but the page was scrolled, ignore the event (#9356)
176
+ if ( event.clientX === this.lastMousePosition.x &&
177
+ event.clientY === this.lastMousePosition.y ) {
178
+ return;
179
+ }
180
+
181
+ this.lastMousePosition = {
182
+ x: event.clientX,
183
+ y: event.clientY
184
+ };
185
+
186
+ var actualTarget = $( event.target ).closest( ".ui-menu-item" ),
187
+ target = $( event.currentTarget );
188
+
189
+ // Ignore bubbled events on parent items, see #11641
190
+ if ( actualTarget[ 0 ] !== target[ 0 ] ) {
191
+ return;
192
+ }
193
+
194
+ // If the item is already active, there's nothing to do
195
+ if ( target.is( ".ui-state-active" ) ) {
196
+ return;
197
+ }
198
+
199
+ // Remove ui-state-active class from siblings of the newly focused menu item
200
+ // to avoid a jump caused by adjacent elements both having a class with a border
201
+ this._removeClass( target.siblings().children( ".ui-state-active" ),
202
+ null, "ui-state-active" );
203
+ this.focus( event, target );
204
+ },
205
+
206
+ _destroy: function() {
207
+ var items = this.element.find( ".ui-menu-item" )
208
+ .removeAttr( "role aria-disabled" ),
209
+ submenus = items.children( ".ui-menu-item-wrapper" )
210
+ .removeUniqueId()
211
+ .removeAttr( "tabIndex role aria-haspopup" );
212
+
213
+ // Destroy (sub)menus
214
+ this.element
215
+ .removeAttr( "aria-activedescendant" )
216
+ .find( ".ui-menu" ).addBack()
217
+ .removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " +
218
+ "tabIndex" )
219
+ .removeUniqueId()
220
+ .show();
221
+
222
+ submenus.children().each( function() {
223
+ var elem = $( this );
224
+ if ( elem.data( "ui-menu-submenu-caret" ) ) {
225
+ elem.remove();
226
+ }
227
+ } );
228
+ },
229
+
230
+ _keydown: function( event ) {
231
+ var match, prev, character, skip,
232
+ preventDefault = true;
233
+
234
+ switch ( event.keyCode ) {
235
+ case $.ui.keyCode.PAGE_UP:
236
+ this.previousPage( event );
237
+ break;
238
+ case $.ui.keyCode.PAGE_DOWN:
239
+ this.nextPage( event );
240
+ break;
241
+ case $.ui.keyCode.HOME:
242
+ this._move( "first", "first", event );
243
+ break;
244
+ case $.ui.keyCode.END:
245
+ this._move( "last", "last", event );
246
+ break;
247
+ case $.ui.keyCode.UP:
248
+ this.previous( event );
249
+ break;
250
+ case $.ui.keyCode.DOWN:
251
+ this.next( event );
252
+ break;
253
+ case $.ui.keyCode.LEFT:
254
+ this.collapse( event );
255
+ break;
256
+ case $.ui.keyCode.RIGHT:
257
+ if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
258
+ this.expand( event );
259
+ }
260
+ break;
261
+ case $.ui.keyCode.ENTER:
262
+ case $.ui.keyCode.SPACE:
263
+ this._activate( event );
264
+ break;
265
+ case $.ui.keyCode.ESCAPE:
266
+ this.collapse( event );
267
+ break;
268
+ default:
269
+ preventDefault = false;
270
+ prev = this.previousFilter || "";
271
+ skip = false;
272
+
273
+ // Support number pad values
274
+ character = event.keyCode >= 96 && event.keyCode <= 105 ?
275
+ ( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode );
276
+
277
+ clearTimeout( this.filterTimer );
278
+
279
+ if ( character === prev ) {
280
+ skip = true;
281
+ } else {
282
+ character = prev + character;
283
+ }
284
+
285
+ match = this._filterMenuItems( character );
286
+ match = skip && match.index( this.active.next() ) !== -1 ?
287
+ this.active.nextAll( ".ui-menu-item" ) :
288
+ match;
289
+
290
+ // If no matches on the current filter, reset to the last character pressed
291
+ // to move down the menu to the first item that starts with that character
292
+ if ( !match.length ) {
293
+ character = String.fromCharCode( event.keyCode );
294
+ match = this._filterMenuItems( character );
295
+ }
296
+
297
+ if ( match.length ) {
298
+ this.focus( event, match );
299
+ this.previousFilter = character;
300
+ this.filterTimer = this._delay( function() {
301
+ delete this.previousFilter;
302
+ }, 1000 );
303
+ } else {
304
+ delete this.previousFilter;
305
+ }
306
+ }
307
+
308
+ if ( preventDefault ) {
309
+ event.preventDefault();
310
+ }
311
+ },
312
+
313
+ _activate: function( event ) {
314
+ if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
315
+ if ( this.active.children( "[aria-haspopup='true']" ).length ) {
316
+ this.expand( event );
317
+ } else {
318
+ this.select( event );
319
+ }
320
+ }
321
+ },
322
+
323
+ refresh: function() {
324
+ var menus, items, newSubmenus, newItems, newWrappers,
325
+ that = this,
326
+ icon = this.options.icons.submenu,
327
+ submenus = this.element.find( this.options.menus );
328
+
329
+ this._toggleClass( "ui-menu-icons", null, !!this.element.find( ".ui-icon" ).length );
330
+
331
+ // Initialize nested menus
332
+ newSubmenus = submenus.filter( ":not(.ui-menu)" )
333
+ .hide()
334
+ .attr( {
335
+ role: this.options.role,
336
+ "aria-hidden": "true",
337
+ "aria-expanded": "false"
338
+ } )
339
+ .each( function() {
340
+ var menu = $( this ),
341
+ item = menu.prev(),
342
+ submenuCaret = $( "<span>" ).data( "ui-menu-submenu-caret", true );
343
+
344
+ that._addClass( submenuCaret, "ui-menu-icon", "ui-icon " + icon );
345
+ item
346
+ .attr( "aria-haspopup", "true" )
347
+ .prepend( submenuCaret );
348
+ menu.attr( "aria-labelledby", item.attr( "id" ) );
349
+ } );
350
+
351
+ this._addClass( newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front" );
352
+
353
+ menus = submenus.add( this.element );
354
+ items = menus.find( this.options.items );
355
+
356
+ // Initialize menu-items containing spaces and/or dashes only as dividers
357
+ items.not( ".ui-menu-item" ).each( function() {
358
+ var item = $( this );
359
+ if ( that._isDivider( item ) ) {
360
+ that._addClass( item, "ui-menu-divider", "ui-widget-content" );
361
+ }
362
+ } );
363
+
364
+ // Don't refresh list items that are already adapted
365
+ newItems = items.not( ".ui-menu-item, .ui-menu-divider" );
366
+ newWrappers = newItems.children()
367
+ .not( ".ui-menu" )
368
+ .uniqueId()
369
+ .attr( {
370
+ tabIndex: -1,
371
+ role: this._itemRole()
372
+ } );
373
+ this._addClass( newItems, "ui-menu-item" )
374
+ ._addClass( newWrappers, "ui-menu-item-wrapper" );
375
+
376
+ // Add aria-disabled attribute to any disabled menu item
377
+ items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
378
+
379
+ // If the active item has been removed, blur the menu
380
+ if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
381
+ this.blur();
382
+ }
383
+ },
384
+
385
+ _itemRole: function() {
386
+ return {
387
+ menu: "menuitem",
388
+ listbox: "option"
389
+ }[ this.options.role ];
390
+ },
391
+
392
+ _setOption: function( key, value ) {
393
+ if ( key === "icons" ) {
394
+ var icons = this.element.find( ".ui-menu-icon" );
395
+ this._removeClass( icons, null, this.options.icons.submenu )
396
+ ._addClass( icons, null, value.submenu );
397
+ }
398
+ this._super( key, value );
399
+ },
400
+
401
+ _setOptionDisabled: function( value ) {
402
+ this._super( value );
403
+
404
+ this.element.attr( "aria-disabled", String( value ) );
405
+ this._toggleClass( null, "ui-state-disabled", !!value );
406
+ },
407
+
408
+ focus: function( event, item ) {
409
+ var nested, focused, activeParent;
410
+ this.blur( event, event && event.type === "focus" );
411
+
412
+ this._scrollIntoView( item );
413
+
414
+ this.active = item.first();
415
+
416
+ focused = this.active.children( ".ui-menu-item-wrapper" );
417
+ this._addClass( focused, null, "ui-state-active" );
418
+
419
+ // Only update aria-activedescendant if there's a role
420
+ // otherwise we assume focus is managed elsewhere
421
+ if ( this.options.role ) {
422
+ this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
423
+ }
424
+
425
+ // Highlight active parent menu item, if any
426
+ activeParent = this.active
427
+ .parent()
428
+ .closest( ".ui-menu-item" )
429
+ .children( ".ui-menu-item-wrapper" );
430
+ this._addClass( activeParent, null, "ui-state-active" );
431
+
432
+ if ( event && event.type === "keydown" ) {
433
+ this._close();
434
+ } else {
435
+ this.timer = this._delay( function() {
436
+ this._close();
437
+ }, this.delay );
438
+ }
439
+
440
+ nested = item.children( ".ui-menu" );
441
+ if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
442
+ this._startOpening( nested );
443
+ }
444
+ this.activeMenu = item.parent();
445
+
446
+ this._trigger( "focus", event, { item: item } );
447
+ },
448
+
449
+ _scrollIntoView: function( item ) {
450
+ var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
451
+ if ( this._hasScroll() ) {
452
+ borderTop = parseFloat( $.css( this.activeMenu[ 0 ], "borderTopWidth" ) ) || 0;
453
+ paddingTop = parseFloat( $.css( this.activeMenu[ 0 ], "paddingTop" ) ) || 0;
454
+ offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
455
+ scroll = this.activeMenu.scrollTop();
456
+ elementHeight = this.activeMenu.height();
457
+ itemHeight = item.outerHeight();
458
+
459
+ if ( offset < 0 ) {
460
+ this.activeMenu.scrollTop( scroll + offset );
461
+ } else if ( offset + itemHeight > elementHeight ) {
462
+ this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
463
+ }
464
+ }
465
+ },
466
+
467
+ blur: function( event, fromFocus ) {
468
+ if ( !fromFocus ) {
469
+ clearTimeout( this.timer );
470
+ }
471
+
472
+ if ( !this.active ) {
473
+ return;
474
+ }
475
+
476
+ this._removeClass( this.active.children( ".ui-menu-item-wrapper" ),
477
+ null, "ui-state-active" );
478
+
479
+ this._trigger( "blur", event, { item: this.active } );
480
+ this.active = null;
481
+ },
482
+
483
+ _startOpening: function( submenu ) {
484
+ clearTimeout( this.timer );
485
+
486
+ // Don't open if already open fixes a Firefox bug that caused a .5 pixel
487
+ // shift in the submenu position when mousing over the caret icon
488
+ if ( submenu.attr( "aria-hidden" ) !== "true" ) {
489
+ return;
490
+ }
491
+
492
+ this.timer = this._delay( function() {
493
+ this._close();
494
+ this._open( submenu );
495
+ }, this.delay );
496
+ },
497
+
498
+ _open: function( submenu ) {
499
+ var position = $.extend( {
500
+ of: this.active
501
+ }, this.options.position );
502
+
503
+ clearTimeout( this.timer );
504
+ this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
505
+ .hide()
506
+ .attr( "aria-hidden", "true" );
507
+
508
+ submenu
509
+ .show()
510
+ .removeAttr( "aria-hidden" )
511
+ .attr( "aria-expanded", "true" )
512
+ .position( position );
513
+ },
514
+
515
+ collapseAll: function( event, all ) {
516
+ clearTimeout( this.timer );
517
+ this.timer = this._delay( function() {
518
+
519
+ // If we were passed an event, look for the submenu that contains the event
520
+ var currentMenu = all ? this.element :
521
+ $( event && event.target ).closest( this.element.find( ".ui-menu" ) );
522
+
523
+ // If we found no valid submenu ancestor, use the main menu to close all
524
+ // sub menus anyway
525
+ if ( !currentMenu.length ) {
526
+ currentMenu = this.element;
527
+ }
528
+
529
+ this._close( currentMenu );
530
+
531
+ this.blur( event );
532
+
533
+ // Work around active item staying active after menu is blurred
534
+ this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" );
535
+
536
+ this.activeMenu = currentMenu;
537
+ }, all ? 0 : this.delay );
538
+ },
539
+
540
+ // With no arguments, closes the currently active menu - if nothing is active
541
+ // it closes all menus. If passed an argument, it will search for menus BELOW
542
+ _close: function( startMenu ) {
543
+ if ( !startMenu ) {
544
+ startMenu = this.active ? this.active.parent() : this.element;
545
+ }
546
+
547
+ startMenu.find( ".ui-menu" )
548
+ .hide()
549
+ .attr( "aria-hidden", "true" )
550
+ .attr( "aria-expanded", "false" );
551
+ },
552
+
553
+ _closeOnDocumentClick: function( event ) {
554
+ return !$( event.target ).closest( ".ui-menu" ).length;
555
+ },
556
+
557
+ _isDivider: function( item ) {
558
+
559
+ // Match hyphen, em dash, en dash
560
+ return !/[^\-\u2014\u2013\s]/.test( item.text() );
561
+ },
562
+
563
+ collapse: function( event ) {
564
+ var newItem = this.active &&
565
+ this.active.parent().closest( ".ui-menu-item", this.element );
566
+ if ( newItem && newItem.length ) {
567
+ this._close();
568
+ this.focus( event, newItem );
569
+ }
570
+ },
571
+
572
+ expand: function( event ) {
573
+ var newItem = this.active && this._menuItems( this.active.children( ".ui-menu" ) ).first();
574
+
575
+ if ( newItem && newItem.length ) {
576
+ this._open( newItem.parent() );
577
+
578
+ // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
579
+ this._delay( function() {
580
+ this.focus( event, newItem );
581
+ } );
582
+ }
583
+ },
584
+
585
+ next: function( event ) {
586
+ this._move( "next", "first", event );
587
+ },
588
+
589
+ previous: function( event ) {
590
+ this._move( "prev", "last", event );
591
+ },
592
+
593
+ isFirstItem: function() {
594
+ return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
595
+ },
596
+
597
+ isLastItem: function() {
598
+ return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
599
+ },
600
+
601
+ _menuItems: function( menu ) {
602
+ return ( menu || this.element )
603
+ .find( this.options.items )
604
+ .filter( ".ui-menu-item" );
605
+ },
606
+
607
+ _move: function( direction, filter, event ) {
608
+ var next;
609
+ if ( this.active ) {
610
+ if ( direction === "first" || direction === "last" ) {
611
+ next = this.active
612
+ [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
613
+ .last();
614
+ } else {
615
+ next = this.active
616
+ [ direction + "All" ]( ".ui-menu-item" )
617
+ .first();
618
+ }
619
+ }
620
+ if ( !next || !next.length || !this.active ) {
621
+ next = this._menuItems( this.activeMenu )[ filter ]();
622
+ }
623
+
624
+ this.focus( event, next );
625
+ },
626
+
627
+ nextPage: function( event ) {
628
+ var item, base, height;
629
+
630
+ if ( !this.active ) {
631
+ this.next( event );
632
+ return;
633
+ }
634
+ if ( this.isLastItem() ) {
635
+ return;
636
+ }
637
+ if ( this._hasScroll() ) {
638
+ base = this.active.offset().top;
639
+ height = this.element.innerHeight();
640
+
641
+ // jQuery 3.2 doesn't include scrollbars in innerHeight, add it back.
642
+ if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) {
643
+ height += this.element[ 0 ].offsetHeight - this.element.outerHeight();
644
+ }
645
+
646
+ this.active.nextAll( ".ui-menu-item" ).each( function() {
647
+ item = $( this );
648
+ return item.offset().top - base - height < 0;
649
+ } );
650
+
651
+ this.focus( event, item );
652
+ } else {
653
+ this.focus( event, this._menuItems( this.activeMenu )
654
+ [ !this.active ? "first" : "last" ]() );
655
+ }
656
+ },
657
+
658
+ previousPage: function( event ) {
659
+ var item, base, height;
660
+ if ( !this.active ) {
661
+ this.next( event );
662
+ return;
663
+ }
664
+ if ( this.isFirstItem() ) {
665
+ return;
666
+ }
667
+ if ( this._hasScroll() ) {
668
+ base = this.active.offset().top;
669
+ height = this.element.innerHeight();
670
+
671
+ // jQuery 3.2 doesn't include scrollbars in innerHeight, add it back.
672
+ if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) {
673
+ height += this.element[ 0 ].offsetHeight - this.element.outerHeight();
674
+ }
675
+
676
+ this.active.prevAll( ".ui-menu-item" ).each( function() {
677
+ item = $( this );
678
+ return item.offset().top - base + height > 0;
679
+ } );
680
+
681
+ this.focus( event, item );
682
+ } else {
683
+ this.focus( event, this._menuItems( this.activeMenu ).first() );
684
+ }
685
+ },
686
+
687
+ _hasScroll: function() {
688
+ return this.element.outerHeight() < this.element.prop( "scrollHeight" );
689
+ },
690
+
691
+ select: function( event ) {
692
+
693
+ // TODO: It should never be possible to not have an active item at this
694
+ // point, but the tests don't trigger mouseenter before click.
695
+ this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
696
+ var ui = { item: this.active };
697
+ if ( !this.active.has( ".ui-menu" ).length ) {
698
+ this.collapseAll( event, true );
699
+ }
700
+ this._trigger( "select", event, ui );
701
+ },
702
+
703
+ _filterMenuItems: function( character ) {
704
+ var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
705
+ regex = new RegExp( "^" + escapedCharacter, "i" );
706
+
707
+ return this.activeMenu
708
+ .find( this.options.items )
709
+
710
+ // Only match on items, not dividers or other content (#10571)
711
+ .filter( ".ui-menu-item" )
712
+ .filter( function() {
713
+ return regex.test(
714
+ String.prototype.trim.call(
715
+ $( this ).children( ".ui-menu-item-wrapper" ).text() ) );
716
+ } );
717
+ }
718
+ } );
719
+
720
+ } );