nitro 0.26.0 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +312 -0
- data/INSTALL +3 -1
- data/ProjectInfo +6 -9
- data/README +32 -5
- data/Rakefile +5 -1
- data/bin/nitrogen +3 -60
- data/doc/MIGRATION +24 -0
- data/doc/RELEASES +141 -0
- data/doc/lhttpd.txt +3 -0
- data/lib/glue/magick.rb +38 -0
- data/lib/glue/thumbnails.rb +3 -0
- data/lib/glue/webfile.rb +137 -0
- data/lib/nitro.rb +1 -1
- data/lib/nitro/adapter/acgi.rb +235 -0
- data/lib/nitro/adapter/cgi.rb +16 -17
- data/lib/nitro/adapter/scgi.rb +4 -4
- data/lib/nitro/adapter/webrick.rb +9 -2
- data/lib/nitro/cgi.rb +49 -49
- data/lib/nitro/cgi/response.rb +4 -0
- data/lib/nitro/cgi/stream.rb +7 -7
- data/lib/nitro/cgi/utils.rb +2 -1
- data/lib/nitro/compiler.rb +47 -4
- data/lib/nitro/compiler/elements.rb +40 -20
- data/lib/nitro/compiler/layout.rb +21 -0
- data/lib/nitro/compiler/localization.rb +3 -1
- data/lib/nitro/compiler/markup.rb +2 -0
- data/lib/nitro/compiler/morphing.rb +16 -4
- data/lib/nitro/compiler/script.rb +109 -0
- data/lib/nitro/context.rb +10 -10
- data/lib/nitro/dispatcher.rb +4 -2
- data/lib/nitro/element.rb +107 -26
- data/lib/nitro/element/{java_script.rb → javascript.rb} +7 -1
- data/lib/nitro/flash.rb +4 -1
- data/lib/nitro/helper.rb +15 -0
- data/lib/nitro/helper/benchmark.rb +8 -2
- data/lib/nitro/helper/form.rb +3 -3
- data/lib/nitro/helper/form/controls.rb +131 -29
- data/lib/nitro/helper/{dojo.rb → form/test.xhtml} +0 -0
- data/lib/nitro/helper/javascript.rb +69 -59
- data/lib/nitro/helper/{scriptaculous.rb → javascript/dojo.rb} +0 -0
- data/lib/nitro/helper/javascript/morphing.rb +163 -0
- data/lib/nitro/helper/javascript/prototype.rb +96 -0
- data/lib/nitro/helper/javascript/scriptaculous.rb +18 -0
- data/lib/nitro/helper/layout.rb +42 -0
- data/lib/nitro/helper/table.rb +190 -27
- data/lib/nitro/{adapter → helper}/wee.rb +9 -3
- data/lib/nitro/render.rb +23 -17
- data/lib/nitro/scaffolding.rb +19 -2
- data/lib/nitro/server.rb +4 -8
- data/lib/nitro/server/runner.rb +28 -6
- data/lib/nitro/session.rb +7 -7
- data/lib/nitro_and_og.rb +2 -0
- data/proto/public/Makefile.acgi +40 -0
- data/proto/public/acgi.c +138 -0
- data/proto/public/js/builder.js +7 -3
- data/proto/public/js/controls.js +32 -12
- data/proto/public/js/dragdrop.js +4 -3
- data/proto/public/js/effects.js +111 -62
- data/proto/public/js/scriptaculous.js +10 -13
- data/proto/public/js/slider.js +88 -31
- data/proto/public/scaffold/new.xhtml +2 -2
- data/setup.rb +1585 -0
- data/src/part/admin.rb +6 -0
- data/src/part/admin/controller.rb +3 -3
- data/src/part/admin/skin.rb +1 -8
- data/test/nitro/adapter/tc_webrick.rb +2 -0
- data/test/nitro/tc_controller_aspect.rb +1 -1
- data/test/nitro/tc_element.rb +5 -6
- data/test/nitro/tc_table.rb +66 -0
- metadata +277 -271
- data/doc/architecture.txt +0 -2
- data/doc/bugs.txt +0 -15
- data/doc/tutorial.txt +0 -26
- data/install.rb +0 -37
- data/lib/nitro/compiler/script_generator.rb +0 -14
- data/lib/nitro/compiler/shaders.rb +0 -206
- data/lib/nitro/helper/prototype.rb +0 -49
- data/lib/nitro/scaffold/relations.rb +0 -54
data/proto/public/js/dragdrop.js
CHANGED
@@ -146,6 +146,7 @@ var Draggables = {
|
|
146
146
|
if(!this.activeDraggable) return;
|
147
147
|
this._lastPointer = null;
|
148
148
|
this.activeDraggable.endDrag(event);
|
149
|
+
this.activeDraggable = null;
|
149
150
|
},
|
150
151
|
|
151
152
|
keyPress: function(event) {
|
@@ -191,7 +192,7 @@ Draggable.prototype = {
|
|
191
192
|
},
|
192
193
|
reverteffect: function(element, top_offset, left_offset) {
|
193
194
|
var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02;
|
194
|
-
element._revert = new Effect.
|
195
|
+
element._revert = new Effect.Move(element, { x: -left_offset, y: -top_offset, duration: dur});
|
195
196
|
},
|
196
197
|
endeffect: function(element) {
|
197
198
|
new Effect.Opacity(element, {duration:0.2, from:0.7, to:1.0});
|
@@ -227,8 +228,8 @@ Draggable.prototype = {
|
|
227
228
|
|
228
229
|
currentDelta: function() {
|
229
230
|
return([
|
230
|
-
parseInt(this.element
|
231
|
-
parseInt(this.element
|
231
|
+
parseInt(Element.getStyle(this.element,'left') || '0'),
|
232
|
+
parseInt(Element.getStyle(this.element,'top') || '0')]);
|
232
233
|
},
|
233
234
|
|
234
235
|
initDrag: function(event) {
|
data/proto/public/js/effects.js
CHANGED
@@ -22,23 +22,21 @@ String.prototype.parseColor = function() {
|
|
22
22
|
}
|
23
23
|
}
|
24
24
|
return(color.length==7 ? color : (arguments[0] || this));
|
25
|
-
}
|
25
|
+
}
|
26
26
|
|
27
|
-
Element.
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
}
|
40
|
-
|
41
|
-
return text;
|
27
|
+
Element.collectTextNodes = function(element) {
|
28
|
+
return $A($(element).childNodes).collect( function(node) {
|
29
|
+
return (node.nodeType==3 ? node.nodeValue :
|
30
|
+
(node.hasChildNodes() ? Element.collectTextNodes(node) : ''));
|
31
|
+
}).flatten().join('');
|
32
|
+
}
|
33
|
+
|
34
|
+
Element.collectTextNodesIgnoreClass = function(element, className) {
|
35
|
+
return $A($(element).childNodes).collect( function(node) {
|
36
|
+
return (node.nodeType==3 ? node.nodeValue :
|
37
|
+
((node.hasChildNodes() && !Element.hasClassName(node,className)) ?
|
38
|
+
Element.collectTextNodes(node) : ''));
|
39
|
+
}).flatten().join('');
|
42
40
|
}
|
43
41
|
|
44
42
|
Element.setStyle = function(element, style) {
|
@@ -129,6 +127,20 @@ var Effect = {
|
|
129
127
|
$A(elements).each( function(element, index) {
|
130
128
|
new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay }));
|
131
129
|
});
|
130
|
+
},
|
131
|
+
PAIRS: {
|
132
|
+
'slide': ['SlideDown','SlideUp'],
|
133
|
+
'blind': ['BlindDown','BlindUp'],
|
134
|
+
'appear': ['Appear','Fade']
|
135
|
+
},
|
136
|
+
toggle: function(element, effect) {
|
137
|
+
element = $(element);
|
138
|
+
effect = (effect || 'appear').toLowerCase();
|
139
|
+
var options = Object.extend({
|
140
|
+
queue: { position:'end', scope:(element.id || 'global') }
|
141
|
+
}, arguments[2] || {});
|
142
|
+
Effect[Element.visible(element) ?
|
143
|
+
Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options);
|
132
144
|
}
|
133
145
|
};
|
134
146
|
|
@@ -166,16 +178,22 @@ Effect.Transitions.full = function(pos) {
|
|
166
178
|
|
167
179
|
/* ------------- core effects ------------- */
|
168
180
|
|
169
|
-
Effect.
|
170
|
-
|
181
|
+
Effect.ScopedQueue = Class.create();
|
182
|
+
Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), {
|
183
|
+
initialize: function() {
|
184
|
+
this.effects = [];
|
185
|
+
this.interval = null;
|
186
|
+
},
|
171
187
|
_each: function(iterator) {
|
172
188
|
this.effects._each(iterator);
|
173
189
|
},
|
174
|
-
interval: null,
|
175
190
|
add: function(effect) {
|
176
191
|
var timestamp = new Date().getTime();
|
177
192
|
|
178
|
-
|
193
|
+
var position = (typeof effect.options.queue == 'string') ?
|
194
|
+
effect.options.queue : effect.options.queue.position;
|
195
|
+
|
196
|
+
switch(position) {
|
179
197
|
case 'front':
|
180
198
|
// move unstarted effects after this effect
|
181
199
|
this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
|
@@ -206,32 +224,45 @@ Effect.Queue = {
|
|
206
224
|
var timePos = new Date().getTime();
|
207
225
|
this.effects.invoke('loop', timePos);
|
208
226
|
}
|
227
|
+
});
|
228
|
+
|
229
|
+
Effect.Queues = {
|
230
|
+
instances: $H(),
|
231
|
+
get: function(queueName) {
|
232
|
+
if(typeof queueName != 'string') return queueName;
|
233
|
+
|
234
|
+
if(!this.instances[queueName])
|
235
|
+
this.instances[queueName] = new Effect.ScopedQueue();
|
236
|
+
|
237
|
+
return this.instances[queueName];
|
238
|
+
}
|
239
|
+
}
|
240
|
+
Effect.Queue = Effect.Queues.get('global');
|
241
|
+
|
242
|
+
Effect.DefaultOptions = {
|
243
|
+
transition: Effect.Transitions.sinoidal,
|
244
|
+
duration: 1.0, // seconds
|
245
|
+
fps: 25.0, // max. 25fps due to Effect.Queue implementation
|
246
|
+
sync: false, // true for combining
|
247
|
+
from: 0.0,
|
248
|
+
to: 1.0,
|
249
|
+
delay: 0.0,
|
250
|
+
queue: 'parallel'
|
209
251
|
}
|
210
|
-
Object.extend(Effect.Queue, Enumerable);
|
211
252
|
|
212
253
|
Effect.Base = function() {};
|
213
254
|
Effect.Base.prototype = {
|
214
255
|
position: null,
|
215
|
-
setOptions: function(options) {
|
216
|
-
this.options = Object.extend({
|
217
|
-
transition: Effect.Transitions.sinoidal,
|
218
|
-
duration: 1.0, // seconds
|
219
|
-
fps: 25.0, // max. 25fps due to Effect.Queue implementation
|
220
|
-
sync: false, // true for combining
|
221
|
-
from: 0.0,
|
222
|
-
to: 1.0,
|
223
|
-
delay: 0.0,
|
224
|
-
queue: 'parallel'
|
225
|
-
}, options || {});
|
226
|
-
},
|
227
256
|
start: function(options) {
|
228
|
-
this.
|
257
|
+
this.options = Object.extend(Object.extend({},Effect.DefaultOptions), options || {});
|
229
258
|
this.currentFrame = 0;
|
230
259
|
this.state = 'idle';
|
231
260
|
this.startOn = this.options.delay*1000;
|
232
261
|
this.finishOn = this.startOn + (this.options.duration*1000);
|
233
262
|
this.event('beforeStart');
|
234
|
-
if(!this.options.sync)
|
263
|
+
if(!this.options.sync)
|
264
|
+
Effect.Queues.get(typeof this.options.queue == 'string' ?
|
265
|
+
'global' : this.options.queue.scope).add(this);
|
235
266
|
},
|
236
267
|
loop: function(timePos) {
|
237
268
|
if(timePos >= this.startOn) {
|
@@ -269,7 +300,9 @@ Effect.Base.prototype = {
|
|
269
300
|
}
|
270
301
|
},
|
271
302
|
cancel: function() {
|
272
|
-
if(!this.options.sync)
|
303
|
+
if(!this.options.sync)
|
304
|
+
Effect.Queues.get(typeof this.options.queue == 'string' ?
|
305
|
+
'global' : this.options.queue.scope).remove(this);
|
273
306
|
this.state = 'finished';
|
274
307
|
},
|
275
308
|
event: function(eventName) {
|
@@ -319,13 +352,16 @@ Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), {
|
|
319
352
|
}
|
320
353
|
});
|
321
354
|
|
322
|
-
Effect.
|
323
|
-
Object.extend(Object.extend(Effect.
|
324
|
-
initialize: function(element
|
325
|
-
this.element
|
326
|
-
|
327
|
-
|
328
|
-
|
355
|
+
Effect.Move = Class.create();
|
356
|
+
Object.extend(Object.extend(Effect.Move.prototype, Effect.Base.prototype), {
|
357
|
+
initialize: function(element) {
|
358
|
+
this.element = $(element);
|
359
|
+
var options = Object.extend({
|
360
|
+
x: 0,
|
361
|
+
y: 0,
|
362
|
+
mode: 'relative'
|
363
|
+
}, arguments[1] || {});
|
364
|
+
this.start(options);
|
329
365
|
},
|
330
366
|
setup: function() {
|
331
367
|
// Bug in Opera: Opera returns the "real" position of a static element or
|
@@ -333,17 +369,28 @@ Object.extend(Object.extend(Effect.MoveBy.prototype, Effect.Base.prototype), {
|
|
333
369
|
// ==> Always set top and left for position relative elements in your stylesheets
|
334
370
|
// (to 0 if you do not need them)
|
335
371
|
Element.makePositioned(this.element);
|
336
|
-
this.originalTop = parseFloat(Element.getStyle(this.element,'top') || '0');
|
337
372
|
this.originalLeft = parseFloat(Element.getStyle(this.element,'left') || '0');
|
373
|
+
this.originalTop = parseFloat(Element.getStyle(this.element,'top') || '0');
|
374
|
+
if(this.options.mode == 'absolute') {
|
375
|
+
// absolute movement, so we need to calc deltaX and deltaY
|
376
|
+
this.options.x = this.options.x - this.originalLeft;
|
377
|
+
this.options.y = this.options.y - this.originalTop;
|
378
|
+
}
|
338
379
|
},
|
339
380
|
update: function(position) {
|
340
381
|
Element.setStyle(this.element, {
|
341
|
-
|
342
|
-
|
382
|
+
left: this.options.x * position + this.originalLeft + 'px',
|
383
|
+
top: this.options.y * position + this.originalTop + 'px'
|
343
384
|
});
|
344
385
|
}
|
345
386
|
});
|
346
387
|
|
388
|
+
// for backwards compatibility
|
389
|
+
Effect.MoveBy = function(element, toTop, toLeft) {
|
390
|
+
return new Effect.Move(element,
|
391
|
+
Object.extend({ x: toLeft, y: toTop }, arguments[3] || {}));
|
392
|
+
};
|
393
|
+
|
347
394
|
Effect.Scale = Class.create();
|
348
395
|
Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
|
349
396
|
initialize: function(element, percent) {
|
@@ -585,7 +632,7 @@ Effect.DropOut = function(element) {
|
|
585
632
|
left: Element.getStyle(element, 'left'),
|
586
633
|
opacity: Element.getInlineOpacity(element) };
|
587
634
|
return new Effect.Parallel(
|
588
|
-
[ new Effect.
|
635
|
+
[ new Effect.Move(element, {x: 0, y: 100, sync: true }),
|
589
636
|
new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
|
590
637
|
Object.extend(
|
591
638
|
{ duration: 0.5,
|
@@ -602,18 +649,18 @@ Effect.Shake = function(element) {
|
|
602
649
|
var oldStyle = {
|
603
650
|
top: Element.getStyle(element, 'top'),
|
604
651
|
left: Element.getStyle(element, 'left') };
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
652
|
+
return new Effect.Move(element,
|
653
|
+
{ x: 20, y: 0, duration: 0.05, afterFinishInternal: function(effect) {
|
654
|
+
new Effect.Move(effect.element,
|
655
|
+
{ x: -40, y: 0, duration: 0.1, afterFinishInternal: function(effect) {
|
656
|
+
new Effect.Move(effect.element,
|
657
|
+
{ x: 40, y: 0, duration: 0.1, afterFinishInternal: function(effect) {
|
658
|
+
new Effect.Move(effect.element,
|
659
|
+
{ x: -40, y: 0, duration: 0.1, afterFinishInternal: function(effect) {
|
660
|
+
new Effect.Move(effect.element,
|
661
|
+
{ x: 40, y: 0, duration: 0.1, afterFinishInternal: function(effect) {
|
662
|
+
new Effect.Move(effect.element,
|
663
|
+
{ x: -20, y: 0, duration: 0.05, afterFinishInternal: function(effect) { with(Element) {
|
617
664
|
undoPositioned(effect.element);
|
618
665
|
setStyle(effect.element, oldStyle);
|
619
666
|
}}}) }}) }}) }}) }}) }});
|
@@ -737,7 +784,9 @@ Effect.Grow = function(element) {
|
|
737
784
|
break;
|
738
785
|
}
|
739
786
|
|
740
|
-
return new Effect.
|
787
|
+
return new Effect.Move(element, {
|
788
|
+
x: initialMoveX,
|
789
|
+
y: initialMoveY,
|
741
790
|
duration: 0.01,
|
742
791
|
beforeSetup: function(effect) { with(Element) {
|
743
792
|
hide(effect.element);
|
@@ -747,7 +796,7 @@ Effect.Grow = function(element) {
|
|
747
796
|
afterFinishInternal: function(effect) {
|
748
797
|
new Effect.Parallel(
|
749
798
|
[ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
|
750
|
-
new Effect.
|
799
|
+
new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }),
|
751
800
|
new Effect.Scale(effect.element, 100, {
|
752
801
|
scaleMode: { originalHeight: dims.height, originalWidth: dims.width },
|
753
802
|
sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
|
@@ -807,7 +856,7 @@ Effect.Shrink = function(element) {
|
|
807
856
|
return new Effect.Parallel(
|
808
857
|
[ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
|
809
858
|
new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
|
810
|
-
new Effect.
|
859
|
+
new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
|
811
860
|
], Object.extend({
|
812
861
|
beforeStartInternal: function(effect) { with(Element) {
|
813
862
|
[makePositioned, makeClipping].call(effect.effects[0].element) }},
|
@@ -20,7 +20,7 @@
|
|
20
20
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
21
|
|
22
22
|
var Scriptaculous = {
|
23
|
-
Version: '1.
|
23
|
+
Version: '1.5.1',
|
24
24
|
require: function(libraryName) {
|
25
25
|
// inserting via DOM fails in Safari 2.0, so brute force approach
|
26
26
|
document.write('<script type="text/javascript" src="'+libraryName+'"></script>');
|
@@ -30,18 +30,15 @@ var Scriptaculous = {
|
|
30
30
|
parseFloat(Prototype.Version.split(".")[0] + "." +
|
31
31
|
Prototype.Version.split(".")[1]) < 1.4)
|
32
32
|
throw("script.aculo.us requires the Prototype JavaScript framework >= 1.4.0");
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
break;
|
43
|
-
}
|
44
|
-
}
|
33
|
+
|
34
|
+
$A(document.getElementsByTagName("script")).findAll( function(s) {
|
35
|
+
return (s.src && s.src.match(/scriptaculous\.js(\?.*)?$/))
|
36
|
+
}).each( function(s) {
|
37
|
+
var path = s.src.replace(/scriptaculous\.js(\?.*)?$/,'');
|
38
|
+
var includes = s.src.match(/\?.*load=([a-z,]*)/);
|
39
|
+
(includes ? includes[1] : 'builder,effects,dragdrop,controls,slider').split(',').each(
|
40
|
+
function(include) { Scriptaculous.require(path+include+'.js') });
|
41
|
+
});
|
45
42
|
}
|
46
43
|
}
|
47
44
|
|
data/proto/public/js/slider.js
CHANGED
@@ -1,6 +1,25 @@
|
|
1
|
-
// Copyright (c) 2005 Marty Haught
|
1
|
+
// Copyright (c) 2005 Marty Haught, Thomas Fuchs
|
2
|
+
//
|
3
|
+
// See http://script.aculo.us for more info
|
4
|
+
//
|
5
|
+
// Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
// a copy of this software and associated documentation files (the
|
7
|
+
// "Software"), to deal in the Software without restriction, including
|
8
|
+
// without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
// distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
// permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
// the following conditions:
|
2
12
|
//
|
3
|
-
//
|
13
|
+
// The above copyright notice and this permission notice shall be
|
14
|
+
// included in all copies or substantial portions of the Software.
|
15
|
+
//
|
16
|
+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
4
23
|
|
5
24
|
if(!Control) var Control = {};
|
6
25
|
Control.Slider = Class.create();
|
@@ -32,6 +51,9 @@ Control.Slider.prototype = {
|
|
32
51
|
this.value = 0; // assure backwards compat
|
33
52
|
this.values = this.handles.map( function() { return 0 });
|
34
53
|
this.spans = this.options.spans ? this.options.spans.map(function(s){ return $(s) }) : false;
|
54
|
+
this.options.startSpan = $(this.options.startSpan || null);
|
55
|
+
this.options.endSpan = $(this.options.endSpan || null);
|
56
|
+
|
35
57
|
this.restricted = this.options.restricted || false;
|
36
58
|
|
37
59
|
this.maximum = this.options.maximum || this.range.end;
|
@@ -42,6 +64,7 @@ Control.Slider.prototype = {
|
|
42
64
|
this.alignY = parseInt(this.options.alignY || '0');
|
43
65
|
|
44
66
|
this.trackLength = this.maximumOffset() - this.minimumOffset();
|
67
|
+
this.handleLength = this.isVertical() ? this.handles[0].offsetHeight : this.handles[0].offsetWidth;
|
45
68
|
|
46
69
|
this.active = false;
|
47
70
|
this.dragging = false;
|
@@ -60,18 +83,26 @@ Control.Slider.prototype = {
|
|
60
83
|
this.eventMouseUp = this.endDrag.bindAsEventListener(this);
|
61
84
|
this.eventMouseMove = this.update.bindAsEventListener(this);
|
62
85
|
|
63
|
-
// Initialize handles
|
86
|
+
// Initialize handles in reverse (make sure first handle is active)
|
64
87
|
this.handles.each( function(h,i) {
|
65
|
-
|
88
|
+
i = slider.handles.length-1-i;
|
89
|
+
slider.setValue(parseFloat(
|
90
|
+
(slider.options.sliderValue instanceof Array ?
|
91
|
+
slider.options.sliderValue[i] : slider.options.sliderValue) ||
|
92
|
+
slider.range.start), i);
|
66
93
|
Element.makePositioned(h); // fix IE
|
67
94
|
Event.observe(h, "mousedown", slider.eventMouseDown);
|
68
95
|
});
|
69
96
|
|
97
|
+
Event.observe(this.track, "mousedown", this.eventMouseDown);
|
70
98
|
Event.observe(document, "mouseup", this.eventMouseUp);
|
71
99
|
Event.observe(document, "mousemove", this.eventMouseMove);
|
100
|
+
|
101
|
+
this.initialized = true;
|
72
102
|
},
|
73
103
|
dispose: function() {
|
74
104
|
var slider = this;
|
105
|
+
Event.stopObserving(this.track, "mousedown", this.eventMouseDown);
|
75
106
|
Event.stopObserving(document, "mouseup", this.eventMouseUp);
|
76
107
|
Event.stopObserving(document, "mousemove", this.eventMouseMove);
|
77
108
|
this.handles.each( function(h) {
|
@@ -108,9 +139,10 @@ Control.Slider.prototype = {
|
|
108
139
|
if(!this.active) {
|
109
140
|
this.activeHandle = this.handles[handleIdx];
|
110
141
|
this.activeHandleIdx = handleIdx;
|
142
|
+
this.updateStyles();
|
111
143
|
}
|
112
144
|
handleIdx = handleIdx || this.activeHandleIdx || 0;
|
113
|
-
if(this.restricted) {
|
145
|
+
if(this.initialized && this.restricted) {
|
114
146
|
if((handleIdx>0) && (sliderValue<this.values[handleIdx-1]))
|
115
147
|
sliderValue = this.values[handleIdx-1];
|
116
148
|
if((handleIdx < (this.handles.length-1)) && (sliderValue>this.values[handleIdx+1]))
|
@@ -120,21 +152,24 @@ Control.Slider.prototype = {
|
|
120
152
|
this.values[handleIdx] = sliderValue;
|
121
153
|
this.value = this.values[0]; // assure backwards compat
|
122
154
|
|
123
|
-
this.handles[handleIdx].style[
|
155
|
+
this.handles[handleIdx].style[this.isVertical() ? 'top' : 'left'] =
|
124
156
|
this.translateToPx(sliderValue);
|
125
157
|
|
126
158
|
this.drawSpans();
|
127
|
-
this.updateFinished();
|
159
|
+
if(!this.dragging || !this.event) this.updateFinished();
|
128
160
|
},
|
129
161
|
setValueBy: function(delta, handleIdx) {
|
130
162
|
this.setValue(this.values[handleIdx || this.activeHandleIdx || 0] + delta,
|
131
163
|
handleIdx || this.activeHandleIdx || 0);
|
132
164
|
},
|
133
165
|
translateToPx: function(value) {
|
134
|
-
return Math.round(
|
166
|
+
return Math.round(
|
167
|
+
((this.trackLength-this.handleLength)/(this.range.end-this.range.start)) *
|
168
|
+
(value - this.range.start)) + "px";
|
135
169
|
},
|
136
170
|
translateToValue: function(offset) {
|
137
|
-
return ((offset/this.trackLength
|
171
|
+
return ((offset/(this.trackLength-this.handleLength) *
|
172
|
+
(this.range.end-this.range.start)) + this.range.start);
|
138
173
|
},
|
139
174
|
getRange: function(range) {
|
140
175
|
var v = this.values.sortBy(Prototype.K);
|
@@ -154,45 +189,63 @@ Control.Slider.prototype = {
|
|
154
189
|
drawSpans: function() {
|
155
190
|
var slider = this;
|
156
191
|
if(this.spans)
|
157
|
-
$R(0, this.spans.length-1).each(function(r) { slider.setSpan(r, slider.getRange(r)) });
|
192
|
+
$R(0, this.spans.length-1).each(function(r) { slider.setSpan(slider.spans[r], slider.getRange(r)) });
|
193
|
+
if(this.options.startSpan)
|
194
|
+
this.setSpan(this.options.startSpan,
|
195
|
+
$R(0, this.values.length>1 ? this.getRange(0).min() : this.value ));
|
196
|
+
if(this.options.endSpan)
|
197
|
+
this.setSpan(this.options.endSpan,
|
198
|
+
$R(this.values.length>1 ? this.getRange(this.spans.length-1).max() : this.value, this.maximum));
|
158
199
|
},
|
159
200
|
setSpan: function(span, range) {
|
160
201
|
if(this.isVertical()) {
|
161
|
-
|
162
|
-
|
202
|
+
span.style.top = this.translateToPx(range.start);
|
203
|
+
span.style.height = this.translateToPx(range.end - range.start);
|
163
204
|
} else {
|
164
|
-
|
165
|
-
|
205
|
+
span.style.left = this.translateToPx(range.start);
|
206
|
+
span.style.width = this.translateToPx(range.end - range.start);
|
166
207
|
}
|
167
208
|
},
|
209
|
+
updateStyles: function() {
|
210
|
+
this.handles.each( function(h){ Element.removeClassName(h, 'selected') });
|
211
|
+
Element.addClassName(this.activeHandle, 'selected');
|
212
|
+
},
|
168
213
|
startDrag: function(event) {
|
169
214
|
if(Event.isLeftClick(event)) {
|
170
215
|
if(!this.disabled){
|
171
216
|
this.active = true;
|
172
217
|
|
173
|
-
// find the handle (prevents issues with Safari)
|
174
218
|
var handle = Event.element(event);
|
175
|
-
while((this.handles.indexOf(handle) == -1) && handle.parentNode)
|
176
|
-
handle = handle.parentNode;
|
177
|
-
|
178
|
-
this.activeHandle = handle;
|
179
|
-
this.activeHandleIdx = this.handles.indexOf(this.activeHandle);
|
180
|
-
|
181
219
|
var pointer = [Event.pointerX(event), Event.pointerY(event)];
|
182
|
-
|
183
|
-
|
184
|
-
|
220
|
+
if(handle==this.track) {
|
221
|
+
var offsets = Position.cumulativeOffset(this.track);
|
222
|
+
this.event = event;
|
223
|
+
this.setValue(this.translateToValue(
|
224
|
+
(this.isVertical() ? pointer[1]-offsets[1] : pointer[0]-offsets[0])-(this.handleLength/2)
|
225
|
+
));
|
226
|
+
var offsets = Position.cumulativeOffset(this.activeHandle);
|
227
|
+
this.offsetX = (pointer[0] - offsets[0]);
|
228
|
+
this.offsetY = (pointer[1] - offsets[1]);
|
229
|
+
} else {
|
230
|
+
// find the handle (prevents issues with Safari)
|
231
|
+
while((this.handles.indexOf(handle) == -1) && handle.parentNode)
|
232
|
+
handle = handle.parentNode;
|
185
233
|
|
234
|
+
this.activeHandle = handle;
|
235
|
+
this.activeHandleIdx = this.handles.indexOf(this.activeHandle);
|
236
|
+
this.updateStyles();
|
237
|
+
|
238
|
+
var offsets = Position.cumulativeOffset(this.activeHandle);
|
239
|
+
this.offsetX = (pointer[0] - offsets[0]);
|
240
|
+
this.offsetY = (pointer[1] - offsets[1]);
|
241
|
+
}
|
186
242
|
}
|
187
243
|
Event.stop(event);
|
188
244
|
}
|
189
245
|
},
|
190
246
|
update: function(event) {
|
191
247
|
if(this.active) {
|
192
|
-
if(!this.dragging)
|
193
|
-
this.dragging = true;
|
194
|
-
if(this.activeHandle.style.position=="") style.position = "relative";
|
195
|
-
}
|
248
|
+
if(!this.dragging) this.dragging = true;
|
196
249
|
this.draw(event);
|
197
250
|
// fix AppleWebKit rendering
|
198
251
|
if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
|
@@ -204,8 +257,10 @@ Control.Slider.prototype = {
|
|
204
257
|
var offsets = Position.cumulativeOffset(this.track);
|
205
258
|
pointer[0] -= this.offsetX + offsets[0];
|
206
259
|
pointer[1] -= this.offsetY + offsets[1];
|
260
|
+
this.event = event;
|
207
261
|
this.setValue(this.translateToValue( this.isVertical() ? pointer[1] : pointer[0] ));
|
208
|
-
if(this.
|
262
|
+
if(this.initialized && this.options.onSlide)
|
263
|
+
this.options.onSlide(this.values.length>1 ? this.values : this.value, this);
|
209
264
|
},
|
210
265
|
endDrag: function(event) {
|
211
266
|
if(this.active && this.dragging) {
|
@@ -221,6 +276,8 @@ Control.Slider.prototype = {
|
|
221
276
|
this.updateFinished();
|
222
277
|
},
|
223
278
|
updateFinished: function() {
|
224
|
-
if(this.
|
279
|
+
if(this.initialized && this.options.onChange)
|
280
|
+
this.options.onChange(this.values.length>1 ? this.values : this.value, this);
|
281
|
+
this.event = null;
|
225
282
|
}
|
226
|
-
}
|
283
|
+
}
|