jqueryui-requirejs-rails 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. data/LICENSE +22 -0
  2. data/README.md +3 -0
  3. data/Rakefile +27 -0
  4. data/app/assets/javascripts/jqueryui/accordion.js +575 -0
  5. data/app/assets/javascripts/jqueryui/autocomplete.js +613 -0
  6. data/app/assets/javascripts/jqueryui/button.js +422 -0
  7. data/app/assets/javascripts/jqueryui/core.js +323 -0
  8. data/app/assets/javascripts/jqueryui/datepicker-af.js +26 -0
  9. data/app/assets/javascripts/jqueryui/datepicker-ar-DZ.js +26 -0
  10. data/app/assets/javascripts/jqueryui/datepicker-ar.js +26 -0
  11. data/app/assets/javascripts/jqueryui/datepicker-az.js +26 -0
  12. data/app/assets/javascripts/jqueryui/datepicker-be.js +26 -0
  13. data/app/assets/javascripts/jqueryui/datepicker-bg.js +27 -0
  14. data/app/assets/javascripts/jqueryui/datepicker-bs.js +26 -0
  15. data/app/assets/javascripts/jqueryui/datepicker-ca.js +26 -0
  16. data/app/assets/javascripts/jqueryui/datepicker-cs.js +26 -0
  17. data/app/assets/javascripts/jqueryui/datepicker-cy-GB.js +26 -0
  18. data/app/assets/javascripts/jqueryui/datepicker-da.js +26 -0
  19. data/app/assets/javascripts/jqueryui/datepicker-de.js +26 -0
  20. data/app/assets/javascripts/jqueryui/datepicker-el.js +26 -0
  21. data/app/assets/javascripts/jqueryui/datepicker-en-AU.js +26 -0
  22. data/app/assets/javascripts/jqueryui/datepicker-en-GB.js +26 -0
  23. data/app/assets/javascripts/jqueryui/datepicker-en-NZ.js +26 -0
  24. data/app/assets/javascripts/jqueryui/datepicker-eo.js +26 -0
  25. data/app/assets/javascripts/jqueryui/datepicker-es.js +26 -0
  26. data/app/assets/javascripts/jqueryui/datepicker-et.js +26 -0
  27. data/app/assets/javascripts/jqueryui/datepicker-eu.js +26 -0
  28. data/app/assets/javascripts/jqueryui/datepicker-fa.js +62 -0
  29. data/app/assets/javascripts/jqueryui/datepicker-fi.js +26 -0
  30. data/app/assets/javascripts/jqueryui/datepicker-fo.js +26 -0
  31. data/app/assets/javascripts/jqueryui/datepicker-fr-CA.js +26 -0
  32. data/app/assets/javascripts/jqueryui/datepicker-fr-CH.js +26 -0
  33. data/app/assets/javascripts/jqueryui/datepicker-fr.js +28 -0
  34. data/app/assets/javascripts/jqueryui/datepicker-gl.js +26 -0
  35. data/app/assets/javascripts/jqueryui/datepicker-he.js +26 -0
  36. data/app/assets/javascripts/jqueryui/datepicker-hi.js +26 -0
  37. data/app/assets/javascripts/jqueryui/datepicker-hr.js +26 -0
  38. data/app/assets/javascripts/jqueryui/datepicker-hu.js +26 -0
  39. data/app/assets/javascripts/jqueryui/datepicker-hy.js +26 -0
  40. data/app/assets/javascripts/jqueryui/datepicker-id.js +26 -0
  41. data/app/assets/javascripts/jqueryui/datepicker-is.js +26 -0
  42. data/app/assets/javascripts/jqueryui/datepicker-it.js +26 -0
  43. data/app/assets/javascripts/jqueryui/datepicker-ja.js +26 -0
  44. data/app/assets/javascripts/jqueryui/datepicker-ka.js +24 -0
  45. data/app/assets/javascripts/jqueryui/datepicker-kk.js +26 -0
  46. data/app/assets/javascripts/jqueryui/datepicker-km.js +26 -0
  47. data/app/assets/javascripts/jqueryui/datepicker-ko.js +26 -0
  48. data/app/assets/javascripts/jqueryui/datepicker-ky.js +27 -0
  49. data/app/assets/javascripts/jqueryui/datepicker-lb.js +26 -0
  50. data/app/assets/javascripts/jqueryui/datepicker-lt.js +26 -0
  51. data/app/assets/javascripts/jqueryui/datepicker-lv.js +26 -0
  52. data/app/assets/javascripts/jqueryui/datepicker-mk.js +26 -0
  53. data/app/assets/javascripts/jqueryui/datepicker-ml.js +26 -0
  54. data/app/assets/javascripts/jqueryui/datepicker-ms.js +26 -0
  55. data/app/assets/javascripts/jqueryui/datepicker-nb.js +25 -0
  56. data/app/assets/javascripts/jqueryui/datepicker-nl-BE.js +26 -0
  57. data/app/assets/javascripts/jqueryui/datepicker-nl.js +26 -0
  58. data/app/assets/javascripts/jqueryui/datepicker-nn.js +25 -0
  59. data/app/assets/javascripts/jqueryui/datepicker-no.js +26 -0
  60. data/app/assets/javascripts/jqueryui/datepicker-pl.js +26 -0
  61. data/app/assets/javascripts/jqueryui/datepicker-pt-BR.js +26 -0
  62. data/app/assets/javascripts/jqueryui/datepicker-pt.js +25 -0
  63. data/app/assets/javascripts/jqueryui/datepicker-rm.js +24 -0
  64. data/app/assets/javascripts/jqueryui/datepicker-ro.js +29 -0
  65. data/app/assets/javascripts/jqueryui/datepicker-ru.js +26 -0
  66. data/app/assets/javascripts/jqueryui/datepicker-sk.js +26 -0
  67. data/app/assets/javascripts/jqueryui/datepicker-sl.js +27 -0
  68. data/app/assets/javascripts/jqueryui/datepicker-sq.js +26 -0
  69. data/app/assets/javascripts/jqueryui/datepicker-sr-SR.js +26 -0
  70. data/app/assets/javascripts/jqueryui/datepicker-sr.js +26 -0
  71. data/app/assets/javascripts/jqueryui/datepicker-sv.js +26 -0
  72. data/app/assets/javascripts/jqueryui/datepicker-ta.js +26 -0
  73. data/app/assets/javascripts/jqueryui/datepicker-th.js +26 -0
  74. data/app/assets/javascripts/jqueryui/datepicker-tj.js +26 -0
  75. data/app/assets/javascripts/jqueryui/datepicker-tr.js +26 -0
  76. data/app/assets/javascripts/jqueryui/datepicker-uk.js +27 -0
  77. data/app/assets/javascripts/jqueryui/datepicker-vi.js +26 -0
  78. data/app/assets/javascripts/jqueryui/datepicker-zh-CN.js +26 -0
  79. data/app/assets/javascripts/jqueryui/datepicker-zh-HK.js +26 -0
  80. data/app/assets/javascripts/jqueryui/datepicker-zh-TW.js +26 -0
  81. data/app/assets/javascripts/jqueryui/datepicker.js +2053 -0
  82. data/app/assets/javascripts/jqueryui/dialog.js +811 -0
  83. data/app/assets/javascripts/jqueryui/draggable.js +936 -0
  84. data/app/assets/javascripts/jqueryui/droppable.js +375 -0
  85. data/app/assets/javascripts/jqueryui/effect-blind.js +85 -0
  86. data/app/assets/javascripts/jqueryui/effect-bounce.js +116 -0
  87. data/app/assets/javascripts/jqueryui/effect-clip.js +70 -0
  88. data/app/assets/javascripts/jqueryui/effect-drop.js +68 -0
  89. data/app/assets/javascripts/jqueryui/effect-explode.js +100 -0
  90. data/app/assets/javascripts/jqueryui/effect-fade.js +33 -0
  91. data/app/assets/javascripts/jqueryui/effect-fold.js +79 -0
  92. data/app/assets/javascripts/jqueryui/effect-highlight.js +53 -0
  93. data/app/assets/javascripts/jqueryui/effect-pulsate.js +66 -0
  94. data/app/assets/javascripts/jqueryui/effect-scale.js +321 -0
  95. data/app/assets/javascripts/jqueryui/effect-shake.js +77 -0
  96. data/app/assets/javascripts/jqueryui/effect-slide.js +67 -0
  97. data/app/assets/javascripts/jqueryui/effect-transfer.js +50 -0
  98. data/app/assets/javascripts/jqueryui/effect.js +1292 -0
  99. data/app/assets/javascripts/jqueryui/menu.js +624 -0
  100. data/app/assets/javascripts/jqueryui/mouse.js +172 -0
  101. data/app/assets/javascripts/jqueryui/position.js +500 -0
  102. data/app/assets/javascripts/jqueryui/progressbar.js +148 -0
  103. data/app/assets/javascripts/jqueryui/resizable.js +971 -0
  104. data/app/assets/javascripts/jqueryui/selectable.js +280 -0
  105. data/app/assets/javascripts/jqueryui/slider.js +675 -0
  106. data/app/assets/javascripts/jqueryui/sortable.js +1285 -0
  107. data/app/assets/javascripts/jqueryui/spinner.js +496 -0
  108. data/app/assets/javascripts/jqueryui/tabs.js +849 -0
  109. data/app/assets/javascripts/jqueryui/tooltip.js +405 -0
  110. data/app/assets/javascripts/jqueryui/widget.js +524 -0
  111. data/lib/jqueryui-requirejs-rails.rb +4 -0
  112. data/lib/jqueryui-requirejs-rails/engine.rb +4 -0
  113. data/lib/jqueryui-requirejs-rails/version.rb +3 -0
  114. metadata +196 -0
