Fingertips-headless-squirrel 0.2.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.
Files changed (124) hide show
  1. data/README.rdoc +53 -0
  2. data/Rakefile +49 -0
  3. data/VERSION.yml +4 -0
  4. data/bin/jstest +10 -0
  5. data/lib/headless_squirrel/runner.rb +70 -0
  6. data/lib/headless_squirrel/test.rb +17 -0
  7. data/lib/headless_squirrel/test_case.rb +121 -0
  8. data/lib/headless_squirrel.rb +2 -0
  9. data/test/fixtures/a_unit_test.html +27 -0
  10. data/test/fixtures/a_unit_test.js +22 -0
  11. data/test/regression/prototype/unit/ajax_test.html +29 -0
  12. data/test/regression/prototype/unit/array_test.html +28 -0
  13. data/test/regression/prototype/unit/assets/prototype.js +4900 -0
  14. data/test/regression/prototype/unit/assets/unittest.css +50 -0
  15. data/test/regression/prototype/unit/assets/unittest.js +615 -0
  16. data/test/regression/prototype/unit/assets/unittest_transport.js +1 -0
  17. data/test/regression/prototype/unit/base_test.html +27 -0
  18. data/test/regression/prototype/unit/class_test.html +27 -0
  19. data/test/regression/prototype/unit/date_test.html +27 -0
  20. data/test/regression/prototype/unit/dom_test.html +304 -0
  21. data/test/regression/prototype/unit/element_mixins_test.html +30 -0
  22. data/test/regression/prototype/unit/enumerable_test.html +35 -0
  23. data/test/regression/prototype/unit/event_test.html +31 -0
  24. data/test/regression/prototype/unit/fixtures/ajax.html +2 -0
  25. data/test/regression/prototype/unit/fixtures/ajax.js +42 -0
  26. data/test/regression/prototype/unit/fixtures/array.html +1 -0
  27. data/test/regression/prototype/unit/fixtures/class.js +83 -0
  28. data/test/regression/prototype/unit/fixtures/content.html +1 -0
  29. data/test/regression/prototype/unit/fixtures/data.json +1 -0
  30. data/test/regression/prototype/unit/fixtures/dom.css +84 -0
  31. data/test/regression/prototype/unit/fixtures/dom.html +278 -0
  32. data/test/regression/prototype/unit/fixtures/dom.js +17 -0
  33. data/test/regression/prototype/unit/fixtures/element_mixins.html +4 -0
  34. data/test/regression/prototype/unit/fixtures/element_mixins.js +2 -0
  35. data/test/regression/prototype/unit/fixtures/empty.html +0 -0
  36. data/test/regression/prototype/unit/fixtures/empty.js +1 -0
  37. data/test/regression/prototype/unit/fixtures/enumerable.html +8 -0
  38. data/test/regression/prototype/unit/fixtures/enumerable.js +23 -0
  39. data/test/regression/prototype/unit/fixtures/event.html +4 -0
  40. data/test/regression/prototype/unit/fixtures/form.html +108 -0
  41. data/test/regression/prototype/unit/fixtures/function.js +13 -0
  42. data/test/regression/prototype/unit/fixtures/hash.js +25 -0
  43. data/test/regression/prototype/unit/fixtures/hello.js +1 -0
  44. data/test/regression/prototype/unit/fixtures/logo.gif +0 -0
  45. data/test/regression/prototype/unit/fixtures/object.html +6 -0
  46. data/test/regression/prototype/unit/fixtures/object.js +7 -0
  47. data/test/regression/prototype/unit/fixtures/position.html +9 -0
  48. data/test/regression/prototype/unit/fixtures/selector.html +71 -0
  49. data/test/regression/prototype/unit/fixtures/string.js +8 -0
  50. data/test/regression/prototype/unit/fixtures/unittest.html +18 -0
  51. data/test/regression/prototype/unit/form_test.html +135 -0
  52. data/test/regression/prototype/unit/function_test.html +27 -0
  53. data/test/regression/prototype/unit/hash_test.html +27 -0
  54. data/test/regression/prototype/unit/number_test.html +27 -0
  55. data/test/regression/prototype/unit/object_test.html +32 -0
  56. data/test/regression/prototype/unit/periodical_executer_test.html +27 -0
  57. data/test/regression/prototype/unit/position_test.html +36 -0
  58. data/test/regression/prototype/unit/prototype_test.html +27 -0
  59. data/test/regression/prototype/unit/range_test.html +27 -0
  60. data/test/regression/prototype/unit/regexp_test.html +27 -0
  61. data/test/regression/prototype/unit/selector_test.html +98 -0
  62. data/test/regression/prototype/unit/string_test.html +27 -0
  63. data/test/regression/prototype/unit/tests/ajax_test.js +379 -0
  64. data/test/regression/prototype/unit/tests/array_test.js +186 -0
  65. data/test/regression/prototype/unit/tests/base_test.js +43 -0
  66. data/test/regression/prototype/unit/tests/class_test.js +136 -0
  67. data/test/regression/prototype/unit/tests/date_test.js +5 -0
  68. data/test/regression/prototype/unit/tests/dom_test.js +1493 -0
  69. data/test/regression/prototype/unit/tests/element_mixins_test.js +32 -0
  70. data/test/regression/prototype/unit/tests/enumerable_test.js +271 -0
  71. data/test/regression/prototype/unit/tests/event_test.js +235 -0
  72. data/test/regression/prototype/unit/tests/form_test.js +382 -0
  73. data/test/regression/prototype/unit/tests/function_test.js +133 -0
  74. data/test/regression/prototype/unit/tests/hash_test.js +178 -0
  75. data/test/regression/prototype/unit/tests/number_test.js +44 -0
  76. data/test/regression/prototype/unit/tests/object_test.js +180 -0
  77. data/test/regression/prototype/unit/tests/periodical_executer_test.js +15 -0
  78. data/test/regression/prototype/unit/tests/position_test.js +44 -0
  79. data/test/regression/prototype/unit/tests/prototype_test.js +43 -0
  80. data/test/regression/prototype/unit/tests/range_test.js +58 -0
  81. data/test/regression/prototype/unit/tests/regexp_test.js +42 -0
  82. data/test/regression/prototype/unit/tests/selector_test.js +408 -0
  83. data/test/regression/prototype/unit/tests/string_test.js +548 -0
  84. data/test/regression/prototype/unit/tests/unittest_test.js +148 -0
  85. data/test/regression/prototype/unit/unittest_test.html +45 -0
  86. data/test/regression/prototype/upstream +1 -0
  87. data/test/regression/scriptaculous/src/builder.js +134 -0
  88. data/test/regression/scriptaculous/src/controls.js +963 -0
  89. data/test/regression/scriptaculous/src/dragdrop.js +973 -0
  90. data/test/regression/scriptaculous/src/effects.js +1122 -0
  91. data/test/regression/scriptaculous/src/javascripttest.rb +203 -0
  92. data/test/regression/scriptaculous/src/scriptaculous.js +66 -0
  93. data/test/regression/scriptaculous/src/slider.js +273 -0
  94. data/test/regression/scriptaculous/src/sound.js +57 -0
  95. data/test/regression/scriptaculous/src/unittest.js +566 -0
  96. data/test/regression/scriptaculous/unit/_ajax_inplaceeditor_ipce_alt_text.html +1 -0
  97. data/test/regression/scriptaculous/unit/_ajax_inplaceeditor_ipce_collection.js +1 -0
  98. data/test/regression/scriptaculous/unit/_ajax_inplaceeditor_result.html +1 -0
  99. data/test/regression/scriptaculous/unit/_ajax_inplaceeditor_result2.html +1 -0
  100. data/test/regression/scriptaculous/unit/_ajax_inplaceeditor_tagged.html +1 -0
  101. data/test/regression/scriptaculous/unit/_ajax_inplaceeditor_text.html +1 -0
  102. data/test/regression/scriptaculous/unit/_ajax_updater_result.html +20 -0
  103. data/test/regression/scriptaculous/unit/_autocomplete_result.html +11 -0
  104. data/test/regression/scriptaculous/unit/_autocomplete_result_nobr.html +1 -0
  105. data/test/regression/scriptaculous/unit/ajax_autocompleter_test.html +243 -0
  106. data/test/regression/scriptaculous/unit/ajax_inplaceeditor_test.html +895 -0
  107. data/test/regression/scriptaculous/unit/builder_test.html +262 -0
  108. data/test/regression/scriptaculous/unit/dragdrop_test.html +131 -0
  109. data/test/regression/scriptaculous/unit/effects_test.html +547 -0
  110. data/test/regression/scriptaculous/unit/element_test.html +116 -0
  111. data/test/regression/scriptaculous/unit/icon.png +0 -0
  112. data/test/regression/scriptaculous/unit/index.html +70 -0
  113. data/test/regression/scriptaculous/unit/loading_test.html +41 -0
  114. data/test/regression/scriptaculous/unit/position_clone_test.html +312 -0
  115. data/test/regression/scriptaculous/unit/slider_test.html +437 -0
  116. data/test/regression/scriptaculous/unit/sortable_test.html +205 -0
  117. data/test/regression/scriptaculous/unit/string_test.html +71 -0
  118. data/test/regression/scriptaculous/unit/unittest_test.html +154 -0
  119. data/test/regression/scriptaculous/upstream +1 -0
  120. data/test/test_helper.rb +20 -0
  121. data/test/unit/runner_test.rb +165 -0
  122. data/test/unit/test_case_test.rb +168 -0
  123. data/test/unit/test_test.rb +24 -0
  124. metadata +179 -0
