blob: 0b0aed0bcf27ec8ce8fdbefcb477289d3683c44c [file] [log] [blame]
Akron9905e2a2016-05-10 16:06:44 +02001define({
2
3 /**
Akron6ed13992016-05-23 18:06:05 +02004 * Create new slider object.
5 * The slider will only be used by mouse - touch support
6 * shouldn't be necessary.
Akron9905e2a2016-05-10 16:06:44 +02007 */
Akron47c086c2016-05-18 21:22:06 +02008 create : function (menu) {
9 return Object.create(this)._init(menu);
Akron9905e2a2016-05-10 16:06:44 +020010 },
11
Akron6ed13992016-05-23 18:06:05 +020012 length : function (i) {
13 if (arguments.length === 0)
14 return this._length;
15 if (i == this._length)
16 return;
17 this._length = i;
18 this._initSize();
19 },
20
21 limit : function (i) {
22 if (arguments.length === 0)
23 return this._limit;
24 if (i == this._limit)
25 return;
26 this._limit = i;
27 this._initSize();
28 },
29
Akrona92fd8d2016-05-24 21:13:41 +020030 active : function (bool) {
31 if (arguments.length === 1) {
32 if (bool) {
33 if (!this._active) {
34 this._element.classList.add('active');
35 this._active = true;
36 };
37 }
38 else if (this._active) {
39 this._element.classList.remove('active');
40 this._active = false;
41 }
42 };
43 return this._active;
44 },
45
Akron6ed13992016-05-23 18:06:05 +020046 movetoRel : function (relativePos) {
Akron24b1eaa2016-05-18 16:00:25 +020047 var diffHeight = (this._rulerHeight - this._sliderHeight);
Akron47c086c2016-05-18 21:22:06 +020048 var relativeOffset = (relativePos / diffHeight);
49
50 var off = this.offset(parseInt(relativeOffset * this._screens));
51 if (off !== undefined) {
52 this._menu.screen(off);
53 };
Akron6b24b202016-05-17 23:04:36 +020054 },
55
Akron6ed13992016-05-23 18:06:05 +020056 movetoAbs : function (absPos) {
57 var absOffset = (absPos / this._rulerHeight);
58
59 var off = this.offset(parseInt(absOffset * (this._screens + 1)));
60 if (off !== undefined) {
61 this._menu.screen(off);
62 };
Akron6b24b202016-05-17 23:04:36 +020063 },
64
Akron6ed13992016-05-23 18:06:05 +020065 offset : function (off) {
66 if (arguments.length === 0)
67 return this._offset;
Akron6b24b202016-05-17 23:04:36 +020068
Akron6ed13992016-05-23 18:06:05 +020069 if (off > this._screens) {
70 off = this._screens;
71 }
72 else if (off < 0) {
73 off = 0;
74 };
Akron24b1eaa2016-05-18 16:00:25 +020075
Akron6ed13992016-05-23 18:06:05 +020076 if (off === this._offset)
77 return undefined;
Akron6b24b202016-05-17 23:04:36 +020078
Akron6ed13992016-05-23 18:06:05 +020079 this._offset = off;
80 this._slider.style.top = (this._step * off) + '%';
Akrona92fd8d2016-05-24 21:13:41 +020081
Akron6ed13992016-05-23 18:06:05 +020082 return off;
83 },
Akron6b24b202016-05-17 23:04:36 +020084
Akron6ed13992016-05-23 18:06:05 +020085 element : function () {
86 return this._element;
Akron6b24b202016-05-17 23:04:36 +020087 },
88
Akron9905e2a2016-05-10 16:06:44 +020089 // Initialize prefix object
Akron47c086c2016-05-18 21:22:06 +020090 _init : function (menu) {
91
92 this._menu = menu;
Akron9905e2a2016-05-10 16:06:44 +020093
Akronf86eaea2016-05-13 18:02:27 +020094 this._offset = 0;
Akron6b24b202016-05-17 23:04:36 +020095 this._event = {};
Akrona92fd8d2016-05-24 21:13:41 +020096 this._active = false;
Akronf86eaea2016-05-13 18:02:27 +020097
Akron9905e2a2016-05-10 16:06:44 +020098 this._element = document.createElement('div');
99 this._element.setAttribute('class', 'ruler');
100
101 this._slider = this._element.appendChild(
102 document.createElement('span')
103 );
104
Akron6ed13992016-05-23 18:06:05 +0200105 this._ruler = this._element.appendChild(document.createElement('div'));
Akron47c086c2016-05-18 21:22:06 +0200106
Akron6ed13992016-05-23 18:06:05 +0200107 // Do not mark the menu on mousedown
108 this._ruler.addEventListener('mousedown', function (e) {
109 e.halt()
110 }, false);
111
112 // Move the slider to the click position
113 this._ruler.addEventListener('click', this._mouseclick.bind(this), false);
114
Akron6b24b202016-05-17 23:04:36 +0200115 this._slider.addEventListener('mousedown', this._mousedown.bind(this), false);
116
Akron9905e2a2016-05-10 16:06:44 +0200117 return this;
118 },
119
Akronf86eaea2016-05-13 18:02:27 +0200120 _initSize : function () {
Akron6ed13992016-05-23 18:06:05 +0200121 if (this._length <= this._limit) {
122 this._element.style.display = 'none';
123 return;
124 }
125 else {
126 this._element.style.display = 'block';
127 };
128
Akronf86eaea2016-05-13 18:02:27 +0200129 this._height = ((this._limit / this._length) * 100);
Akron6b24b202016-05-17 23:04:36 +0200130 this._screens = this._length - this._limit;
131 this._step = (100 - this._height) / this._screens;
Akronf86eaea2016-05-13 18:02:27 +0200132 this._slider.style.height = this._height + '%';
Akron9905e2a2016-05-10 16:06:44 +0200133 },
134
Akron6ed13992016-05-23 18:06:05 +0200135 _initClientHeight : function () {
136 this._rulerHeight = this._element.clientHeight; // offsetHeight?
137 this._sliderHeight = this._slider.clientHeight; // offsetHeight?
Akron9905e2a2016-05-10 16:06:44 +0200138 },
139
Akron6ed13992016-05-23 18:06:05 +0200140 _mousemove : function (e) {
141 this.movetoRel(e.clientY - this._event.init);
142 e.halt();
143 // Support touch!
Akronf86eaea2016-05-13 18:02:27 +0200144 },
145
Akron6ed13992016-05-23 18:06:05 +0200146 _mouseup : function (e) {
Akrona92fd8d2016-05-24 21:13:41 +0200147 this.active(false);
Akron6ed13992016-05-23 18:06:05 +0200148 window.removeEventListener('mousemove', this._event.mov);
149 window.removeEventListener('mouseup', this._event.up);
150 this._menu.focus();
Akron9905e2a2016-05-10 16:06:44 +0200151 },
152
Akron6ed13992016-05-23 18:06:05 +0200153 _mousedown : function (e) {
154 // Bind drag handler
155 var ev = this._event;
156 ev.init = e.clientY - (this._step * this._offset);
157 ev.mov = this._mousemove.bind(this);
158 ev.up = this._mouseup.bind(this);
159
160 // TODO: This may not be necessary all the time
161 this._initClientHeight();
162
Akrona92fd8d2016-05-24 21:13:41 +0200163 this.active(true);
Akron6ed13992016-05-23 18:06:05 +0200164
165 window.addEventListener('mousemove', ev.mov);
166 window.addEventListener('mouseup', ev.up);
167
168 e.halt();
169 },
170
171 _mouseclick : function (e) {
172 this._initClientHeight();
173
174 this.movetoAbs(
175 e.clientY - this._ruler.getClientRects()[0].top
176 );
177 e.halt();
Akron9905e2a2016-05-10 16:06:44 +0200178 }
179});