stuff_to_do_plugin 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (159) hide show
  1. data/COPYRIGHT.txt +18 -0
  2. data/CREDITS.txt +6 -0
  3. data/GPL.txt +339 -0
  4. data/README.rdoc +61 -0
  5. data/Rakefile +38 -0
  6. data/VERSION +1 -0
  7. data/app/controllers/stuff_to_do_controller.rb +161 -0
  8. data/app/helpers/stuff_to_do_helper.rb +88 -0
  9. data/app/models/stuff_to_do.rb +208 -0
  10. data/app/models/stuff_to_do_filter.rb +32 -0
  11. data/app/models/stuff_to_do_mailer.rb +16 -0
  12. data/app/views/settings/_stuff_to_do_settings.html.erb +27 -0
  13. data/app/views/stuff_to_do/_issue.html.erb +16 -0
  14. data/app/views/stuff_to_do/_item.html.erb +5 -0
  15. data/app/views/stuff_to_do/_left_panes.html.erb +51 -0
  16. data/app/views/stuff_to_do/_panes.html.erb +11 -0
  17. data/app/views/stuff_to_do/_project.html.erb +6 -0
  18. data/app/views/stuff_to_do/_right_panes.html.erb +25 -0
  19. data/app/views/stuff_to_do/_time_grid.html.erb +113 -0
  20. data/app/views/stuff_to_do/_time_grid_form.html.erb +32 -0
  21. data/app/views/stuff_to_do/index.html.erb +44 -0
  22. data/app/views/stuff_to_do_mailer/recommended_below_threshold.erb +3 -0
  23. data/app/views/stuff_to_do_mailer/recommended_below_threshold.text.html.rhtml +1 -0
  24. data/assets/images/b.png +0 -0
  25. data/assets/images/bl.png +0 -0
  26. data/assets/images/br.png +0 -0
  27. data/assets/images/closelabel.gif +0 -0
  28. data/assets/images/loading.gif +0 -0
  29. data/assets/images/tl.png +0 -0
  30. data/assets/images/tr.png +0 -0
  31. data/assets/javascripts/facebox.js +319 -0
  32. data/assets/javascripts/jquery-1.2.6.min.js +32 -0
  33. data/assets/javascripts/jquery-ui.js +2839 -0
  34. data/assets/javascripts/jquery.contextMenu.js +212 -0
  35. data/assets/javascripts/semantic.cache +15 -0
  36. data/assets/javascripts/stuff-to-do.js +270 -0
  37. data/assets/javascripts/ui/build.xml +24 -0
  38. data/assets/javascripts/ui/effects.blind.js +49 -0
  39. data/assets/javascripts/ui/effects.bounce.js +78 -0
  40. data/assets/javascripts/ui/effects.clip.js +54 -0
  41. data/assets/javascripts/ui/effects.core.js +510 -0
  42. data/assets/javascripts/ui/effects.drop.js +50 -0
  43. data/assets/javascripts/ui/effects.explode.js +79 -0
  44. data/assets/javascripts/ui/effects.fold.js +55 -0
  45. data/assets/javascripts/ui/effects.highlight.js +48 -0
  46. data/assets/javascripts/ui/effects.pulsate.js +55 -0
  47. data/assets/javascripts/ui/effects.scale.js +180 -0
  48. data/assets/javascripts/ui/effects.shake.js +57 -0
  49. data/assets/javascripts/ui/effects.slide.js +50 -0
  50. data/assets/javascripts/ui/effects.transfer.js +59 -0
  51. data/assets/javascripts/ui/i18n/ui.datepicker-ar.js +26 -0
  52. data/assets/javascripts/ui/i18n/ui.datepicker-bg.js +25 -0
  53. data/assets/javascripts/ui/i18n/ui.datepicker-ca.js +25 -0
  54. data/assets/javascripts/ui/i18n/ui.datepicker-cs.js +25 -0
  55. data/assets/javascripts/ui/i18n/ui.datepicker-da.js +25 -0
  56. data/assets/javascripts/ui/i18n/ui.datepicker-de.js +25 -0
  57. data/assets/javascripts/ui/i18n/ui.datepicker-eo.js +25 -0
  58. data/assets/javascripts/ui/i18n/ui.datepicker-es.js +25 -0
  59. data/assets/javascripts/ui/i18n/ui.datepicker-fa.js +25 -0
  60. data/assets/javascripts/ui/i18n/ui.datepicker-fi.js +25 -0
  61. data/assets/javascripts/ui/i18n/ui.datepicker-fr.js +25 -0
  62. data/assets/javascripts/ui/i18n/ui.datepicker-he.js +25 -0
  63. data/assets/javascripts/ui/i18n/ui.datepicker-hr.js +25 -0
  64. data/assets/javascripts/ui/i18n/ui.datepicker-hu.js +25 -0
  65. data/assets/javascripts/ui/i18n/ui.datepicker-hy.js +25 -0
  66. data/assets/javascripts/ui/i18n/ui.datepicker-id.js +25 -0
  67. data/assets/javascripts/ui/i18n/ui.datepicker-is.js +25 -0
  68. data/assets/javascripts/ui/i18n/ui.datepicker-it.js +25 -0
  69. data/assets/javascripts/ui/i18n/ui.datepicker-ja.js +26 -0
  70. data/assets/javascripts/ui/i18n/ui.datepicker-ko.js +25 -0
  71. data/assets/javascripts/ui/i18n/ui.datepicker-lt.js +25 -0
  72. data/assets/javascripts/ui/i18n/ui.datepicker-lv.js +25 -0
  73. data/assets/javascripts/ui/i18n/ui.datepicker-nl.js +25 -0
  74. data/assets/javascripts/ui/i18n/ui.datepicker-no.js +25 -0
  75. data/assets/javascripts/ui/i18n/ui.datepicker-pl.js +25 -0
  76. data/assets/javascripts/ui/i18n/ui.datepicker-pt-BR.js +25 -0
  77. data/assets/javascripts/ui/i18n/ui.datepicker-ro.js +25 -0
  78. data/assets/javascripts/ui/i18n/ui.datepicker-ru.js +25 -0
  79. data/assets/javascripts/ui/i18n/ui.datepicker-sk.js +25 -0
  80. data/assets/javascripts/ui/i18n/ui.datepicker-sl.js +26 -0
  81. data/assets/javascripts/ui/i18n/ui.datepicker-sq.js +25 -0
  82. data/assets/javascripts/ui/i18n/ui.datepicker-sv.js +25 -0
  83. data/assets/javascripts/ui/i18n/ui.datepicker-th.js +25 -0
  84. data/assets/javascripts/ui/i18n/ui.datepicker-tr.js +25 -0
  85. data/assets/javascripts/ui/i18n/ui.datepicker-uk.js +25 -0
  86. data/assets/javascripts/ui/i18n/ui.datepicker-zh-CN.js +25 -0
  87. data/assets/javascripts/ui/i18n/ui.datepicker-zh-TW.js +25 -0
  88. data/assets/javascripts/ui/svn.log +11 -0
  89. data/assets/javascripts/ui/ui.accordion.js +400 -0
  90. data/assets/javascripts/ui/ui.core.js +533 -0
  91. data/assets/javascripts/ui/ui.datepicker.js +1754 -0
  92. data/assets/javascripts/ui/ui.dialog.js +630 -0
  93. data/assets/javascripts/ui/ui.draggable.js +696 -0
  94. data/assets/javascripts/ui/ui.droppable.js +314 -0
  95. data/assets/javascripts/ui/ui.progressbar.js +114 -0
  96. data/assets/javascripts/ui/ui.resizable.js +805 -0
  97. data/assets/javascripts/ui/ui.selectable.js +266 -0
  98. data/assets/javascripts/ui/ui.slider.js +552 -0
  99. data/assets/javascripts/ui/ui.sortable.js +1012 -0
  100. data/assets/javascripts/ui/ui.tabs.js +572 -0
  101. data/assets/stylesheets/stuff_to_do.css +216 -0
  102. data/config/locales/bg.yml +18 -0
  103. data/config/locales/ca-fr.yml +18 -0
  104. data/config/locales/cs.yml +16 -0
  105. data/config/locales/da.yml +16 -0
  106. data/config/locales/de.yml +18 -0
  107. data/config/locales/en.yml +24 -0
  108. data/config/locales/es.yml +19 -0
  109. data/config/locales/fr.yml +17 -0
  110. data/config/locales/hu.yml +16 -0
  111. data/config/locales/it.yml +16 -0
  112. data/config/locales/ja.yml +18 -0
  113. data/config/locales/ko.yml +18 -0
  114. data/config/locales/lt.yml +18 -0
  115. data/config/locales/nl.yml +20 -0
  116. data/config/locales/pt-BR.yml +18 -0
  117. data/config/locales/ru.yml +19 -0
  118. data/config/locales/sv.yml +19 -0
  119. data/config/locales/tr.yml +18 -0
  120. data/config/routes.rb +3 -0
  121. data/init.rb +54 -0
  122. data/lang/bg.yml +17 -0
  123. data/lang/ca-fr.yml +17 -0
  124. data/lang/cs.yml +15 -0
  125. data/lang/da.yml +15 -0
  126. data/lang/de.yml +17 -0
  127. data/lang/en.yml +21 -0
  128. data/lang/es.yml +18 -0
  129. data/lang/fr.yml +16 -0
  130. data/lang/hu.yml +15 -0
  131. data/lang/it.yml +15 -0
  132. data/lang/ja.yml +17 -0
  133. data/lang/ko.yml +17 -0
  134. data/lang/lt.yml +17 -0
  135. data/lang/pt-br.yml +17 -0
  136. data/lang/ru.yml +15 -0
  137. data/lang/sv.yml +18 -0
  138. data/lang/tr.yml +17 -0
  139. data/lib/redmine_stuff_to_do/stuff_to_do_compatibility.rb +15 -0
  140. data/lib/stuff_to_do_array_patch.rb +8 -0
  141. data/lib/stuff_to_do_issue_patch.rb +57 -0
  142. data/lib/stuff_to_do_project_patch.rb +31 -0
  143. data/lib/stuff_to_do_user_patch.rb +10 -0
  144. data/rails/init.rb +1 -0
  145. data/spec/controllers/stuff_to_do_controller_add_to_time_grid_spec.rb +58 -0
  146. data/spec/controllers/stuff_to_do_controller_index_spec.rb +155 -0
  147. data/spec/controllers/stuff_to_do_controller_remove_from_time_grid_spec.rb +56 -0
  148. data/spec/controllers/stuff_to_do_controller_reorder_spec.rb +179 -0
  149. data/spec/controllers/stuff_to_do_controller_save_time_entries_spec.rb +56 -0
  150. data/spec/controllers/stuff_to_do_private_methods_spec.rb +82 -0
  151. data/spec/lib/stuff_to_do_issue_patch_spec.rb +60 -0
  152. data/spec/lib/stuff_to_do_project_patch_spec.rb +50 -0
  153. data/spec/lib/stuff_to_do_user_patch_spec.rb +8 -0
  154. data/spec/models/stuff_to_do_filter_spec.rb +3 -0
  155. data/spec/models/stuff_to_do_mailer_spec.rb +42 -0
  156. data/spec/models/stuff_to_do_spec.rb +426 -0
  157. data/spec/sanity_spec.rb +7 -0
  158. data/spec/spec_helper.rb +130 -0
  159. metadata +211 -0
