jquery-ui-rails 0.0.1

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 (137) hide show
  1. data/.gitmodules +3 -0
  2. data/Gemfile +3 -0
  3. data/README.md +1 -0
  4. data/Rakefile +77 -0
  5. data/dependencies.js +1 -0
  6. data/jquery-ui-rails.gemspec +23 -0
  7. data/lib/jquery-ui-rails.rb +1 -0
  8. data/lib/jquery/ui/rails.rb +2 -0
  9. data/lib/jquery/ui/rails/engine.rb +8 -0
  10. data/lib/jquery/ui/rails/version.rb +7 -0
  11. data/vendor/assets/images/jquery-ui/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  12. data/vendor/assets/images/jquery-ui/ui-bg_flat_75_ffffff_40x100.png +0 -0
  13. data/vendor/assets/images/jquery-ui/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  14. data/vendor/assets/images/jquery-ui/ui-bg_glass_65_ffffff_1x400.png +0 -0
  15. data/vendor/assets/images/jquery-ui/ui-bg_glass_75_dadada_1x400.png +0 -0
  16. data/vendor/assets/images/jquery-ui/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  17. data/vendor/assets/images/jquery-ui/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  18. data/vendor/assets/images/jquery-ui/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  19. data/vendor/assets/images/jquery-ui/ui-icons_222222_256x240.png +0 -0
  20. data/vendor/assets/images/jquery-ui/ui-icons_2e83ff_256x240.png +0 -0
  21. data/vendor/assets/images/jquery-ui/ui-icons_454545_256x240.png +0 -0
  22. data/vendor/assets/images/jquery-ui/ui-icons_888888_256x240.png +0 -0
  23. data/vendor/assets/images/jquery-ui/ui-icons_cd0a0a_256x240.png +0 -0
  24. data/vendor/assets/javascripts/jquery-ui.js +31 -0
  25. data/vendor/assets/javascripts/jquery-uix.js +31 -0
  26. data/vendor/assets/javascripts/jquery.effects.blind.js +52 -0
  27. data/vendor/assets/javascripts/jquery.effects.bounce.js +81 -0
  28. data/vendor/assets/javascripts/jquery.effects.clip.js +57 -0
  29. data/vendor/assets/javascripts/jquery.effects.core.js +764 -0
  30. data/vendor/assets/javascripts/jquery.effects.drop.js +53 -0
  31. data/vendor/assets/javascripts/jquery.effects.explode.js +82 -0
  32. data/vendor/assets/javascripts/jquery.effects.fade.js +35 -0
  33. data/vendor/assets/javascripts/jquery.effects.fold.js +59 -0
  34. data/vendor/assets/javascripts/jquery.effects.highlight.js +53 -0
  35. data/vendor/assets/javascripts/jquery.effects.pulsate.js +54 -0
  36. data/vendor/assets/javascripts/jquery.effects.scale.js +181 -0
  37. data/vendor/assets/javascripts/jquery.effects.shake.js +60 -0
  38. data/vendor/assets/javascripts/jquery.effects.slide.js +53 -0
  39. data/vendor/assets/javascripts/jquery.effects.transfer.js +48 -0
  40. data/vendor/assets/javascripts/jquery.ui.accordion.js +615 -0
  41. data/vendor/assets/javascripts/jquery.ui.autocomplete.js +627 -0
  42. data/vendor/assets/javascripts/jquery.ui.button.js +420 -0
  43. data/vendor/assets/javascripts/jquery.ui.core.js +315 -0
  44. data/vendor/assets/javascripts/jquery.ui.datepicker-af.js +26 -0
  45. data/vendor/assets/javascripts/jquery.ui.datepicker-ar-DZ.js +26 -0
  46. data/vendor/assets/javascripts/jquery.ui.datepicker-ar.js +26 -0
  47. data/vendor/assets/javascripts/jquery.ui.datepicker-az.js +26 -0
  48. data/vendor/assets/javascripts/jquery.ui.datepicker-bg.js +27 -0
  49. data/vendor/assets/javascripts/jquery.ui.datepicker-bs.js +26 -0
  50. data/vendor/assets/javascripts/jquery.ui.datepicker-ca.js +26 -0
  51. data/vendor/assets/javascripts/jquery.ui.datepicker-cs.js +26 -0
  52. data/vendor/assets/javascripts/jquery.ui.datepicker-cy-GB.js +26 -0
  53. data/vendor/assets/javascripts/jquery.ui.datepicker-da.js +26 -0
  54. data/vendor/assets/javascripts/jquery.ui.datepicker-de.js +26 -0
  55. data/vendor/assets/javascripts/jquery.ui.datepicker-el.js +26 -0
  56. data/vendor/assets/javascripts/jquery.ui.datepicker-en-AU.js +26 -0
  57. data/vendor/assets/javascripts/jquery.ui.datepicker-en-GB.js +26 -0
  58. data/vendor/assets/javascripts/jquery.ui.datepicker-en-NZ.js +26 -0
  59. data/vendor/assets/javascripts/jquery.ui.datepicker-eo.js +26 -0
  60. data/vendor/assets/javascripts/jquery.ui.datepicker-es.js +26 -0
  61. data/vendor/assets/javascripts/jquery.ui.datepicker-et.js +26 -0
  62. data/vendor/assets/javascripts/jquery.ui.datepicker-eu.js +26 -0
  63. data/vendor/assets/javascripts/jquery.ui.datepicker-fa.js +26 -0
  64. data/vendor/assets/javascripts/jquery.ui.datepicker-fi.js +26 -0
  65. data/vendor/assets/javascripts/jquery.ui.datepicker-fo.js +26 -0
  66. data/vendor/assets/javascripts/jquery.ui.datepicker-fr-CH.js +26 -0
  67. data/vendor/assets/javascripts/jquery.ui.datepicker-fr.js +28 -0
  68. data/vendor/assets/javascripts/jquery.ui.datepicker-gl.js +26 -0
  69. data/vendor/assets/javascripts/jquery.ui.datepicker-he.js +26 -0
  70. data/vendor/assets/javascripts/jquery.ui.datepicker-hr.js +26 -0
  71. data/vendor/assets/javascripts/jquery.ui.datepicker-hu.js +26 -0
  72. data/vendor/assets/javascripts/jquery.ui.datepicker-hy.js +26 -0
  73. data/vendor/assets/javascripts/jquery.ui.datepicker-id.js +26 -0
  74. data/vendor/assets/javascripts/jquery.ui.datepicker-is.js +26 -0
  75. data/vendor/assets/javascripts/jquery.ui.datepicker-it.js +26 -0
  76. data/vendor/assets/javascripts/jquery.ui.datepicker-ja.js +26 -0
  77. data/vendor/assets/javascripts/jquery.ui.datepicker-kk.js +26 -0
  78. data/vendor/assets/javascripts/jquery.ui.datepicker-ko.js +26 -0
  79. data/vendor/assets/javascripts/jquery.ui.datepicker-lb.js +26 -0
  80. data/vendor/assets/javascripts/jquery.ui.datepicker-lt.js +26 -0
  81. data/vendor/assets/javascripts/jquery.ui.datepicker-lv.js +26 -0
  82. data/vendor/assets/javascripts/jquery.ui.datepicker-mk.js +26 -0
  83. data/vendor/assets/javascripts/jquery.ui.datepicker-ml.js +26 -0
  84. data/vendor/assets/javascripts/jquery.ui.datepicker-ms.js +26 -0
  85. data/vendor/assets/javascripts/jquery.ui.datepicker-nl-BE.js +26 -0
  86. data/vendor/assets/javascripts/jquery.ui.datepicker-nl.js +26 -0
  87. data/vendor/assets/javascripts/jquery.ui.datepicker-no.js +26 -0
  88. data/vendor/assets/javascripts/jquery.ui.datepicker-pl.js +26 -0
  89. data/vendor/assets/javascripts/jquery.ui.datepicker-pt-BR.js +26 -0
  90. data/vendor/assets/javascripts/jquery.ui.datepicker-pt.js +25 -0
  91. data/vendor/assets/javascripts/jquery.ui.datepicker-rm.js +24 -0
  92. data/vendor/assets/javascripts/jquery.ui.datepicker-ro.js +29 -0
  93. data/vendor/assets/javascripts/jquery.ui.datepicker-ru.js +26 -0
  94. data/vendor/assets/javascripts/jquery.ui.datepicker-sk.js +26 -0
  95. data/vendor/assets/javascripts/jquery.ui.datepicker-sl.js +27 -0
  96. data/vendor/assets/javascripts/jquery.ui.datepicker-sq.js +26 -0
  97. data/vendor/assets/javascripts/jquery.ui.datepicker-sr-SR.js +26 -0
  98. data/vendor/assets/javascripts/jquery.ui.datepicker-sr.js +26 -0
  99. data/vendor/assets/javascripts/jquery.ui.datepicker-sv.js +26 -0
  100. data/vendor/assets/javascripts/jquery.ui.datepicker-ta.js +26 -0
  101. data/vendor/assets/javascripts/jquery.ui.datepicker-th.js +26 -0
  102. data/vendor/assets/javascripts/jquery.ui.datepicker-tj.js +26 -0
  103. data/vendor/assets/javascripts/jquery.ui.datepicker-tr.js +26 -0
  104. data/vendor/assets/javascripts/jquery.ui.datepicker-uk.js +27 -0
  105. data/vendor/assets/javascripts/jquery.ui.datepicker-vi.js +26 -0
  106. data/vendor/assets/javascripts/jquery.ui.datepicker-zh-CN.js +26 -0
  107. data/vendor/assets/javascripts/jquery.ui.datepicker-zh-HK.js +26 -0
  108. data/vendor/assets/javascripts/jquery.ui.datepicker-zh-TW.js +26 -0
  109. data/vendor/assets/javascripts/jquery.ui.datepicker.js +1826 -0
  110. data/vendor/assets/javascripts/jquery.ui.dialog.js +883 -0
  111. data/vendor/assets/javascripts/jquery.ui.draggable.js +830 -0
  112. data/vendor/assets/javascripts/jquery.ui.droppable.js +302 -0
  113. data/vendor/assets/javascripts/jquery.ui.mouse.js +166 -0
  114. data/vendor/assets/javascripts/jquery.ui.position.js +299 -0
  115. data/vendor/assets/javascripts/jquery.ui.progressbar.js +113 -0
  116. data/vendor/assets/javascripts/jquery.ui.resizable.js +847 -0
  117. data/vendor/assets/javascripts/jquery.ui.selectable.js +272 -0
  118. data/vendor/assets/javascripts/jquery.ui.slider.js +671 -0
  119. data/vendor/assets/javascripts/jquery.ui.sortable.js +1081 -0
  120. data/vendor/assets/javascripts/jquery.ui.tabs.js +762 -0
  121. data/vendor/assets/javascripts/jquery.ui.widget.js +273 -0
  122. data/vendor/assets/stylesheets/jquery-ui.js +1 -0
  123. data/vendor/assets/stylesheets/jquery.ui.accordion.css +19 -0
  124. data/vendor/assets/stylesheets/jquery.ui.all.css +13 -0
  125. data/vendor/assets/stylesheets/jquery.ui.autocomplete.css +53 -0
  126. data/vendor/assets/stylesheets/jquery.ui.base.css +23 -0
  127. data/vendor/assets/stylesheets/jquery.ui.button.css +38 -0
  128. data/vendor/assets/stylesheets/jquery.ui.core.css +38 -0
  129. data/vendor/assets/stylesheets/jquery.ui.datepicker.css +68 -0
  130. data/vendor/assets/stylesheets/jquery.ui.dialog.css +21 -0
  131. data/vendor/assets/stylesheets/jquery.ui.progressbar.css +11 -0
  132. data/vendor/assets/stylesheets/jquery.ui.resizable.css +20 -0
  133. data/vendor/assets/stylesheets/jquery.ui.selectable.css +10 -0
  134. data/vendor/assets/stylesheets/jquery.ui.slider.css +24 -0
  135. data/vendor/assets/stylesheets/jquery.ui.tabs.css +18 -0
  136. data/vendor/assets/stylesheets/jquery.ui.theme.css +247 -0
  137. metadata +216 -0
