spiderfw 0.6.27 → 0.6.28

Sign up to get free protection for your applications and to get access to all the features.
Files changed (179) hide show
  1. data/CHANGELOG +4 -0
  2. data/VERSION +1 -1
  3. data/apps/core/admin/admin.rb +6 -2
  4. data/apps/core/admin/controllers/admin_controller.rb +10 -3
  5. data/apps/core/admin/controllers/app_admin_controller.rb +15 -0
  6. data/apps/core/admin/public/css/sass/admin.css +29 -33
  7. data/apps/core/admin/public/css/sass/grid.css +14 -0
  8. data/apps/core/admin/public/sass/admin.scss +3 -2
  9. data/apps/core/admin/views/admin.layout.shtml +1 -0
  10. data/apps/core/auth/controllers/mixins/auth_helper.rb +15 -5
  11. data/apps/core/components/assets.rb +60 -41
  12. data/apps/core/components/public/js/jquery/jquery-1.8.3.js +9472 -0
  13. data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/ui/jquery.ui.core.js +1 -1
  14. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/css/Aristo/images/button_bg.png +0 -0
  15. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/css/Aristo/images/datepicker.gif +0 -0
  16. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/css/Aristo/images/icon_sprite.png +0 -0
  17. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/css/Aristo/images/progress_bar.gif +0 -0
  18. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/css/Aristo/images/slider_h_bg.gif +0 -0
  19. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/css/Aristo/images/slider_handles.png +0 -0
  20. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/css/Aristo/images/slider_v_bg.gif +0 -0
  21. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/css/Aristo/images/tab_bg.gif +0 -0
  22. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/css/Aristo/images/the_gradient.gif +0 -0
  23. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/css/Aristo/images/ui-anim_basic_16x16.gif +0 -0
  24. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/css/Aristo/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  25. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/css/Aristo/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
  26. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/css/Aristo/images/ui-bg_flat_10_000000_40x100.png +0 -0
  27. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/css/Aristo/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  28. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/css/Aristo/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  29. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/css/Aristo/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  30. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/css/Aristo/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
  31. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/css/Aristo/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  32. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/css/Aristo/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  33. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/css/Aristo/images/ui-icons_222222_256x240.png +0 -0
  34. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/css/Aristo/images/ui-icons_228ef1_256x240.png +0 -0
  35. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/css/Aristo/images/ui-icons_ef8c08_256x240.png +0 -0
  36. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/css/Aristo/images/ui-icons_ffd27a_256x240.png +0 -0
  37. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/css/Aristo/images/ui-icons_ffffff_256x240.png +0 -0
  38. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/css/Aristo/jquery-ui.custom.css +528 -0
  39. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-af.js +23 -0
  40. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-ar-DZ.js +23 -0
  41. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-ar.js +23 -0
  42. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-az.js +23 -0
  43. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-be.js +23 -0
  44. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-bg.js +24 -0
  45. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-bs.js +23 -0
  46. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-ca.js +23 -0
  47. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-cs.js +23 -0
  48. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-cy-GB.js +23 -0
  49. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-da.js +23 -0
  50. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-de.js +23 -0
  51. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-el.js +23 -0
  52. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-en-AU.js +23 -0
  53. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-en-GB.js +23 -0
  54. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-en-NZ.js +23 -0
  55. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-eo.js +23 -0
  56. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-es.js +23 -0
  57. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-et.js +23 -0
  58. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-eu.js +23 -0
  59. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-fa.js +59 -0
  60. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-fi.js +23 -0
  61. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-fo.js +23 -0
  62. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-fr-CA.js +23 -0
  63. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-fr-CH.js +23 -0
  64. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-fr.js +25 -0
  65. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-gl.js +23 -0
  66. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-he.js +23 -0
  67. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-hi.js +23 -0
  68. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-hr.js +23 -0
  69. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-hu.js +23 -0
  70. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-hy.js +23 -0
  71. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-id.js +23 -0
  72. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-is.js +23 -0
  73. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-it.js +23 -0
  74. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-ja.js +23 -0
  75. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-ka.js +21 -0
  76. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-kk.js +23 -0
  77. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-km.js +23 -0
  78. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-ko.js +23 -0
  79. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-ky.js +24 -0
  80. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-lb.js +23 -0
  81. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-lt.js +23 -0
  82. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-lv.js +23 -0
  83. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-mk.js +23 -0
  84. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-ml.js +23 -0
  85. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-ms.js +23 -0
  86. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-nb.js +22 -0
  87. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-nl-BE.js +23 -0
  88. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-nl.js +23 -0
  89. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-nn.js +22 -0
  90. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-no.js +23 -0
  91. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-pl.js +23 -0
  92. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-pt-BR.js +23 -0
  93. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-pt.js +22 -0
  94. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-rm.js +21 -0
  95. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-ro.js +26 -0
  96. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-ru.js +23 -0
  97. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-sk.js +23 -0
  98. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-sl.js +24 -0
  99. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-sq.js +23 -0
  100. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-sr-SR.js +23 -0
  101. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-sr.js +23 -0
  102. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-sv.js +23 -0
  103. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-ta.js +23 -0
  104. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-th.js +23 -0
  105. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-tj.js +23 -0
  106. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-tr.js +23 -0
  107. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-uk.js +24 -0
  108. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-vi.js +23 -0
  109. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-zh-CN.js +23 -0
  110. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-zh-HK.js +23 -0
  111. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-zh-TW.js +23 -0
  112. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/jquery.ui.accordion.js +571 -0
  113. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/jquery.ui.autocomplete.js +614 -0
  114. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/jquery.ui.button.js +419 -0
  115. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/jquery.ui.core.js +324 -0
  116. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/jquery.ui.datepicker.js +2044 -0
  117. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/jquery.ui.dialog.js +767 -0
  118. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/jquery.ui.draggable.js +941 -0
  119. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/jquery.ui.droppable.js +364 -0
  120. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/jquery.ui.effect-blind.js +82 -0
  121. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/jquery.ui.effect-bounce.js +113 -0
  122. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/jquery.ui.effect-clip.js +67 -0
  123. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/jquery.ui.effect-drop.js +65 -0
  124. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/jquery.ui.effect-explode.js +97 -0
  125. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/jquery.ui.effect-fade.js +30 -0
  126. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/jquery.ui.effect-fold.js +76 -0
  127. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/jquery.ui.effect-highlight.js +50 -0
  128. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/jquery.ui.effect-pulsate.js +63 -0
  129. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/jquery.ui.effect-scale.js +318 -0
  130. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/jquery.ui.effect-shake.js +74 -0
  131. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/jquery.ui.effect-slide.js +64 -0
  132. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/jquery.ui.effect-transfer.js +47 -0
  133. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/jquery.ui.effect.js +1259 -0
  134. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/jquery.ui.menu.js +621 -0
  135. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/jquery.ui.mouse.js +169 -0
  136. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/jquery.ui.position.js +497 -0
  137. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/jquery.ui.progressbar.js +145 -0
  138. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/jquery.ui.resizable.js +963 -0
  139. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/jquery.ui.selectable.js +269 -0
  140. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/jquery.ui.slider.js +641 -0
  141. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/jquery.ui.sortable.js +1236 -0
  142. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/jquery.ui.spinner.js +492 -0
  143. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/jquery.ui.tabs.js +846 -0
  144. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/jquery.ui.tooltip.js +400 -0
  145. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/jquery.ui.widget.js +521 -0
  146. data/apps/core/components/public/js/jquery/plugins/bsmselect/js/jquery.bsmselect.js +3 -1
  147. data/apps/core/components/public/js/plugins/sortable.js +5 -5
  148. data/apps/core/components/widgets/month_calendar/month_calendar.shtml +1 -1
  149. data/apps/core/components/widgets/table/table.rb +18 -5
  150. data/apps/core/forms/public/date_time.js +3 -0
  151. data/apps/core/forms/widgets/form/form.rb +1 -1
  152. data/apps/core/forms/widgets/inputs/date_time/date_time.rb +5 -0
  153. data/apps/core/forms/widgets/inputs/file_input/file_input.rb +1 -1
  154. data/apps/core/forms/widgets/inputs/select/select.rb +11 -16
  155. data/apps/messenger/config/options.rb +5 -5
  156. data/apps/messenger/controllers/messenger_admin_controller.rb +1 -1
  157. data/apps/messenger/controllers/messenger_controller.rb +1 -1
  158. data/apps/messenger/lib/backends/mobyt.rb +1 -1
  159. data/apps/messenger/messenger.rb +4 -2
  160. data/apps/messenger/views/admin/index.shtml +1 -1
  161. data/lib/spiderfw/controller/dispatcher.rb +5 -5
  162. data/lib/spiderfw/controller/mixins/visual.rb +10 -8
  163. data/lib/spiderfw/http/http.rb +1 -1
  164. data/lib/spiderfw/model/base_model.rb +2 -2
  165. data/lib/spiderfw/model/mappers/db_mapper.rb +4 -2
  166. data/lib/spiderfw/model/mixins/tree.rb +4 -5
  167. data/lib/spiderfw/model/model.rb +2 -1
  168. data/lib/spiderfw/model/storage/db/adapters/mysql.rb +18 -20
  169. data/lib/spiderfw/model/storage/db/adapters/oracle.rb +1 -1
  170. data/lib/spiderfw/spider.rb +5 -1
  171. data/lib/spiderfw/templates/blocks/layout_assets.rb +5 -2
  172. data/lib/spiderfw/templates/layout.rb +7 -3
  173. data/lib/spiderfw/templates/template.rb +8 -1
  174. data/lib/spiderfw/utils/monkey/date_time.rb +7 -5
  175. data/lib/spiderfw/utils/monkey/module.rb +12 -0
  176. metadata +373 -157
  177. data/lib/spiderfw/model/storage/db/connectors/mysql.rb +0 -16
  178. data/lib/spiderfw/model/storage/db/connectors/mysql2.rb +0 -9
  179. /data/apps/core/admin/public/img/{icons-s845a69dd9f.png → icons-s8b18557db6.png} +0 -0