@@ -0,0 +1,613 @@
1
+ define(['jquery','./core','./widget','./position','./menu'], function (jQuery) {
2
+ /*!
3
+ * jQuery UI Autocomplete 1.10.2
4
+ * http://jqueryui.com
5
+ *
6
+ * Copyright 2013 jQuery Foundation and other contributors
7
+ * Released under the MIT license.
8
+ * http://jquery.org/license
9
+ *
10
+ * http://api.jqueryui.com/autocomplete/
11
+ *
12
+ * Depends:
13
+ * jquery.ui.core.js
14
+ * jquery.ui.widget.js
15
+ * jquery.ui.position.js
16
+ * jquery.ui.menu.js
17
+ */
18
+ (function( $, undefined ) {
19
+
20
+ // used to prevent race conditions with remote data sources
21
+ var requestIndex = 0;
22
+
23
+ $.widget( "ui.autocomplete", {
24
+ version: "1.10.2",
25
+ defaultElement: "<input>",
26
+ options: {
27
+ appendTo: null,
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
+ // callbacks
39
+ change: null,
40
+ close: null,
41
+ focus: null,
42
+ open: null,
43
+ response: null,
44
+ search: null,
45
+ select: null
46
+ },
47
+
48
+ pending: 0,
49
+
50
+ _create: function() {
51
+ // Some browsers only repeat keydown events, not keypress events,
52
+ // so we use the suppressKeyPress flag to determine if we've already
53
+ // handled the keydown event. #7269
54
+ // Unfortunately the code for & in keypress is the same as the up arrow,
55
+ // so we use the suppressKeyPressRepeat flag to avoid handling keypress
56
+ // events when we know the keydown event was used to modify the
57
+ // search term. #7799
58
+ var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
59
+ nodeName = this.element[0].nodeName.toLowerCase(),
60
+ isTextarea = nodeName === "textarea",
61
+ isInput = nodeName === "input";
62
+
63
+ this.isMultiLine =
64
+ // Textareas are always multi-line
65
+ isTextarea ? true :
66
+ // Inputs are always single-line, even if inside a contentEditable element
67
+ // IE also treats inputs as contentEditable
68
+ isInput ? false :
69
+ // All other element types are determined by whether or not they're contentEditable
70
+ this.element.prop( "isContentEditable" );
71
+
72
+ this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
73
+ this.isNewMenu = true;
74
+
75
+ this.element
76
+ .addClass( "ui-autocomplete-input" )
77
+ .attr( "autocomplete", "off" );
78
+
79
+ this._on( this.element, {
80
+ keydown: function( event ) {
81
+ /*jshint maxcomplexity:15*/
82
+ if ( this.element.prop( "readOnly" ) ) {
83
+ suppressKeyPress = true;
84
+ suppressInput = true;
85
+ suppressKeyPressRepeat = true;
86
+ return;
87
+ }
88
+
89
+ suppressKeyPress = false;
90
+ suppressInput = false;
91
+ suppressKeyPressRepeat = false;
92
+ var keyCode = $.ui.keyCode;
93
+ switch( event.keyCode ) {
94
+ case keyCode.PAGE_UP:
95
+ suppressKeyPress = true;
96
+ this._move( "previousPage", event );
97
+ break;
98
+ case keyCode.PAGE_DOWN:
99
+ suppressKeyPress = true;
100
+ this._move( "nextPage", event );
101
+ break;
102
+ case keyCode.UP:
103
+ suppressKeyPress = true;
104
+ this._keyEvent( "previous", event );
105
+ break;
106
+ case keyCode.DOWN:
107
+ suppressKeyPress = true;
108
+ this._keyEvent( "next", event );
109
+ break;
110
+ case keyCode.ENTER:
111
+ case keyCode.NUMPAD_ENTER:
112
+ // when menu is open and has focus
113
+ if ( this.menu.active ) {
114
+ // #6055 - Opera still allows the keypress to occur
115
+ // which causes forms to submit
116
+ suppressKeyPress = true;
117
+ event.preventDefault();
118
+ this.menu.select( event );
119
+ }
120
+ break;
121
+ case keyCode.TAB:
122
+ if ( this.menu.active ) {
123
+ this.menu.select( event );
124
+ }
125
+ break;
126
+ case keyCode.ESCAPE:
127
+ if ( this.menu.element.is( ":visible" ) ) {
128
+ this._value( this.term );
129
+ this.close( event );
130
+ // Different browsers have different default behavior for escape
131
+ // Single press can mean undo or clear
132
+ // Double press in IE means clear the whole form
133
+ event.preventDefault();
134
+ }
135
+ break;
136
+ default:
137
+ suppressKeyPressRepeat = true;
138
+ // search timeout should be triggered before the input value is changed
139
+ this._searchTimeout( event );
140
+ break;
141
+ }
142
+ },
143
+ keypress: function( event ) {
144
+ if ( suppressKeyPress ) {
145
+ suppressKeyPress = false;
146
+ event.preventDefault();
147
+ return;
148
+ }
149
+ if ( suppressKeyPressRepeat ) {
150
+ return;
151
+ }
152
+
153
+ // replicate some key handlers to allow them to repeat in Firefox and Opera
154
+ var keyCode = $.ui.keyCode;
155
+ switch( event.keyCode ) {
156
+ case keyCode.PAGE_UP:
157
+ this._move( "previousPage", event );
158
+ break;
159
+ case keyCode.PAGE_DOWN:
160
+ this._move( "nextPage", event );
161
+ break;
162
+ case keyCode.UP:
163
+ this._keyEvent( "previous", event );
164
+ break;
165
+ case keyCode.DOWN:
166
+ this._keyEvent( "next", event );
167
+ break;
168
+ }
169
+ },
170
+ input: function( event ) {
171
+ if ( suppressInput ) {
172
+ suppressInput = false;
173
+ event.preventDefault();
174
+ return;
175
+ }
176
+ this._searchTimeout( event );
177
+ },
178
+ focus: function() {
179
+ this.selectedItem = null;
180
+ this.previous = this._value();
181
+ },
182
+ blur: function( event ) {
183
+ if ( this.cancelBlur ) {
184
+ delete this.cancelBlur;
185
+ return;
186
+ }
187
+
188
+ clearTimeout( this.searching );
189
+ this.close( event );
190
+ this._change( event );
191
+ }
192
+ });
193
+
194
+ this._initSource();
195
+ this.menu = $( "<ul>" )
196
+ .addClass( "ui-autocomplete ui-front" )
197
+ .appendTo( this._appendTo() )
198
+ .menu({
199
+ // custom key handling for now
200
+ input: $(),
201
+ // disable ARIA support, the live region takes care of that
202
+ role: null
203
+ })
204
+ .hide()
205
+ .data( "ui-menu" );
206
+
207
+ this._on( this.menu.element, {
208
+ mousedown: function( event ) {
209
+ // prevent moving focus out of the text field
210
+ event.preventDefault();
211
+
212
+ // IE doesn't prevent moving focus even with event.preventDefault()
213
+ // so we set a flag to know when we should ignore the blur event
214
+ this.cancelBlur = true;
215
+ this._delay(function() {
216
+ delete this.cancelBlur;
217
+ });
218
+
219
+ // clicking on the scrollbar causes focus to shift to the body
220
+ // but we can't detect a mouseup or a click immediately afterward
221
+ // so we have to track the next mousedown and close the menu if
222
+ // the user clicks somewhere outside of the autocomplete
223
+ var menuElement = this.menu.element[ 0 ];
224
+ if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
225
+ this._delay(function() {
226
+ var that = this;
227
+ this.document.one( "mousedown", function( event ) {
228
+ if ( event.target !== that.element[ 0 ] &&
229
+ event.target !== menuElement &&
230
+ !$.contains( menuElement, event.target ) ) {
231
+ that.close();
232
+ }
233
+ });
234
+ });
235
+ }
236
+ },
237
+ menufocus: function( event, ui ) {
238
+ // support: Firefox
239
+ // Prevent accidental activation of menu items in Firefox (#7024 #9118)
240
+ if ( this.isNewMenu ) {
241
+ this.isNewMenu = false;
242
+ if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
243
+ this.menu.blur();
244
+
245
+ this.document.one( "mousemove", function() {
246
+ $( event.target ).trigger( event.originalEvent );
247
+ });
248
+
249
+ return;
250
+ }
251
+ }
252
+
253
+ var item = ui.item.data( "ui-autocomplete-item" );
254
+ if ( false !== this._trigger( "focus", event, { item: item } ) ) {
255
+ // use value to match what will end up in the input, if it was a key event
256
+ if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
257
+ this._value( item.value );
258
+ }
259
+ } else {
260
+ // Normally the input is populated with the item's value as the
261
+ // menu is navigated, causing screen readers to notice a change and
262
+ // announce the item. Since the focus event was canceled, this doesn't
263
+ // happen, so we update the live region so that screen readers can
264
+ // still notice the change and announce it.
265
+ this.liveRegion.text( item.value );
266
+ }
267
+ },
268
+ menuselect: function( event, ui ) {
269
+ var item = ui.item.data( "ui-autocomplete-item" ),
270
+ previous = this.previous;
271
+
272
+ // only trigger when focus was lost (click on menu)
273
+ if ( this.element[0] !== this.document[0].activeElement ) {
274
+ this.element.focus();
275
+ this.previous = previous;
276
+ // #6109 - IE triggers two focus events and the second
277
+ // is asynchronous, so we need to reset the previous
278
+ // term synchronously and asynchronously :-(
279
+ this._delay(function() {
280
+ this.previous = previous;
281
+ this.selectedItem = item;
282
+ });
283
+ }
284
+
285
+ if ( false !== this._trigger( "select", event, { item: item } ) ) {
286
+ this._value( item.value );
287
+ }
288
+ // reset the term after the select event
289
+ // this allows custom select handling to work properly
290
+ this.term = this._value();
291
+
292
+ this.close( event );
293
+ this.selectedItem = item;
294
+ }
295
+ });
296
+
297
+ this.liveRegion = $( "<span>", {
298
+ role: "status",
299
+ "aria-live": "polite"
300
+ })
301
+ .addClass( "ui-helper-hidden-accessible" )
302
+ .insertAfter( this.element );
303
+
304
+ // turning off autocomplete prevents the browser from remembering the
305
+ // value when navigating through history, so we re-enable autocomplete
306
+ // if the page is unloaded before the widget is destroyed. #7790
307
+ this._on( this.window, {
308
+ beforeunload: function() {
309
+ this.element.removeAttr( "autocomplete" );
310
+ }
311
+ });
312
+ },
313
+
314
+ _destroy: function() {
315
+ clearTimeout( this.searching );
316
+ this.element
317
+ .removeClass( "ui-autocomplete-input" )
318
+ .removeAttr( "autocomplete" );
319
+ this.menu.element.remove();
320
+ this.liveRegion.remove();
321
+ },
322
+
323
+ _setOption: function( key, value ) {
324
+ this._super( key, value );
325
+ if ( key === "source" ) {
326
+ this._initSource();
327
+ }
328
+ if ( key === "appendTo" ) {
329
+ this.menu.element.appendTo( this._appendTo() );
330
+ }
331
+ if ( key === "disabled" && value && this.xhr ) {
332
+ this.xhr.abort();
333
+ }
334
+ },
335
+
336
+ _appendTo: function() {
337
+ var element = this.options.appendTo;
338
+
339
+ if ( element ) {
340
+ element = element.jquery || element.nodeType ?
341
+ $( element ) :
342
+ this.document.find( element ).eq( 0 );
343
+ }
344
+
345
+ if ( !element ) {
346
+ element = this.element.closest( ".ui-front" );
347
+ }
348
+
349
+ if ( !element.length ) {
350
+ element = this.document[0].body;
351
+ }
352
+
353
+ return element;
354
+ },
355
+
356
+ _initSource: function() {
357
+ var array, url,
358
+ that = this;
359
+ if ( $.isArray(this.options.source) ) {
360
+ array = this.options.source;
361
+ this.source = function( request, response ) {
362
+ response( $.ui.autocomplete.filter( array, request.term ) );
363
+ };
364
+ } else if ( typeof this.options.source === "string" ) {
365
+ url = this.options.source;
366
+ this.source = function( request, response ) {
367
+ if ( that.xhr ) {
368
+ that.xhr.abort();
369
+ }
370
+ that.xhr = $.ajax({
371
+ url: url,
372
+ data: request,
373
+ dataType: "json",
374
+ success: function( data ) {
375
+ response( data );
376
+ },
377
+ error: function() {
378
+ response( [] );
379
+ }
380
+ });
381
+ };
382
+ } else {
383
+ this.source = this.options.source;
384
+ }
385
+ },
386
+
387
+ _searchTimeout: function( event ) {
388
+ clearTimeout( this.searching );
389
+ this.searching = this._delay(function() {
390
+ // only search if the value has changed
391
+ if ( this.term !== this._value() ) {
392
+ this.selectedItem = null;
393
+ this.search( null, event );
394
+ }
395
+ }, this.options.delay );
396
+ },
397
+
398
+ search: function( value, event ) {
399
+ value = value != null ? value : this._value();
400
+
401
+ // always save the actual value, not the one passed as an argument
402
+ this.term = this._value();
403
+
404
+ if ( value.length < this.options.minLength ) {
405
+ return this.close( event );
406
+ }
407
+
408
+ if ( this._trigger( "search", event ) === false ) {
409
+ return;
410
+ }
411
+
412
+ return this._search( value );
413
+ },
414
+
415
+ _search: function( value ) {
416
+ this.pending++;
417
+ this.element.addClass( "ui-autocomplete-loading" );
418
+ this.cancelSearch = false;
419
+
420
+ this.source( { term: value }, this._response() );
421
+ },
422
+
423
+ _response: function() {
424
+ var that = this,
425
+ index = ++requestIndex;
426
+
427
+ return function( content ) {
428
+ if ( index === requestIndex ) {
429
+ that.__response( content );
430
+ }
431
+
432
+ that.pending--;
433
+ if ( !that.pending ) {
434
+ that.element.removeClass( "ui-autocomplete-loading" );
435
+ }
436
+ };
437
+ },
438
+
439
+ __response: function( content ) {
440
+ if ( content ) {
441
+ content = this._normalize( content );
442
+ }
443
+ this._trigger( "response", null, { content: content } );
444
+ if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
445
+ this._suggest( content );
446
+ this._trigger( "open" );
447
+ } else {
448
+ // use ._close() instead of .close() so we don't cancel future searches
449
+ this._close();
450
+ }
451
+ },
452
+
453
+ close: function( event ) {
454
+ this.cancelSearch = true;
455
+ this._close( event );
456
+ },
457
+
458
+ _close: function( event ) {
459
+ if ( this.menu.element.is( ":visible" ) ) {
460
+ this.menu.element.hide();
461
+ this.menu.blur();
462
+ this.isNewMenu = true;
463
+ this._trigger( "close", event );
464
+ }
465
+ },
466
+
467
+ _change: function( event ) {
468
+ if ( this.previous !== this._value() ) {
469
+ this._trigger( "change", event, { item: this.selectedItem } );
470
+ }
471
+ },
472
+
473
+ _normalize: function( items ) {
474
+ // assume all items have the right format when the first item is complete
475
+ if ( items.length && items[0].label && items[0].value ) {
476
+ return items;
477
+ }
478
+ return $.map( items, function( item ) {
479
+ if ( typeof item === "string" ) {
480
+ return {
481
+ label: item,
482
+ value: item
483
+ };
484
+ }
485
+ return $.extend({
486
+ label: item.label || item.value,
487
+ value: item.value || item.label
488
+ }, item );
489
+ });
490
+ },
491
+
492
+ _suggest: function( items ) {
493
+ var ul = this.menu.element.empty();
494
+ this._renderMenu( ul, items );
495
+ this.isNewMenu = true;
496
+ this.menu.refresh();
497
+
498
+ // size and position menu
499
+ ul.show();
500
+ this._resizeMenu();
501
+ ul.position( $.extend({
502
+ of: this.element
503
+ }, this.options.position ));
504
+
505
+ if ( this.options.autoFocus ) {
506
+ this.menu.next();
507
+ }
508
+ },
509
+
510
+ _resizeMenu: function() {
511
+ var ul = this.menu.element;
512
+ ul.outerWidth( Math.max(
513
+ // Firefox wraps long text (possibly a rounding bug)
514
+ // so we add 1px to avoid the wrapping (#7513)
515
+ ul.width( "" ).outerWidth() + 1,
516
+ this.element.outerWidth()
517
+ ) );
518
+ },
519
+
520
+ _renderMenu: function( ul, items ) {
521
+ var that = this;
522
+ $.each( items, function( index, item ) {
523
+ that._renderItemData( ul, item );
524
+ });
525
+ },
526
+
527
+ _renderItemData: function( ul, item ) {
528
+ return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
529
+ },
530
+
531
+ _renderItem: function( ul, item ) {
532
+ return $( "<li>" )
533
+ .append( $( "<a>" ).text( item.label ) )
534
+ .appendTo( ul );
535
+ },
536
+
537
+ _move: function( direction, event ) {
538
+ if ( !this.menu.element.is( ":visible" ) ) {
539
+ this.search( null, event );
540
+ return;
541
+ }
542
+ if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
543
+ this.menu.isLastItem() && /^next/.test( direction ) ) {
544
+ this._value( this.term );
545
+ this.menu.blur();
546
+ return;
547
+ }
548
+ this.menu[ direction ]( event );
549
+ },
550
+
551
+ widget: function() {
552
+ return this.menu.element;
553
+ },
554
+
555
+ _value: function() {
556
+ return this.valueMethod.apply( this.element, arguments );
557
+ },
558
+
559
+ _keyEvent: function( keyEvent, event ) {
560
+ if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
561
+ this._move( keyEvent, event );
562
+
563
+ // prevents moving cursor to beginning/end of the text field in some browsers
564
+ event.preventDefault();
565
+ }
566
+ }
567
+ });
568
+
569
+ $.extend( $.ui.autocomplete, {
570
+ escapeRegex: function( value ) {
571
+ return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
572
+ },
573
+ filter: function(array, term) {
574
+ var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
575
+ return $.grep( array, function(value) {
576
+ return matcher.test( value.label || value.value || value );
577
+ });
578
+ }
579
+ });
580
+
581
+
582
+ // live region extension, adding a `messages` option
583
+ // NOTE: This is an experimental API. We are still investigating
584
+ // a full solution for string manipulation and internationalization.
585
+ $.widget( "ui.autocomplete", $.ui.autocomplete, {
586
+ options: {
587
+ messages: {
588
+ noResults: "No search results.",
589
+ results: function( amount ) {
590
+ return amount + ( amount > 1 ? " results are" : " result is" ) +
591
+ " available, use up and down arrow keys to navigate.";
592
+ }
593
+ }
594
+ },
595
+
596
+ __response: function( content ) {
597
+ var message;
598
+ this._superApply( arguments );
599
+ if ( this.options.disabled || this.cancelSearch ) {
600
+ return;
601
+ }
602
+ if ( content && content.length ) {
603
+ message = this.options.messages.results( content.length );
604
+ } else {
605
+ message = this.options.messages.noResults;
606
+ }
607
+ this.liveRegion.text( message );
608
+ }
609
+ });
610
+
611
+ }( jQuery ));
612
+
613
+ });