@@ -0,0 +1,627 @@
1
+ //= require jquery
2
+ //= require jquery.ui.core
3
+ //= require jquery.ui.widget
4
+ //= require jquery.ui.position
5
+
6
+ /*
7
+ * jQuery UI Autocomplete 1.8.17
8
+ *
9
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
10
+ * Dual licensed under the MIT or GPL Version 2 licenses.
11
+ * http://jquery.org/license
12
+ *
13
+ * http://docs.jquery.com/UI/Autocomplete
14
+ *
15
+ * Depends:
16
+ * jquery.ui.core.js
17
+ * jquery.ui.widget.js
18
+ * jquery.ui.position.js
19
+ */
20
+ (function( $, undefined ) {
21
+
22
+ // used to prevent race conditions with remote data sources
23
+ var requestIndex = 0;
24
+
25
+ $.widget( "ui.autocomplete", {
26
+ options: {
27
+ appendTo: "body",
28
+ autoFocus: false,
29
+ delay: 300,
30
+ minLength: 1,
31
+ position: {
32
+ my: "left top",
33
+ at: "left bottom",
34
+ collision: "none"
35
+ },
36
+ source: null
37
+ },
38
+
39
+ pending: 0,
40
+
41
+ _create: function() {
42
+ var self = this,
43
+ doc = this.element[ 0 ].ownerDocument,
44
+ suppressKeyPress;
45
+
46
+ this.element
47
+ .addClass( "ui-autocomplete-input" )
48
+ .attr( "autocomplete", "off" )
49
+ // TODO verify these actually work as intended
50
+ .attr({
51
+ role: "textbox",
52
+ "aria-autocomplete": "list",
53
+ "aria-haspopup": "true"
54
+ })
55
+ .bind( "keydown.autocomplete", function( event ) {
56
+ if ( self.options.disabled || self.element.propAttr( "readOnly" ) ) {
57
+ return;
58
+ }
59
+
60
+ suppressKeyPress = false;
61
+ var keyCode = $.ui.keyCode;
62
+ switch( event.keyCode ) {
63
+ case keyCode.PAGE_UP:
64
+ self._move( "previousPage", event );
65
+ break;
66
+ case keyCode.PAGE_DOWN:
67
+ self._move( "nextPage", event );
68
+ break;
69
+ case keyCode.UP:
70
+ self._move( "previous", event );
71
+ // prevent moving cursor to beginning of text field in some browsers
72
+ event.preventDefault();
73
+ break;
74
+ case keyCode.DOWN:
75
+ self._move( "next", event );
76
+ // prevent moving cursor to end of text field in some browsers
77
+ event.preventDefault();
78
+ break;
79
+ case keyCode.ENTER:
80
+ case keyCode.NUMPAD_ENTER:
81
+ // when menu is open and has focus
82
+ if ( self.menu.active ) {
83
+ // #6055 - Opera still allows the keypress to occur
84
+ // which causes forms to submit
85
+ suppressKeyPress = true;
86
+ event.preventDefault();
87
+ }
88
+ //passthrough - ENTER and TAB both select the current element
89
+ case keyCode.TAB:
90
+ if ( !self.menu.active ) {
91
+ return;
92
+ }
93
+ self.menu.select( event );
94
+ break;
95
+ case keyCode.ESCAPE:
96
+ self.element.val( self.term );
97
+ self.close( event );
98
+ break;
99
+ default:
100
+ // keypress is triggered before the input value is changed
101
+ clearTimeout( self.searching );
102
+ self.searching = setTimeout(function() {
103
+ // only search if the value has changed
104
+ if ( self.term != self.element.val() ) {
105
+ self.selectedItem = null;
106
+ self.search( null, event );
107
+ }
108
+ }, self.options.delay );
109
+ break;
110
+ }
111
+ })
112
+ .bind( "keypress.autocomplete", function( event ) {
113
+ if ( suppressKeyPress ) {
114
+ suppressKeyPress = false;
115
+ event.preventDefault();
116
+ }
117
+ })
118
+ .bind( "focus.autocomplete", function() {
119
+ if ( self.options.disabled ) {
120
+ return;
121
+ }
122
+
123
+ self.selectedItem = null;
124
+ self.previous = self.element.val();
125
+ })
126
+ .bind( "blur.autocomplete", function( event ) {
127
+ if ( self.options.disabled ) {
128
+ return;
129
+ }
130
+
131
+ clearTimeout( self.searching );
132
+ // clicks on the menu (or a button to trigger a search) will cause a blur event
133
+ self.closing = setTimeout(function() {
134
+ self.close( event );
135
+ self._change( event );
136
+ }, 150 );
137
+ });
138
+ this._initSource();
139
+ this.response = function() {
140
+ return self._response.apply( self, arguments );
141
+ };
142
+ this.menu = $( "<ul></ul>" )
143
+ .addClass( "ui-autocomplete" )
144
+ .appendTo( $( this.options.appendTo || "body", doc )[0] )
145
+ // prevent the close-on-blur in case of a "slow" click on the menu (long mousedown)
146
+ .mousedown(function( event ) {
147
+ // clicking on the scrollbar causes focus to shift to the body
148
+ // but we can't detect a mouseup or a click immediately afterward
149
+ // so we have to track the next mousedown and close the menu if
150
+ // the user clicks somewhere outside of the autocomplete
151
+ var menuElement = self.menu.element[ 0 ];
152
+ if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
153
+ setTimeout(function() {
154
+ $( document ).one( 'mousedown', function( event ) {
155
+ if ( event.target !== self.element[ 0 ] &&
156
+ event.target !== menuElement &&
157
+ !$.ui.contains( menuElement, event.target ) ) {
158
+ self.close();
159
+ }
160
+ });
161
+ }, 1 );
162
+ }
163
+
164
+ // use another timeout to make sure the blur-event-handler on the input was already triggered
165
+ setTimeout(function() {
166
+ clearTimeout( self.closing );
167
+ }, 13);
168
+ })
169
+ .menu({
170
+ focus: function( event, ui ) {
171
+ var item = ui.item.data( "item.autocomplete" );
172
+ if ( false !== self._trigger( "focus", event, { item: item } ) ) {
173
+ // use value to match what will end up in the input, if it was a key event
174
+ if ( /^key/.test(event.originalEvent.type) ) {
175
+ self.element.val( item.value );
176
+ }
177
+ }
178
+ },
179
+ selected: function( event, ui ) {
180
+ var item = ui.item.data( "item.autocomplete" ),
181
+ previous = self.previous;
182
+
183
+ // only trigger when focus was lost (click on menu)
184
+ if ( self.element[0] !== doc.activeElement ) {
185
+ self.element.focus();
186
+ self.previous = previous;
187
+ // #6109 - IE triggers two focus events and the second
188
+ // is asynchronous, so we need to reset the previous
189
+ // term synchronously and asynchronously :-(
190
+ setTimeout(function() {
191
+ self.previous = previous;
192
+ self.selectedItem = item;
193
+ }, 1);
194
+ }
195
+
196
+ if ( false !== self._trigger( "select", event, { item: item } ) ) {
197
+ self.element.val( item.value );
198
+ }
199
+ // reset the term after the select event
200
+ // this allows custom select handling to work properly
201
+ self.term = self.element.val();
202
+
203
+ self.close( event );
204
+ self.selectedItem = item;
205
+ },
206
+ blur: function( event, ui ) {
207
+ // don't set the value of the text field if it's already correct
208
+ // this prevents moving the cursor unnecessarily
209
+ if ( self.menu.element.is(":visible") &&
210
+ ( self.element.val() !== self.term ) ) {
211
+ self.element.val( self.term );
212
+ }
213
+ }
214
+ })
215
+ .zIndex( this.element.zIndex() + 1 )
216
+ // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
217
+ .css({ top: 0, left: 0 })
218
+ .hide()
219
+ .data( "menu" );
220
+ if ( $.fn.bgiframe ) {
221
+ this.menu.element.bgiframe();
222
+ }
223
+ // turning off autocomplete prevents the browser from remembering the
224
+ // value when navigating through history, so we re-enable autocomplete
225
+ // if the page is unloaded before the widget is destroyed. #7790
226
+ self.beforeunloadHandler = function() {
227
+ self.element.removeAttr( "autocomplete" );
228
+ };
229
+ $( window ).bind( "beforeunload", self.beforeunloadHandler );
230
+ },
231
+
232
+ destroy: function() {
233
+ this.element
234
+ .removeClass( "ui-autocomplete-input" )
235
+ .removeAttr( "autocomplete" )
236
+ .removeAttr( "role" )
237
+ .removeAttr( "aria-autocomplete" )
238
+ .removeAttr( "aria-haspopup" );
239
+ this.menu.element.remove();
240
+ $( window ).unbind( "beforeunload", this.beforeunloadHandler );
241
+ $.Widget.prototype.destroy.call( this );
242
+ },
243
+
244
+ _setOption: function( key, value ) {
245
+ $.Widget.prototype._setOption.apply( this, arguments );
246
+ if ( key === "source" ) {
247
+ this._initSource();
248
+ }
249
+ if ( key === "appendTo" ) {
250
+ this.menu.element.appendTo( $( value || "body", this.element[0].ownerDocument )[0] )
251
+ }
252
+ if ( key === "disabled" && value && this.xhr ) {
253
+ this.xhr.abort();
254
+ }
255
+ },
256
+
257
+ _initSource: function() {
258
+ var self = this,
259
+ array,
260
+ url;
261
+ if ( $.isArray(this.options.source) ) {
262
+ array = this.options.source;
263
+ this.source = function( request, response ) {
264
+ response( $.ui.autocomplete.filter(array, request.term) );
265
+ };
266
+ } else if ( typeof this.options.source === "string" ) {
267
+ url = this.options.source;
268
+ this.source = function( request, response ) {
269
+ if ( self.xhr ) {
270
+ self.xhr.abort();
271
+ }
272
+ self.xhr = $.ajax({
273
+ url: url,
274
+ data: request,
275
+ dataType: "json",
276
+ autocompleteRequest: ++requestIndex,
277
+ success: function( data, status ) {
278
+ if ( this.autocompleteRequest === requestIndex ) {
279
+ response( data );
280
+ }
281
+ },
282
+ error: function() {
283
+ if ( this.autocompleteRequest === requestIndex ) {
284
+ response( [] );
285
+ }
286
+ }
287
+ });
288
+ };
289
+ } else {
290
+ this.source = this.options.source;
291
+ }
292
+ },
293
+
294
+ search: function( value, event ) {
295
+ value = value != null ? value : this.element.val();
296
+
297
+ // always save the actual value, not the one passed as an argument
298
+ this.term = this.element.val();
299
+
300
+ if ( value.length < this.options.minLength ) {
301
+ return this.close( event );
302
+ }
303
+
304
+ clearTimeout( this.closing );
305
+ if ( this._trigger( "search", event ) === false ) {
306
+ return;
307
+ }
308
+
309
+ return this._search( value );
310
+ },
311
+
312
+ _search: function( value ) {
313
+ this.pending++;
314
+ this.element.addClass( "ui-autocomplete-loading" );
315
+
316
+ this.source( { term: value }, this.response );
317
+ },
318
+
319
+ _response: function( content ) {
320
+ if ( !this.options.disabled && content && content.length ) {
321
+ content = this._normalize( content );
322
+ this._suggest( content );
323
+ this._trigger( "open" );
324
+ } else {
325
+ this.close();
326
+ }
327
+ this.pending--;
328
+ if ( !this.pending ) {
329
+ this.element.removeClass( "ui-autocomplete-loading" );
330
+ }
331
+ },
332
+
333
+ close: function( event ) {
334
+ clearTimeout( this.closing );
335
+ if ( this.menu.element.is(":visible") ) {
336
+ this.menu.element.hide();
337
+ this.menu.deactivate();
338
+ this._trigger( "close", event );
339
+ }
340
+ },
341
+
342
+ _change: function( event ) {
343
+ if ( this.previous !== this.element.val() ) {
344
+ this._trigger( "change", event, { item: this.selectedItem } );
345
+ }
346
+ },
347
+
348
+ _normalize: function( items ) {
349
+ // assume all items have the right format when the first item is complete
350
+ if ( items.length && items[0].label && items[0].value ) {
351
+ return items;
352
+ }
353
+ return $.map( items, function(item) {
354
+ if ( typeof item === "string" ) {
355
+ return {
356
+ label: item,
357
+ value: item
358
+ };
359
+ }
360
+ return $.extend({
361
+ label: item.label || item.value,
362
+ value: item.value || item.label
363
+ }, item );
364
+ });
365
+ },
366
+
367
+ _suggest: function( items ) {
368
+ var ul = this.menu.element
369
+ .empty()
370
+ .zIndex( this.element.zIndex() + 1 );
371
+ this._renderMenu( ul, items );
372
+ // TODO refresh should check if the active item is still in the dom, removing the need for a manual deactivate
373
+ this.menu.deactivate();
374
+ this.menu.refresh();
375
+
376
+ // size and position menu
377
+ ul.show();
378
+ this._resizeMenu();
379
+ ul.position( $.extend({
380
+ of: this.element
381
+ }, this.options.position ));
382
+
383
+ if ( this.options.autoFocus ) {
384
+ this.menu.next( new $.Event("mouseover") );
385
+ }
386
+ },
387
+
388
+ _resizeMenu: function() {
389
+ var ul = this.menu.element;
390
+ ul.outerWidth( Math.max(
391
+ // Firefox wraps long text (possibly a rounding bug)
392
+ // so we add 1px to avoid the wrapping (#7513)
393
+ ul.width( "" ).outerWidth() + 1,
394
+ this.element.outerWidth()
395
+ ) );
396
+ },
397
+
398
+ _renderMenu: function( ul, items ) {
399
+ var self = this;
400
+ $.each( items, function( index, item ) {
401
+ self._renderItem( ul, item );
402
+ });
403
+ },
404
+
405
+ _renderItem: function( ul, item) {
406
+ return $( "<li></li>" )
407
+ .data( "item.autocomplete", item )
408
+ .append( $( "<a></a>" ).text( item.label ) )
409
+ .appendTo( ul );
410
+ },
411
+
412
+ _move: function( direction, event ) {
413
+ if ( !this.menu.element.is(":visible") ) {
414
+ this.search( null, event );
415
+ return;
416
+ }
417
+ if ( this.menu.first() && /^previous/.test(direction) ||
418
+ this.menu.last() && /^next/.test(direction) ) {
419
+ this.element.val( this.term );
420
+ this.menu.deactivate();
421
+ return;
422
+ }
423
+ this.menu[ direction ]( event );
424
+ },
425
+
426
+ widget: function() {
427
+ return this.menu.element;
428
+ }
429
+ });
430
+
431
+ $.extend( $.ui.autocomplete, {
432
+ escapeRegex: function( value ) {
433
+ return value.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
434
+ },
435
+ filter: function(array, term) {
436
+ var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
437
+ return $.grep( array, function(value) {
438
+ return matcher.test( value.label || value.value || value );
439
+ });
440
+ }
441
+ });
442
+
443
+ }( jQuery ));
444
+
445
+ /*
446
+ * jQuery UI Menu (not officially released)
447
+ *
448
+ * This widget isn't yet finished and the API is subject to change. We plan to finish
449
+ * it for the next release. You're welcome to give it a try anyway and give us feedback,
450
+ * as long as you're okay with migrating your code later on. We can help with that, too.
451
+ *
452
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
453
+ * Dual licensed under the MIT or GPL Version 2 licenses.
454
+ * http://jquery.org/license
455
+ *
456
+ * http://docs.jquery.com/UI/Menu
457
+ *
458
+ * Depends:
459
+ * jquery.ui.core.js
460
+ * jquery.ui.widget.js
461
+ */
462
+ (function($) {
463
+
464
+ $.widget("ui.menu", {
465
+ _create: function() {
466
+ var self = this;
467
+ this.element
468
+ .addClass("ui-menu ui-widget ui-widget-content ui-corner-all")
469
+ .attr({
470
+ role: "listbox",
471
+ "aria-activedescendant": "ui-active-menuitem"
472
+ })
473
+ .click(function( event ) {
474
+ if ( !$( event.target ).closest( ".ui-menu-item a" ).length ) {
475
+ return;
476
+ }
477
+ // temporary
478
+ event.preventDefault();
479
+ self.select( event );
480
+ });
481
+ this.refresh();
482
+ },
483
+
484
+ refresh: function() {
485
+ var self = this;
486
+
487
+ // don't refresh list items that are already adapted
488
+ var items = this.element.children("li:not(.ui-menu-item):has(a)")
489
+ .addClass("ui-menu-item")
490
+ .attr("role", "menuitem");
491
+
492
+ items.children("a")
493
+ .addClass("ui-corner-all")
494
+ .attr("tabindex", -1)
495
+ // mouseenter doesn't work with event delegation
496
+ .mouseenter(function( event ) {
497
+ self.activate( event, $(this).parent() );
498
+ })
499
+ .mouseleave(function() {
500
+ self.deactivate();
501
+ });
502
+ },
503
+
504
+ activate: function( event, item ) {
505
+ this.deactivate();
506
+ if (this.hasScroll()) {
507
+ var offset = item.offset().top - this.element.offset().top,
508
+ scroll = this.element.scrollTop(),
509
+ elementHeight = this.element.height();
510
+ if (offset < 0) {
511
+ this.element.scrollTop( scroll + offset);
512
+ } else if (offset >= elementHeight) {
513
+ this.element.scrollTop( scroll + offset - elementHeight + item.height());
514
+ }
515
+ }
516
+ this.active = item.eq(0)
517
+ .children("a")
518
+ .addClass("ui-state-hover")
519
+ .attr("id", "ui-active-menuitem")
520
+ .end();
521
+ this._trigger("focus", event, { item: item });
522
+ },
523
+
524
+ deactivate: function() {
525
+ if (!this.active) { return; }
526
+
527
+ this.active.children("a")
528
+ .removeClass("ui-state-hover")
529
+ .removeAttr("id");
530
+ this._trigger("blur");
531
+ this.active = null;
532
+ },
533
+
534
+ next: function(event) {
535
+ this.move("next", ".ui-menu-item:first", event);
536
+ },
537
+
538
+ previous: function(event) {
539
+ this.move("prev", ".ui-menu-item:last", event);
540
+ },
541
+
542
+ first: function() {
543
+ return this.active && !this.active.prevAll(".ui-menu-item").length;
544
+ },
545
+
546
+ last: function() {
547
+ return this.active && !this.active.nextAll(".ui-menu-item").length;
548
+ },
549
+
550
+ move: function(direction, edge, event) {
551
+ if (!this.active) {
552
+ this.activate(event, this.element.children(edge));
553
+ return;
554
+ }
555
+ var next = this.active[direction + "All"](".ui-menu-item").eq(0);
556
+ if (next.length) {
557
+ this.activate(event, next);
558
+ } else {
559
+ this.activate(event, this.element.children(edge));
560
+ }
561
+ },
562
+
563
+ // TODO merge with previousPage
564
+ nextPage: function(event) {
565
+ if (this.hasScroll()) {
566
+ // TODO merge with no-scroll-else
567
+ if (!this.active || this.last()) {
568
+ this.activate(event, this.element.children(".ui-menu-item:first"));
569
+ return;
570
+ }
571
+ var base = this.active.offset().top,
572
+ height = this.element.height(),
573
+ result = this.element.children(".ui-menu-item").filter(function() {
574
+ var close = $(this).offset().top - base - height + $(this).height();
575
+ // TODO improve approximation
576
+ return close < 10 && close > -10;
577
+ });
578
+
579
+ // TODO try to catch this earlier when scrollTop indicates the last page anyway
580
+ if (!result.length) {
581
+ result = this.element.children(".ui-menu-item:last");
582
+ }
583
+ this.activate(event, result);
584
+ } else {
585
+ this.activate(event, this.element.children(".ui-menu-item")
586
+ .filter(!this.active || this.last() ? ":first" : ":last"));
587
+ }
588
+ },
589
+
590
+ // TODO merge with nextPage
591
+ previousPage: function(event) {
592
+ if (this.hasScroll()) {
593
+ // TODO merge with no-scroll-else
594
+ if (!this.active || this.first()) {
595
+ this.activate(event, this.element.children(".ui-menu-item:last"));
596
+ return;
597
+ }
598
+
599
+ var base = this.active.offset().top,
600
+ height = this.element.height();
601
+ result = this.element.children(".ui-menu-item").filter(function() {
602
+ var close = $(this).offset().top - base + height - $(this).height();
603
+ // TODO improve approximation
604
+ return close < 10 && close > -10;
605
+ });
606
+
607
+ // TODO try to catch this earlier when scrollTop indicates the last page anyway
608
+ if (!result.length) {
609
+ result = this.element.children(".ui-menu-item:first");
610
+ }
611
+ this.activate(event, result);
612
+ } else {
613
+ this.activate(event, this.element.children(".ui-menu-item")
614
+ .filter(!this.active || this.first() ? ":last" : ":first"));
615
+ }
616
+ },
617
+
618
+ hasScroll: function() {
619
+ return this.element.height() < this.element[ $.fn.prop ? "prop" : "attr" ]("scrollHeight");
620
+ },
621
+
622
+ select: function( event ) {
623
+ this._trigger("selected", event, { item: this.active });
624
+ }
625
+ });
626
+
627
+ }(jQuery));