@@ -0,0 +1,492 @@
1
+ /*!
2
+ * jQuery UI Spinner @VERSION
3
+ * http://jqueryui.com
4
+ *
5
+ * Copyright 2012 jQuery Foundation and other contributors
6
+ * Released under the MIT license.
7
+ * http://jquery.org/license
8
+ *
9
+ * http://api.jqueryui.com/spinner/
10
+ *
11
+ * Depends:
12
+ * jquery.ui.core.js
13
+ * jquery.ui.widget.js
14
+ * jquery.ui.button.js
15
+ */
16
+ (function( $ ) {
17
+
18
+ function modifier( fn ) {
19
+ return function() {
20
+ var previous = this.element.val();
21
+ fn.apply( this, arguments );
22
+ this._refresh();
23
+ if ( previous !== this.element.val() ) {
24
+ this._trigger( "change" );
25
+ }
26
+ };
27
+ }
28
+
29
+ $.widget( "ui.spinner", {
30
+ version: "@VERSION",
31
+ defaultElement: "<input>",
32
+ widgetEventPrefix: "spin",
33
+ options: {
34
+ culture: null,
35
+ icons: {
36
+ down: "ui-icon-triangle-1-s",
37
+ up: "ui-icon-triangle-1-n"
38
+ },
39
+ incremental: true,
40
+ max: null,
41
+ min: null,
42
+ numberFormat: null,
43
+ page: 10,
44
+ step: 1,
45
+
46
+ change: null,
47
+ spin: null,
48
+ start: null,
49
+ stop: null
50
+ },
51
+
52
+ _create: function() {
53
+ // handle string values that need to be parsed
54
+ this._setOption( "max", this.options.max );
55
+ this._setOption( "min", this.options.min );
56
+ this._setOption( "step", this.options.step );
57
+
58
+ // format the value, but don't constrain
59
+ this._value( this.element.val(), true );
60
+
61
+ this._draw();
62
+ this._on( this._events );
63
+ this._refresh();
64
+
65
+ // turning off autocomplete prevents the browser from remembering the
66
+ // value when navigating through history, so we re-enable autocomplete
67
+ // if the page is unloaded before the widget is destroyed. #7790
68
+ this._on( this.window, {
69
+ beforeunload: function() {
70
+ this.element.removeAttr( "autocomplete" );
71
+ }
72
+ });
73
+ },
74
+
75
+ _getCreateOptions: function() {
76
+ var options = {},
77
+ element = this.element;
78
+
79
+ $.each( [ "min", "max", "step" ], function( i, option ) {
80
+ var value = element.attr( option );
81
+ if ( value !== undefined && value.length ) {
82
+ options[ option ] = value;
83
+ }
84
+ });
85
+
86
+ return options;
87
+ },
88
+
89
+ _events: {
90
+ keydown: function( event ) {
91
+ if ( this._start( event ) && this._keydown( event ) ) {
92
+ event.preventDefault();
93
+ }
94
+ },
95
+ keyup: "_stop",
96
+ focus: function() {
97
+ this.previous = this.element.val();
98
+ },
99
+ blur: function( event ) {
100
+ if ( this.cancelBlur ) {
101
+ delete this.cancelBlur;
102
+ return;
103
+ }
104
+
105
+ this._refresh();
106
+ if ( this.previous !== this.element.val() ) {
107
+ this._trigger( "change", event );
108
+ }
109
+ },
110
+ mousewheel: function( event, delta ) {
111
+ if ( !delta ) {
112
+ return;
113
+ }
114
+ if ( !this.spinning && !this._start( event ) ) {
115
+ return false;
116
+ }
117
+
118
+ this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
119
+ clearTimeout( this.mousewheelTimer );
120
+ this.mousewheelTimer = this._delay(function() {
121
+ if ( this.spinning ) {
122
+ this._stop( event );
123
+ }
124
+ }, 100 );
125
+ event.preventDefault();
126
+ },
127
+ "mousedown .ui-spinner-button": function( event ) {
128
+ var previous;
129
+
130
+ // We never want the buttons to have focus; whenever the user is
131
+ // interacting with the spinner, the focus should be on the input.
132
+ // If the input is focused then this.previous is properly set from
133
+ // when the input first received focus. If the input is not focused
134
+ // then we need to set this.previous based on the value before spinning.
135
+ previous = this.element[0] === this.document[0].activeElement ?
136
+ this.previous : this.element.val();
137
+ function checkFocus() {
138
+ var isActive = this.element[0] === this.document[0].activeElement;
139
+ if ( !isActive ) {
140
+ this.element.focus();
141
+ this.previous = previous;
142
+ // support: IE
143
+ // IE sets focus asynchronously, so we need to check if focus
144
+ // moved off of the input because the user clicked on the button.
145
+ this._delay(function() {
146
+ this.previous = previous;
147
+ });
148
+ }
149
+ }
150
+
151
+ // ensure focus is on (or stays on) the text field
152
+ event.preventDefault();
153
+ checkFocus.call( this );
154
+
155
+ // support: IE
156
+ // IE doesn't prevent moving focus even with event.preventDefault()
157
+ // so we set a flag to know when we should ignore the blur event
158
+ // and check (again) if focus moved off of the input.
159
+ this.cancelBlur = true;
160
+ this._delay(function() {
161
+ delete this.cancelBlur;
162
+ checkFocus.call( this );
163
+ });
164
+
165
+ if ( this._start( event ) === false ) {
166
+ return;
167
+ }
168
+
169
+ this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
170
+ },
171
+ "mouseup .ui-spinner-button": "_stop",
172
+ "mouseenter .ui-spinner-button": function( event ) {
173
+ // button will add ui-state-active if mouse was down while mouseleave and kept down
174
+ if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
175
+ return;
176
+ }
177
+
178
+ if ( this._start( event ) === false ) {
179
+ return false;
180
+ }
181
+ this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
182
+ },
183
+ // TODO: do we really want to consider this a stop?
184
+ // shouldn't we just stop the repeater and wait until mouseup before
185
+ // we trigger the stop event?
186
+ "mouseleave .ui-spinner-button": "_stop"
187
+ },
188
+
189
+ _draw: function() {
190
+ var uiSpinner = this.uiSpinner = this.element
191
+ .addClass( "ui-spinner-input" )
192
+ .attr( "autocomplete", "off" )
193
+ .wrap( this._uiSpinnerHtml() )
194
+ .parent()
195
+ // add buttons
196
+ .append( this._buttonHtml() );
197
+
198
+ this.element.attr( "role", "spinbutton" );
199
+
200
+ // button bindings
201
+ this.buttons = uiSpinner.find( ".ui-spinner-button" )
202
+ .attr( "tabIndex", -1 )
203
+ .button()
204
+ .removeClass( "ui-corner-all" );
205
+
206
+ // IE 6 doesn't understand height: 50% for the buttons
207
+ // unless the wrapper has an explicit height
208
+ if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
209
+ uiSpinner.height() > 0 ) {
210
+ uiSpinner.height( uiSpinner.height() );
211
+ }
212
+
213
+ // disable spinner if element was already disabled
214
+ if ( this.options.disabled ) {
215
+ this.disable();
216
+ }
217
+ },
218
+
219
+ _keydown: function( event ) {
220
+ var options = this.options,
221
+ keyCode = $.ui.keyCode;
222
+
223
+ switch ( event.keyCode ) {
224
+ case keyCode.UP:
225
+ this._repeat( null, 1, event );
226
+ return true;
227
+ case keyCode.DOWN:
228
+ this._repeat( null, -1, event );
229
+ return true;
230
+ case keyCode.PAGE_UP:
231
+ this._repeat( null, options.page, event );
232
+ return true;
233
+ case keyCode.PAGE_DOWN:
234
+ this._repeat( null, -options.page, event );
235
+ return true;
236
+ }
237
+
238
+ return false;
239
+ },
240
+
241
+ _uiSpinnerHtml: function() {
242
+ return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
243
+ },
244
+
245
+ _buttonHtml: function() {
246
+ return "" +
247
+ "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
248
+ "<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
249
+ "</a>" +
250
+ "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
251
+ "<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
252
+ "</a>";
253
+ },
254
+
255
+ _start: function( event ) {
256
+ if ( !this.spinning && this._trigger( "start", event ) === false ) {
257
+ return false;
258
+ }
259
+
260
+ if ( !this.counter ) {
261
+ this.counter = 1;
262
+ }
263
+ this.spinning = true;
264
+ return true;
265
+ },
266
+
267
+ _repeat: function( i, steps, event ) {
268
+ i = i || 500;
269
+
270
+ clearTimeout( this.timer );
271
+ this.timer = this._delay(function() {
272
+ this._repeat( 40, steps, event );
273
+ }, i );
274
+
275
+ this._spin( steps * this.options.step, event );
276
+ },
277
+
278
+ _spin: function( step, event ) {
279
+ var value = this.value() || 0;
280
+
281
+ if ( !this.counter ) {
282
+ this.counter = 1;
283
+ }
284
+
285
+ value = this._adjustValue( value + step * this._increment( this.counter ) );
286
+
287
+ if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
288
+ this._value( value );
289
+ this.counter++;
290
+ }
291
+ },
292
+
293
+ _increment: function( i ) {
294
+ var incremental = this.options.incremental;
295
+
296
+ if ( incremental ) {
297
+ return $.isFunction( incremental ) ?
298
+ incremental( i ) :
299
+ Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 );
300
+ }
301
+
302
+ return 1;
303
+ },
304
+
305
+ _precision: function() {
306
+ var precision = this._precisionOf( this.options.step );
307
+ if ( this.options.min !== null ) {
308
+ precision = Math.max( precision, this._precisionOf( this.options.min ) );
309
+ }
310
+ return precision;
311
+ },
312
+
313
+ _precisionOf: function( num ) {
314
+ var str = num.toString(),
315
+ decimal = str.indexOf( "." );
316
+ return decimal === -1 ? 0 : str.length - decimal - 1;
317
+ },
318
+
319
+ _adjustValue: function( value ) {
320
+ var base, aboveMin,
321
+ options = this.options;
322
+
323
+ // make sure we're at a valid step
324
+ // - find out where we are relative to the base (min or 0)
325
+ base = options.min !== null ? options.min : 0;
326
+ aboveMin = value - base;
327
+ // - round to the nearest step
328
+ aboveMin = Math.round(aboveMin / options.step) * options.step;
329
+ // - rounding is based on 0, so adjust back to our base
330
+ value = base + aboveMin;
331
+
332
+ // fix precision from bad JS floating point math
333
+ value = parseFloat( value.toFixed( this._precision() ) );
334
+
335
+ // clamp the value
336
+ if ( options.max !== null && value > options.max) {
337
+ return options.max;
338
+ }
339
+ if ( options.min !== null && value < options.min ) {
340
+ return options.min;
341
+ }
342
+
343
+ return value;
344
+ },
345
+
346
+ _stop: function( event ) {
347
+ if ( !this.spinning ) {
348
+ return;
349
+ }
350
+
351
+ clearTimeout( this.timer );
352
+ clearTimeout( this.mousewheelTimer );
353
+ this.counter = 0;
354
+ this.spinning = false;
355
+ this._trigger( "stop", event );
356
+ },
357
+
358
+ _setOption: function( key, value ) {
359
+ if ( key === "culture" || key === "numberFormat" ) {
360
+ var prevValue = this._parse( this.element.val() );
361
+ this.options[ key ] = value;
362
+ this.element.val( this._format( prevValue ) );
363
+ return;
364
+ }
365
+
366
+ if ( key === "max" || key === "min" || key === "step" ) {
367
+ if ( typeof value === "string" ) {
368
+ value = this._parse( value );
369
+ }
370
+ }
371
+ if ( key === "icons" ) {
372
+ this.buttons.first().find( ".ui-icon" )
373
+ .removeClass( this.options.icons.up )
374
+ .addClass( value.up );
375
+ this.buttons.last().find( ".ui-icon" )
376
+ .removeClass( this.options.icons.down )
377
+ .addClass( value.down );
378
+ }
379
+
380
+ this._super( key, value );
381
+
382
+ if ( key === "disabled" ) {
383
+ if ( value ) {
384
+ this.element.prop( "disabled", true );
385
+ this.buttons.button( "disable" );
386
+ } else {
387
+ this.element.prop( "disabled", false );
388
+ this.buttons.button( "enable" );
389
+ }
390
+ }
391
+ },
392
+
393
+ _setOptions: modifier(function( options ) {
394
+ this._super( options );
395
+ this._value( this.element.val() );
396
+ }),
397
+
398
+ _parse: function( val ) {
399
+ if ( typeof val === "string" && val !== "" ) {
400
+ val = window.Globalize && this.options.numberFormat ?
401
+ Globalize.parseFloat( val, 10, this.options.culture ) : +val;
402
+ }
403
+ return val === "" || isNaN( val ) ? null : val;
404
+ },
405
+
406
+ _format: function( value ) {
407
+ if ( value === "" ) {
408
+ return "";
409
+ }
410
+ return window.Globalize && this.options.numberFormat ?
411
+ Globalize.format( value, this.options.numberFormat, this.options.culture ) :
412
+ value;
413
+ },
414
+
415
+ _refresh: function() {
416
+ this.element.attr({
417
+ "aria-valuemin": this.options.min,
418
+ "aria-valuemax": this.options.max,
419
+ // TODO: what should we do with values that can't be parsed?
420
+ "aria-valuenow": this._parse( this.element.val() )
421
+ });
422
+ },
423
+
424
+ // update the value without triggering change
425
+ _value: function( value, allowAny ) {
426
+ var parsed;
427
+ if ( value !== "" ) {
428
+ parsed = this._parse( value );
429
+ if ( parsed !== null ) {
430
+ if ( !allowAny ) {
431
+ parsed = this._adjustValue( parsed );
432
+ }
433
+ value = this._format( parsed );
434
+ }
435
+ }
436
+ this.element.val( value );
437
+ this._refresh();
438
+ },
439
+
440
+ _destroy: function() {
441
+ this.element
442
+ .removeClass( "ui-spinner-input" )
443
+ .prop( "disabled", false )
444
+ .removeAttr( "autocomplete" )
445
+ .removeAttr( "role" )
446
+ .removeAttr( "aria-valuemin" )
447
+ .removeAttr( "aria-valuemax" )
448
+ .removeAttr( "aria-valuenow" );
449
+ this.uiSpinner.replaceWith( this.element );
450
+ },
451
+
452
+ stepUp: modifier(function( steps ) {
453
+ this._stepUp( steps );
454
+ }),
455
+ _stepUp: function( steps ) {
456
+ if ( this._start() ) {
457
+ this._spin( (steps || 1) * this.options.step );
458
+ this._stop();
459
+ }
460
+ },
461
+
462
+ stepDown: modifier(function( steps ) {
463
+ this._stepDown( steps );
464
+ }),
465
+ _stepDown: function( steps ) {
466
+ if ( this._start() ) {
467
+ this._spin( (steps || 1) * -this.options.step );
468
+ this._stop();
469
+ }
470
+ },
471
+
472
+ pageUp: modifier(function( pages ) {
473
+ this._stepUp( (pages || 1) * this.options.page );
474
+ }),
475
+
476
+ pageDown: modifier(function( pages ) {
477
+ this._stepDown( (pages || 1) * this.options.page );
478
+ }),
479
+
480
+ value: function( newVal ) {
481
+ if ( !arguments.length ) {
482
+ return this._parse( this.element.val() );
483
+ }
484
+ modifier( this._value ).call( this, newVal );
485
+ },
486
+
487
+ widget: function() {
488
+ return this.uiSpinner;
489
+ }
490
+ });
491
+
492
+ }( jQuery ) );