@@ -0,0 +1,266 @@
1
+ /*
2
+ * jQuery UI Selectable @VERSION
3
+ *
4
+ * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)
5
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
6
+ * and GPL (GPL-LICENSE.txt) licenses.
7
+ *
8
+ * http://docs.jquery.com/UI/Selectables
9
+ *
10
+ * Depends:
11
+ * ui.core.js
12
+ */
13
+ (function($) {
14
+
15
+ $.widget("ui.selectable", $.extend({}, $.ui.mouse, {
16
+
17
+ _init: function() {
18
+ var self = this;
19
+
20
+ this.element.addClass("ui-selectable");
21
+
22
+ this.dragged = false;
23
+
24
+ // cache selectee children based on filter
25
+ var selectees;
26
+ this.refresh = function() {
27
+ selectees = $(self.options.filter, self.element[0]);
28
+ selectees.each(function() {
29
+ var $this = $(this);
30
+ var pos = $this.offset();
31
+ $.data(this, "selectable-item", {
32
+ element: this,
33
+ $element: $this,
34
+ left: pos.left,
35
+ top: pos.top,
36
+ right: pos.left + $this.width(),
37
+ bottom: pos.top + $this.height(),
38
+ startselected: false,
39
+ selected: $this.hasClass('ui-selected'),
40
+ selecting: $this.hasClass('ui-selecting'),
41
+ unselecting: $this.hasClass('ui-unselecting')
42
+ });
43
+ });
44
+ };
45
+ this.refresh();
46
+
47
+ this.selectees = selectees.addClass("ui-selectee");
48
+
49
+ this._mouseInit();
50
+
51
+ this.helper = $(document.createElement('div'))
52
+ .css({border:'1px dotted black'})
53
+ .addClass("ui-selectable-helper");
54
+ },
55
+
56
+ destroy: function() {
57
+ this.element
58
+ .removeClass("ui-selectable ui-selectable-disabled")
59
+ .removeData("selectable")
60
+ .unbind(".selectable");
61
+ this._mouseDestroy();
62
+ },
63
+
64
+ _mouseStart: function(event) {
65
+ var self = this;
66
+
67
+ this.opos = [event.pageX, event.pageY];
68
+
69
+ if (this.options.disabled)
70
+ return;
71
+
72
+ var options = this.options;
73
+
74
+ this.selectees = $(options.filter, this.element[0]);
75
+
76
+ // selectable START callback
77
+ this.element.triggerHandler("selectablestart", [event, {
78
+ "selectable": this.element[0],
79
+ "options": options
80
+ }], options.start);
81
+
82
+ $('body').append(this.helper);
83
+ // position helper (lasso)
84
+ this.helper.css({
85
+ "z-index": 100,
86
+ "position": "absolute",
87
+ "left": event.clientX,
88
+ "top": event.clientY,
89
+ "width": 0,
90
+ "height": 0
91
+ });
92
+
93
+ if (options.autoRefresh) {
94
+ this.refresh();
95
+ }
96
+
97
+ this.selectees.filter('.ui-selected').each(function() {
98
+ var selectee = $.data(this, "selectable-item");
99
+ selectee.startselected = true;
100
+ if (!event.metaKey) {
101
+ selectee.$element.removeClass('ui-selected');
102
+ selectee.selected = false;
103
+ selectee.$element.addClass('ui-unselecting');
104
+ selectee.unselecting = true;
105
+ // selectable UNSELECTING callback
106
+ self.element.triggerHandler("selectableunselecting", [event, {
107
+ selectable: self.element[0],
108
+ unselecting: selectee.element,
109
+ options: options
110
+ }], options.unselecting);
111
+ }
112
+ });
113
+
114
+ var isSelectee = false;
115
+ $(event.target).parents().andSelf().each(function() {
116
+ if($.data(this, "selectable-item")) isSelectee = true;
117
+ });
118
+ return this.options.keyboard ? !isSelectee : true;
119
+ },
120
+
121
+ _mouseDrag: function(event) {
122
+ var self = this;
123
+ this.dragged = true;
124
+
125
+ if (this.options.disabled)
126
+ return;
127
+
128
+ var options = this.options;
129
+
130
+ var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY;
131
+ if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; }
132
+ if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; }
133
+ this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
134
+
135
+ this.selectees.each(function() {
136
+ var selectee = $.data(this, "selectable-item");
137
+ //prevent helper from being selected if appendTo: selectable
138
+ if (!selectee || selectee.element == self.element[0])
139
+ return;
140
+ var hit = false;
141
+ if (options.tolerance == 'touch') {
142
+ hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
143
+ } else if (options.tolerance == 'fit') {
144
+ hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
145
+ }
146
+
147
+ if (hit) {
148
+ // SELECT
149
+ if (selectee.selected) {
150
+ selectee.$element.removeClass('ui-selected');
151
+ selectee.selected = false;
152
+ }
153
+ if (selectee.unselecting) {
154
+ selectee.$element.removeClass('ui-unselecting');
155
+ selectee.unselecting = false;
156
+ }
157
+ if (!selectee.selecting) {
158
+ selectee.$element.addClass('ui-selecting');
159
+ selectee.selecting = true;
160
+ // selectable SELECTING callback
161
+ self.element.triggerHandler("selectableselecting", [event, {
162
+ selectable: self.element[0],
163
+ selecting: selectee.element,
164
+ options: options
165
+ }], options.selecting);
166
+ }
167
+ } else {
168
+ // UNSELECT
169
+ if (selectee.selecting) {
170
+ if (event.metaKey && selectee.startselected) {
171
+ selectee.$element.removeClass('ui-selecting');
172
+ selectee.selecting = false;
173
+ selectee.$element.addClass('ui-selected');
174
+ selectee.selected = true;
175
+ } else {
176
+ selectee.$element.removeClass('ui-selecting');
177
+ selectee.selecting = false;
178
+ if (selectee.startselected) {
179
+ selectee.$element.addClass('ui-unselecting');
180
+ selectee.unselecting = true;
181
+ }
182
+ // selectable UNSELECTING callback
183
+ self.element.triggerHandler("selectableunselecting", [event, {
184
+ selectable: self.element[0],
185
+ unselecting: selectee.element,
186
+ options: options
187
+ }], options.unselecting);
188
+ }
189
+ }
190
+ if (selectee.selected) {
191
+ if (!event.metaKey && !selectee.startselected) {
192
+ selectee.$element.removeClass('ui-selected');
193
+ selectee.selected = false;
194
+
195
+ selectee.$element.addClass('ui-unselecting');
196
+ selectee.unselecting = true;
197
+ // selectable UNSELECTING callback
198
+ self.element.triggerHandler("selectableunselecting", [event, {
199
+ selectable: self.element[0],
200
+ unselecting: selectee.element,
201
+ options: options
202
+ }], options.unselecting);
203
+ }
204
+ }
205
+ }
206
+ });
207
+
208
+ return false;
209
+ },
210
+
211
+ _mouseStop: function(event) {
212
+ var self = this;
213
+
214
+ this.dragged = false;
215
+
216
+ var options = this.options;
217
+
218
+ $('.ui-unselecting', this.element[0]).each(function() {
219
+ var selectee = $.data(this, "selectable-item");
220
+ selectee.$element.removeClass('ui-unselecting');
221
+ selectee.unselecting = false;
222
+ selectee.startselected = false;
223
+ self.element.triggerHandler("selectableunselected", [event, {
224
+ selectable: self.element[0],
225
+ unselected: selectee.element,
226
+ options: options
227
+ }], options.unselected);
228
+ });
229
+ $('.ui-selecting', this.element[0]).each(function() {
230
+ var selectee = $.data(this, "selectable-item");
231
+ selectee.$element.removeClass('ui-selecting').addClass('ui-selected');
232
+ selectee.selecting = false;
233
+ selectee.selected = true;
234
+ selectee.startselected = true;
235
+ self.element.triggerHandler("selectableselected", [event, {
236
+ selectable: self.element[0],
237
+ selected: selectee.element,
238
+ options: options
239
+ }], options.selected);
240
+ });
241
+ this.element.triggerHandler("selectablestop", [event, {
242
+ selectable: self.element[0],
243
+ options: this.options
244
+ }], this.options.stop);
245
+
246
+ this.helper.remove();
247
+
248
+ return false;
249
+ }
250
+
251
+ }));
252
+
253
+ $.extend($.ui.selectable, {
254
+ version: "@VERSION",
255
+ defaults: {
256
+ appendTo: 'body',
257
+ autoRefresh: true,
258
+ cancel: ":input",
259
+ delay: 0,
260
+ distance: 1,
261
+ filter: '*',
262
+ tolerance: 'touch'
263
+ }
264
+ });
265
+
266
+ })(jQuery);
@@ -0,0 +1,552 @@
1
+ /*
2
+ * jQuery UI Slider @VERSION
3
+ *
4
+ * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)
5
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
6
+ * and GPL (GPL-LICENSE.txt) licenses.
7
+ *
8
+ * http://docs.jquery.com/UI/Slider
9
+ *
10
+ * Depends:
11
+ * ui.core.js
12
+ */
13
+ (function($) {
14
+
15
+ $.fn.unwrap = $.fn.unwrap || function(expr) {
16
+ return this.each(function(){
17
+ $(this).parents(expr).eq(0).after(this).remove();
18
+ });
19
+ };
20
+
21
+ $.widget("ui.slider", {
22
+
23
+ _init: function() {
24
+
25
+ var self = this;
26
+ this.element.addClass("ui-slider ui-widget ui-widget-content ui-corner-all");
27
+ this._initBoundaries();
28
+
29
+ // Initialize mouse and key events for interaction
30
+ this.handle = $(this.options.handle, this.element);
31
+ if (!this.handle.length) {
32
+ self.handle = self.generated = $(self.options.handles || [0]).map(function() {
33
+ var handle = $('<a href="#"></a>').addClass("ui-slider-handle ui-state-default ui-corner-all").appendTo(self.element);
34
+ if (this.id)
35
+ handle.attr("id", this.id);
36
+ return handle[0];
37
+ });
38
+ }
39
+
40
+ var handleclass = function(el) {
41
+ this.element = $(el);
42
+ this.element.data("mouse", this);
43
+ this.options = self.options;
44
+
45
+ this.element.bind("mousedown", function() {
46
+ if(self.currentHandle) this.blur(self.currentHandle);
47
+ self._focus(this, true);
48
+ });
49
+
50
+ this._mouseInit();
51
+ };
52
+
53
+ $.extend(handleclass.prototype, $.ui.mouse, {
54
+ _mouseCapture: function() { return true; },
55
+ _mouseStart: function(event) { return self._start.call(self, event, this.element[0]); },
56
+ _mouseDrag: function(event) { return self._drag.call(self, event, this.element[0]); },
57
+ _mouseStop: function(event) { return self._stop.call(self, event, this.element[0]); },
58
+ trigger: function(event) { this._mouseDown(event); }
59
+ });
60
+
61
+ $(this.handle)
62
+ .each(function() {
63
+ new handleclass(this);
64
+ })
65
+ .parent()
66
+ .bind('click', function() { return false; })
67
+ .bind('focus', function(event) { self._focus(this.firstChild); })
68
+ .bind('blur', function(event) { self._blur(this.firstChild); })
69
+ .bind('keydown', function(event) { if(!self.options.noKeyboard) return self._keydown(event.keyCode, this.firstChild); })
70
+ ;
71
+
72
+ // Bind the click to the slider itself
73
+ this.element.bind('mousedown.slider', function(event) {
74
+
75
+ if($(event.target).is('.ui-slider-handle')) return;
76
+
77
+ //Go to the actual clicked posiion, apply a click
78
+ self._click.apply(self, [event]);
79
+
80
+ //initiate a handle drag, so we can click+drag somewhere
81
+ self.currentHandle.data("mouse").trigger(event);
82
+
83
+ //This is for always triggering the change event
84
+ self.firstValue = self.firstValue + 1;
85
+
86
+ });
87
+
88
+ // Move the first handle to the startValue
89
+ $.each(this.options.handles || [], function(index, handle) {
90
+ self.moveTo(handle.start, index, true);
91
+ });
92
+ if (!isNaN(this.options.startValue))
93
+ this.moveTo(this.options.startValue, 0, true);
94
+
95
+ this.previousHandle = $(this.handle[0]); //set the previous handle to the first to allow clicking before selecting the handle
96
+ if(this.handle.length == 2 && this.options.range) this._createRange();
97
+
98
+ },
99
+
100
+ destroy: function() {
101
+
102
+ this.element
103
+ .removeClass("ui-slider ui-slider-disabled ui-widget ui-widget-content ui-corner-all")
104
+ .removeData("slider")
105
+ .unbind(".slider");
106
+
107
+ if(this.handle && this.handle.length) {
108
+ this.handle
109
+ .unwrap("a");
110
+ this.handle.each(function() {
111
+ var mouse = $(this).data("mouse");
112
+ mouse && mouse._mouseDestroy();
113
+ });
114
+ }
115
+
116
+ this.generated && this.generated.remove();
117
+
118
+ },
119
+
120
+ _start: function(event, handle) {
121
+
122
+ var o = this.options;
123
+ if(o.disabled) return false;
124
+
125
+ // Prepare the outer size
126
+ this.actualSize = { width: this.element.outerWidth() , height: this.element.outerHeight() };
127
+
128
+ // This is a especially ugly fix for strange blur events happening on mousemove events
129
+ if (!this.currentHandle)
130
+ this._focus(this.previousHandle, true);
131
+
132
+ this.offset = this.element.offset();
133
+
134
+ this.handleOffset = this.currentHandle.offset();
135
+ this.clickOffset = { top: event.pageY - this.handleOffset.top, left: event.pageX - this.handleOffset.left };
136
+
137
+ this.firstValue = this.value();
138
+
139
+ this._propagate('start', event);
140
+ this._drag(event, handle);
141
+ return true;
142
+
143
+ },
144
+
145
+ _drag: function(event, handle) {
146
+
147
+ var o = this.options;
148
+
149
+ var position = { top: event.pageY - this.offset.top - this.clickOffset.top, left: event.pageX - this.offset.left - this.clickOffset.left};
150
+ if(!this.currentHandle) this._focus(this.previousHandle, true); //This is a especially ugly fix for strange blur events happening on mousemove events
151
+
152
+ position.left = this._translateLimits(position.left, "x");
153
+ position.top = this._translateLimits(position.top, "y");
154
+
155
+ if (o.stepping.x) {
156
+ var value = this._convertValue(position.left, "x");
157
+ value = this._round(value / o.stepping.x) * o.stepping.x;
158
+ position.left = this._translateValue(value, "x");
159
+ }
160
+ if (o.stepping.y) {
161
+ var value = this._convertValue(position.top, "y");
162
+ value = this._round(value / o.stepping.y) * o.stepping.y;
163
+ position.top = this._translateValue(value, "y");
164
+ }
165
+
166
+ position.left = this._translateRange(position.left, "x");
167
+ position.top = this._translateRange(position.top, "y");
168
+
169
+ if(o.axis != "vertical") this.currentHandle.css({ left: position.left });
170
+ if(o.axis != "horizontal") this.currentHandle.css({ top: position.top });
171
+
172
+ //Store the slider's value
173
+ this.currentHandle.data("mouse").sliderValue = {
174
+ x: this._round(this._convertValue(position.left, "x")) || 0,
175
+ y: this._round(this._convertValue(position.top, "y")) || 0
176
+ };
177
+
178
+ if (this.rangeElement)
179
+ this._updateRange();
180
+ this._propagate('slide', event);
181
+ return false;
182
+
183
+ },
184
+
185
+ _stop: function(event) {
186
+
187
+ this._propagate('stop', event);
188
+
189
+ if (this.firstValue != this.value())
190
+ this._propagate('change', event);
191
+
192
+ // This is a especially ugly fix for strange blur events happening on mousemove events
193
+ this._focus(this.currentHandle, true);
194
+
195
+ return false;
196
+
197
+ },
198
+
199
+ _round: function(value) {
200
+
201
+ return this.options.round ? parseInt(value,10) : parseFloat(value);
202
+
203
+ },
204
+
205
+ _setData: function(key, value) {
206
+
207
+ $.widget.prototype._setData.apply(this, arguments);
208
+
209
+ if (/min|max|steps/.test(key)) {
210
+ this._initBoundaries();
211
+ }
212
+
213
+ if(key == "range") {
214
+ value ? this.handle.length == 2 && this._createRange() : this._removeRange();
215
+ }
216
+
217
+ },
218
+
219
+ _initBoundaries: function() {
220
+
221
+ var element = this.element[0], o = this.options;
222
+ this.actualSize = { width: this.element.outerWidth() , height: this.element.outerHeight() };
223
+
224
+ $.extend(o, {
225
+ axis: o.axis || (element.offsetWidth < element.offsetHeight ? 'vertical' : 'horizontal'),
226
+ max: !isNaN(parseInt(o.max,10)) ? { x: parseInt(o.max, 10), y: parseInt(o.max, 10) } : ({ x: o.max && o.max.x || 100, y: o.max && o.max.y || 100 }),
227
+ min: !isNaN(parseInt(o.min,10)) ? { x: parseInt(o.min, 10), y: parseInt(o.min, 10) } : ({ x: o.min && o.min.x || 0, y: o.min && o.min.y || 0 })
228
+ });
229
+ //Prepare the real maxValue
230
+ o.realMax = {
231
+ x: o.max.x - o.min.x,
232
+ y: o.max.y - o.min.y
233
+ };
234
+ //Calculate stepping based on steps
235
+ o.stepping = {
236
+ x: o.stepping && o.stepping.x || parseInt(o.stepping, 10) || (o.steps ? o.realMax.x/(o.steps.x || parseInt(o.steps, 10) || o.realMax.x) : 0),
237
+ y: o.stepping && o.stepping.y || parseInt(o.stepping, 10) || (o.steps ? o.realMax.y/(o.steps.y || parseInt(o.steps, 10) || o.realMax.y) : 0)
238
+ };
239
+
240
+ },
241
+
242
+ _keydown: function(keyCode, handle) {
243
+
244
+ if (this.options.disabled)
245
+ return;
246
+
247
+ var k = keyCode;
248
+ if(/(33|34|35|36|37|38|39|40)/.test(k)) {
249
+ var o = this.options, xpos, ypos;
250
+ if (/(35|36)/.test(k)) {
251
+ xpos = (k == 35) ? o.max.x : o.min.x;
252
+ ypos = (k == 35) ? o.max.y : o.min.y;
253
+ } else {
254
+ var oper = /(34|37|40)/.test(k) ? "-=" : "+=";
255
+ var step = /(37|38|39|40)/.test(k) ? "_oneStep" : "_pageStep";
256
+ xpos = oper + this[step]("x");
257
+ ypos = oper + this[step]("y");
258
+ }
259
+ this.moveTo({
260
+ x: xpos,
261
+ y: ypos
262
+ }, handle);
263
+ return false;
264
+ }
265
+ return true;
266
+
267
+ },
268
+
269
+ _focus: function(handle,hard) {
270
+
271
+ this.currentHandle = $(handle).addClass('ui-slider-handle-active');
272
+
273
+ if (hard)
274
+ this.currentHandle.parent()[0].focus();
275
+
276
+ },
277
+
278
+ _blur: function(handle) {
279
+
280
+ $(handle).removeClass('ui-slider-handle-active');
281
+
282
+ if(this.currentHandle && this.currentHandle[0] == handle) {
283
+ this.previousHandle = this.currentHandle;
284
+ this.currentHandle = null;
285
+ };
286
+
287
+ },
288
+
289
+ _click: function(event) {
290
+
291
+ // This method is only used if:
292
+ // - The user didn't click a handle
293
+ // - The Slider is not disabled
294
+ // - There is a current, or previous selected handle (otherwise we wouldn't know which one to move)
295
+
296
+ var pointer = [event.pageX, event.pageY];
297
+
298
+ var clickedHandle = false;
299
+ this.handle.each(function() {
300
+ if(this == event.target)
301
+ clickedHandle = true;
302
+ });
303
+ if (clickedHandle || this.options.disabled || !(this.currentHandle || this.previousHandle))
304
+ return;
305
+
306
+ // If a previous handle was focussed, focus it again
307
+ if (!this.currentHandle && this.previousHandle)
308
+ this._focus(this.previousHandle, true);
309
+
310
+ // propagate only for distance > 0, otherwise propagation is done my drag
311
+ this.offset = this.element.offset();
312
+
313
+ this.moveTo({
314
+ y: this._convertValue(event.pageY - this.offset.top - this.currentHandle[0].offsetHeight/2, "y"),
315
+ x: this._convertValue(event.pageX - this.offset.left - this.currentHandle[0].offsetWidth/2, "x")
316
+ }, null, !this.options.distance);
317
+
318
+ },
319
+
320
+ _createRange: function() {
321
+
322
+ if(this.rangeElement) return;
323
+ this.rangeElement = $('<div></div>')
324
+ .addClass('ui-slider-range')
325
+ .css({ position: 'absolute' })
326
+ .appendTo(this.element);
327
+ this._updateRange();
328
+
329
+ },
330
+
331
+ _removeRange: function() {
332
+
333
+ this.rangeElement.remove();
334
+ this.rangeElement = null;
335
+
336
+ },
337
+
338
+ _updateRange: function() {
339
+
340
+ var prop = this.options.axis == "vertical" ? "top" : "left";
341
+ var size = this.options.axis == "vertical" ? "height" : "width";
342
+
343
+ this.rangeElement.css(prop, (this._round($(this.handle[0]).css(prop)) || 0) + this._handleSize(0, this.options.axis == "vertical" ? "y" : "x")/2);
344
+ this.rangeElement.css(size, (this._round($(this.handle[1]).css(prop)) || 0) - (this._round($(this.handle[0]).css(prop)) || 0));
345
+
346
+ },
347
+
348
+ _getRange: function() {
349
+
350
+ return this.rangeElement ? this._convertValue(this._round(this.rangeElement.css(this.options.axis == "vertical" ? "height" : "width")), this.options.axis == "vertical" ? "y" : "x") : null;
351
+
352
+ },
353
+
354
+ _handleIndex: function() {
355
+
356
+ return this.handle.index(this.currentHandle[0]);
357
+
358
+ },
359
+
360
+ value: function(handle, axis) {
361
+
362
+ if(this.handle.length == 1) this.currentHandle = this.handle;
363
+ if(!axis) axis = this.options.axis == "vertical" ? "y" : "x";
364
+
365
+ var curHandle = $(handle != undefined && handle !== null ? this.handle[handle] || handle : this.currentHandle);
366
+
367
+ if(curHandle.data("mouse").sliderValue) {
368
+ return this._round(curHandle.data("mouse").sliderValue[axis]);
369
+ } else {
370
+ return this._round(((this._round(curHandle.css(axis == "x" ? "left" : "top")) / (this.actualSize[axis == "x" ? "width" : "height"] - this._handleSize(handle,axis))) * this.options.realMax[axis]) + this.options.min[axis]);
371
+ }
372
+
373
+ },
374
+
375
+ _convertValue: function(value,axis) {
376
+
377
+ return this.options.min[axis] + (value / (this.actualSize[axis == "x" ? "width" : "height"] - this._handleSize(null,axis))) * this.options.realMax[axis];
378
+
379
+ },
380
+
381
+ _translateValue: function(value,axis) {
382
+
383
+ return ((value - this.options.min[axis]) / this.options.realMax[axis]) * (this.actualSize[axis == "x" ? "width" : "height"] - this._handleSize(null,axis));
384
+
385
+ },
386
+
387
+ _translateRange: function(value,axis) {
388
+
389
+ if (this.rangeElement) {
390
+ if (this.currentHandle[0] == this.handle[0] && value >= this._translateValue(this.value(1),axis))
391
+ value = this._translateValue(this.value(1,axis) - this._oneStep(axis), axis);
392
+ if (this.currentHandle[0] == this.handle[1] && value <= this._translateValue(this.value(0),axis))
393
+ value = this._translateValue(this.value(0,axis) + this._oneStep(axis), axis);
394
+ }
395
+
396
+ if (this.options.handles) {
397
+ var handle = this.options.handles[this._handleIndex()];
398
+ if (value < this._translateValue(handle.min,axis)) {
399
+ value = this._translateValue(handle.min,axis);
400
+ } else if (value > this._translateValue(handle.max,axis)) {
401
+ value = this._translateValue(handle.max,axis);
402
+ }
403
+ }
404
+
405
+ return value;
406
+
407
+ },
408
+
409
+ _translateLimits: function(value,axis) {
410
+
411
+ if (value >= this.actualSize[axis == "x" ? "width" : "height"] - this._handleSize(null,axis))
412
+ value = this.actualSize[axis == "x" ? "width" : "height"] - this._handleSize(null,axis);
413
+
414
+ if (value <= 0)
415
+ value = 0;
416
+
417
+ return value;
418
+
419
+ },
420
+
421
+ _handleSize: function(handle,axis) {
422
+
423
+ return $(handle != undefined && handle !== null ? this.handle[handle] : this.currentHandle)[0]["offset"+(axis == "x" ? "Width" : "Height")];
424
+
425
+ },
426
+
427
+ _oneStep: function(axis) {
428
+
429
+ return this.options.stepping[axis] || 1;
430
+
431
+ },
432
+
433
+ _pageStep: function(axis) {
434
+
435
+ return /* this.options.paging[axis] ||*/ 10;
436
+
437
+ },
438
+
439
+ moveTo: function(value, handle, noPropagation) {
440
+
441
+ var o = this.options;
442
+
443
+ // Prepare the outer size
444
+ this.actualSize = { width: this.element.outerWidth() , height: this.element.outerHeight() };
445
+
446
+ //If no handle has been passed, no current handle is available and we have multiple handles, return false
447
+ if (handle == undefined && !this.currentHandle && this.handle.length != 1)
448
+ return false;
449
+
450
+ //If only one handle is available, use it
451
+ if (handle == undefined && !this.currentHandle)
452
+ handle = 0;
453
+
454
+ if (handle != undefined)
455
+ this.currentHandle = this.previousHandle = $(this.handle[handle] || handle);
456
+
457
+ if(value.x !== undefined && value.y !== undefined) {
458
+ var x = value.x, y = value.y;
459
+ } else {
460
+ var x = value, y = value;
461
+ }
462
+
463
+ if(x !== undefined && x.constructor != Number) {
464
+ var me = /^\-\=/.test(x), pe = /^\+\=/.test(x);
465
+ if(me || pe) {
466
+ x = this.value(null, "x") + this._round(x.replace(me ? '=' : '+=', ''));
467
+ } else {
468
+ x = isNaN(this._round(x)) ? undefined : this._round(x);
469
+ }
470
+ }
471
+
472
+ if(y !== undefined && y.constructor != Number) {
473
+ var me = /^\-\=/.test(y), pe = /^\+\=/.test(y);
474
+ if(me || pe) {
475
+ y = this.value(null, "y") + this._round(y.replace(me ? '=' : '+=', ''));
476
+ } else {
477
+ y = isNaN(this._round(y)) ? undefined : this._round(y);
478
+ }
479
+ }
480
+
481
+ if(o.axis != "vertical" && x !== undefined) {
482
+ if(o.stepping.x) x = this._round(x / o.stepping.x) * o.stepping.x;
483
+ x = this._translateValue(x, "x");
484
+ x = this._translateLimits(x, "x");
485
+ x = this._translateRange(x, "x");
486
+
487
+ o.animate ? this.currentHandle.stop().animate({ left: x }, (Math.abs(parseInt(this.currentHandle.css("left"),10) - x)) * (!isNaN(parseInt(o.animate,10)) ? o.animate : 5)) : this.currentHandle.css({ left: x });
488
+ }
489
+
490
+ if(o.axis != "horizontal" && y !== undefined) {
491
+ if(o.stepping.y) y = this._round(y / o.stepping.y) * o.stepping.y;
492
+ y = this._translateValue(y, "y");
493
+ y = this._translateLimits(y, "y");
494
+ y = this._translateRange(y, "y");
495
+ o.animate ? this.currentHandle.stop().animate({ top: y }, (Math.abs(parseInt(this.currentHandle.css("top"),10) - y)) * (!isNaN(parseInt(o.animate,10)) ? o.animate : 5)) : this.currentHandle.css({ top: y });
496
+ }
497
+
498
+ if (this.rangeElement)
499
+ this._updateRange();
500
+
501
+ //Store the slider's value
502
+ this.currentHandle.data("mouse").sliderValue = {
503
+ x: this._round(this._convertValue(x, "x")) || 0,
504
+ y: this._round(this._convertValue(y, "y")) || 0
505
+ };
506
+
507
+ if (!noPropagation) {
508
+ this._propagate('start', null);
509
+ this._propagate("slide", null);
510
+ this._propagate('stop', null);
511
+ this._propagate('change', null);
512
+ }
513
+
514
+ },
515
+
516
+ _propagate: function(n, event) {
517
+
518
+ $.ui.plugin.call(this, n, [event, this.ui()]);
519
+ this.element.triggerHandler(n == "slide" ? n : "slide"+n, [event, this.ui()], this.options[n]);
520
+
521
+ },
522
+
523
+ plugins: {},
524
+
525
+ ui: function(event) {
526
+ return {
527
+ options: this.options,
528
+ handle: this.currentHandle,
529
+ value: this.options.axis != "both" || !this.options.axis ?
530
+ this._round(this.value(null, this.options.axis == "vertical" ? "y" : "x")) :
531
+ {
532
+ x: this._round(this.value(null, "x")),
533
+ y: this._round(this.value(null, "y"))
534
+ },
535
+ range: this._getRange()
536
+ };
537
+ }
538
+
539
+ });
540
+
541
+ $.extend($.ui.slider, {
542
+ getter: "value",
543
+ version: "@VERSION",
544
+ defaults: {
545
+ animate: false,
546
+ distance: 1,
547
+ handle: ".ui-slider-handle",
548
+ round: true
549
+ }
550
+ });
551
+
552
+ })(jQuery);