@@ -0,0 +1,203 @@
1
+ require 'rake/tasklib'
2
+ require 'thread'
3
+ require 'webrick'
4
+
5
+ class Browser
6
+ def supported?; true; end
7
+ def setup ; end
8
+ def open(url) ; end
9
+ def teardown ; end
10
+
11
+ def host
12
+ require 'rbconfig'
13
+ Config::CONFIG['host']
14
+ end
15
+
16
+ def macos?
17
+ host.include?('darwin')
18
+ end
19
+
20
+ def windows?
21
+ host.include?('mswin')
22
+ end
23
+
24
+ def linux?
25
+ host.include?('linux')
26
+ end
27
+
28
+ def applescript(script)
29
+ raise "Can't run AppleScript on #{host}" unless macos?
30
+ system "osascript -e '#{script}' 2>&1 >/dev/null"
31
+ end
32
+ end
33
+
34
+ class FirefoxBrowser < Browser
35
+ def initialize(path='c:\Program Files\Mozilla Firefox\firefox.exe')
36
+ @path = path
37
+ end
38
+
39
+ def visit(url)
40
+ applescript('tell application "Firefox" to Get URL "' + url + '"') if macos?
41
+ system("#{@path} #{url}") if windows?
42
+ system("firefox #{url}") if linux?
43
+ end
44
+
45
+ def to_s
46
+ "Firefox"
47
+ end
48
+ end
49
+
50
+ class SafariBrowser < Browser
51
+ def supported?
52
+ macos?
53
+ end
54
+
55
+ def setup
56
+ applescript('tell application "Safari" to make new document')
57
+ end
58
+
59
+ def visit(url)
60
+ applescript('tell application "Safari" to set URL of front document to "' + url + '"')
61
+ end
62
+
63
+ def teardown
64
+ #applescript('tell application "Safari" to close front document')
65
+ end
66
+
67
+ def to_s
68
+ "Safari"
69
+ end
70
+ end
71
+
72
+ class IEBrowser < Browser
73
+ def initialize(path='C:\Program Files\Internet Explorer\IEXPLORE.EXE')
74
+ @path = path
75
+ end
76
+
77
+ def setup
78
+ if windows?
79
+ puts %{
80
+ MAJOR ANNOYANCE on Windows.
81
+ You have to shut down the Internet Explorer manually after each test
82
+ for the script to proceed.
83
+ Any suggestions on fixing this is GREATLY appreaciated!
84
+ Thank you for your understanding.
85
+ }
86
+ end
87
+ end
88
+
89
+ def supported?
90
+ windows?
91
+ end
92
+
93
+ def visit(url)
94
+ system("#{@path} #{url}") if windows?
95
+ end
96
+
97
+ def to_s
98
+ "Internet Explorer"
99
+ end
100
+ end
101
+
102
+ class KonquerorBrowser < Browser
103
+ def supported?
104
+ linux?
105
+ end
106
+
107
+ def visit(url)
108
+ system("kfmclient openURL #{url}")
109
+ end
110
+
111
+ def to_s
112
+ "Konqueror"
113
+ end
114
+ end
115
+
116
+ # shut up, webrick :-)
117
+ class ::WEBrick::HTTPServer
118
+ def access_log(config, req, res)
119
+ # nop
120
+ end
121
+ end
122
+ class ::WEBrick::BasicLog
123
+ def log(level, data)
124
+ # nop
125
+ end
126
+ end
127
+
128
+ class JavaScriptTestTask < ::Rake::TaskLib
129
+
130
+ def initialize(name=:test)
131
+ @name = name
132
+ @tests = []
133
+ @browsers = []
134
+
135
+ @queue = Queue.new
136
+
137
+ result = []
138
+
139
+ @server = WEBrick::HTTPServer.new(:Port => 4711) # TODO: make port configurable
140
+ @server.mount_proc("/results") do |req, res|
141
+ @queue.push(req.query['result'])
142
+ res.body = "OK"
143
+ end
144
+ yield self if block_given?
145
+ define
146
+ end
147
+
148
+ def define
149
+ task @name do
150
+ trap("INT") { @server.shutdown }
151
+ t = Thread.new { @server.start }
152
+
153
+ # run all combinations of browsers and tests
154
+ @browsers.each do |browser|
155
+ if browser.supported?
156
+ browser.setup
157
+ @tests.each do |test|
158
+ browser.visit("http://localhost:4711#{test}?resultsURL=http://localhost:4711/results&t=" + ("%.6f" % Time.now.to_f))
159
+ result = @queue.pop
160
+ puts "#{test} on #{browser}: #{result}"
161
+ end
162
+ browser.teardown
163
+ else
164
+ puts "Skipping #{browser}, not supported on this OS"
165
+ end
166
+ browser.teardown
167
+ end
168
+
169
+ @server.shutdown
170
+ t.join
171
+ end
172
+ end
173
+
174
+ def mount(path, dir=nil)
175
+ dir = Dir.pwd + path unless dir
176
+
177
+ @server.mount(path, WEBrick::HTTPServlet::FileHandler, dir)
178
+ end
179
+
180
+ # test should be specified as a url
181
+ def run(test)
182
+ @tests<<test
183
+ end
184
+
185
+ def browser(browser)
186
+ browser =
187
+ case(browser)
188
+ when :firefox
189
+ FirefoxBrowser.new
190
+ when :safari
191
+ SafariBrowser.new
192
+ when :ie
193
+ IEBrowser.new
194
+ when :konqueror
195
+ KonquerorBrowser.new
196
+ else
197
+ browser
198
+ end
199
+
200
+ @browsers<<browser
201
+ end
202
+ end
203
+
@@ -0,0 +1,66 @@
1
+ // Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
2
+ //
3
+ // Permission is hereby granted, free of charge, to any person obtaining
4
+ // a copy of this software and associated documentation files (the
5
+ // "Software"), to deal in the Software without restriction, including
6
+ // without limitation the rights to use, copy, modify, merge, publish,
7
+ // distribute, sublicense, and/or sell copies of the Software, and to
8
+ // permit persons to whom the Software is furnished to do so, subject to
9
+ // the following conditions:
10
+ //
11
+ // The above copyright notice and this permission notice shall be
12
+ // included in all copies or substantial portions of the Software.
13
+ //
14
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+ //
22
+ // For details, see the script.aculo.us web site: http://script.aculo.us/
23
+
24
+ var Scriptaculous = {
25
+ Version: '1.8.2',
26
+ require: function(libraryName) {
27
+ try{
28
+ // inserting via DOM fails in Safari 2.0, so brute force approach
29
+ document.write('<script type="text/javascript" src="'+libraryName+'"><\/script>');
30
+ } catch(e) {
31
+ // for xhtml+xml served content, fall back to DOM methods
32
+ var script = document.createElement('script');
33
+ script.type = 'text/javascript';
34
+ script.src = libraryName;
35
+ document.getElementsByTagName('head')[0].appendChild(script);
36
+ }
37
+ },
38
+ REQUIRED_PROTOTYPE: '1.6.0.3',
39
+ load: function() {
40
+ function convertVersionString(versionString) {
41
+ var v = versionString.replace(/_.*|\./g, '');
42
+ v = parseInt(v + '0'.times(4-v.length));
43
+ return versionString.indexOf('_') > -1 ? v-1 : v;
44
+ }
45
+
46
+ if((typeof Prototype=='undefined') ||
47
+ (typeof Element == 'undefined') ||
48
+ (typeof Element.Methods=='undefined') ||
49
+ (convertVersionString(Prototype.Version) <
50
+ convertVersionString(Scriptaculous.REQUIRED_PROTOTYPE)))
51
+ throw("script.aculo.us requires the Prototype JavaScript framework >= " +
52
+ Scriptaculous.REQUIRED_PROTOTYPE);
53
+
54
+ var js = /scriptaculous\.js(\?.*)?$/;
55
+ $$('head script[src]').findAll(function(s) {
56
+ return s.src.match(js);
57
+ }).each(function(s) {
58
+ var path = s.src.replace(js, ''),
59
+ includes = s.src.match(/\?.*load=([a-z,]*)/);
60
+ (includes ? includes[1] : 'builder,effects,dragdrop,controls,slider,sound').split(',').each(
61
+ function(include) { Scriptaculous.require(path+include+'.js') });
62
+ });
63
+ }
64
+ };
65
+
66
+ Scriptaculous.load();
@@ -0,0 +1,273 @@
1
+ // Copyright (c) 2005-2008 Marty Haught, Thomas Fuchs
2
+ //
3
+ // script.aculo.us is freely distributable under the terms of an MIT-style license.
4
+ // For details, see the script.aculo.us web site: http://script.aculo.us/
5
+
6
+ if (!Control) var Control = { };
7
+
8
+ // options:
9
+ // axis: 'vertical', or 'horizontal' (default)
10
+ //
11
+ // callbacks:
12
+ // onChange(value)
13
+ // onSlide(value)
14
+ Control.Slider = Class.create({
15
+ initialize: function(handle, track, options) {
16
+ var slider = this;
17
+
18
+ if (Object.isArray(handle)) {
19
+ this.handles = handle.collect( function(e) { return $(e) });
20
+ } else {
21
+ this.handles = [$(handle)];
22
+ }
23
+
24
+ this.track = $(track);
25
+ this.options = options || { };
26
+
27
+ this.axis = this.options.axis || 'horizontal';
28
+ this.increment = this.options.increment || 1;
29
+ this.step = parseInt(this.options.step || '1');
30
+ this.range = this.options.range || $R(0,1);
31
+
32
+ this.value = 0; // assure backwards compat
33
+ this.values = this.handles.map( function() { return 0 });
34
+ this.spans = this.options.spans ? this.options.spans.map(function(s){ return $(s) }) : false;
35
+ this.options.startSpan = $(this.options.startSpan || null);
36
+ this.options.endSpan = $(this.options.endSpan || null);
37
+
38
+ this.restricted = this.options.restricted || false;
39
+
40
+ this.maximum = this.options.maximum || this.range.end;
41
+ this.minimum = this.options.minimum || this.range.start;
42
+
43
+ // Will be used to align the handle onto the track, if necessary
44
+ this.alignX = parseInt(this.options.alignX || '0');
45
+ this.alignY = parseInt(this.options.alignY || '0');
46
+
47
+ this.trackLength = this.maximumOffset() - this.minimumOffset();
48
+
49
+ this.handleLength = this.isVertical() ?
50
+ (this.handles[0].offsetHeight != 0 ?
51
+ this.handles[0].offsetHeight : this.handles[0].style.height.replace(/px$/,"")) :
52
+ (this.handles[0].offsetWidth != 0 ? this.handles[0].offsetWidth :
53
+ this.handles[0].style.width.replace(/px$/,""));
54
+
55
+ this.active = false;
56
+ this.dragging = false;
57
+ this.disabled = false;
58
+
59
+ if (this.options.disabled) this.setDisabled();
60
+
61
+ // Allowed values array
62
+ this.allowedValues = this.options.values ? this.options.values.sortBy(Prototype.K) : false;
63
+ if (this.allowedValues) {
64
+ this.minimum = this.allowedValues.min();
65
+ this.maximum = this.allowedValues.max();
66
+ }
67
+
68
+ this.eventMouseDown = this.startDrag.bindAsEventListener(this);
69
+ this.eventMouseUp = this.endDrag.bindAsEventListener(this);
70
+ this.eventMouseMove = this.update.bindAsEventListener(this);
71
+
72
+ // Initialize handles in reverse (make sure first handle is active)
73
+ this.handles.each( function(h,i) {
74
+ i = slider.handles.length-1-i;
75
+ slider.setValue(parseFloat(
76
+ (Object.isArray(slider.options.sliderValue) ?
77
+ slider.options.sliderValue[i] : slider.options.sliderValue) ||
78
+ slider.range.start), i);
79
+ h.makePositioned().observe("mousedown", slider.eventMouseDown);
80
+ });
81
+
82
+ this.track.observe("mousedown", this.eventMouseDown);
83
+ document.observe("mouseup", this.eventMouseUp);
84
+ document.observe("mousemove", this.eventMouseMove);
85
+
86
+ this.initialized = true;
87
+ },
88
+ dispose: function() {
89
+ var slider = this;
90
+ Event.stopObserving(this.track, "mousedown", this.eventMouseDown);
91
+ Event.stopObserving(document, "mouseup", this.eventMouseUp);
92
+ Event.stopObserving(document, "mousemove", this.eventMouseMove);
93
+ this.handles.each( function(h) {
94
+ Event.stopObserving(h, "mousedown", slider.eventMouseDown);
95
+ });
96
+ },
97
+ setDisabled: function(){
98
+ this.disabled = true;
99
+ },
100
+ setEnabled: function(){
101
+ this.disabled = false;
102
+ },
103
+ getNearestValue: function(value){
104
+ if (this.allowedValues){
105
+ if (value >= this.allowedValues.max()) return(this.allowedValues.max());
106
+ if (value <= this.allowedValues.min()) return(this.allowedValues.min());
107
+
108
+ var offset = Math.abs(this.allowedValues[0] - value);
109
+ var newValue = this.allowedValues[0];
110
+ this.allowedValues.each( function(v) {
111
+ var currentOffset = Math.abs(v - value);
112
+ if (currentOffset <= offset){
113
+ newValue = v;
114
+ offset = currentOffset;
115
+ }
116
+ });
117
+ return newValue;
118
+ }
119
+ if (value > this.range.end) return this.range.end;
120
+ if (value < this.range.start) return this.range.start;
121
+ return value;
122
+ },
123
+ setValue: function(sliderValue, handleIdx){
124
+ if (!this.active) {
125
+ this.activeHandleIdx = handleIdx || 0;
126
+ this.activeHandle = this.handles[this.activeHandleIdx];
127
+ this.updateStyles();
128
+ }
129
+ handleIdx = handleIdx || this.activeHandleIdx || 0;
130
+ if (this.initialized && this.restricted) {
131
+ if ((handleIdx>0) && (sliderValue<this.values[handleIdx-1]))
132
+ sliderValue = this.values[handleIdx-1];
133
+ if ((handleIdx < (this.handles.length-1)) && (sliderValue>this.values[handleIdx+1]))
134
+ sliderValue = this.values[handleIdx+1];
135
+ }
136
+ sliderValue = this.getNearestValue(sliderValue);
137
+ this.values[handleIdx] = sliderValue;
138
+ this.value = this.values[0]; // assure backwards compat
139
+
140
+ this.handles[handleIdx].style[this.isVertical() ? 'top' : 'left'] =
141
+ this.translateToPx(sliderValue);
142
+
143
+ this.drawSpans();
144
+ if (!this.dragging || !this.event) this.updateFinished();
145
+ },
146
+ setValueBy: function(delta, handleIdx) {
147
+ this.setValue(this.values[handleIdx || this.activeHandleIdx || 0] + delta,
148
+ handleIdx || this.activeHandleIdx || 0);
149
+ },
150
+ translateToPx: function(value) {
151
+ return Math.round(
152
+ ((this.trackLength-this.handleLength)/(this.range.end-this.range.start)) *
153
+ (value - this.range.start)) + "px";
154
+ },
155
+ translateToValue: function(offset) {
156
+ return ((offset/(this.trackLength-this.handleLength) *
157
+ (this.range.end-this.range.start)) + this.range.start);
158
+ },
159
+ getRange: function(range) {
160
+ var v = this.values.sortBy(Prototype.K);
161
+ range = range || 0;
162
+ return $R(v[range],v[range+1]);
163
+ },
164
+ minimumOffset: function(){
165
+ return(this.isVertical() ? this.alignY : this.alignX);
166
+ },
167
+ maximumOffset: function(){
168
+ return(this.isVertical() ?
169
+ (this.track.offsetHeight != 0 ? this.track.offsetHeight :
170
+ this.track.style.height.replace(/px$/,"")) - this.alignY :
171
+ (this.track.offsetWidth != 0 ? this.track.offsetWidth :
172
+ this.track.style.width.replace(/px$/,"")) - this.alignX);
173
+ },
174
+ isVertical: function(){
175
+ return (this.axis == 'vertical');
176
+ },
177
+ drawSpans: function() {
178
+ var slider = this;
179
+ if (this.spans)
180
+ $R(0, this.spans.length-1).each(function(r) { slider.setSpan(slider.spans[r], slider.getRange(r)) });
181
+ if (this.options.startSpan)
182
+ this.setSpan(this.options.startSpan,
183
+ $R(0, this.values.length>1 ? this.getRange(0).min() : this.value ));
184
+ if (this.options.endSpan)
185
+ this.setSpan(this.options.endSpan,
186
+ $R(this.values.length>1 ? this.getRange(this.spans.length-1).max() : this.value, this.maximum));
187
+ },
188
+ setSpan: function(span, range) {
189
+ if (this.isVertical()) {
190
+ span.style.top = this.translateToPx(range.start);
191
+ span.style.height = this.translateToPx(range.end - range.start + this.range.start);
192
+ } else {
193
+ span.style.left = this.translateToPx(range.start);
194
+ span.style.width = this.translateToPx(range.end - range.start + this.range.start);
195
+ }
196
+ },
197
+ updateStyles: function() {
198
+ this.handles.each( function(h){ Element.removeClassName(h, 'selected') });
199
+ Element.addClassName(this.activeHandle, 'selected');
200
+ },
201
+ startDrag: function(event) {
202
+ if (Event.isLeftClick(event)) {
203
+ if (!this.disabled){
204
+ this.active = true;
205
+
206
+ var handle = Event.element(event);
207
+ var pointer = [Event.pointerX(event), Event.pointerY(event)];
208
+ var track = handle;
209
+ if (track==this.track) {
210
+ var offsets = Position.cumulativeOffset(this.track);
211
+ this.event = event;
212
+ this.setValue(this.translateToValue(
213
+ (this.isVertical() ? pointer[1]-offsets[1] : pointer[0]-offsets[0])-(this.handleLength/2)
214
+ ));
215
+ var offsets = Position.cumulativeOffset(this.activeHandle);
216
+ this.offsetX = (pointer[0] - offsets[0]);
217
+ this.offsetY = (pointer[1] - offsets[1]);
218
+ } else {
219
+ // find the handle (prevents issues with Safari)
220
+ while((this.handles.indexOf(handle) == -1) && handle.parentNode)
221
+ handle = handle.parentNode;
222
+
223
+ if (this.handles.indexOf(handle)!=-1) {
224
+ this.activeHandle = handle;
225
+ this.activeHandleIdx = this.handles.indexOf(this.activeHandle);
226
+ this.updateStyles();
227
+
228
+ var offsets = Position.cumulativeOffset(this.activeHandle);
229
+ this.offsetX = (pointer[0] - offsets[0]);
230
+ this.offsetY = (pointer[1] - offsets[1]);
231
+ }
232
+ }
233
+ }
234
+ Event.stop(event);
235
+ }
236
+ },
237
+ update: function(event) {
238
+ if (this.active) {
239
+ if (!this.dragging) this.dragging = true;
240
+ this.draw(event);
241
+ if (Prototype.Browser.WebKit) window.scrollBy(0,0);
242
+ Event.stop(event);
243
+ }
244
+ },
245
+ draw: function(event) {
246
+ var pointer = [Event.pointerX(event), Event.pointerY(event)];
247
+ var offsets = Position.cumulativeOffset(this.track);
248
+ pointer[0] -= this.offsetX + offsets[0];
249
+ pointer[1] -= this.offsetY + offsets[1];
250
+ this.event = event;
251
+ this.setValue(this.translateToValue( this.isVertical() ? pointer[1] : pointer[0] ));
252
+ if (this.initialized && this.options.onSlide)
253
+ this.options.onSlide(this.values.length>1 ? this.values : this.value, this);
254
+ },
255
+ endDrag: function(event) {
256
+ if (this.active && this.dragging) {
257
+ this.finishDrag(event, true);
258
+ Event.stop(event);
259
+ }
260
+ this.active = false;
261
+ this.dragging = false;
262
+ },
263
+ finishDrag: function(event, success) {
264
+ this.active = false;
265
+ this.dragging = false;
266
+ this.updateFinished();
267
+ },
268
+ updateFinished: function() {
269
+ if (this.initialized && this.options.onChange)
270
+ this.options.onChange(this.values.length>1 ? this.values : this.value, this);
271
+ this.event = null;
272
+ }
273
+ });
@@ -0,0 +1,57 @@
1
+ // Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
2
+ //
3
+ // Based on code created by Jules Gravinese (http://www.webveteran.com/)
4
+ //
5
+ // script.aculo.us is freely distributable under the terms of an MIT-style license.
6
+ // For details, see the script.aculo.us web site: http://script.aculo.us/
7
+
8
+ Sound = {
9
+ tracks: {},
10
+ _enabled: true,
11
+ template:
12
+ new Template('<embed style="height:0" id="sound_#{track}_#{id}" src="#{url}" loop="false" autostart="true" hidden="true"/>'),
13
+ enable: function(){
14
+ Sound._enabled = true;
15
+ },
16
+ disable: function(){
17
+ Sound._enabled = false;
18
+ },
19
+ play: function(url){
20
+ if(!Sound._enabled) return;
21
+ var options = Object.extend({
22
+ track: 'global', url: url, replace: false
23
+ }, arguments[1] || {});
24
+
25
+ if(options.replace && this.tracks[options.track]) {
26
+ $R(0, this.tracks[options.track].id).each(function(id){
27
+ var sound = $('sound_'+options.track+'_'+id);
28
+ sound.Stop && sound.Stop();
29
+ sound.remove();
30
+ });
31
+ this.tracks[options.track] = null;
32
+ }
33
+
34
+ if(!this.tracks[options.track])
35
+ this.tracks[options.track] = { id: 0 };
36
+ else
37
+ this.tracks[options.track].id++;
38
+
39
+ options.id = this.tracks[options.track].id;
40
+ $$('body')[0].insert(
41
+ Prototype.Browser.IE ? new Element('bgsound',{
42
+ id: 'sound_'+options.track+'_'+options.id,
43
+ src: options.url, loop: 1, autostart: true
44
+ }) : Sound.template.evaluate(options));
45
+ }
46
+ };
47
+
48
+ if(Prototype.Browser.Gecko && navigator.userAgent.indexOf("Win") > 0){
49
+ if(navigator.plugins && $A(navigator.plugins).detect(function(p){ return p.name.indexOf('QuickTime') != -1 }))
50
+ Sound.template = new Template('<object id="sound_#{track}_#{id}" width="0" height="0" type="audio/mpeg" data="#{url}"/>');
51
+ else if(navigator.plugins && $A(navigator.plugins).detect(function(p){ return p.name.indexOf('Windows Media') != -1 }))
52
+ Sound.template = new Template('<object id="sound_#{track}_#{id}" type="application/x-mplayer2" data="#{url}"></object>');
53
+ else if(navigator.plugins && $A(navigator.plugins).detect(function(p){ return p.name.indexOf('RealPlayer') != -1 }))
54
+ Sound.template = new Template('<embed type="audio/x-pn-realaudio-plugin" style="height:0" id="sound_#{track}_#{id}" src="#{url}" loop="false" autostart="true" hidden="true"/>');
55
+ else
56
+ Sound.play = function(){};
57
+ }