rails_admin 3.2.1 → 4.0.0.beta

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 (214) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +8 -6
  3. data/README.md +11 -11
  4. data/Rakefile +3 -11
  5. data/app/assets/builds/rails_admin.css +10 -0
  6. data/app/assets/builds/rails_admin.js +34 -0
  7. data/app/controllers/rails_admin/main_controller.rb +3 -3
  8. data/app/helpers/rails_admin/application_helper.rb +3 -15
  9. data/app/helpers/rails_admin/form_builder.rb +10 -9
  10. data/app/views/layouts/rails_admin/_head.html.erb +10 -27
  11. data/app/views/layouts/rails_admin/_head_custom.html.erb +3 -0
  12. data/app/views/layouts/rails_admin/_secondary_navigation.html.erb +1 -1
  13. data/app/views/rails_admin/main/_dashboard_history.html.erb +1 -1
  14. data/app/views/rails_admin/main/_delete_notice.html.erb +3 -3
  15. data/app/views/rails_admin/main/_form_boolean.html.erb +9 -13
  16. data/app/views/rails_admin/main/_submit_buttons.html.erb +4 -4
  17. data/app/views/rails_admin/main/bulk_delete.html.erb +2 -2
  18. data/app/views/rails_admin/main/dashboard.html.erb +3 -3
  19. data/app/views/rails_admin/main/delete.html.erb +2 -2
  20. data/app/views/rails_admin/main/export.html.erb +2 -2
  21. data/app/views/rails_admin/main/history.html.erb +2 -2
  22. data/app/views/rails_admin/main/index.html.erb +3 -3
  23. data/config/initializers/active_record_extensions.rb +1 -4
  24. data/lib/generators/rails_admin/install_generator.rb +37 -92
  25. data/lib/generators/rails_admin/templates/rails_admin.scss.erb +1 -1
  26. data/lib/rails_admin/abstract_model.rb +69 -191
  27. data/lib/rails_admin/adapters/active_record/association.rb +1 -1
  28. data/lib/rails_admin/adapters/active_record/property.rb +7 -0
  29. data/lib/rails_admin/adapters/active_record/reflection.rb +87 -0
  30. data/lib/rails_admin/adapters/active_record/repository.rb +216 -0
  31. data/lib/rails_admin/adapters/active_record/statement_builder.rb +148 -0
  32. data/lib/rails_admin/adapters/active_record/where_builder.rb +40 -0
  33. data/lib/rails_admin/adapters/active_record.rb +7 -356
  34. data/lib/rails_admin/adapters/mongoid/association.rb +1 -1
  35. data/lib/rails_admin/adapters/mongoid/extension.rb +16 -6
  36. data/lib/rails_admin/adapters/mongoid/property.rb +7 -0
  37. data/lib/rails_admin/adapters/mongoid/reflection.rb +58 -0
  38. data/lib/rails_admin/adapters/mongoid/repository.rb +237 -0
  39. data/lib/rails_admin/adapters/mongoid/statement_builder.rb +93 -0
  40. data/lib/rails_admin/adapters/mongoid.rb +7 -300
  41. data/lib/rails_admin/adapters/reflection.rb +105 -0
  42. data/lib/rails_admin/adapters/repository.rb +169 -0
  43. data/lib/rails_admin/adapters/statement_builder.rb +109 -0
  44. data/lib/rails_admin/adapters.rb +94 -0
  45. data/lib/rails_admin/config/actions/base.rb +8 -0
  46. data/lib/rails_admin/config/actions/bulk_delete.rb +4 -4
  47. data/lib/rails_admin/config/actions/dashboard.rb +1 -1
  48. data/lib/rails_admin/config/actions/edit.rb +3 -2
  49. data/lib/rails_admin/config/actions/index.rb +1 -1
  50. data/lib/rails_admin/config/actions/new.rb +3 -2
  51. data/lib/rails_admin/config/actions/show.rb +1 -1
  52. data/lib/rails_admin/config/configurable.rb +4 -3
  53. data/lib/rails_admin/config/fields/association.rb +9 -8
  54. data/lib/rails_admin/config/fields/base.rb +55 -37
  55. data/lib/rails_admin/config/fields/collection_association.rb +2 -2
  56. data/lib/rails_admin/config/fields/factories/carrierwave.rb +35 -20
  57. data/lib/rails_admin/config/fields/factories/dragonfly.rb +30 -18
  58. data/lib/rails_admin/config/fields/factories/enum.rb +14 -8
  59. data/lib/rails_admin/config/fields/factories/paperclip.rb +29 -19
  60. data/lib/rails_admin/config/fields/factories/shrine.rb +19 -8
  61. data/lib/rails_admin/config/fields/singular_association.rb +6 -1
  62. data/lib/rails_admin/config/fields/types/active_record_enum.rb +3 -7
  63. data/lib/rails_admin/config/fields/types/belongs_to_association.rb +8 -4
  64. data/lib/rails_admin/config/fields/types/bson_object_id.rb +1 -1
  65. data/lib/rails_admin/config/fields/types/datetime.rb +0 -4
  66. data/lib/rails_admin/config/fields/types/dragonfly.rb +1 -1
  67. data/lib/rails_admin/config/fields/types/enum.rb +11 -2
  68. data/lib/rails_admin/config/fields/types/multiple_file_upload.rb +0 -2
  69. data/lib/rails_admin/config/fields/types/polymorphic_association.rb +4 -4
  70. data/lib/rails_admin/config/fields/types/time.rb +1 -1
  71. data/lib/rails_admin/config/model.rb +27 -5
  72. data/lib/rails_admin/config/sections/list.rb +0 -8
  73. data/lib/rails_admin/config.rb +7 -21
  74. data/lib/rails_admin/criteria/path.rb +66 -0
  75. data/lib/rails_admin/criteria/period.rb +67 -0
  76. data/lib/rails_admin/engine.rb +11 -15
  77. data/lib/rails_admin/extensions/pundit/authorization_adapter.rb +2 -2
  78. data/lib/rails_admin/extensions/url_for_extension.rb +8 -0
  79. data/lib/rails_admin/support/asset_source.rb +42 -0
  80. data/lib/rails_admin/support/composite_keys_serializer.rb +28 -2
  81. data/lib/rails_admin/support/csv_converter.rb +3 -10
  82. data/lib/rails_admin/version.rb +8 -7
  83. data/lib/rails_admin.rb +7 -0
  84. data/lib/tasks/assets.rake +23 -0
  85. data/package.json +12 -7
  86. data/src/rails_admin/base.js +18 -15
  87. data/src/rails_admin/filter-box.js +7 -4
  88. data/src/rails_admin/filtering-multiselect.js +1 -1
  89. data/src/rails_admin/filtering-select.js +8 -8
  90. data/src/rails_admin/flatpickr.js +14 -0
  91. data/src/rails_admin/remote-form.js +74 -48
  92. data/src/rails_admin/styles/base/theming.scss +48 -25
  93. data/src/rails_admin/styles/base.scss +25 -1
  94. data/src/rails_admin/styles/filtering-select.scss +23 -62
  95. data/src/rails_admin/ui.js +1 -1
  96. data/src/rails_admin/vendor/jquery_nested_form.js +4 -4
  97. data/src/rails_admin/widgets.js +44 -11
  98. metadata +34 -130
  99. data/app/assets/javascripts/rails_admin/application.js.erb +0 -30
  100. data/app/assets/javascripts/rails_admin/custom/ui.js +0 -1
  101. data/app/assets/stylesheets/rails_admin/application.scss.erb +0 -35
  102. data/app/assets/stylesheets/rails_admin/custom/mixins.scss +0 -11
  103. data/app/assets/stylesheets/rails_admin/custom/theming.scss +0 -13
  104. data/app/assets/stylesheets/rails_admin/custom/variables.scss +0 -15
  105. data/lib/generators/rails_admin/importmap_formatter.rb +0 -28
  106. data/lib/generators/rails_admin/templates/rails_admin.vite.js +0 -2
  107. data/lib/generators/rails_admin/templates/rails_admin.webpacker.js +0 -2
  108. data/lib/rails_admin/adapters/active_record/object_extension.rb +0 -13
  109. data/lib/rails_admin/adapters/active_record.rb.bak +0 -348
  110. data/lib/rails_admin/adapters/mongoid/object_extension.rb +0 -29
  111. data/lib/rails_admin/support/es_module_processor.rb +0 -23
  112. data/vendor/assets/fonts/rails_admin/fa-solid-900.ttf +0 -0
  113. data/vendor/assets/javascripts/rails_admin/bootstrap.js +0 -5046
  114. data/vendor/assets/javascripts/rails_admin/flatpickr-with-locales.js +0 -11246
  115. data/vendor/assets/javascripts/rails_admin/jquery-ui/data.js +0 -41
  116. data/vendor/assets/javascripts/rails_admin/jquery-ui/effect.js +0 -1637
  117. data/vendor/assets/javascripts/rails_admin/jquery-ui/ie.js +0 -17
  118. data/vendor/assets/javascripts/rails_admin/jquery-ui/keycode.js +0 -47
  119. data/vendor/assets/javascripts/rails_admin/jquery-ui/position.js +0 -500
  120. data/vendor/assets/javascripts/rails_admin/jquery-ui/safe-active-element.js +0 -42
  121. data/vendor/assets/javascripts/rails_admin/jquery-ui/scroll-parent.js +0 -47
  122. data/vendor/assets/javascripts/rails_admin/jquery-ui/unique-id.js +0 -51
  123. data/vendor/assets/javascripts/rails_admin/jquery-ui/version.js +0 -17
  124. data/vendor/assets/javascripts/rails_admin/jquery-ui/widget.js +0 -735
  125. data/vendor/assets/javascripts/rails_admin/jquery-ui/widgets/autocomplete.js +0 -689
  126. data/vendor/assets/javascripts/rails_admin/jquery-ui/widgets/menu.js +0 -680
  127. data/vendor/assets/javascripts/rails_admin/jquery-ui/widgets/mouse.js +0 -230
  128. data/vendor/assets/javascripts/rails_admin/jquery-ui/widgets/sortable.js +0 -1561
  129. data/vendor/assets/javascripts/rails_admin/jquery3.js +0 -10881
  130. data/vendor/assets/javascripts/rails_admin/popper.js +0 -1974
  131. data/vendor/assets/stylesheets/rails_admin/bootstrap/_accordion.scss +0 -118
  132. data/vendor/assets/stylesheets/rails_admin/bootstrap/_alert.scss +0 -57
  133. data/vendor/assets/stylesheets/rails_admin/bootstrap/_badge.scss +0 -29
  134. data/vendor/assets/stylesheets/rails_admin/bootstrap/_breadcrumb.scss +0 -28
  135. data/vendor/assets/stylesheets/rails_admin/bootstrap/_button-group.scss +0 -139
  136. data/vendor/assets/stylesheets/rails_admin/bootstrap/_buttons.scss +0 -111
  137. data/vendor/assets/stylesheets/rails_admin/bootstrap/_card.scss +0 -216
  138. data/vendor/assets/stylesheets/rails_admin/bootstrap/_carousel.scss +0 -229
  139. data/vendor/assets/stylesheets/rails_admin/bootstrap/_close.scss +0 -40
  140. data/vendor/assets/stylesheets/rails_admin/bootstrap/_containers.scss +0 -41
  141. data/vendor/assets/stylesheets/rails_admin/bootstrap/_dropdown.scss +0 -240
  142. data/vendor/assets/stylesheets/rails_admin/bootstrap/_forms.scss +0 -9
  143. data/vendor/assets/stylesheets/rails_admin/bootstrap/_functions.scss +0 -302
  144. data/vendor/assets/stylesheets/rails_admin/bootstrap/_grid.scss +0 -33
  145. data/vendor/assets/stylesheets/rails_admin/bootstrap/_helpers.scss +0 -9
  146. data/vendor/assets/stylesheets/rails_admin/bootstrap/_images.scss +0 -42
  147. data/vendor/assets/stylesheets/rails_admin/bootstrap/_list-group.scss +0 -174
  148. data/vendor/assets/stylesheets/rails_admin/bootstrap/_mixins.scss +0 -43
  149. data/vendor/assets/stylesheets/rails_admin/bootstrap/_modal.scss +0 -209
  150. data/vendor/assets/stylesheets/rails_admin/bootstrap/_nav.scss +0 -139
  151. data/vendor/assets/stylesheets/rails_admin/bootstrap/_navbar.scss +0 -335
  152. data/vendor/assets/stylesheets/rails_admin/bootstrap/_offcanvas.scss +0 -83
  153. data/vendor/assets/stylesheets/rails_admin/bootstrap/_pagination.scss +0 -64
  154. data/vendor/assets/stylesheets/rails_admin/bootstrap/_placeholders.scss +0 -51
  155. data/vendor/assets/stylesheets/rails_admin/bootstrap/_popover.scss +0 -158
  156. data/vendor/assets/stylesheets/rails_admin/bootstrap/_progress.scss +0 -48
  157. data/vendor/assets/stylesheets/rails_admin/bootstrap/_reboot.scss +0 -625
  158. data/vendor/assets/stylesheets/rails_admin/bootstrap/_root.scss +0 -54
  159. data/vendor/assets/stylesheets/rails_admin/bootstrap/_spinners.scss +0 -69
  160. data/vendor/assets/stylesheets/rails_admin/bootstrap/_tables.scss +0 -155
  161. data/vendor/assets/stylesheets/rails_admin/bootstrap/_toasts.scss +0 -51
  162. data/vendor/assets/stylesheets/rails_admin/bootstrap/_tooltip.scss +0 -115
  163. data/vendor/assets/stylesheets/rails_admin/bootstrap/_transitions.scss +0 -27
  164. data/vendor/assets/stylesheets/rails_admin/bootstrap/_type.scss +0 -104
  165. data/vendor/assets/stylesheets/rails_admin/bootstrap/_utilities.scss +0 -630
  166. data/vendor/assets/stylesheets/rails_admin/bootstrap/_variables.scss +0 -1641
  167. data/vendor/assets/stylesheets/rails_admin/bootstrap/bootstrap.scss +0 -53
  168. data/vendor/assets/stylesheets/rails_admin/bootstrap/forms/_floating-labels.scss +0 -63
  169. data/vendor/assets/stylesheets/rails_admin/bootstrap/forms/_form-check.scss +0 -152
  170. data/vendor/assets/stylesheets/rails_admin/bootstrap/forms/_form-control.scss +0 -219
  171. data/vendor/assets/stylesheets/rails_admin/bootstrap/forms/_form-range.scss +0 -91
  172. data/vendor/assets/stylesheets/rails_admin/bootstrap/forms/_form-select.scss +0 -72
  173. data/vendor/assets/stylesheets/rails_admin/bootstrap/forms/_form-text.scss +0 -11
  174. data/vendor/assets/stylesheets/rails_admin/bootstrap/forms/_input-group.scss +0 -121
  175. data/vendor/assets/stylesheets/rails_admin/bootstrap/forms/_labels.scss +0 -36
  176. data/vendor/assets/stylesheets/rails_admin/bootstrap/forms/_validation.scss +0 -12
  177. data/vendor/assets/stylesheets/rails_admin/bootstrap/helpers/_clearfix.scss +0 -3
  178. data/vendor/assets/stylesheets/rails_admin/bootstrap/helpers/_colored-links.scss +0 -12
  179. data/vendor/assets/stylesheets/rails_admin/bootstrap/helpers/_position.scss +0 -30
  180. data/vendor/assets/stylesheets/rails_admin/bootstrap/helpers/_ratio.scss +0 -26
  181. data/vendor/assets/stylesheets/rails_admin/bootstrap/helpers/_stacks.scss +0 -15
  182. data/vendor/assets/stylesheets/rails_admin/bootstrap/helpers/_stretched-link.scss +0 -15
  183. data/vendor/assets/stylesheets/rails_admin/bootstrap/helpers/_text-truncation.scss +0 -7
  184. data/vendor/assets/stylesheets/rails_admin/bootstrap/helpers/_visually-hidden.scss +0 -8
  185. data/vendor/assets/stylesheets/rails_admin/bootstrap/helpers/_vr.scss +0 -8
  186. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_alert.scss +0 -11
  187. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_backdrop.scss +0 -14
  188. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_border-radius.scss +0 -78
  189. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_box-shadow.scss +0 -18
  190. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_breakpoints.scss +0 -127
  191. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_buttons.scss +0 -133
  192. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_caret.scss +0 -64
  193. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_clearfix.scss +0 -9
  194. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_color-scheme.scss +0 -7
  195. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_container.scss +0 -9
  196. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_deprecate.scss +0 -10
  197. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_forms.scss +0 -144
  198. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_gradients.scss +0 -47
  199. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_grid.scss +0 -151
  200. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_image.scss +0 -16
  201. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_list-group.scss +0 -24
  202. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_lists.scss +0 -7
  203. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_pagination.scss +0 -31
  204. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_reset-text.scss +0 -17
  205. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_resize.scss +0 -6
  206. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_table-variants.scss +0 -21
  207. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_text-truncate.scss +0 -8
  208. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_transition.scss +0 -26
  209. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_utilities.scss +0 -89
  210. data/vendor/assets/stylesheets/rails_admin/bootstrap/mixins/_visually-hidden.scss +0 -29
  211. data/vendor/assets/stylesheets/rails_admin/bootstrap/utilities/_api.scss +0 -47
  212. data/vendor/assets/stylesheets/rails_admin/bootstrap/vendor/_rfs.scss +0 -354
  213. data/vendor/assets/stylesheets/rails_admin/flatpickr.css +0 -791
  214. data/vendor/assets/stylesheets/rails_admin/font-awesome.scss +0 -6351
