sn-jquery-ui-rails 6.0.2

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