express_ui 0.1.7 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/express_ui/application.js +46 -0
  3. data/app/assets/javascripts/express_ui/sidebar.js +6 -0
  4. data/app/assets/javascripts/express_ui/styleguide.js +9 -10
  5. data/app/assets/stylesheets/express_ui/application.css +3 -0
  6. data/app/assets/stylesheets/express_ui/atoms/_animations.sass +3 -0
  7. data/app/assets/stylesheets/express_ui/atoms/_buttons.sass +35 -28
  8. data/app/assets/stylesheets/express_ui/atoms/_headings.sass +5 -5
  9. data/app/assets/stylesheets/express_ui/atoms/_icons.sass +1 -1
  10. data/app/assets/stylesheets/express_ui/atoms/_typography.sass +6 -3
  11. data/app/assets/stylesheets/express_ui/atoms/_variables.sass +5 -1
  12. data/app/assets/stylesheets/express_ui/molecules/_container.sass +23 -0
  13. data/app/assets/stylesheets/express_ui/molecules/_form_groups.sass +30 -1
  14. data/app/assets/stylesheets/express_ui/molecules/_forms.sass +15 -8
  15. data/app/assets/stylesheets/express_ui/molecules/_nav.sass +29 -4
  16. data/app/assets/stylesheets/express_ui/molecules/_tables.sass +9 -18
  17. data/app/assets/stylesheets/express_ui/organisms/_header.sass +6 -2
  18. data/app/assets/stylesheets/express_ui/organisms/_sidebar.sass +2 -1
  19. data/app/assets/stylesheets/express_ui/scripts/_accordion.sass +39 -0
  20. data/app/assets/stylesheets/express_ui/scripts/_calendar.sass +35 -0
  21. data/app/assets/stylesheets/express_ui/scripts/_carousel.sass +43 -0
  22. data/app/assets/stylesheets/express_ui/scripts/_datepicker.sass +10 -0
  23. data/app/assets/stylesheets/express_ui/scripts/_popup.sass +48 -0
  24. data/app/assets/stylesheets/express_ui/scripts/_select.sass +12 -0
  25. data/app/assets/stylesheets/express_ui/scripts/_slider.sass +30 -0
  26. data/app/assets/stylesheets/express_ui/style.sass +19 -0
  27. data/app/assets/stylesheets/express_ui/styleguide.sass +0 -4
  28. data/app/assets/stylesheets/express_ui/templates/_content_sidebar.sass +2 -2
  29. data/app/components/code_demo.rb +2 -4
  30. data/app/controllers/express_ui/scripts_controller.rb +10 -0
  31. data/app/views/express_ui/molecules/_forms.html.erb +1 -1
  32. data/app/views/express_ui/molecules/_forms_select.html.erb +2 -2
  33. data/app/views/express_ui/molecules/_table.html.erb +0 -2
  34. data/app/views/express_ui/molecules/_table_with_filtering.html.erb +83 -54
  35. data/app/views/express_ui/scripts/_accordion.html.et +27 -0
  36. data/app/views/express_ui/scripts/_calendar.html.et +35 -0
  37. data/app/views/express_ui/scripts/_carousel.html.et +21 -0
  38. data/app/views/express_ui/scripts/_datepicker.html.et +37 -0
  39. data/app/views/express_ui/scripts/_popup.html.et +58 -0
  40. data/app/views/express_ui/scripts/_select.html.et +40 -0
  41. data/app/views/express_ui/scripts/_tabs.html.et +17 -0
  42. data/app/views/express_ui/scripts/index.html.erb +41 -0
  43. data/app/views/express_ui/shared/_header.html.erb +1 -0
  44. data/app/views/layouts/express_ui/_head.html.erb +3 -1
  45. data/config/routes.rb +1 -0
  46. data/lib/express_ui/engine.rb +5 -3
  47. data/lib/express_ui/version.rb +1 -1
  48. data/vendor/assets/javascripts/forms.js +39 -0
  49. data/vendor/assets/javascripts/ion.rangeSlider.js +2368 -0
  50. data/vendor/assets/javascripts/picker.date.js +1354 -0
  51. data/vendor/assets/javascripts/picker.js +1163 -0
  52. data/vendor/assets/stylesheets/classic.css +99 -0
  53. data/vendor/assets/stylesheets/default.css +4 -0
  54. data/vendor/assets/stylesheets/default.date.css +1 -0
  55. data/vendor/assets/stylesheets/ion.rangeSlider.css +146 -0
  56. data/vendor/assets/stylesheets/ion.rangeSlider.skinFlat.css +86 -0
  57. metadata +102 -20
  58. data/app/components/express_ui/table/express_table.rb +0 -6
