jquery-ui-rails 0.0.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of jquery-ui-rails might be problematic. Click here for more details.

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));