@@ -1,689 +0,0 @@
1
- //= require rails_admin/jquery-ui/widgets/menu
2
- //= require rails_admin/jquery-ui/keycode
3
- //= require rails_admin/jquery-ui/position
4
- //= require rails_admin/jquery-ui/safe-active-element
5
- //= require rails_admin/jquery-ui/version
6
- //= require rails_admin/jquery-ui/widget
7
-
8
- /*!
9
- * jQuery UI Autocomplete 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: Autocomplete
18
- //>>group: Widgets
19
- //>>description: Lists suggested words as the user is typing.
20
- //>>docs: http://api.jqueryui.com/autocomplete/
21
- //>>demos: http://jqueryui.com/autocomplete/
22
- //>>css.structure: ../../themes/base/core.css
23
- //>>css.structure: ../../themes/base/autocomplete.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
- "./menu",
33
- "../keycode",
34
- "../position",
35
- "../safe-active-element",
36
- "../version",
37
- "../widget"
38
- ], factory );
39
- } else {
40
-
41
- // Browser globals
42
- factory( jQuery );
43
- }
44
- }( function( $ ) {
45
-
46
- $.widget( "ui.autocomplete", {
47
- version: "1.12.1",
48
- defaultElement: "<input>",
49
- options: {
50
- appendTo: null,
51
- autoFocus: false,
52
- delay: 300,
53
- minLength: 1,
54
- position: {
55
- my: "left top",
56
- at: "left bottom",
57
- collision: "none"
58
- },
59
- source: null,
60
-
61
- // Callbacks
62
- change: null,
63
- close: null,
64
- focus: null,
65
- open: null,
66
- response: null,
67
- search: null,
68
- select: null
69
- },
70
-
71
- requestIndex: 0,
72
- pending: 0,
73
-
74
- _create: function() {
75
-
76
- // Some browsers only repeat keydown events, not keypress events,
77
- // so we use the suppressKeyPress flag to determine if we've already
78
- // handled the keydown event. #7269
79
- // Unfortunately the code for & in keypress is the same as the up arrow,
80
- // so we use the suppressKeyPressRepeat flag to avoid handling keypress
81
- // events when we know the keydown event was used to modify the
82
- // search term. #7799
83
- var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
84
- nodeName = this.element[ 0 ].nodeName.toLowerCase(),
85
- isTextarea = nodeName === "textarea",
86
- isInput = nodeName === "input";
87
-
88
- // Textareas are always multi-line
89
- // Inputs are always single-line, even if inside a contentEditable element
90
- // IE also treats inputs as contentEditable
91
- // All other element types are determined by whether or not they're contentEditable
92
- this.isMultiLine = isTextarea || !isInput && this._isContentEditable( this.element );
93
-
94
- this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
95
- this.isNewMenu = true;
96
-
97
- this._addClass( "ui-autocomplete-input" );
98
- this.element.attr( "autocomplete", "off" );
99
-
100
- this._on( this.element, {
101
- keydown: function( event ) {
102
- if ( this.element.prop( "readOnly" ) ) {
103
- suppressKeyPress = true;
104
- suppressInput = true;
105
- suppressKeyPressRepeat = true;
106
- return;
107
- }
108
-
109
- suppressKeyPress = false;
110
- suppressInput = false;
111
- suppressKeyPressRepeat = false;
112
- var keyCode = $.ui.keyCode;
113
- switch ( event.keyCode ) {
114
- case keyCode.PAGE_UP:
115
- suppressKeyPress = true;
116
- this._move( "previousPage", event );
117
- break;
118
- case keyCode.PAGE_DOWN:
119
- suppressKeyPress = true;
120
- this._move( "nextPage", event );
121
- break;
122
- case keyCode.UP:
123
- suppressKeyPress = true;
124
- this._keyEvent( "previous", event );
125
- break;
126
- case keyCode.DOWN:
127
- suppressKeyPress = true;
128
- this._keyEvent( "next", event );
129
- break;
130
- case keyCode.ENTER:
131
-
132
- // when menu is open and has focus
133
- if ( this.menu.active ) {
134
-
135
- // #6055 - Opera still allows the keypress to occur
136
- // which causes forms to submit
137
- suppressKeyPress = true;
138
- event.preventDefault();
139
- this.menu.select( event );
140
- }
141
- break;
142
- case keyCode.TAB:
143
- if ( this.menu.active ) {
144
- this.menu.select( event );
145
- }
146
- break;
147
- case keyCode.ESCAPE:
148
- if ( this.menu.element.is( ":visible" ) ) {
149
- if ( !this.isMultiLine ) {
150
- this._value( this.term );
151
- }
152
- this.close( event );
153
-
154
- // Different browsers have different default behavior for escape
155
- // Single press can mean undo or clear
156
- // Double press in IE means clear the whole form
157
- event.preventDefault();
158
- }
159
- break;
160
- default:
161
- suppressKeyPressRepeat = true;
162
-
163
- // search timeout should be triggered before the input value is changed
164
- this._searchTimeout( event );
165
- break;
166
- }
167
- },
168
- keypress: function( event ) {
169
- if ( suppressKeyPress ) {
170
- suppressKeyPress = false;
171
- if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
172
- event.preventDefault();
173
- }
174
- return;
175
- }
176
- if ( suppressKeyPressRepeat ) {
177
- return;
178
- }
179
-
180
- // Replicate some key handlers to allow them to repeat in Firefox and Opera
181
- var keyCode = $.ui.keyCode;
182
- switch ( event.keyCode ) {
183
- case keyCode.PAGE_UP:
184
- this._move( "previousPage", event );
185
- break;
186
- case keyCode.PAGE_DOWN:
187
- this._move( "nextPage", event );
188
- break;
189
- case keyCode.UP:
190
- this._keyEvent( "previous", event );
191
- break;
192
- case keyCode.DOWN:
193
- this._keyEvent( "next", event );
194
- break;
195
- }
196
- },
197
- input: function( event ) {
198
- if ( suppressInput ) {
199
- suppressInput = false;
200
- event.preventDefault();
201
- return;
202
- }
203
- this._searchTimeout( event );
204
- },
205
- focus: function() {
206
- this.selectedItem = null;
207
- this.previous = this._value();
208
- },
209
- blur: function( event ) {
210
- if ( this.cancelBlur ) {
211
- delete this.cancelBlur;
212
- return;
213
- }
214
-
215
- clearTimeout( this.searching );
216
- this.close( event );
217
- this._change( event );
218
- }
219
- } );
220
-
221
- this._initSource();
222
- this.menu = $( "<ul>" )
223
- .appendTo( this._appendTo() )
224
- .menu( {
225
-
226
- // disable ARIA support, the live region takes care of that
227
- role: null
228
- } )
229
- .hide()
230
- .menu( "instance" );
231
-
232
- this._addClass( this.menu.element, "ui-autocomplete", "ui-front" );
233
- this._on( this.menu.element, {
234
- mousedown: function( event ) {
235
-
236
- // prevent moving focus out of the text field
237
- event.preventDefault();
238
-
239
- // IE doesn't prevent moving focus even with event.preventDefault()
240
- // so we set a flag to know when we should ignore the blur event
241
- this.cancelBlur = true;
242
- this._delay( function() {
243
- delete this.cancelBlur;
244
-
245
- // Support: IE 8 only
246
- // Right clicking a menu item or selecting text from the menu items will
247
- // result in focus moving out of the input. However, we've already received
248
- // and ignored the blur event because of the cancelBlur flag set above. So
249
- // we restore focus to ensure that the menu closes properly based on the user's
250
- // next actions.
251
- if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {
252
- this.element.trigger( "focus" );
253
- }
254
- } );
255
- },
256
- menufocus: function( event, ui ) {
257
- var label, item;
258
-
259
- // support: Firefox
260
- // Prevent accidental activation of menu items in Firefox (#7024 #9118)
261
- if ( this.isNewMenu ) {
262
- this.isNewMenu = false;
263
- if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
264
- this.menu.blur();
265
-
266
- this.document.one( "mousemove", function() {
267
- $( event.target ).trigger( event.originalEvent );
268
- } );
269
-
270
- return;
271
- }
272
- }
273
-
274
- item = ui.item.data( "ui-autocomplete-item" );
275
- if ( false !== this._trigger( "focus", event, { item: item } ) ) {
276
-
277
- // use value to match what will end up in the input, if it was a key event
278
- if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
279
- this._value( item.value );
280
- }
281
- }
282
-
283
- // Announce the value in the liveRegion
284
- label = ui.item.attr( "aria-label" ) || item.value;
285
- if ( label && $.trim( label ).length ) {
286
- this.liveRegion.children().hide();
287
- $( "<div>" ).text( label ).appendTo( this.liveRegion );
288
- }
289
- },
290
- menuselect: function( event, ui ) {
291
- var item = ui.item.data( "ui-autocomplete-item" ),
292
- previous = this.previous;
293
-
294
- // Only trigger when focus was lost (click on menu)
295
- if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {
296
- this.element.trigger( "focus" );
297
- this.previous = previous;
298
-
299
- // #6109 - IE triggers two focus events and the second
300
- // is asynchronous, so we need to reset the previous
301
- // term synchronously and asynchronously :-(
302
- this._delay( function() {
303
- this.previous = previous;
304
- this.selectedItem = item;
305
- } );
306
- }
307
-
308
- if ( false !== this._trigger( "select", event, { item: item } ) ) {
309
- this._value( item.value );
310
- }
311
-
312
- // reset the term after the select event
313
- // this allows custom select handling to work properly
314
- this.term = this._value();
315
-
316
- this.close( event );
317
- this.selectedItem = item;
318
- }
319
- } );
320
-
321
- this.liveRegion = $( "<div>", {
322
- role: "status",
323
- "aria-live": "assertive",
324
- "aria-relevant": "additions"
325
- } )
326
- .appendTo( this.document[ 0 ].body );
327
-
328
- this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
329
-
330
- // Turning off autocomplete prevents the browser from remembering the
331
- // value when navigating through history, so we re-enable autocomplete
332
- // if the page is unloaded before the widget is destroyed. #7790
333
- this._on( this.window, {
334
- beforeunload: function() {
335
- this.element.removeAttr( "autocomplete" );
336
- }
337
- } );
338
- },
339
-
340
- _destroy: function() {
341
- clearTimeout( this.searching );
342
- this.element.removeAttr( "autocomplete" );
343
- this.menu.element.remove();
344
- this.liveRegion.remove();
345
- },
346
-
347
- _setOption: function( key, value ) {
348
- this._super( key, value );
349
- if ( key === "source" ) {
350
- this._initSource();
351
- }
352
- if ( key === "appendTo" ) {
353
- this.menu.element.appendTo( this._appendTo() );
354
- }
355
- if ( key === "disabled" && value && this.xhr ) {
356
- this.xhr.abort();
357
- }
358
- },
359
-
360
- _isEventTargetInWidget: function( event ) {
361
- var menuElement = this.menu.element[ 0 ];
362
-
363
- return event.target === this.element[ 0 ] ||
364
- event.target === menuElement ||
365
- $.contains( menuElement, event.target );
366
- },
367
-
368
- _closeOnClickOutside: function( event ) {
369
- if ( !this._isEventTargetInWidget( event ) ) {
370
- this.close();
371
- }
372
- },
373
-
374
- _appendTo: function() {
375
- var element = this.options.appendTo;
376
-
377
- if ( element ) {
378
- element = element.jquery || element.nodeType ?
379
- $( element ) :
380
- this.document.find( element ).eq( 0 );
381
- }
382
-
383
- if ( !element || !element[ 0 ] ) {
384
- element = this.element.closest( ".ui-front, dialog" );
385
- }
386
-
387
- if ( !element.length ) {
388
- element = this.document[ 0 ].body;
389
- }
390
-
391
- return element;
392
- },
393
-
394
- _initSource: function() {
395
- var array, url,
396
- that = this;
397
- if ( $.isArray( this.options.source ) ) {
398
- array = this.options.source;
399
- this.source = function( request, response ) {
400
- response( $.ui.autocomplete.filter( array, request.term ) );
401
- };
402
- } else if ( typeof this.options.source === "string" ) {
403
- url = this.options.source;
404
- this.source = function( request, response ) {
405
- if ( that.xhr ) {
406
- that.xhr.abort();
407
- }
408
- that.xhr = $.ajax( {
409
- url: url,
410
- data: request,
411
- dataType: "json",
412
- success: function( data ) {
413
- response( data );
414
- },
415
- error: function() {
416
- response( [] );
417
- }
418
- } );
419
- };
420
- } else {
421
- this.source = this.options.source;
422
- }
423
- },
424
-
425
- _searchTimeout: function( event ) {
426
- clearTimeout( this.searching );
427
- this.searching = this._delay( function() {
428
-
429
- // Search if the value has changed, or if the user retypes the same value (see #7434)
430
- var equalValues = this.term === this._value(),
431
- menuVisible = this.menu.element.is( ":visible" ),
432
- modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
433
-
434
- if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
435
- this.selectedItem = null;
436
- this.search( null, event );
437
- }
438
- }, this.options.delay );
439
- },
440
-
441
- search: function( value, event ) {
442
- value = value != null ? value : this._value();
443
-
444
- // Always save the actual value, not the one passed as an argument
445
- this.term = this._value();
446
-
447
- if ( value.length < this.options.minLength ) {
448
- return this.close( event );
449
- }
450
-
451
- if ( this._trigger( "search", event ) === false ) {
452
- return;
453
- }
454
-
455
- return this._search( value );
456
- },
457
-
458
- _search: function( value ) {
459
- this.pending++;
460
- this._addClass( "ui-autocomplete-loading" );
461
- this.cancelSearch = false;
462
-
463
- this.source( { term: value }, this._response() );
464
- },
465
-
466
- _response: function() {
467
- var index = ++this.requestIndex;
468
-
469
- return $.proxy( function( content ) {
470
- if ( index === this.requestIndex ) {
471
- this.__response( content );
472
- }
473
-
474
- this.pending--;
475
- if ( !this.pending ) {
476
- this._removeClass( "ui-autocomplete-loading" );
477
- }
478
- }, this );
479
- },
480
-
481
- __response: function( content ) {
482
- if ( content ) {
483
- content = this._normalize( content );
484
- }
485
- this._trigger( "response", null, { content: content } );
486
- if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
487
- this._suggest( content );
488
- this._trigger( "open" );
489
- } else {
490
-
491
- // use ._close() instead of .close() so we don't cancel future searches
492
- this._close();
493
- }
494
- },
495
-
496
- close: function( event ) {
497
- this.cancelSearch = true;
498
- this._close( event );
499
- },
500
-
501
- _close: function( event ) {
502
-
503
- // Remove the handler that closes the menu on outside clicks
504
- this._off( this.document, "mousedown" );
505
-
506
- if ( this.menu.element.is( ":visible" ) ) {
507
- this.menu.element.hide();
508
- this.menu.blur();
509
- this.isNewMenu = true;
510
- this._trigger( "close", event );
511
- }
512
- },
513
-
514
- _change: function( event ) {
515
- if ( this.previous !== this._value() ) {
516
- this._trigger( "change", event, { item: this.selectedItem } );
517
- }
518
- },
519
-
520
- _normalize: function( items ) {
521
-
522
- // assume all items have the right format when the first item is complete
523
- if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
524
- return items;
525
- }
526
- return $.map( items, function( item ) {
527
- if ( typeof item === "string" ) {
528
- return {
529
- label: item,
530
- value: item
531
- };
532
- }
533
- return $.extend( {}, item, {
534
- label: item.label || item.value,
535
- value: item.value || item.label
536
- } );
537
- } );
538
- },
539
-
540
- _suggest: function( items ) {
541
- var ul = this.menu.element.empty();
542
- this._renderMenu( ul, items );
543
- this.isNewMenu = true;
544
- this.menu.refresh();
545
-
546
- // Size and position menu
547
- ul.show();
548
- this._resizeMenu();
549
- ul.position( $.extend( {
550
- of: this.element
551
- }, this.options.position ) );
552
-
553
- if ( this.options.autoFocus ) {
554
- this.menu.next();
555
- }
556
-
557
- // Listen for interactions outside of the widget (#6642)
558
- this._on( this.document, {
559
- mousedown: "_closeOnClickOutside"
560
- } );
561
- },
562
-
563
- _resizeMenu: function() {
564
- var ul = this.menu.element;
565
- ul.outerWidth( Math.max(
566
-
567
- // Firefox wraps long text (possibly a rounding bug)
568
- // so we add 1px to avoid the wrapping (#7513)
569
- ul.width( "" ).outerWidth() + 1,
570
- this.element.outerWidth()
571
- ) );
572
- },
573
-
574
- _renderMenu: function( ul, items ) {
575
- var that = this;
576
- $.each( items, function( index, item ) {
577
- that._renderItemData( ul, item );
578
- } );
579
- },
580
-
581
- _renderItemData: function( ul, item ) {
582
- return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
583
- },
584
-
585
- _renderItem: function( ul, item ) {
586
- return $( "<li>" )
587
- .append( $( "<div>" ).text( item.label ) )
588
- .appendTo( ul );
589
- },
590
-
591
- _move: function( direction, event ) {
592
- if ( !this.menu.element.is( ":visible" ) ) {
593
- this.search( null, event );
594
- return;
595
- }
596
- if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
597
- this.menu.isLastItem() && /^next/.test( direction ) ) {
598
-
599
- if ( !this.isMultiLine ) {
600
- this._value( this.term );
601
- }
602
-
603
- this.menu.blur();
604
- return;
605
- }
606
- this.menu[ direction ]( event );
607
- },
608
-
609
- widget: function() {
610
- return this.menu.element;
611
- },
612
-
613
- _value: function() {
614
- return this.valueMethod.apply( this.element, arguments );
615
- },
616
-
617
- _keyEvent: function( keyEvent, event ) {
618
- if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
619
- this._move( keyEvent, event );
620
-
621
- // Prevents moving cursor to beginning/end of the text field in some browsers
622
- event.preventDefault();
623
- }
624
- },
625
-
626
- // Support: Chrome <=50
627
- // We should be able to just use this.element.prop( "isContentEditable" )
628
- // but hidden elements always report false in Chrome.
629
- // https://code.google.com/p/chromium/issues/detail?id=313082
630
- _isContentEditable: function( element ) {
631
- if ( !element.length ) {
632
- return false;
633
- }
634
-
635
- var editable = element.prop( "contentEditable" );
636
-
637
- if ( editable === "inherit" ) {
638
- return this._isContentEditable( element.parent() );
639
- }
640
-
641
- return editable === "true";
642
- }
643
- } );
644
-
645
- $.extend( $.ui.autocomplete, {
646
- escapeRegex: function( value ) {
647
- return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
648
- },
649
- filter: function( array, term ) {
650
- var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
651
- return $.grep( array, function( value ) {
652
- return matcher.test( value.label || value.value || value );
653
- } );
654
- }
655
- } );
656
-
657
- // Live region extension, adding a `messages` option
658
- // NOTE: This is an experimental API. We are still investigating
659
- // a full solution for string manipulation and internationalization.
660
- $.widget( "ui.autocomplete", $.ui.autocomplete, {
661
- options: {
662
- messages: {
663
- noResults: "No search results.",
664
- results: function( amount ) {
665
- return amount + ( amount > 1 ? " results are" : " result is" ) +
666
- " available, use up and down arrow keys to navigate.";
667
- }
668
- }
669
- },
670
-
671
- __response: function( content ) {
672
- var message;
673
- this._superApply( arguments );
674
- if ( this.options.disabled || this.cancelSearch ) {
675
- return;
676
- }
677
- if ( content && content.length ) {
678
- message = this.options.messages.results( content.length );
679
- } else {
680
- message = this.options.messages.noResults;
681
- }
682
- this.liveRegion.children().hide();
683
- $( "<div>" ).text( message ).appendTo( this.liveRegion );
684
- }
685
- } );
686
-
687
- return $.ui.autocomplete;
688
-
689
- } ) );