@@ -0,0 +1,2368 @@
1
+ // Ion.RangeSlider
2
+ // version 2.1.7 Build: 371
3
+ // © Denis Ineshin, 2017
4
+ // https://github.com/IonDen
5
+ //
6
+ // Project page: http://ionden.com/a/plugins/ion.rangeSlider/en.html
7
+ // GitHub page: https://github.com/IonDen/ion.rangeSlider
8
+ //
9
+ // Released under MIT licence:
10
+ // http://ionden.com/a/plugins/licence-en.html
11
+ // =====================================================================================================================
12
+
13
+ ;(function(factory) {
14
+ if (typeof define === "function" && define.amd) {
15
+ define(["jquery"], function (jQuery) {
16
+ return factory(jQuery, document, window, navigator);
17
+ });
18
+ } else if (typeof exports === "object") {
19
+ factory(require("jquery"), document, window, navigator);
20
+ } else {
21
+ factory(jQuery, document, window, navigator);
22
+ }
23
+ } (function ($, document, window, navigator, undefined) {
24
+ "use strict";
25
+
26
+ // =================================================================================================================
27
+ // Service
28
+
29
+ var plugin_count = 0;
30
+
31
+ // IE8 fix
32
+ var is_old_ie = (function () {
33
+ var n = navigator.userAgent,
34
+ r = /msie\s\d+/i,
35
+ v;
36
+ if (n.search(r) > 0) {
37
+ v = r.exec(n).toString();
38
+ v = v.split(" ")[1];
39
+ if (v < 9) {
40
+ $("html").addClass("lt-ie9");
41
+ return true;
42
+ }
43
+ }
44
+ return false;
45
+ } ());
46
+ if (!Function.prototype.bind) {
47
+ Function.prototype.bind = function bind(that) {
48
+
49
+ var target = this;
50
+ var slice = [].slice;
51
+
52
+ if (typeof target != "function") {
53
+ throw new TypeError();
54
+ }
55
+
56
+ var args = slice.call(arguments, 1),
57
+ bound = function () {
58
+
59
+ if (this instanceof bound) {
60
+
61
+ var F = function(){};
62
+ F.prototype = target.prototype;
63
+ var self = new F();
64
+
65
+ var result = target.apply(
66
+ self,
67
+ args.concat(slice.call(arguments))
68
+ );
69
+ if (Object(result) === result) {
70
+ return result;
71
+ }
72
+ return self;
73
+
74
+ } else {
75
+
76
+ return target.apply(
77
+ that,
78
+ args.concat(slice.call(arguments))
79
+ );
80
+
81
+ }
82
+
83
+ };
84
+
85
+ return bound;
86
+ };
87
+ }
88
+ if (!Array.prototype.indexOf) {
89
+ Array.prototype.indexOf = function(searchElement, fromIndex) {
90
+ var k;
91
+ if (this == null) {
92
+ throw new TypeError('"this" is null or not defined');
93
+ }
94
+ var O = Object(this);
95
+ var len = O.length >>> 0;
96
+ if (len === 0) {
97
+ return -1;
98
+ }
99
+ var n = +fromIndex || 0;
100
+ if (Math.abs(n) === Infinity) {
101
+ n = 0;
102
+ }
103
+ if (n >= len) {
104
+ return -1;
105
+ }
106
+ k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
107
+ while (k < len) {
108
+ if (k in O && O[k] === searchElement) {
109
+ return k;
110
+ }
111
+ k++;
112
+ }
113
+ return -1;
114
+ };
115
+ }
116
+
117
+
118
+
119
+ // =================================================================================================================
120
+ // Template
121
+
122
+ var base_html =
123
+ '<span class="irs">' +
124
+ '<span class="irs-line" tabindex="-1"><span class="irs-line-left"></span><span class="irs-line-mid"></span><span class="irs-line-right"></span></span>' +
125
+ '<span class="irs-min">0</span><span class="irs-max">1</span>' +
126
+ '<span class="irs-from">0</span><span class="irs-to">0</span><span class="irs-single">0</span>' +
127
+ '</span>' +
128
+ '<span class="irs-grid"></span>' +
129
+ '<span class="irs-bar"></span>';
130
+
131
+ var single_html =
132
+ '<span class="irs-bar-edge"></span>' +
133
+ '<span class="irs-shadow shadow-single"></span>' +
134
+ '<span class="irs-slider single"></span>';
135
+
136
+ var double_html =
137
+ '<span class="irs-shadow shadow-from"></span>' +
138
+ '<span class="irs-shadow shadow-to"></span>' +
139
+ '<span class="irs-slider from"></span>' +
140
+ '<span class="irs-slider to"></span>';
141
+
142
+ var disable_html =
143
+ '<span class="irs-disable-mask"></span>';
144
+
145
+
146
+
147
+ // =================================================================================================================
148
+ // Core
149
+
150
+ /**
151
+ * Main plugin constructor
152
+ *
153
+ * @param input {Object} link to base input element
154
+ * @param options {Object} slider config
155
+ * @param plugin_count {Number}
156
+ * @constructor
157
+ */
158
+ var IonRangeSlider = function (input, options, plugin_count) {
159
+ this.VERSION = "2.1.7";
160
+ this.input = input;
161
+ this.plugin_count = plugin_count;
162
+ this.current_plugin = 0;
163
+ this.calc_count = 0;
164
+ this.update_tm = 0;
165
+ this.old_from = 0;
166
+ this.old_to = 0;
167
+ this.old_min_interval = null;
168
+ this.raf_id = null;
169
+ this.dragging = false;
170
+ this.force_redraw = false;
171
+ this.no_diapason = false;
172
+ this.is_key = false;
173
+ this.is_update = false;
174
+ this.is_start = true;
175
+ this.is_finish = false;
176
+ this.is_active = false;
177
+ this.is_resize = false;
178
+ this.is_click = false;
179
+
180
+ options = options || {};
181
+
182
+ // cache for links to all DOM elements
183
+ this.$cache = {
184
+ win: $(window),
185
+ body: $(document.body),
186
+ input: $(input),
187
+ cont: null,
188
+ rs: null,
189
+ min: null,
190
+ max: null,
191
+ from: null,
192
+ to: null,
193
+ single: null,
194
+ bar: null,
195
+ line: null,
196
+ s_single: null,
197
+ s_from: null,
198
+ s_to: null,
199
+ shad_single: null,
200
+ shad_from: null,
201
+ shad_to: null,
202
+ edge: null,
203
+ grid: null,
204
+ grid_labels: []
205
+ };
206
+
207
+ // storage for measure variables
208
+ this.coords = {
209
+ // left
210
+ x_gap: 0,
211
+ x_pointer: 0,
212
+
213
+ // width
214
+ w_rs: 0,
215
+ w_rs_old: 0,
216
+ w_handle: 0,
217
+
218
+ // percents
219
+ p_gap: 0,
220
+ p_gap_left: 0,
221
+ p_gap_right: 0,
222
+ p_step: 0,
223
+ p_pointer: 0,
224
+ p_handle: 0,
225
+ p_single_fake: 0,
226
+ p_single_real: 0,
227
+ p_from_fake: 0,
228
+ p_from_real: 0,
229
+ p_to_fake: 0,
230
+ p_to_real: 0,
231
+ p_bar_x: 0,
232
+ p_bar_w: 0,
233
+
234
+ // grid
235
+ grid_gap: 0,
236
+ big_num: 0,
237
+ big: [],
238
+ big_w: [],
239
+ big_p: [],
240
+ big_x: []
241
+ };
242
+
243
+ // storage for labels measure variables
244
+ this.labels = {
245
+ // width
246
+ w_min: 0,
247
+ w_max: 0,
248
+ w_from: 0,
249
+ w_to: 0,
250
+ w_single: 0,
251
+
252
+ // percents
253
+ p_min: 0,
254
+ p_max: 0,
255
+ p_from_fake: 0,
256
+ p_from_left: 0,
257
+ p_to_fake: 0,
258
+ p_to_left: 0,
259
+ p_single_fake: 0,
260
+ p_single_left: 0
261
+ };
262
+
263
+
264
+
265
+ /**
266
+ * get and validate config
267
+ */
268
+ var $inp = this.$cache.input,
269
+ val = $inp.prop("value"),
270
+ config, config_from_data, prop;
271
+
272
+ // default config
273
+ config = {
274
+ type: "single",
275
+
276
+ min: 10,
277
+ max: 100,
278
+ from: null,
279
+ to: null,
280
+ step: 1,
281
+
282
+ min_interval: 0,
283
+ max_interval: 0,
284
+ drag_interval: false,
285
+
286
+ values: [],
287
+ p_values: [],
288
+
289
+ from_fixed: false,
290
+ from_min: null,
291
+ from_max: null,
292
+ from_shadow: false,
293
+
294
+ to_fixed: false,
295
+ to_min: null,
296
+ to_max: null,
297
+ to_shadow: false,
298
+
299
+ prettify_enabled: true,
300
+ prettify_separator: " ",
301
+ prettify: null,
302
+
303
+ force_edges: false,
304
+
305
+ keyboard: false,
306
+ keyboard_step: 5,
307
+
308
+ grid: false,
309
+ grid_margin: true,
310
+ grid_num: 4,
311
+ grid_snap: false,
312
+
313
+ hide_min_max: false,
314
+ hide_from_to: false,
315
+
316
+ prefix: "",
317
+ postfix: "",
318
+ max_postfix: "",
319
+ decorate_both: true,
320
+ values_separator: " — ",
321
+
322
+ input_values_separator: ";",
323
+
324
+ disable: false,
325
+
326
+ onStart: null,
327
+ onChange: null,
328
+ onFinish: null,
329
+ onUpdate: null
330
+ };
331
+
332
+
333
+ // check if base element is input
334
+ if ($inp[0].nodeName !== "INPUT") {
335
+ console && console.warn && console.warn("Base element should be <input>!", $inp[0]);
336
+ }
337
+
338
+
339
+ // config from data-attributes extends js config
340
+ config_from_data = {
341
+ type: $inp.data("type"),
342
+
343
+ min: $inp.data("min"),
344
+ max: $inp.data("max"),
345
+ from: $inp.data("from"),
346
+ to: $inp.data("to"),
347
+ step: $inp.data("step"),
348
+
349
+ min_interval: $inp.data("minInterval"),
350
+ max_interval: $inp.data("maxInterval"),
351
+ drag_interval: $inp.data("dragInterval"),
352
+
353
+ values: $inp.data("values"),
354
+
355
+ from_fixed: $inp.data("fromFixed"),
356
+ from_min: $inp.data("fromMin"),
357
+ from_max: $inp.data("fromMax"),
358
+ from_shadow: $inp.data("fromShadow"),
359
+
360
+ to_fixed: $inp.data("toFixed"),
361
+ to_min: $inp.data("toMin"),
362
+ to_max: $inp.data("toMax"),
363
+ to_shadow: $inp.data("toShadow"),
364
+
365
+ prettify_enabled: $inp.data("prettifyEnabled"),
366
+ prettify_separator: $inp.data("prettifySeparator"),
367
+
368
+ force_edges: $inp.data("forceEdges"),
369
+
370
+ keyboard: $inp.data("keyboard"),
371
+ keyboard_step: $inp.data("keyboardStep"),
372
+
373
+ grid: $inp.data("grid"),
374
+ grid_margin: $inp.data("gridMargin"),
375
+ grid_num: $inp.data("gridNum"),
376
+ grid_snap: $inp.data("gridSnap"),
377
+
378
+ hide_min_max: $inp.data("hideMinMax"),
379
+ hide_from_to: $inp.data("hideFromTo"),
380
+
381
+ prefix: $inp.data("prefix"),
382
+ postfix: $inp.data("postfix"),
383
+ max_postfix: $inp.data("maxPostfix"),
384
+ decorate_both: $inp.data("decorateBoth"),
385
+ values_separator: $inp.data("valuesSeparator"),
386
+
387
+ input_values_separator: $inp.data("inputValuesSeparator"),
388
+
389
+ disable: $inp.data("disable")
390
+ };
391
+ config_from_data.values = config_from_data.values && config_from_data.values.split(",");
392
+
393
+ for (prop in config_from_data) {
394
+ if (config_from_data.hasOwnProperty(prop)) {
395
+ if (config_from_data[prop] === undefined || config_from_data[prop] === "") {
396
+ delete config_from_data[prop];
397
+ }
398
+ }
399
+ }
400
+
401
+
402
+ // input value extends default config
403
+ if (val !== undefined && val !== "") {
404
+ val = val.split(config_from_data.input_values_separator || options.input_values_separator || ";");
405
+
406
+ if (val[0] && val[0] == +val[0]) {
407
+ val[0] = +val[0];
408
+ }
409
+ if (val[1] && val[1] == +val[1]) {
410
+ val[1] = +val[1];
411
+ }
412
+
413
+ if (options && options.values && options.values.length) {
414
+ config.from = val[0] && options.values.indexOf(val[0]);
415
+ config.to = val[1] && options.values.indexOf(val[1]);
416
+ } else {
417
+ config.from = val[0] && +val[0];
418
+ config.to = val[1] && +val[1];
419
+ }
420
+ }
421
+
422
+
423
+
424
+ // js config extends default config
425
+ $.extend(config, options);
426
+
427
+
428
+ // data config extends config
429
+ $.extend(config, config_from_data);
430
+ this.options = config;
431
+
432
+
433
+
434
+ // validate config, to be sure that all data types are correct
435
+ this.update_check = {};
436
+ this.validate();
437
+
438
+
439
+
440
+ // default result object, returned to callbacks
441
+ this.result = {
442
+ input: this.$cache.input,
443
+ slider: null,
444
+
445
+ min: this.options.min,
446
+ max: this.options.max,
447
+
448
+ from: this.options.from,
449
+ from_percent: 0,
450
+ from_value: null,
451
+
452
+ to: this.options.to,
453
+ to_percent: 0,
454
+ to_value: null
455
+ };
456
+
457
+
458
+
459
+ this.init();
460
+ };
461
+
462
+ IonRangeSlider.prototype = {
463
+
464
+ /**
465
+ * Starts or updates the plugin instance
466
+ *
467
+ * @param [is_update] {boolean}
468
+ */
469
+ init: function (is_update) {
470
+ this.no_diapason = false;
471
+ this.coords.p_step = this.convertToPercent(this.options.step, true);
472
+
473
+ this.target = "base";
474
+
475
+ this.toggleInput();
476
+ this.append();
477
+ this.setMinMax();
478
+
479
+ if (is_update) {
480
+ this.force_redraw = true;
481
+ this.calc(true);
482
+
483
+ // callbacks called
484
+ this.callOnUpdate();
485
+ } else {
486
+ this.force_redraw = true;
487
+ this.calc(true);
488
+
489
+ // callbacks called
490
+ this.callOnStart();
491
+ }
492
+
493
+ this.updateScene();
494
+ },
495
+
496
+ /**
497
+ * Appends slider template to a DOM
498
+ */
499
+ append: function () {
500
+ var container_html = '<span class="irs js-irs-' + this.plugin_count + '"></span>';
501
+ this.$cache.input.before(container_html);
502
+ this.$cache.input.prop("readonly", true);
503
+ this.$cache.cont = this.$cache.input.prev();
504
+ this.result.slider = this.$cache.cont;
505
+
506
+ this.$cache.cont.html(base_html);
507
+ this.$cache.rs = this.$cache.cont.find(".irs");
508
+ this.$cache.min = this.$cache.cont.find(".irs-min");
509
+ this.$cache.max = this.$cache.cont.find(".irs-max");
510
+ this.$cache.from = this.$cache.cont.find(".irs-from");
511
+ this.$cache.to = this.$cache.cont.find(".irs-to");
512
+ this.$cache.single = this.$cache.cont.find(".irs-single");
513
+ this.$cache.bar = this.$cache.cont.find(".irs-bar");
514
+ this.$cache.line = this.$cache.cont.find(".irs-line");
515
+ this.$cache.grid = this.$cache.cont.find(".irs-grid");
516
+
517
+ if (this.options.type === "single") {
518
+ this.$cache.cont.append(single_html);
519
+ this.$cache.edge = this.$cache.cont.find(".irs-bar-edge");
520
+ this.$cache.s_single = this.$cache.cont.find(".single");
521
+ this.$cache.from[0].style.visibility = "hidden";
522
+ this.$cache.to[0].style.visibility = "hidden";
523
+ this.$cache.shad_single = this.$cache.cont.find(".shadow-single");
524
+ } else {
525
+ this.$cache.cont.append(double_html);
526
+ this.$cache.s_from = this.$cache.cont.find(".from");
527
+ this.$cache.s_to = this.$cache.cont.find(".to");
528
+ this.$cache.shad_from = this.$cache.cont.find(".shadow-from");
529
+ this.$cache.shad_to = this.$cache.cont.find(".shadow-to");
530
+
531
+ this.setTopHandler();
532
+ }
533
+
534
+ if (this.options.hide_from_to) {
535
+ this.$cache.from[0].style.display = "none";
536
+ this.$cache.to[0].style.display = "none";
537
+ this.$cache.single[0].style.display = "none";
538
+ }
539
+
540
+ this.appendGrid();
541
+
542
+ if (this.options.disable) {
543
+ this.appendDisableMask();
544
+ this.$cache.input[0].disabled = true;
545
+ } else {
546
+ this.$cache.cont.removeClass("irs-disabled");
547
+ this.$cache.input[0].disabled = false;
548
+ this.bindEvents();
549
+ }
550
+
551
+ if (this.options.drag_interval) {
552
+ this.$cache.bar[0].style.cursor = "ew-resize";
553
+ }
554
+ },
555
+
556
+ /**
557
+ * Determine which handler has a priority
558
+ * works only for double slider type
559
+ */
560
+ setTopHandler: function () {
561
+ var min = this.options.min,
562
+ max = this.options.max,
563
+ from = this.options.from,
564
+ to = this.options.to;
565
+
566
+ if (from > min && to === max) {
567
+ this.$cache.s_from.addClass("type_last");
568
+ } else if (to < max) {
569
+ this.$cache.s_to.addClass("type_last");
570
+ }
571
+ },
572
+
573
+ /**
574
+ * Determine which handles was clicked last
575
+ * and which handler should have hover effect
576
+ *
577
+ * @param target {String}
578
+ */
579
+ changeLevel: function (target) {
580
+ switch (target) {
581
+ case "single":
582
+ this.coords.p_gap = this.toFixed(this.coords.p_pointer - this.coords.p_single_fake);
583
+ break;
584
+ case "from":
585
+ this.coords.p_gap = this.toFixed(this.coords.p_pointer - this.coords.p_from_fake);
586
+ this.$cache.s_from.addClass("state_hover");
587
+ this.$cache.s_from.addClass("type_last");
588
+ this.$cache.s_to.removeClass("type_last");
589
+ break;
590
+ case "to":
591
+ this.coords.p_gap = this.toFixed(this.coords.p_pointer - this.coords.p_to_fake);
592
+ this.$cache.s_to.addClass("state_hover");
593
+ this.$cache.s_to.addClass("type_last");
594
+ this.$cache.s_from.removeClass("type_last");
595
+ break;
596
+ case "both":
597
+ this.coords.p_gap_left = this.toFixed(this.coords.p_pointer - this.coords.p_from_fake);
598
+ this.coords.p_gap_right = this.toFixed(this.coords.p_to_fake - this.coords.p_pointer);
599
+ this.$cache.s_to.removeClass("type_last");
600
+ this.$cache.s_from.removeClass("type_last");
601
+ break;
602
+ }
603
+ },
604
+
605
+ /**
606
+ * Then slider is disabled
607
+ * appends extra layer with opacity
608
+ */
609
+ appendDisableMask: function () {
610
+ this.$cache.cont.append(disable_html);
611
+ this.$cache.cont.addClass("irs-disabled");
612
+ },
613
+
614
+ /**
615
+ * Remove slider instance
616
+ * and ubind all events
617
+ */
618
+ remove: function () {
619
+ this.$cache.cont.remove();
620
+ this.$cache.cont = null;
621
+
622
+ this.$cache.line.off("keydown.irs_" + this.plugin_count);
623
+
624
+ this.$cache.body.off("touchmove.irs_" + this.plugin_count);
625
+ this.$cache.body.off("mousemove.irs_" + this.plugin_count);
626
+
627
+ this.$cache.win.off("touchend.irs_" + this.plugin_count);
628
+ this.$cache.win.off("mouseup.irs_" + this.plugin_count);
629
+
630
+ if (is_old_ie) {
631
+ this.$cache.body.off("mouseup.irs_" + this.plugin_count);
632
+ this.$cache.body.off("mouseleave.irs_" + this.plugin_count);
633
+ }
634
+
635
+ this.$cache.grid_labels = [];
636
+ this.coords.big = [];
637
+ this.coords.big_w = [];
638
+ this.coords.big_p = [];
639
+ this.coords.big_x = [];
640
+
641
+ cancelAnimationFrame(this.raf_id);
642
+ },
643
+
644
+ /**
645
+ * bind all slider events
646
+ */
647
+ bindEvents: function () {
648
+ if (this.no_diapason) {
649
+ return;
650
+ }
651
+
652
+ this.$cache.body.on("touchmove.irs_" + this.plugin_count, this.pointerMove.bind(this));
653
+ this.$cache.body.on("mousemove.irs_" + this.plugin_count, this.pointerMove.bind(this));
654
+
655
+ this.$cache.win.on("touchend.irs_" + this.plugin_count, this.pointerUp.bind(this));
656
+ this.$cache.win.on("mouseup.irs_" + this.plugin_count, this.pointerUp.bind(this));
657
+
658
+ this.$cache.line.on("touchstart.irs_" + this.plugin_count, this.pointerClick.bind(this, "click"));
659
+ this.$cache.line.on("mousedown.irs_" + this.plugin_count, this.pointerClick.bind(this, "click"));
660
+
661
+ if (this.options.drag_interval && this.options.type === "double") {
662
+ this.$cache.bar.on("touchstart.irs_" + this.plugin_count, this.pointerDown.bind(this, "both"));
663
+ this.$cache.bar.on("mousedown.irs_" + this.plugin_count, this.pointerDown.bind(this, "both"));
664
+ } else {
665
+ this.$cache.bar.on("touchstart.irs_" + this.plugin_count, this.pointerClick.bind(this, "click"));
666
+ this.$cache.bar.on("mousedown.irs_" + this.plugin_count, this.pointerClick.bind(this, "click"));
667
+ }
668
+
669
+ if (this.options.type === "single") {
670
+ this.$cache.single.on("touchstart.irs_" + this.plugin_count, this.pointerDown.bind(this, "single"));
671
+ this.$cache.s_single.on("touchstart.irs_" + this.plugin_count, this.pointerDown.bind(this, "single"));
672
+ this.$cache.shad_single.on("touchstart.irs_" + this.plugin_count, this.pointerClick.bind(this, "click"));
673
+
674
+ this.$cache.single.on("mousedown.irs_" + this.plugin_count, this.pointerDown.bind(this, "single"));
675
+ this.$cache.s_single.on("mousedown.irs_" + this.plugin_count, this.pointerDown.bind(this, "single"));
676
+ this.$cache.edge.on("mousedown.irs_" + this.plugin_count, this.pointerClick.bind(this, "click"));
677
+ this.$cache.shad_single.on("mousedown.irs_" + this.plugin_count, this.pointerClick.bind(this, "click"));
678
+ } else {
679
+ this.$cache.single.on("touchstart.irs_" + this.plugin_count, this.pointerDown.bind(this, null));
680
+ this.$cache.single.on("mousedown.irs_" + this.plugin_count, this.pointerDown.bind(this, null));
681
+
682
+ this.$cache.from.on("touchstart.irs_" + this.plugin_count, this.pointerDown.bind(this, "from"));
683
+ this.$cache.s_from.on("touchstart.irs_" + this.plugin_count, this.pointerDown.bind(this, "from"));
684
+ this.$cache.to.on("touchstart.irs_" + this.plugin_count, this.pointerDown.bind(this, "to"));
685
+ this.$cache.s_to.on("touchstart.irs_" + this.plugin_count, this.pointerDown.bind(this, "to"));
686
+ this.$cache.shad_from.on("touchstart.irs_" + this.plugin_count, this.pointerClick.bind(this, "click"));
687
+ this.$cache.shad_to.on("touchstart.irs_" + this.plugin_count, this.pointerClick.bind(this, "click"));
688
+
689
+ this.$cache.from.on("mousedown.irs_" + this.plugin_count, this.pointerDown.bind(this, "from"));
690
+ this.$cache.s_from.on("mousedown.irs_" + this.plugin_count, this.pointerDown.bind(this, "from"));
691
+ this.$cache.to.on("mousedown.irs_" + this.plugin_count, this.pointerDown.bind(this, "to"));
692
+ this.$cache.s_to.on("mousedown.irs_" + this.plugin_count, this.pointerDown.bind(this, "to"));
693
+ this.$cache.shad_from.on("mousedown.irs_" + this.plugin_count, this.pointerClick.bind(this, "click"));
694
+ this.$cache.shad_to.on("mousedown.irs_" + this.plugin_count, this.pointerClick.bind(this, "click"));
695
+ }
696
+
697
+ if (this.options.keyboard) {
698
+ this.$cache.line.on("keydown.irs_" + this.plugin_count, this.key.bind(this, "keyboard"));
699
+ }
700
+
701
+ if (is_old_ie) {
702
+ this.$cache.body.on("mouseup.irs_" + this.plugin_count, this.pointerUp.bind(this));
703
+ this.$cache.body.on("mouseleave.irs_" + this.plugin_count, this.pointerUp.bind(this));
704
+ }
705
+ },
706
+
707
+ /**
708
+ * Mousemove or touchmove
709
+ * only for handlers
710
+ *
711
+ * @param e {Object} event object
712
+ */
713
+ pointerMove: function (e) {
714
+ if (!this.dragging) {
715
+ return;
716
+ }
717
+
718
+ var x = e.pageX || e.originalEvent.touches && e.originalEvent.touches[0].pageX;
719
+ this.coords.x_pointer = x - this.coords.x_gap;
720
+
721
+ this.calc();
722
+ },
723
+
724
+ /**
725
+ * Mouseup or touchend
726
+ * only for handlers
727
+ *
728
+ * @param e {Object} event object
729
+ */
730
+ pointerUp: function (e) {
731
+ if (this.current_plugin !== this.plugin_count) {
732
+ return;
733
+ }
734
+
735
+ if (this.is_active) {
736
+ this.is_active = false;
737
+ } else {
738
+ return;
739
+ }
740
+
741
+ this.$cache.cont.find(".state_hover").removeClass("state_hover");
742
+
743
+ this.force_redraw = true;
744
+
745
+ if (is_old_ie) {
746
+ $("*").prop("unselectable", false);
747
+ }
748
+
749
+ this.updateScene();
750
+ this.restoreOriginalMinInterval();
751
+
752
+ // callbacks call
753
+ if ($.contains(this.$cache.cont[0], e.target) || this.dragging) {
754
+ this.callOnFinish();
755
+ }
756
+
757
+ this.dragging = false;
758
+ },
759
+
760
+ /**
761
+ * Mousedown or touchstart
762
+ * only for handlers
763
+ *
764
+ * @param target {String|null}
765
+ * @param e {Object} event object
766
+ */
767
+ pointerDown: function (target, e) {
768
+ e.preventDefault();
769
+ var x = e.pageX || e.originalEvent.touches && e.originalEvent.touches[0].pageX;
770
+ if (e.button === 2) {
771
+ return;
772
+ }
773
+
774
+ if (target === "both") {
775
+ this.setTempMinInterval();
776
+ }
777
+
778
+ if (!target) {
779
+ target = this.target || "from";
780
+ }
781
+
782
+ this.current_plugin = this.plugin_count;
783
+ this.target = target;
784
+
785
+ this.is_active = true;
786
+ this.dragging = true;
787
+
788
+ this.coords.x_gap = this.$cache.rs.offset().left;
789
+ this.coords.x_pointer = x - this.coords.x_gap;
790
+
791
+ this.calcPointerPercent();
792
+ this.changeLevel(target);
793
+
794
+ if (is_old_ie) {
795
+ $("*").prop("unselectable", true);
796
+ }
797
+
798
+ this.$cache.line.trigger("focus");
799
+
800
+ this.updateScene();
801
+ },
802
+
803
+ /**
804
+ * Mousedown or touchstart
805
+ * for other slider elements, like diapason line
806
+ *
807
+ * @param target {String}
808
+ * @param e {Object} event object
809
+ */
810
+ pointerClick: function (target, e) {
811
+ e.preventDefault();
812
+ var x = e.pageX || e.originalEvent.touches && e.originalEvent.touches[0].pageX;
813
+ if (e.button === 2) {
814
+ return;
815
+ }
816
+
817
+ this.current_plugin = this.plugin_count;
818
+ this.target = target;
819
+
820
+ this.is_click = true;
821
+ this.coords.x_gap = this.$cache.rs.offset().left;
822
+ this.coords.x_pointer = +(x - this.coords.x_gap).toFixed();
823
+
824
+ this.force_redraw = true;
825
+ this.calc();
826
+
827
+ this.$cache.line.trigger("focus");
828
+ },
829
+
830
+ /**
831
+ * Keyborard controls for focused slider
832
+ *
833
+ * @param target {String}
834
+ * @param e {Object} event object
835
+ * @returns {boolean|undefined}
836
+ */
837
+ key: function (target, e) {
838
+ if (this.current_plugin !== this.plugin_count || e.altKey || e.ctrlKey || e.shiftKey || e.metaKey) {
839
+ return;
840
+ }
841
+
842
+ switch (e.which) {
843
+ case 83: // W
844
+ case 65: // A
845
+ case 40: // DOWN
846
+ case 37: // LEFT
847
+ e.preventDefault();
848
+ this.moveByKey(false);
849
+ break;
850
+
851
+ case 87: // S
852
+ case 68: // D
853
+ case 38: // UP
854
+ case 39: // RIGHT
855
+ e.preventDefault();
856
+ this.moveByKey(true);
857
+ break;
858
+ }
859
+
860
+ return true;
861
+ },
862
+
863
+ /**
864
+ * Move by key. Beta
865
+ * @todo refactor than have plenty of time
866
+ *
867
+ * @param right {boolean} direction to move
868
+ */
869
+ moveByKey: function (right) {
870
+ var p = this.coords.p_pointer;
871
+
872
+ if (right) {
873
+ p += this.options.keyboard_step;
874
+ } else {
875
+ p -= this.options.keyboard_step;
876
+ }
877
+
878
+ this.coords.x_pointer = this.toFixed(this.coords.w_rs / 100 * p);
879
+ this.is_key = true;
880
+ this.calc();
881
+ },
882
+
883
+ /**
884
+ * Set visibility and content
885
+ * of Min and Max labels
886
+ */
887
+ setMinMax: function () {
888
+ if (!this.options) {
889
+ return;
890
+ }
891
+
892
+ if (this.options.hide_min_max) {
893
+ this.$cache.min[0].style.display = "none";
894
+ this.$cache.max[0].style.display = "none";
895
+ return;
896
+ }
897
+
898
+ if (this.options.values.length) {
899
+ this.$cache.min.html(this.decorate(this.options.p_values[this.options.min]));
900
+ this.$cache.max.html(this.decorate(this.options.p_values[this.options.max]));
901
+ } else {
902
+ this.$cache.min.html(this.decorate(this._prettify(this.options.min), this.options.min));
903
+ this.$cache.max.html(this.decorate(this._prettify(this.options.max), this.options.max));
904
+ }
905
+
906
+ this.labels.w_min = this.$cache.min.outerWidth(false);
907
+ this.labels.w_max = this.$cache.max.outerWidth(false);
908
+ },
909
+
910
+ /**
911
+ * Then dragging interval, prevent interval collapsing
912
+ * using min_interval option
913
+ */
914
+ setTempMinInterval: function () {
915
+ var interval = this.result.to - this.result.from;
916
+
917
+ if (this.old_min_interval === null) {
918
+ this.old_min_interval = this.options.min_interval;
919
+ }
920
+
921
+ this.options.min_interval = interval;
922
+ },
923
+
924
+ /**
925
+ * Restore min_interval option to original
926
+ */
927
+ restoreOriginalMinInterval: function () {
928
+ if (this.old_min_interval !== null) {
929
+ this.options.min_interval = this.old_min_interval;
930
+ this.old_min_interval = null;
931
+ }
932
+ },
933
+
934
+
935
+
936
+ // =============================================================================================================
937
+ // Calculations
938
+
939
+ /**
940
+ * All calculations and measures start here
941
+ *
942
+ * @param update {boolean=}
943
+ */
944
+ calc: function (update) {
945
+ if (!this.options) {
946
+ return;
947
+ }
948
+
949
+ this.calc_count++;
950
+
951
+ if (this.calc_count === 10 || update) {
952
+ this.calc_count = 0;
953
+ this.coords.w_rs = this.$cache.rs.outerWidth(false);
954
+
955
+ this.calcHandlePercent();
956
+ }
957
+
958
+ if (!this.coords.w_rs) {
959
+ return;
960
+ }
961
+
962
+ this.calcPointerPercent();
963
+ var handle_x = this.getHandleX();
964
+
965
+
966
+ if (this.target === "both") {
967
+ this.coords.p_gap = 0;
968
+ handle_x = this.getHandleX();
969
+ }
970
+
971
+ if (this.target === "click") {
972
+ this.coords.p_gap = this.coords.p_handle / 2;
973
+ handle_x = this.getHandleX();
974
+
975
+ if (this.options.drag_interval) {
976
+ this.target = "both_one";
977
+ } else {
978
+ this.target = this.chooseHandle(handle_x);
979
+ }
980
+ }
981
+
982
+ switch (this.target) {
983
+ case "base":
984
+ var w = (this.options.max - this.options.min) / 100,
985
+ f = (this.result.from - this.options.min) / w,
986
+ t = (this.result.to - this.options.min) / w;
987
+
988
+ this.coords.p_single_real = this.toFixed(f);
989
+ this.coords.p_from_real = this.toFixed(f);
990
+ this.coords.p_to_real = this.toFixed(t);
991
+
992
+ this.coords.p_single_real = this.checkDiapason(this.coords.p_single_real, this.options.from_min, this.options.from_max);
993
+ this.coords.p_from_real = this.checkDiapason(this.coords.p_from_real, this.options.from_min, this.options.from_max);
994
+ this.coords.p_to_real = this.checkDiapason(this.coords.p_to_real, this.options.to_min, this.options.to_max);
995
+
996
+ this.coords.p_single_fake = this.convertToFakePercent(this.coords.p_single_real);
997
+ this.coords.p_from_fake = this.convertToFakePercent(this.coords.p_from_real);
998
+ this.coords.p_to_fake = this.convertToFakePercent(this.coords.p_to_real);
999
+
1000
+ this.target = null;
1001
+
1002
+ break;
1003
+
1004
+ case "single":
1005
+ if (this.options.from_fixed) {
1006
+ break;
1007
+ }
1008
+
1009
+ this.coords.p_single_real = this.convertToRealPercent(handle_x);
1010
+ this.coords.p_single_real = this.calcWithStep(this.coords.p_single_real);
1011
+ this.coords.p_single_real = this.checkDiapason(this.coords.p_single_real, this.options.from_min, this.options.from_max);
1012
+
1013
+ this.coords.p_single_fake = this.convertToFakePercent(this.coords.p_single_real);
1014
+
1015
+ break;
1016
+
1017
+ case "from":
1018
+ if (this.options.from_fixed) {
1019
+ break;
1020
+ }
1021
+
1022
+ this.coords.p_from_real = this.convertToRealPercent(handle_x);
1023
+ this.coords.p_from_real = this.calcWithStep(this.coords.p_from_real);
1024
+ if (this.coords.p_from_real > this.coords.p_to_real) {
1025
+ this.coords.p_from_real = this.coords.p_to_real;
1026
+ }
1027
+ this.coords.p_from_real = this.checkDiapason(this.coords.p_from_real, this.options.from_min, this.options.from_max);
1028
+ this.coords.p_from_real = this.checkMinInterval(this.coords.p_from_real, this.coords.p_to_real, "from");
1029
+ this.coords.p_from_real = this.checkMaxInterval(this.coords.p_from_real, this.coords.p_to_real, "from");
1030
+
1031
+ this.coords.p_from_fake = this.convertToFakePercent(this.coords.p_from_real);
1032
+
1033
+ break;
1034
+
1035
+ case "to":
1036
+ if (this.options.to_fixed) {
1037
+ break;
1038
+ }
1039
+
1040
+ this.coords.p_to_real = this.convertToRealPercent(handle_x);
1041
+ this.coords.p_to_real = this.calcWithStep(this.coords.p_to_real);
1042
+ if (this.coords.p_to_real < this.coords.p_from_real) {
1043
+ this.coords.p_to_real = this.coords.p_from_real;
1044
+ }
1045
+ this.coords.p_to_real = this.checkDiapason(this.coords.p_to_real, this.options.to_min, this.options.to_max);
1046
+ this.coords.p_to_real = this.checkMinInterval(this.coords.p_to_real, this.coords.p_from_real, "to");
1047
+ this.coords.p_to_real = this.checkMaxInterval(this.coords.p_to_real, this.coords.p_from_real, "to");
1048
+
1049
+ this.coords.p_to_fake = this.convertToFakePercent(this.coords.p_to_real);
1050
+
1051
+ break;
1052
+
1053
+ case "both":
1054
+ if (this.options.from_fixed || this.options.to_fixed) {
1055
+ break;
1056
+ }
1057
+
1058
+ handle_x = this.toFixed(handle_x + (this.coords.p_handle * 0.001));
1059
+
1060
+ this.coords.p_from_real = this.convertToRealPercent(handle_x) - this.coords.p_gap_left;
1061
+ this.coords.p_from_real = this.calcWithStep(this.coords.p_from_real);
1062
+ this.coords.p_from_real = this.checkDiapason(this.coords.p_from_real, this.options.from_min, this.options.from_max);
1063
+ this.coords.p_from_real = this.checkMinInterval(this.coords.p_from_real, this.coords.p_to_real, "from");
1064
+ this.coords.p_from_fake = this.convertToFakePercent(this.coords.p_from_real);
1065
+
1066
+ this.coords.p_to_real = this.convertToRealPercent(handle_x) + this.coords.p_gap_right;
1067
+ this.coords.p_to_real = this.calcWithStep(this.coords.p_to_real);
1068
+ this.coords.p_to_real = this.checkDiapason(this.coords.p_to_real, this.options.to_min, this.options.to_max);
1069
+ this.coords.p_to_real = this.checkMinInterval(this.coords.p_to_real, this.coords.p_from_real, "to");
1070
+ this.coords.p_to_fake = this.convertToFakePercent(this.coords.p_to_real);
1071
+
1072
+ break;
1073
+
1074
+ case "both_one":
1075
+ if (this.options.from_fixed || this.options.to_fixed) {
1076
+ break;
1077
+ }
1078
+
1079
+ var real_x = this.convertToRealPercent(handle_x),
1080
+ from = this.result.from_percent,
1081
+ to = this.result.to_percent,
1082
+ full = to - from,
1083
+ half = full / 2,
1084
+ new_from = real_x - half,
1085
+ new_to = real_x + half;
1086
+
1087
+ if (new_from < 0) {
1088
+ new_from = 0;
1089
+ new_to = new_from + full;
1090
+ }
1091
+
1092
+ if (new_to > 100) {
1093
+ new_to = 100;
1094
+ new_from = new_to - full;
1095
+ }
1096
+
1097
+ this.coords.p_from_real = this.calcWithStep(new_from);
1098
+ this.coords.p_from_real = this.checkDiapason(this.coords.p_from_real, this.options.from_min, this.options.from_max);
1099
+ this.coords.p_from_fake = this.convertToFakePercent(this.coords.p_from_real);
1100
+
1101
+ this.coords.p_to_real = this.calcWithStep(new_to);
1102
+ this.coords.p_to_real = this.checkDiapason(this.coords.p_to_real, this.options.to_min, this.options.to_max);
1103
+ this.coords.p_to_fake = this.convertToFakePercent(this.coords.p_to_real);
1104
+
1105
+ break;
1106
+ }
1107
+
1108
+ if (this.options.type === "single") {
1109
+ this.coords.p_bar_x = (this.coords.p_handle / 2);
1110
+ this.coords.p_bar_w = this.coords.p_single_fake;
1111
+
1112
+ this.result.from_percent = this.coords.p_single_real;
1113
+ this.result.from = this.convertToValue(this.coords.p_single_real);
1114
+
1115
+ if (this.options.values.length) {
1116
+ this.result.from_value = this.options.values[this.result.from];
1117
+ }
1118
+ } else {
1119
+ this.coords.p_bar_x = this.toFixed(this.coords.p_from_fake + (this.coords.p_handle / 2));
1120
+ this.coords.p_bar_w = this.toFixed(this.coords.p_to_fake - this.coords.p_from_fake);
1121
+
1122
+ this.result.from_percent = this.coords.p_from_real;
1123
+ this.result.from = this.convertToValue(this.coords.p_from_real);
1124
+ this.result.to_percent = this.coords.p_to_real;
1125
+ this.result.to = this.convertToValue(this.coords.p_to_real);
1126
+
1127
+ if (this.options.values.length) {
1128
+ this.result.from_value = this.options.values[this.result.from];
1129
+ this.result.to_value = this.options.values[this.result.to];
1130
+ }
1131
+ }
1132
+
1133
+ this.calcMinMax();
1134
+ this.calcLabels();
1135
+ },
1136
+
1137
+
1138
+ /**
1139
+ * calculates pointer X in percent
1140
+ */
1141
+ calcPointerPercent: function () {
1142
+ if (!this.coords.w_rs) {
1143
+ this.coords.p_pointer = 0;
1144
+ return;
1145
+ }
1146
+
1147
+ if (this.coords.x_pointer < 0 || isNaN(this.coords.x_pointer) ) {
1148
+ this.coords.x_pointer = 0;
1149
+ } else if (this.coords.x_pointer > this.coords.w_rs) {
1150
+ this.coords.x_pointer = this.coords.w_rs;
1151
+ }
1152
+
1153
+ this.coords.p_pointer = this.toFixed(this.coords.x_pointer / this.coords.w_rs * 100);
1154
+ },
1155
+
1156
+ convertToRealPercent: function (fake) {
1157
+ var full = 100 - this.coords.p_handle;
1158
+ return fake / full * 100;
1159
+ },
1160
+
1161
+ convertToFakePercent: function (real) {
1162
+ var full = 100 - this.coords.p_handle;
1163
+ return real / 100 * full;
1164
+ },
1165
+
1166
+ getHandleX: function () {
1167
+ var max = 100 - this.coords.p_handle,
1168
+ x = this.toFixed(this.coords.p_pointer - this.coords.p_gap);
1169
+
1170
+ if (x < 0) {
1171
+ x = 0;
1172
+ } else if (x > max) {
1173
+ x = max;
1174
+ }
1175
+
1176
+ return x;
1177
+ },
1178
+
1179
+ calcHandlePercent: function () {
1180
+ if (this.options.type === "single") {
1181
+ this.coords.w_handle = this.$cache.s_single.outerWidth(false);
1182
+ } else {
1183
+ this.coords.w_handle = this.$cache.s_from.outerWidth(false);
1184
+ }
1185
+
1186
+ this.coords.p_handle = this.toFixed(this.coords.w_handle / this.coords.w_rs * 100);
1187
+ },
1188
+
1189
+ /**
1190
+ * Find closest handle to pointer click
1191
+ *
1192
+ * @param real_x {Number}
1193
+ * @returns {String}
1194
+ */
1195
+ chooseHandle: function (real_x) {
1196
+ if (this.options.type === "single") {
1197
+ return "single";
1198
+ } else {
1199
+ var m_point = this.coords.p_from_real + ((this.coords.p_to_real - this.coords.p_from_real) / 2);
1200
+ if (real_x >= m_point) {
1201
+ return this.options.to_fixed ? "from" : "to";
1202
+ } else {
1203
+ return this.options.from_fixed ? "to" : "from";
1204
+ }
1205
+ }
1206
+ },
1207
+
1208
+ /**
1209
+ * Measure Min and Max labels width in percent
1210
+ */
1211
+ calcMinMax: function () {
1212
+ if (!this.coords.w_rs) {
1213
+ return;
1214
+ }
1215
+
1216
+ this.labels.p_min = this.labels.w_min / this.coords.w_rs * 100;
1217
+ this.labels.p_max = this.labels.w_max / this.coords.w_rs * 100;
1218
+ },
1219
+
1220
+ /**
1221
+ * Measure labels width and X in percent
1222
+ */
1223
+ calcLabels: function () {
1224
+ if (!this.coords.w_rs || this.options.hide_from_to) {
1225
+ return;
1226
+ }
1227
+
1228
+ if (this.options.type === "single") {
1229
+
1230
+ this.labels.w_single = this.$cache.single.outerWidth(false);
1231
+ this.labels.p_single_fake = this.labels.w_single / this.coords.w_rs * 100;
1232
+ this.labels.p_single_left = this.coords.p_single_fake + (this.coords.p_handle / 2) - (this.labels.p_single_fake / 2);
1233
+ this.labels.p_single_left = this.checkEdges(this.labels.p_single_left, this.labels.p_single_fake);
1234
+
1235
+ } else {
1236
+
1237
+ this.labels.w_from = this.$cache.from.outerWidth(false);
1238
+ this.labels.p_from_fake = this.labels.w_from / this.coords.w_rs * 100;
1239
+ this.labels.p_from_left = this.coords.p_from_fake + (this.coords.p_handle / 2) - (this.labels.p_from_fake / 2);
1240
+ this.labels.p_from_left = this.toFixed(this.labels.p_from_left);
1241
+ this.labels.p_from_left = this.checkEdges(this.labels.p_from_left, this.labels.p_from_fake);
1242
+
1243
+ this.labels.w_to = this.$cache.to.outerWidth(false);
1244
+ this.labels.p_to_fake = this.labels.w_to / this.coords.w_rs * 100;
1245
+ this.labels.p_to_left = this.coords.p_to_fake + (this.coords.p_handle / 2) - (this.labels.p_to_fake / 2);
1246
+ this.labels.p_to_left = this.toFixed(this.labels.p_to_left);
1247
+ this.labels.p_to_left = this.checkEdges(this.labels.p_to_left, this.labels.p_to_fake);
1248
+
1249
+ this.labels.w_single = this.$cache.single.outerWidth(false);
1250
+ this.labels.p_single_fake = this.labels.w_single / this.coords.w_rs * 100;
1251
+ this.labels.p_single_left = ((this.labels.p_from_left + this.labels.p_to_left + this.labels.p_to_fake) / 2) - (this.labels.p_single_fake / 2);
1252
+ this.labels.p_single_left = this.toFixed(this.labels.p_single_left);
1253
+ this.labels.p_single_left = this.checkEdges(this.labels.p_single_left, this.labels.p_single_fake);
1254
+
1255
+ }
1256
+ },
1257
+
1258
+
1259
+
1260
+ // =============================================================================================================
1261
+ // Drawings
1262
+
1263
+ /**
1264
+ * Main function called in request animation frame
1265
+ * to update everything
1266
+ */
1267
+ updateScene: function () {
1268
+ if (this.raf_id) {
1269
+ cancelAnimationFrame(this.raf_id);
1270
+ this.raf_id = null;
1271
+ }
1272
+
1273
+ clearTimeout(this.update_tm);
1274
+ this.update_tm = null;
1275
+
1276
+ if (!this.options) {
1277
+ return;
1278
+ }
1279
+
1280
+ this.drawHandles();
1281
+
1282
+ if (this.is_active) {
1283
+ this.raf_id = requestAnimationFrame(this.updateScene.bind(this));
1284
+ } else {
1285
+ this.update_tm = setTimeout(this.updateScene.bind(this), 300);
1286
+ }
1287
+ },
1288
+
1289
+ /**
1290
+ * Draw handles
1291
+ */
1292
+ drawHandles: function () {
1293
+ this.coords.w_rs = this.$cache.rs.outerWidth(false);
1294
+
1295
+ if (!this.coords.w_rs) {
1296
+ return;
1297
+ }
1298
+
1299
+ if (this.coords.w_rs !== this.coords.w_rs_old) {
1300
+ this.target = "base";
1301
+ this.is_resize = true;
1302
+ }
1303
+
1304
+ if (this.coords.w_rs !== this.coords.w_rs_old || this.force_redraw) {
1305
+ this.setMinMax();
1306
+ this.calc(true);
1307
+ this.drawLabels();
1308
+ if (this.options.grid) {
1309
+ this.calcGridMargin();
1310
+ this.calcGridLabels();
1311
+ }
1312
+ this.force_redraw = true;
1313
+ this.coords.w_rs_old = this.coords.w_rs;
1314
+ this.drawShadow();
1315
+ }
1316
+
1317
+ if (!this.coords.w_rs) {
1318
+ return;
1319
+ }
1320
+
1321
+ if (!this.dragging && !this.force_redraw && !this.is_key) {
1322
+ return;
1323
+ }
1324
+
1325
+ if (this.old_from !== this.result.from || this.old_to !== this.result.to || this.force_redraw || this.is_key) {
1326
+
1327
+ this.drawLabels();
1328
+
1329
+ this.$cache.bar[0].style.left = this.coords.p_bar_x + "%";
1330
+ this.$cache.bar[0].style.width = this.coords.p_bar_w + "%";
1331
+
1332
+ if (this.options.type === "single") {
1333
+ this.$cache.s_single[0].style.left = this.coords.p_single_fake + "%";
1334
+
1335
+ this.$cache.single[0].style.left = this.labels.p_single_left + "%";
1336
+ } else {
1337
+ this.$cache.s_from[0].style.left = this.coords.p_from_fake + "%";
1338
+ this.$cache.s_to[0].style.left = this.coords.p_to_fake + "%";
1339
+
1340
+ if (this.old_from !== this.result.from || this.force_redraw) {
1341
+ this.$cache.from[0].style.left = this.labels.p_from_left + "%";
1342
+ }
1343
+ if (this.old_to !== this.result.to || this.force_redraw) {
1344
+ this.$cache.to[0].style.left = this.labels.p_to_left + "%";
1345
+ }
1346
+
1347
+ this.$cache.single[0].style.left = this.labels.p_single_left + "%";
1348
+ }
1349
+
1350
+ this.writeToInput();
1351
+
1352
+ if ((this.old_from !== this.result.from || this.old_to !== this.result.to) && !this.is_start) {
1353
+ this.$cache.input.trigger("change");
1354
+ this.$cache.input.trigger("input");
1355
+ }
1356
+
1357
+ this.old_from = this.result.from;
1358
+ this.old_to = this.result.to;
1359
+
1360
+ // callbacks call
1361
+ if (!this.is_resize && !this.is_update && !this.is_start && !this.is_finish) {
1362
+ this.callOnChange();
1363
+ }
1364
+ if (this.is_key || this.is_click) {
1365
+ this.is_key = false;
1366
+ this.is_click = false;
1367
+ this.callOnFinish();
1368
+ }
1369
+
1370
+ this.is_update = false;
1371
+ this.is_resize = false;
1372
+ this.is_finish = false;
1373
+ }
1374
+
1375
+ this.is_start = false;
1376
+ this.is_key = false;
1377
+ this.is_click = false;
1378
+ this.force_redraw = false;
1379
+ },
1380
+
1381
+ /**
1382
+ * Draw labels
1383
+ * measure labels collisions
1384
+ * collapse close labels
1385
+ */
1386
+ drawLabels: function () {
1387
+ if (!this.options) {
1388
+ return;
1389
+ }
1390
+
1391
+ var values_num = this.options.values.length,
1392
+ p_values = this.options.p_values,
1393
+ text_single,
1394
+ text_from,
1395
+ text_to;
1396
+
1397
+ if (this.options.hide_from_to) {
1398
+ return;
1399
+ }
1400
+
1401
+ if (this.options.type === "single") {
1402
+
1403
+ if (values_num) {
1404
+ text_single = this.decorate(p_values[this.result.from]);
1405
+ this.$cache.single.html(text_single);
1406
+ } else {
1407
+ text_single = this.decorate(this._prettify(this.result.from), this.result.from);
1408
+ this.$cache.single.html(text_single);
1409
+ }
1410
+
1411
+ this.calcLabels();
1412
+
1413
+ if (this.labels.p_single_left < this.labels.p_min + 1) {
1414
+ this.$cache.min[0].style.visibility = "hidden";
1415
+ } else {
1416
+ this.$cache.min[0].style.visibility = "visible";
1417
+ }
1418
+
1419
+ if (this.labels.p_single_left + this.labels.p_single_fake > 100 - this.labels.p_max - 1) {
1420
+ this.$cache.max[0].style.visibility = "hidden";
1421
+ } else {
1422
+ this.$cache.max[0].style.visibility = "visible";
1423
+ }
1424
+
1425
+ } else {
1426
+
1427
+ if (values_num) {
1428
+
1429
+ if (this.options.decorate_both) {
1430
+ text_single = this.decorate(p_values[this.result.from]);
1431
+ text_single += this.options.values_separator;
1432
+ text_single += this.decorate(p_values[this.result.to]);
1433
+ } else {
1434
+ text_single = this.decorate(p_values[this.result.from] + this.options.values_separator + p_values[this.result.to]);
1435
+ }
1436
+ text_from = this.decorate(p_values[this.result.from]);
1437
+ text_to = this.decorate(p_values[this.result.to]);
1438
+
1439
+ this.$cache.single.html(text_single);
1440
+ this.$cache.from.html(text_from);
1441
+ this.$cache.to.html(text_to);
1442
+
1443
+ } else {
1444
+
1445
+ if (this.options.decorate_both) {
1446
+ text_single = this.decorate(this._prettify(this.result.from), this.result.from);
1447
+ text_single += this.options.values_separator;
1448
+ text_single += this.decorate(this._prettify(this.result.to), this.result.to);
1449
+ } else {
1450
+ text_single = this.decorate(this._prettify(this.result.from) + this.options.values_separator + this._prettify(this.result.to), this.result.to);
1451
+ }
1452
+ text_from = this.decorate(this._prettify(this.result.from), this.result.from);
1453
+ text_to = this.decorate(this._prettify(this.result.to), this.result.to);
1454
+
1455
+ this.$cache.single.html(text_single);
1456
+ this.$cache.from.html(text_from);
1457
+ this.$cache.to.html(text_to);
1458
+
1459
+ }
1460
+
1461
+ this.calcLabels();
1462
+
1463
+ var min = Math.min(this.labels.p_single_left, this.labels.p_from_left),
1464
+ single_left = this.labels.p_single_left + this.labels.p_single_fake,
1465
+ to_left = this.labels.p_to_left + this.labels.p_to_fake,
1466
+ max = Math.max(single_left, to_left);
1467
+
1468
+ if (this.labels.p_from_left + this.labels.p_from_fake >= this.labels.p_to_left) {
1469
+ this.$cache.from[0].style.visibility = "hidden";
1470
+ this.$cache.to[0].style.visibility = "hidden";
1471
+ this.$cache.single[0].style.visibility = "visible";
1472
+
1473
+ if (this.result.from === this.result.to) {
1474
+ if (this.target === "from") {
1475
+ this.$cache.from[0].style.visibility = "visible";
1476
+ } else if (this.target === "to") {
1477
+ this.$cache.to[0].style.visibility = "visible";
1478
+ } else if (!this.target) {
1479
+ this.$cache.from[0].style.visibility = "visible";
1480
+ }
1481
+ this.$cache.single[0].style.visibility = "hidden";
1482
+ max = to_left;
1483
+ } else {
1484
+ this.$cache.from[0].style.visibility = "hidden";
1485
+ this.$cache.to[0].style.visibility = "hidden";
1486
+ this.$cache.single[0].style.visibility = "visible";
1487
+ max = Math.max(single_left, to_left);
1488
+ }
1489
+ } else {
1490
+ this.$cache.from[0].style.visibility = "visible";
1491
+ this.$cache.to[0].style.visibility = "visible";
1492
+ this.$cache.single[0].style.visibility = "hidden";
1493
+ }
1494
+
1495
+ if (min < this.labels.p_min + 1) {
1496
+ this.$cache.min[0].style.visibility = "hidden";
1497
+ } else {
1498
+ this.$cache.min[0].style.visibility = "visible";
1499
+ }
1500
+
1501
+ if (max > 100 - this.labels.p_max - 1) {
1502
+ this.$cache.max[0].style.visibility = "hidden";
1503
+ } else {
1504
+ this.$cache.max[0].style.visibility = "visible";
1505
+ }
1506
+
1507
+ }
1508
+ },
1509
+
1510
+ /**
1511
+ * Draw shadow intervals
1512
+ */
1513
+ drawShadow: function () {
1514
+ var o = this.options,
1515
+ c = this.$cache,
1516
+
1517
+ is_from_min = typeof o.from_min === "number" && !isNaN(o.from_min),
1518
+ is_from_max = typeof o.from_max === "number" && !isNaN(o.from_max),
1519
+ is_to_min = typeof o.to_min === "number" && !isNaN(o.to_min),
1520
+ is_to_max = typeof o.to_max === "number" && !isNaN(o.to_max),
1521
+
1522
+ from_min,
1523
+ from_max,
1524
+ to_min,
1525
+ to_max;
1526
+
1527
+ if (o.type === "single") {
1528
+ if (o.from_shadow && (is_from_min || is_from_max)) {
1529
+ from_min = this.convertToPercent(is_from_min ? o.from_min : o.min);
1530
+ from_max = this.convertToPercent(is_from_max ? o.from_max : o.max) - from_min;
1531
+ from_min = this.toFixed(from_min - (this.coords.p_handle / 100 * from_min));
1532
+ from_max = this.toFixed(from_max - (this.coords.p_handle / 100 * from_max));
1533
+ from_min = from_min + (this.coords.p_handle / 2);
1534
+
1535
+ c.shad_single[0].style.display = "block";
1536
+ c.shad_single[0].style.left = from_min + "%";
1537
+ c.shad_single[0].style.width = from_max + "%";
1538
+ } else {
1539
+ c.shad_single[0].style.display = "none";
1540
+ }
1541
+ } else {
1542
+ if (o.from_shadow && (is_from_min || is_from_max)) {
1543
+ from_min = this.convertToPercent(is_from_min ? o.from_min : o.min);
1544
+ from_max = this.convertToPercent(is_from_max ? o.from_max : o.max) - from_min;
1545
+ from_min = this.toFixed(from_min - (this.coords.p_handle / 100 * from_min));
1546
+ from_max = this.toFixed(from_max - (this.coords.p_handle / 100 * from_max));
1547
+ from_min = from_min + (this.coords.p_handle / 2);
1548
+
1549
+ c.shad_from[0].style.display = "block";
1550
+ c.shad_from[0].style.left = from_min + "%";
1551
+ c.shad_from[0].style.width = from_max + "%";
1552
+ } else {
1553
+ c.shad_from[0].style.display = "none";
1554
+ }
1555
+
1556
+ if (o.to_shadow && (is_to_min || is_to_max)) {
1557
+ to_min = this.convertToPercent(is_to_min ? o.to_min : o.min);
1558
+ to_max = this.convertToPercent(is_to_max ? o.to_max : o.max) - to_min;
1559
+ to_min = this.toFixed(to_min - (this.coords.p_handle / 100 * to_min));
1560
+ to_max = this.toFixed(to_max - (this.coords.p_handle / 100 * to_max));
1561
+ to_min = to_min + (this.coords.p_handle / 2);
1562
+
1563
+ c.shad_to[0].style.display = "block";
1564
+ c.shad_to[0].style.left = to_min + "%";
1565
+ c.shad_to[0].style.width = to_max + "%";
1566
+ } else {
1567
+ c.shad_to[0].style.display = "none";
1568
+ }
1569
+ }
1570
+ },
1571
+
1572
+
1573
+
1574
+ /**
1575
+ * Write values to input element
1576
+ */
1577
+ writeToInput: function () {
1578
+ if (this.options.type === "single") {
1579
+ if (this.options.values.length) {
1580
+ this.$cache.input.prop("value", this.result.from_value);
1581
+ } else {
1582
+ this.$cache.input.prop("value", this.result.from);
1583
+ }
1584
+ this.$cache.input.data("from", this.result.from);
1585
+ } else {
1586
+ if (this.options.values.length) {
1587
+ this.$cache.input.prop("value", this.result.from_value + this.options.input_values_separator + this.result.to_value);
1588
+ } else {
1589
+ this.$cache.input.prop("value", this.result.from + this.options.input_values_separator + this.result.to);
1590
+ }
1591
+ this.$cache.input.data("from", this.result.from);
1592
+ this.$cache.input.data("to", this.result.to);
1593
+ }
1594
+ },
1595
+
1596
+
1597
+
1598
+ // =============================================================================================================
1599
+ // Callbacks
1600
+
1601
+ callOnStart: function () {
1602
+ this.writeToInput();
1603
+
1604
+ if (this.options.onStart && typeof this.options.onStart === "function") {
1605
+ this.options.onStart(this.result);
1606
+ }
1607
+ },
1608
+ callOnChange: function () {
1609
+ this.writeToInput();
1610
+
1611
+ if (this.options.onChange && typeof this.options.onChange === "function") {
1612
+ this.options.onChange(this.result);
1613
+ }
1614
+ },
1615
+ callOnFinish: function () {
1616
+ this.writeToInput();
1617
+
1618
+ if (this.options.onFinish && typeof this.options.onFinish === "function") {
1619
+ this.options.onFinish(this.result);
1620
+ }
1621
+ },
1622
+ callOnUpdate: function () {
1623
+ this.writeToInput();
1624
+
1625
+ if (this.options.onUpdate && typeof this.options.onUpdate === "function") {
1626
+ this.options.onUpdate(this.result);
1627
+ }
1628
+ },
1629
+
1630
+
1631
+
1632
+
1633
+ // =============================================================================================================
1634
+ // Service methods
1635
+
1636
+ toggleInput: function () {
1637
+ this.$cache.input.toggleClass("irs-hidden-input");
1638
+ },
1639
+
1640
+ /**
1641
+ * Convert real value to percent
1642
+ *
1643
+ * @param value {Number} X in real
1644
+ * @param no_min {boolean=} don't use min value
1645
+ * @returns {Number} X in percent
1646
+ */
1647
+ convertToPercent: function (value, no_min) {
1648
+ var diapason = this.options.max - this.options.min,
1649
+ one_percent = diapason / 100,
1650
+ val, percent;
1651
+
1652
+ if (!diapason) {
1653
+ this.no_diapason = true;
1654
+ return 0;
1655
+ }
1656
+
1657
+ if (no_min) {
1658
+ val = value;
1659
+ } else {
1660
+ val = value - this.options.min;
1661
+ }
1662
+
1663
+ percent = val / one_percent;
1664
+
1665
+ return this.toFixed(percent);
1666
+ },
1667
+
1668
+ /**
1669
+ * Convert percent to real values
1670
+ *
1671
+ * @param percent {Number} X in percent
1672
+ * @returns {Number} X in real
1673
+ */
1674
+ convertToValue: function (percent) {
1675
+ var min = this.options.min,
1676
+ max = this.options.max,
1677
+ min_decimals = min.toString().split(".")[1],
1678
+ max_decimals = max.toString().split(".")[1],
1679
+ min_length, max_length,
1680
+ avg_decimals = 0,
1681
+ abs = 0;
1682
+
1683
+ if (percent === 0) {
1684
+ return this.options.min;
1685
+ }
1686
+ if (percent === 100) {
1687
+ return this.options.max;
1688
+ }
1689
+
1690
+
1691
+ if (min_decimals) {
1692
+ min_length = min_decimals.length;
1693
+ avg_decimals = min_length;
1694
+ }
1695
+ if (max_decimals) {
1696
+ max_length = max_decimals.length;
1697
+ avg_decimals = max_length;
1698
+ }
1699
+ if (min_length && max_length) {
1700
+ avg_decimals = (min_length >= max_length) ? min_length : max_length;
1701
+ }
1702
+
1703
+ if (min < 0) {
1704
+ abs = Math.abs(min);
1705
+ min = +(min + abs).toFixed(avg_decimals);
1706
+ max = +(max + abs).toFixed(avg_decimals);
1707
+ }
1708
+
1709
+ var number = ((max - min) / 100 * percent) + min,
1710
+ string = this.options.step.toString().split(".")[1],
1711
+ result;
1712
+
1713
+ if (string) {
1714
+ number = +number.toFixed(string.length);
1715
+ } else {
1716
+ number = number / this.options.step;
1717
+ number = number * this.options.step;
1718
+
1719
+ number = +number.toFixed(0);
1720
+ }
1721
+
1722
+ if (abs) {
1723
+ number -= abs;
1724
+ }
1725
+
1726
+ if (string) {
1727
+ result = +number.toFixed(string.length);
1728
+ } else {
1729
+ result = this.toFixed(number);
1730
+ }
1731
+
1732
+ if (result < this.options.min) {
1733
+ result = this.options.min;
1734
+ } else if (result > this.options.max) {
1735
+ result = this.options.max;
1736
+ }
1737
+
1738
+ return result;
1739
+ },
1740
+
1741
+ /**
1742
+ * Round percent value with step
1743
+ *
1744
+ * @param percent {Number}
1745
+ * @returns percent {Number} rounded
1746
+ */
1747
+ calcWithStep: function (percent) {
1748
+ var rounded = Math.round(percent / this.coords.p_step) * this.coords.p_step;
1749
+
1750
+ if (rounded > 100) {
1751
+ rounded = 100;
1752
+ }
1753
+ if (percent === 100) {
1754
+ rounded = 100;
1755
+ }
1756
+
1757
+ return this.toFixed(rounded);
1758
+ },
1759
+
1760
+ checkMinInterval: function (p_current, p_next, type) {
1761
+ var o = this.options,
1762
+ current,
1763
+ next;
1764
+
1765
+ if (!o.min_interval) {
1766
+ return p_current;
1767
+ }
1768
+
1769
+ current = this.convertToValue(p_current);
1770
+ next = this.convertToValue(p_next);
1771
+
1772
+ if (type === "from") {
1773
+
1774
+ if (next - current < o.min_interval) {
1775
+ current = next - o.min_interval;
1776
+ }
1777
+
1778
+ } else {
1779
+
1780
+ if (current - next < o.min_interval) {
1781
+ current = next + o.min_interval;
1782
+ }
1783
+
1784
+ }
1785
+
1786
+ return this.convertToPercent(current);
1787
+ },
1788
+
1789
+ checkMaxInterval: function (p_current, p_next, type) {
1790
+ var o = this.options,
1791
+ current,
1792
+ next;
1793
+
1794
+ if (!o.max_interval) {
1795
+ return p_current;
1796
+ }
1797
+
1798
+ current = this.convertToValue(p_current);
1799
+ next = this.convertToValue(p_next);
1800
+
1801
+ if (type === "from") {
1802
+
1803
+ if (next - current > o.max_interval) {
1804
+ current = next - o.max_interval;
1805
+ }
1806
+
1807
+ } else {
1808
+
1809
+ if (current - next > o.max_interval) {
1810
+ current = next + o.max_interval;
1811
+ }
1812
+
1813
+ }
1814
+
1815
+ return this.convertToPercent(current);
1816
+ },
1817
+
1818
+ checkDiapason: function (p_num, min, max) {
1819
+ var num = this.convertToValue(p_num),
1820
+ o = this.options;
1821
+
1822
+ if (typeof min !== "number") {
1823
+ min = o.min;
1824
+ }
1825
+
1826
+ if (typeof max !== "number") {
1827
+ max = o.max;
1828
+ }
1829
+
1830
+ if (num < min) {
1831
+ num = min;
1832
+ }
1833
+
1834
+ if (num > max) {
1835
+ num = max;
1836
+ }
1837
+
1838
+ return this.convertToPercent(num);
1839
+ },
1840
+
1841
+ toFixed: function (num) {
1842
+ num = num.toFixed(20);
1843
+ return +num;
1844
+ },
1845
+
1846
+ _prettify: function (num) {
1847
+ if (!this.options.prettify_enabled) {
1848
+ return num;
1849
+ }
1850
+
1851
+ if (this.options.prettify && typeof this.options.prettify === "function") {
1852
+ return this.options.prettify(num);
1853
+ } else {
1854
+ return this.prettify(num);
1855
+ }
1856
+ },
1857
+
1858
+ prettify: function (num) {
1859
+ var n = num.toString();
1860
+ return n.replace(/(\d{1,3}(?=(?:\d\d\d)+(?!\d)))/g, "$1" + this.options.prettify_separator);
1861
+ },
1862
+
1863
+ checkEdges: function (left, width) {
1864
+ if (!this.options.force_edges) {
1865
+ return this.toFixed(left);
1866
+ }
1867
+
1868
+ if (left < 0) {
1869
+ left = 0;
1870
+ } else if (left > 100 - width) {
1871
+ left = 100 - width;
1872
+ }
1873
+
1874
+ return this.toFixed(left);
1875
+ },
1876
+
1877
+ validate: function () {
1878
+ var o = this.options,
1879
+ r = this.result,
1880
+ v = o.values,
1881
+ vl = v.length,
1882
+ value,
1883
+ i;
1884
+
1885
+ if (typeof o.min === "string") o.min = +o.min;
1886
+ if (typeof o.max === "string") o.max = +o.max;
1887
+ if (typeof o.from === "string") o.from = +o.from;
1888
+ if (typeof o.to === "string") o.to = +o.to;
1889
+ if (typeof o.step === "string") o.step = +o.step;
1890
+
1891
+ if (typeof o.from_min === "string") o.from_min = +o.from_min;
1892
+ if (typeof o.from_max === "string") o.from_max = +o.from_max;
1893
+ if (typeof o.to_min === "string") o.to_min = +o.to_min;
1894
+ if (typeof o.to_max === "string") o.to_max = +o.to_max;
1895
+
1896
+ if (typeof o.keyboard_step === "string") o.keyboard_step = +o.keyboard_step;
1897
+ if (typeof o.grid_num === "string") o.grid_num = +o.grid_num;
1898
+
1899
+ if (o.max < o.min) {
1900
+ o.max = o.min;
1901
+ }
1902
+
1903
+ if (vl) {
1904
+ o.p_values = [];
1905
+ o.min = 0;
1906
+ o.max = vl - 1;
1907
+ o.step = 1;
1908
+ o.grid_num = o.max;
1909
+ o.grid_snap = true;
1910
+
1911
+ for (i = 0; i < vl; i++) {
1912
+ value = +v[i];
1913
+
1914
+ if (!isNaN(value)) {
1915
+ v[i] = value;
1916
+ value = this._prettify(value);
1917
+ } else {
1918
+ value = v[i];
1919
+ }
1920
+
1921
+ o.p_values.push(value);
1922
+ }
1923
+ }
1924
+
1925
+ if (typeof o.from !== "number" || isNaN(o.from)) {
1926
+ o.from = o.min;
1927
+ }
1928
+
1929
+ if (typeof o.to !== "number" || isNaN(o.to)) {
1930
+ o.to = o.max;
1931
+ }
1932
+
1933
+ if (o.type === "single") {
1934
+
1935
+ if (o.from < o.min) o.from = o.min;
1936
+ if (o.from > o.max) o.from = o.max;
1937
+
1938
+ } else {
1939
+
1940
+ if (o.from < o.min) o.from = o.min;
1941
+ if (o.from > o.max) o.from = o.max;
1942
+
1943
+ if (o.to < o.min) o.to = o.min;
1944
+ if (o.to > o.max) o.to = o.max;
1945
+
1946
+ if (this.update_check.from) {
1947
+
1948
+ if (this.update_check.from !== o.from) {
1949
+ if (o.from > o.to) o.from = o.to;
1950
+ }
1951
+ if (this.update_check.to !== o.to) {
1952
+ if (o.to < o.from) o.to = o.from;
1953
+ }
1954
+
1955
+ }
1956
+
1957
+ if (o.from > o.to) o.from = o.to;
1958
+ if (o.to < o.from) o.to = o.from;
1959
+
1960
+ }
1961
+
1962
+ if (typeof o.step !== "number" || isNaN(o.step) || !o.step || o.step < 0) {
1963
+ o.step = 1;
1964
+ }
1965
+
1966
+ if (typeof o.keyboard_step !== "number" || isNaN(o.keyboard_step) || !o.keyboard_step || o.keyboard_step < 0) {
1967
+ o.keyboard_step = 5;
1968
+ }
1969
+
1970
+ if (typeof o.from_min === "number" && o.from < o.from_min) {
1971
+ o.from = o.from_min;
1972
+ }
1973
+
1974
+ if (typeof o.from_max === "number" && o.from > o.from_max) {
1975
+ o.from = o.from_max;
1976
+ }
1977
+
1978
+ if (typeof o.to_min === "number" && o.to < o.to_min) {
1979
+ o.to = o.to_min;
1980
+ }
1981
+
1982
+ if (typeof o.to_max === "number" && o.from > o.to_max) {
1983
+ o.to = o.to_max;
1984
+ }
1985
+
1986
+ if (r) {
1987
+ if (r.min !== o.min) {
1988
+ r.min = o.min;
1989
+ }
1990
+
1991
+ if (r.max !== o.max) {
1992
+ r.max = o.max;
1993
+ }
1994
+
1995
+ if (r.from < r.min || r.from > r.max) {
1996
+ r.from = o.from;
1997
+ }
1998
+
1999
+ if (r.to < r.min || r.to > r.max) {
2000
+ r.to = o.to;
2001
+ }
2002
+ }
2003
+
2004
+ if (typeof o.min_interval !== "number" || isNaN(o.min_interval) || !o.min_interval || o.min_interval < 0) {
2005
+ o.min_interval = 0;
2006
+ }
2007
+
2008
+ if (typeof o.max_interval !== "number" || isNaN(o.max_interval) || !o.max_interval || o.max_interval < 0) {
2009
+ o.max_interval = 0;
2010
+ }
2011
+
2012
+ if (o.min_interval && o.min_interval > o.max - o.min) {
2013
+ o.min_interval = o.max - o.min;
2014
+ }
2015
+
2016
+ if (o.max_interval && o.max_interval > o.max - o.min) {
2017
+ o.max_interval = o.max - o.min;
2018
+ }
2019
+ },
2020
+
2021
+ decorate: function (num, original) {
2022
+ var decorated = "",
2023
+ o = this.options;
2024
+
2025
+ if (o.prefix) {
2026
+ decorated += o.prefix;
2027
+ }
2028
+
2029
+ decorated += num;
2030
+
2031
+ if (o.max_postfix) {
2032
+ if (o.values.length && num === o.p_values[o.max]) {
2033
+ decorated += o.max_postfix;
2034
+ if (o.postfix) {
2035
+ decorated += " ";
2036
+ }
2037
+ } else if (original === o.max) {
2038
+ decorated += o.max_postfix;
2039
+ if (o.postfix) {
2040
+ decorated += " ";
2041
+ }
2042
+ }
2043
+ }
2044
+
2045
+ if (o.postfix) {
2046
+ decorated += o.postfix;
2047
+ }
2048
+
2049
+ return decorated;
2050
+ },
2051
+
2052
+ updateFrom: function () {
2053
+ this.result.from = this.options.from;
2054
+ this.result.from_percent = this.convertToPercent(this.result.from);
2055
+ if (this.options.values) {
2056
+ this.result.from_value = this.options.values[this.result.from];
2057
+ }
2058
+ },
2059
+
2060
+ updateTo: function () {
2061
+ this.result.to = this.options.to;
2062
+ this.result.to_percent = this.convertToPercent(this.result.to);
2063
+ if (this.options.values) {
2064
+ this.result.to_value = this.options.values[this.result.to];
2065
+ }
2066
+ },
2067
+
2068
+ updateResult: function () {
2069
+ this.result.min = this.options.min;
2070
+ this.result.max = this.options.max;
2071
+ this.updateFrom();
2072
+ this.updateTo();
2073
+ },
2074
+
2075
+
2076
+ // =============================================================================================================
2077
+ // Grid
2078
+
2079
+ appendGrid: function () {
2080
+ if (!this.options.grid) {
2081
+ return;
2082
+ }
2083
+
2084
+ var o = this.options,
2085
+ i, z,
2086
+
2087
+ total = o.max - o.min,
2088
+ big_num = o.grid_num,
2089
+ big_p = 0,
2090
+ big_w = 0,
2091
+
2092
+ small_max = 4,
2093
+ local_small_max,
2094
+ small_p,
2095
+ small_w = 0,
2096
+
2097
+ result,
2098
+ html = '';
2099
+
2100
+
2101
+
2102
+ this.calcGridMargin();
2103
+
2104
+ if (o.grid_snap) {
2105
+
2106
+ if (total > 50) {
2107
+ big_num = 50 / o.step;
2108
+ big_p = this.toFixed(o.step / 0.5);
2109
+ } else {
2110
+ big_num = total / o.step;
2111
+ big_p = this.toFixed(o.step / (total / 100));
2112
+ }
2113
+
2114
+ } else {
2115
+ big_p = this.toFixed(100 / big_num);
2116
+ }
2117
+
2118
+ if (big_num > 4) {
2119
+ small_max = 3;
2120
+ }
2121
+ if (big_num > 7) {
2122
+ small_max = 2;
2123
+ }
2124
+ if (big_num > 14) {
2125
+ small_max = 1;
2126
+ }
2127
+ if (big_num > 28) {
2128
+ small_max = 0;
2129
+ }
2130
+
2131
+ for (i = 0; i < big_num + 1; i++) {
2132
+ local_small_max = small_max;
2133
+
2134
+ big_w = this.toFixed(big_p * i);
2135
+
2136
+ if (big_w > 100) {
2137
+ big_w = 100;
2138
+
2139
+ local_small_max -= 2;
2140
+ if (local_small_max < 0) {
2141
+ local_small_max = 0;
2142
+ }
2143
+ }
2144
+ this.coords.big[i] = big_w;
2145
+
2146
+ small_p = (big_w - (big_p * (i - 1))) / (local_small_max + 1);
2147
+
2148
+ for (z = 1; z <= local_small_max; z++) {
2149
+ if (big_w === 0) {
2150
+ break;
2151
+ }
2152
+
2153
+ small_w = this.toFixed(big_w - (small_p * z));
2154
+
2155
+ html += '<span class="irs-grid-pol small" style="left: ' + small_w + '%"></span>';
2156
+ }
2157
+
2158
+ html += '<span class="irs-grid-pol" style="left: ' + big_w + '%"></span>';
2159
+
2160
+ result = this.convertToValue(big_w);
2161
+ if (o.values.length) {
2162
+ result = o.p_values[result];
2163
+ } else {
2164
+ result = this._prettify(result);
2165
+ }
2166
+
2167
+ html += '<span class="irs-grid-text js-grid-text-' + i + '" style="left: ' + big_w + '%">' + result + '</span>';
2168
+ }
2169
+ this.coords.big_num = Math.ceil(big_num + 1);
2170
+
2171
+
2172
+
2173
+ this.$cache.cont.addClass("irs-with-grid");
2174
+ this.$cache.grid.html(html);
2175
+ this.cacheGridLabels();
2176
+ },
2177
+
2178
+ cacheGridLabels: function () {
2179
+ var $label, i,
2180
+ num = this.coords.big_num;
2181
+
2182
+ for (i = 0; i < num; i++) {
2183
+ $label = this.$cache.grid.find(".js-grid-text-" + i);
2184
+ this.$cache.grid_labels.push($label);
2185
+ }
2186
+
2187
+ this.calcGridLabels();
2188
+ },
2189
+
2190
+ calcGridLabels: function () {
2191
+ var i, label, start = [], finish = [],
2192
+ num = this.coords.big_num;
2193
+
2194
+ for (i = 0; i < num; i++) {
2195
+ this.coords.big_w[i] = this.$cache.grid_labels[i].outerWidth(false);
2196
+ this.coords.big_p[i] = this.toFixed(this.coords.big_w[i] / this.coords.w_rs * 100);
2197
+ this.coords.big_x[i] = this.toFixed(this.coords.big_p[i] / 2);
2198
+
2199
+ start[i] = this.toFixed(this.coords.big[i] - this.coords.big_x[i]);
2200
+ finish[i] = this.toFixed(start[i] + this.coords.big_p[i]);
2201
+ }
2202
+
2203
+ if (this.options.force_edges) {
2204
+ if (start[0] < -this.coords.grid_gap) {
2205
+ start[0] = -this.coords.grid_gap;
2206
+ finish[0] = this.toFixed(start[0] + this.coords.big_p[0]);
2207
+
2208
+ this.coords.big_x[0] = this.coords.grid_gap;
2209
+ }
2210
+
2211
+ if (finish[num - 1] > 100 + this.coords.grid_gap) {
2212
+ finish[num - 1] = 100 + this.coords.grid_gap;
2213
+ start[num - 1] = this.toFixed(finish[num - 1] - this.coords.big_p[num - 1]);
2214
+
2215
+ this.coords.big_x[num - 1] = this.toFixed(this.coords.big_p[num - 1] - this.coords.grid_gap);
2216
+ }
2217
+ }
2218
+
2219
+ this.calcGridCollision(2, start, finish);
2220
+ this.calcGridCollision(4, start, finish);
2221
+
2222
+ for (i = 0; i < num; i++) {
2223
+ label = this.$cache.grid_labels[i][0];
2224
+
2225
+ if (this.coords.big_x[i] !== Number.POSITIVE_INFINITY) {
2226
+ label.style.marginLeft = -this.coords.big_x[i] + "%";
2227
+ }
2228
+ }
2229
+ },
2230
+
2231
+ // Collisions Calc Beta
2232
+ // TODO: Refactor then have plenty of time
2233
+ calcGridCollision: function (step, start, finish) {
2234
+ var i, next_i, label,
2235
+ num = this.coords.big_num;
2236
+
2237
+ for (i = 0; i < num; i += step) {
2238
+ next_i = i + (step / 2);
2239
+ if (next_i >= num) {
2240
+ break;
2241
+ }
2242
+
2243
+ label = this.$cache.grid_labels[next_i][0];
2244
+
2245
+ if (finish[i] <= start[next_i]) {
2246
+ label.style.visibility = "visible";
2247
+ } else {
2248
+ label.style.visibility = "hidden";
2249
+ }
2250
+ }
2251
+ },
2252
+
2253
+ calcGridMargin: function () {
2254
+ if (!this.options.grid_margin) {
2255
+ return;
2256
+ }
2257
+
2258
+ this.coords.w_rs = this.$cache.rs.outerWidth(false);
2259
+ if (!this.coords.w_rs) {
2260
+ return;
2261
+ }
2262
+
2263
+ if (this.options.type === "single") {
2264
+ this.coords.w_handle = this.$cache.s_single.outerWidth(false);
2265
+ } else {
2266
+ this.coords.w_handle = this.$cache.s_from.outerWidth(false);
2267
+ }
2268
+ this.coords.p_handle = this.toFixed(this.coords.w_handle / this.coords.w_rs * 100);
2269
+ this.coords.grid_gap = this.toFixed((this.coords.p_handle / 2) - 0.1);
2270
+
2271
+ this.$cache.grid[0].style.width = this.toFixed(100 - this.coords.p_handle) + "%";
2272
+ this.$cache.grid[0].style.left = this.coords.grid_gap + "%";
2273
+ },
2274
+
2275
+
2276
+
2277
+ // =============================================================================================================
2278
+ // Public methods
2279
+
2280
+ update: function (options) {
2281
+ if (!this.input) {
2282
+ return;
2283
+ }
2284
+
2285
+ this.is_update = true;
2286
+
2287
+ this.options.from = this.result.from;
2288
+ this.options.to = this.result.to;
2289
+ this.update_check.from = this.result.from;
2290
+ this.update_check.to = this.result.to;
2291
+
2292
+ this.options = $.extend(this.options, options);
2293
+ this.validate();
2294
+ this.updateResult(options);
2295
+
2296
+ this.toggleInput();
2297
+ this.remove();
2298
+ this.init(true);
2299
+ },
2300
+
2301
+ reset: function () {
2302
+ if (!this.input) {
2303
+ return;
2304
+ }
2305
+
2306
+ this.updateResult();
2307
+ this.update();
2308
+ },
2309
+
2310
+ destroy: function () {
2311
+ if (!this.input) {
2312
+ return;
2313
+ }
2314
+
2315
+ this.toggleInput();
2316
+ this.$cache.input.prop("readonly", false);
2317
+ $.data(this.input, "ionRangeSlider", null);
2318
+
2319
+ this.remove();
2320
+ this.input = null;
2321
+ this.options = null;
2322
+ }
2323
+ };
2324
+
2325
+ $.fn.ionRangeSlider = function (options) {
2326
+ return this.each(function() {
2327
+ if (!$.data(this, "ionRangeSlider")) {
2328
+ $.data(this, "ionRangeSlider", new IonRangeSlider(this, options, plugin_count++));
2329
+ }
2330
+ });
2331
+ };
2332
+
2333
+
2334
+
2335
+ // =================================================================================================================
2336
+ // http://paulirish.com/2011/requestanimationframe-for-smart-animating/
2337
+ // http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
2338
+
2339
+ // requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel
2340
+
2341
+ // MIT license
2342
+
2343
+ (function() {
2344
+ var lastTime = 0;
2345
+ var vendors = ['ms', 'moz', 'webkit', 'o'];
2346
+ for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
2347
+ window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
2348
+ window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']
2349
+ || window[vendors[x]+'CancelRequestAnimationFrame'];
2350
+ }
2351
+
2352
+ if (!window.requestAnimationFrame)
2353
+ window.requestAnimationFrame = function(callback, element) {
2354
+ var currTime = new Date().getTime();
2355
+ var timeToCall = Math.max(0, 16 - (currTime - lastTime));
2356
+ var id = window.setTimeout(function() { callback(currTime + timeToCall); },
2357
+ timeToCall);
2358
+ lastTime = currTime + timeToCall;
2359
+ return id;
2360
+ };
2361
+
2362
+ if (!window.cancelAnimationFrame)
2363
+ window.cancelAnimationFrame = function(id) {
2364
+ clearTimeout(id);
2365
+ };
2366
+ }());
2367
+
2368
+ }));