nitro 0.26.0 → 0.27.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
}
|