Description:
more updated rails
git-svn-id: http://theory.cpe.ku.ac.th/grader/web/trunk@360 6386c4cd-e34a-4fa8-8920-d93eb39b512e
Commit status:
[Not Reviewed]
References:
Diff options:
Comments:
0 Commit comments
0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
r163:74e3afe899a3 - - The requested commit is too big and content was truncated. 5 files changed. Show full diff
@@ -1,109 +1,110 | |||
|
1 | 1 | # Don't change this file! |
|
2 | 2 | # Configure your app in config/environment.rb and config/environments/*.rb |
|
3 | 3 | |
|
4 | 4 | RAILS_ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(RAILS_ROOT) |
|
5 | 5 | |
|
6 | 6 | module Rails |
|
7 | 7 | class << self |
|
8 | 8 | def boot! |
|
9 | 9 | unless booted? |
|
10 | 10 | preinitialize |
|
11 | 11 | pick_boot.run |
|
12 | 12 | end |
|
13 | 13 | end |
|
14 | 14 | |
|
15 | 15 | def booted? |
|
16 | 16 | defined? Rails::Initializer |
|
17 | 17 | end |
|
18 | 18 | |
|
19 | 19 | def pick_boot |
|
20 | 20 | (vendor_rails? ? VendorBoot : GemBoot).new |
|
21 | 21 | end |
|
22 | 22 | |
|
23 | 23 | def vendor_rails? |
|
24 | 24 | File.exist?("#{RAILS_ROOT}/vendor/rails") |
|
25 | 25 | end |
|
26 | 26 | |
|
27 | 27 | def preinitialize |
|
28 | 28 | load(preinitializer_path) if File.exist?(preinitializer_path) |
|
29 | 29 | end |
|
30 | 30 | |
|
31 | 31 | def preinitializer_path |
|
32 | 32 | "#{RAILS_ROOT}/config/preinitializer.rb" |
|
33 | 33 | end |
|
34 | 34 | end |
|
35 | 35 | |
|
36 | 36 | class Boot |
|
37 | 37 | def run |
|
38 | 38 | load_initializer |
|
39 | 39 | Rails::Initializer.run(:set_load_path) |
|
40 | 40 | end |
|
41 | 41 | end |
|
42 | 42 | |
|
43 | 43 | class VendorBoot < Boot |
|
44 | 44 | def load_initializer |
|
45 | 45 | require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer" |
|
46 | 46 | Rails::Initializer.run(:install_gem_spec_stubs) |
|
47 | + Rails::GemDependency.add_frozen_gem_path | |
|
47 | 48 | end |
|
48 | 49 | end |
|
49 | 50 | |
|
50 | 51 | class GemBoot < Boot |
|
51 | 52 | def load_initializer |
|
52 | 53 | self.class.load_rubygems |
|
53 | 54 | load_rails_gem |
|
54 | 55 | require 'initializer' |
|
55 | 56 | end |
|
56 | 57 | |
|
57 | 58 | def load_rails_gem |
|
58 | 59 | if version = self.class.gem_version |
|
59 | 60 | gem 'rails', version |
|
60 | 61 | else |
|
61 | 62 | gem 'rails' |
|
62 | 63 | end |
|
63 | 64 | rescue Gem::LoadError => load_error |
|
64 | 65 | $stderr.puts %(Missing the Rails #{version} gem. Please `gem install -v=#{version} rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed.) |
|
65 | 66 | exit 1 |
|
66 | 67 | end |
|
67 | 68 | |
|
68 | 69 | class << self |
|
69 | 70 | def rubygems_version |
|
70 |
- Gem::RubyGemsVersion |
|
|
71 | + Gem::RubyGemsVersion rescue nil | |
|
71 | 72 | end |
|
72 | 73 | |
|
73 | 74 | def gem_version |
|
74 | 75 | if defined? RAILS_GEM_VERSION |
|
75 | 76 | RAILS_GEM_VERSION |
|
76 | 77 | elsif ENV.include?('RAILS_GEM_VERSION') |
|
77 | 78 | ENV['RAILS_GEM_VERSION'] |
|
78 | 79 | else |
|
79 | 80 | parse_gem_version(read_environment_rb) |
|
80 | 81 | end |
|
81 | 82 | end |
|
82 | 83 | |
|
83 | 84 | def load_rubygems |
|
84 | 85 | require 'rubygems' |
|
85 |
- min_version = '1. |
|
|
86 | + min_version = '1.3.1' | |
|
86 | 87 | unless rubygems_version >= min_version |
|
87 | 88 | $stderr.puts %Q(Rails requires RubyGems >= #{min_version} (you have #{rubygems_version}). Please `gem update --system` and try again.) |
|
88 | 89 | exit 1 |
|
89 | 90 | end |
|
90 | 91 | |
|
91 | 92 | rescue LoadError |
|
92 | 93 | $stderr.puts %Q(Rails requires RubyGems >= #{min_version}. Please install RubyGems and try again: http://rubygems.rubyforge.org) |
|
93 | 94 | exit 1 |
|
94 | 95 | end |
|
95 | 96 | |
|
96 | 97 | def parse_gem_version(text) |
|
97 | 98 | $1 if text =~ /^[^#]*RAILS_GEM_VERSION\s*=\s*["']([!~<>=]*\s*[\d.]+)["']/ |
|
98 | 99 | end |
|
99 | 100 | |
|
100 | 101 | private |
|
101 | 102 | def read_environment_rb |
|
102 | 103 | File.read("#{RAILS_ROOT}/config/environment.rb") |
|
103 | 104 | end |
|
104 | 105 | end |
|
105 | 106 | end |
|
106 | 107 | end |
|
107 | 108 | |
|
108 | 109 | # All that for this: |
|
109 | 110 | Rails.boot! |
@@ -1,314 +1,314 | |||
|
1 | 1 | // Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) |
|
2 |
- // (c) 2005-200 |
|
|
3 |
- // (c) 2005-200 |
|
|
2 | + // (c) 2005-2008 Ivan Krstic (http://blogs.law.harvard.edu/ivan) | |
|
3 | + // (c) 2005-2008 Jon Tirsen (http://www.tirsen.com) | |
|
4 | 4 | // Contributors: |
|
5 | 5 | // Richard Livsey |
|
6 | 6 | // Rahul Bhargava |
|
7 | 7 | // Rob Wills |
|
8 | 8 |
// |
|
9 | 9 | // script.aculo.us is freely distributable under the terms of an MIT-style license. |
|
10 | 10 | // For details, see the script.aculo.us web site: http://script.aculo.us/ |
|
11 | 11 | |
|
12 | 12 |
// Autocompleter.Base handles all the autocompletion functionality |
|
13 | 13 | // that's independent of the data source for autocompletion. This |
|
14 | 14 | // includes drawing the autocompletion menu, observing keyboard |
|
15 | 15 | // and mouse events, and similar. |
|
16 | 16 | // |
|
17 | 17 |
// Specific autocompleters need to provide, at the very least, |
|
18 | 18 | // a getUpdatedChoices function that will be invoked every time |
|
19 | 19 |
// the text inside the monitored textbox changes. This method |
|
20 | 20 | // should get the text for which to provide autocompletion by |
|
21 | 21 | // invoking this.getToken(), NOT by directly accessing |
|
22 | 22 | // this.element.value. This is to allow incremental tokenized |
|
23 | 23 | // autocompletion. Specific auto-completion logic (AJAX, etc) |
|
24 | 24 | // belongs in getUpdatedChoices. |
|
25 | 25 | // |
|
26 | 26 | // Tokenized incremental autocompletion is enabled automatically |
|
27 | 27 | // when an autocompleter is instantiated with the 'tokens' option |
|
28 | 28 | // in the options parameter, e.g.: |
|
29 | 29 | // new Ajax.Autocompleter('id','upd', '/url/', { tokens: ',' }); |
|
30 | 30 | // will incrementally autocomplete with a comma as the token. |
|
31 | 31 | // Additionally, ',' in the above example can be replaced with |
|
32 | 32 | // a token array, e.g. { tokens: [',', '\n'] } which |
|
33 | 33 |
// enables autocompletion on multiple tokens. This is most |
|
34 | 34 |
// useful when one of the tokens is \n (a newline), as it |
|
35 | 35 | // allows smart autocompletion after linebreaks. |
|
36 | 36 | |
|
37 | 37 | if(typeof Effect == 'undefined') |
|
38 | 38 | throw("controls.js requires including script.aculo.us' effects.js library"); |
|
39 | 39 | |
|
40 | - var Autocompleter = { } | |
|
40 | + var Autocompleter = { }; | |
|
41 | 41 | Autocompleter.Base = Class.create({ |
|
42 | 42 | baseInitialize: function(element, update, options) { |
|
43 | - element = $(element) | |
|
43 | + element = $(element); | |
|
44 | 44 |
this.element = element; |
|
45 | 45 |
this.update = $(update); |
|
46 | 46 |
this.hasFocus = false; |
|
47 | 47 |
this.changed = false; |
|
48 | 48 |
this.active = false; |
|
49 | 49 |
this.index = 0; |
|
50 | 50 | this.entryCount = 0; |
|
51 | 51 | this.oldElementValue = this.element.value; |
|
52 | 52 | |
|
53 | 53 | if(this.setOptions) |
|
54 | 54 | this.setOptions(options); |
|
55 | 55 | else |
|
56 | 56 | this.options = options || { }; |
|
57 | 57 | |
|
58 | 58 | this.options.paramName = this.options.paramName || this.element.name; |
|
59 | 59 | this.options.tokens = this.options.tokens || []; |
|
60 | 60 | this.options.frequency = this.options.frequency || 0.4; |
|
61 | 61 | this.options.minChars = this.options.minChars || 1; |
|
62 | 62 |
this.options.onShow = this.options.onShow || |
|
63 | 63 |
function(element, update){ |
|
64 | 64 | if(!update.style.position || update.style.position=='absolute') { |
|
65 | 65 | update.style.position = 'absolute'; |
|
66 | 66 | Position.clone(element, update, { |
|
67 | 67 |
setHeight: false, |
|
68 | 68 | offsetTop: element.offsetHeight |
|
69 | 69 | }); |
|
70 | 70 | } |
|
71 | 71 | Effect.Appear(update,{duration:0.15}); |
|
72 | 72 | }; |
|
73 | 73 |
this.options.onHide = this.options.onHide || |
|
74 | 74 | function(element, update){ new Effect.Fade(update,{duration:0.15}) }; |
|
75 | 75 | |
|
76 | 76 |
if(typeof(this.options.tokens) == 'string') |
|
77 | 77 | this.options.tokens = new Array(this.options.tokens); |
|
78 | 78 | // Force carriage returns as token delimiters anyway |
|
79 | 79 | if (!this.options.tokens.include('\n')) |
|
80 | 80 | this.options.tokens.push('\n'); |
|
81 | 81 | |
|
82 | 82 | this.observer = null; |
|
83 | 83 | |
|
84 | 84 | this.element.setAttribute('autocomplete','off'); |
|
85 | 85 | |
|
86 | 86 | Element.hide(this.update); |
|
87 | 87 | |
|
88 | 88 | Event.observe(this.element, 'blur', this.onBlur.bindAsEventListener(this)); |
|
89 | 89 | Event.observe(this.element, 'keydown', this.onKeyPress.bindAsEventListener(this)); |
|
90 | 90 | }, |
|
91 | 91 | |
|
92 | 92 | show: function() { |
|
93 | 93 | if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update); |
|
94 | 94 |
if(!this.iefix && |
|
95 | 95 | (Prototype.Browser.IE) && |
|
96 | 96 | (Element.getStyle(this.update, 'position')=='absolute')) { |
|
97 | 97 |
new Insertion.After(this.update, |
|
98 | 98 | '<iframe id="' + this.update.id + '_iefix" '+ |
|
99 | 99 | 'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' + |
|
100 | 100 | 'src="javascript:false;" frameborder="0" scrolling="no"></iframe>'); |
|
101 | 101 | this.iefix = $(this.update.id+'_iefix'); |
|
102 | 102 | } |
|
103 | 103 | if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50); |
|
104 | 104 | }, |
|
105 | 105 | |
|
106 | 106 | fixIEOverlapping: function() { |
|
107 | 107 | Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)}); |
|
108 | 108 | this.iefix.style.zIndex = 1; |
|
109 | 109 | this.update.style.zIndex = 2; |
|
110 | 110 | Element.show(this.iefix); |
|
111 | 111 | }, |
|
112 | 112 | |
|
113 | 113 | hide: function() { |
|
114 | 114 | this.stopIndicator(); |
|
115 | 115 | if(Element.getStyle(this.update, 'display')!='none') this.options.onHide(this.element, this.update); |
|
116 | 116 | if(this.iefix) Element.hide(this.iefix); |
|
117 | 117 | }, |
|
118 | 118 | |
|
119 | 119 | startIndicator: function() { |
|
120 | 120 | if(this.options.indicator) Element.show(this.options.indicator); |
|
121 | 121 | }, |
|
122 | 122 | |
|
123 | 123 | stopIndicator: function() { |
|
124 | 124 | if(this.options.indicator) Element.hide(this.options.indicator); |
|
125 | 125 | }, |
|
126 | 126 | |
|
127 | 127 | onKeyPress: function(event) { |
|
128 | 128 | if(this.active) |
|
129 | 129 | switch(event.keyCode) { |
|
130 | 130 | case Event.KEY_TAB: |
|
131 | 131 | case Event.KEY_RETURN: |
|
132 | 132 | this.selectEntry(); |
|
133 | 133 | Event.stop(event); |
|
134 | 134 | case Event.KEY_ESC: |
|
135 | 135 | this.hide(); |
|
136 | 136 | this.active = false; |
|
137 | 137 | Event.stop(event); |
|
138 | 138 | return; |
|
139 | 139 | case Event.KEY_LEFT: |
|
140 | 140 | case Event.KEY_RIGHT: |
|
141 | 141 | return; |
|
142 | 142 | case Event.KEY_UP: |
|
143 | 143 | this.markPrevious(); |
|
144 | 144 | this.render(); |
|
145 | 145 | Event.stop(event); |
|
146 | 146 | return; |
|
147 | 147 | case Event.KEY_DOWN: |
|
148 | 148 | this.markNext(); |
|
149 | 149 | this.render(); |
|
150 | 150 | Event.stop(event); |
|
151 | 151 | return; |
|
152 | 152 | } |
|
153 | 153 |
else |
|
154 | 154 |
if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN || |
|
155 | 155 | (Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return; |
|
156 | 156 | |
|
157 | 157 | this.changed = true; |
|
158 | 158 | this.hasFocus = true; |
|
159 | 159 | |
|
160 | 160 | if(this.observer) clearTimeout(this.observer); |
|
161 | 161 |
this.observer = |
|
162 | 162 | setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000); |
|
163 | 163 | }, |
|
164 | 164 | |
|
165 | 165 | activate: function() { |
|
166 | 166 | this.changed = false; |
|
167 | 167 | this.hasFocus = true; |
|
168 | 168 | this.getUpdatedChoices(); |
|
169 | 169 | }, |
|
170 | 170 | |
|
171 | 171 | onHover: function(event) { |
|
172 | 172 | var element = Event.findElement(event, 'LI'); |
|
173 | 173 |
if(this.index != element.autocompleteIndex) |
|
174 | 174 | { |
|
175 | 175 | this.index = element.autocompleteIndex; |
|
176 | 176 | this.render(); |
|
177 | 177 | } |
|
178 | 178 | Event.stop(event); |
|
179 | 179 | }, |
|
180 | 180 | |
|
181 | 181 | onClick: function(event) { |
|
182 | 182 | var element = Event.findElement(event, 'LI'); |
|
183 | 183 | this.index = element.autocompleteIndex; |
|
184 | 184 | this.selectEntry(); |
|
185 | 185 | this.hide(); |
|
186 | 186 | }, |
|
187 | 187 | |
|
188 | 188 | onBlur: function(event) { |
|
189 | 189 | // needed to make click events working |
|
190 | 190 | setTimeout(this.hide.bind(this), 250); |
|
191 | 191 | this.hasFocus = false; |
|
192 | 192 |
this.active = false; |
|
193 | 193 |
}, |
|
194 | 194 | |
|
195 | 195 | render: function() { |
|
196 | 196 | if(this.entryCount > 0) { |
|
197 | 197 | for (var i = 0; i < this.entryCount; i++) |
|
198 | 198 |
this.index==i ? |
|
199 | 199 |
Element.addClassName(this.getEntry(i),"selected") : |
|
200 | 200 | Element.removeClassName(this.getEntry(i),"selected"); |
|
201 | 201 |
if(this.hasFocus) { |
|
202 | 202 | this.show(); |
|
203 | 203 | this.active = true; |
|
204 | 204 | } |
|
205 | 205 | } else { |
|
206 | 206 | this.active = false; |
|
207 | 207 | this.hide(); |
|
208 | 208 | } |
|
209 | 209 | }, |
|
210 | 210 | |
|
211 | 211 | markPrevious: function() { |
|
212 | - if(this.index > 0) this.index-- | |
|
212 | + if(this.index > 0) this.index--; | |
|
213 | 213 | else this.index = this.entryCount-1; |
|
214 | 214 | this.getEntry(this.index).scrollIntoView(true); |
|
215 | 215 | }, |
|
216 | 216 | |
|
217 | 217 | markNext: function() { |
|
218 | - if(this.index < this.entryCount-1) this.index++ | |
|
218 | + if(this.index < this.entryCount-1) this.index++; | |
|
219 | 219 | else this.index = 0; |
|
220 | 220 | this.getEntry(this.index).scrollIntoView(false); |
|
221 | 221 | }, |
|
222 | 222 | |
|
223 | 223 | getEntry: function(index) { |
|
224 | 224 | return this.update.firstChild.childNodes[index]; |
|
225 | 225 | }, |
|
226 | 226 | |
|
227 | 227 | getCurrentEntry: function() { |
|
228 | 228 | return this.getEntry(this.index); |
|
229 | 229 | }, |
|
230 | 230 | |
|
231 | 231 | selectEntry: function() { |
|
232 | 232 | this.active = false; |
|
233 | 233 | this.updateElement(this.getCurrentEntry()); |
|
234 | 234 | }, |
|
235 | 235 | |
|
236 | 236 | updateElement: function(selectedElement) { |
|
237 | 237 | if (this.options.updateElement) { |
|
238 | 238 | this.options.updateElement(selectedElement); |
|
239 | 239 | return; |
|
240 | 240 | } |
|
241 | 241 | var value = ''; |
|
242 | 242 | if (this.options.select) { |
|
243 | 243 | var nodes = $(selectedElement).select('.' + this.options.select) || []; |
|
244 | 244 | if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select); |
|
245 | 245 | } else |
|
246 | 246 | value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal'); |
|
247 | 247 | |
|
248 | 248 | var bounds = this.getTokenBounds(); |
|
249 | 249 | if (bounds[0] != -1) { |
|
250 | 250 | var newValue = this.element.value.substr(0, bounds[0]); |
|
251 | 251 | var whitespace = this.element.value.substr(bounds[0]).match(/^\s+/); |
|
252 | 252 | if (whitespace) |
|
253 | 253 | newValue += whitespace[0]; |
|
254 | 254 | this.element.value = newValue + value + this.element.value.substr(bounds[1]); |
|
255 | 255 | } else { |
|
256 | 256 | this.element.value = value; |
|
257 | 257 | } |
|
258 | 258 | this.oldElementValue = this.element.value; |
|
259 | 259 | this.element.focus(); |
|
260 | 260 | |
|
261 | 261 | if (this.options.afterUpdateElement) |
|
262 | 262 | this.options.afterUpdateElement(this.element, selectedElement); |
|
263 | 263 | }, |
|
264 | 264 | |
|
265 | 265 | updateChoices: function(choices) { |
|
266 | 266 | if(!this.changed && this.hasFocus) { |
|
267 | 267 | this.update.innerHTML = choices; |
|
268 | 268 | Element.cleanWhitespace(this.update); |
|
269 | 269 | Element.cleanWhitespace(this.update.down()); |
|
270 | 270 | |
|
271 | 271 | if(this.update.firstChild && this.update.down().childNodes) { |
|
272 | 272 |
this.entryCount = |
|
273 | 273 | this.update.down().childNodes.length; |
|
274 | 274 | for (var i = 0; i < this.entryCount; i++) { |
|
275 | 275 | var entry = this.getEntry(i); |
|
276 | 276 | entry.autocompleteIndex = i; |
|
277 | 277 | this.addObservers(entry); |
|
278 | 278 | } |
|
279 | 279 |
} else { |
|
280 | 280 | this.entryCount = 0; |
|
281 | 281 | } |
|
282 | 282 | |
|
283 | 283 | this.stopIndicator(); |
|
284 | 284 | this.index = 0; |
|
285 | 285 | |
|
286 | 286 | if(this.entryCount==1 && this.options.autoSelect) { |
|
287 | 287 | this.selectEntry(); |
|
288 | 288 | this.hide(); |
|
289 | 289 | } else { |
|
290 | 290 | this.render(); |
|
291 | 291 | } |
|
292 | 292 | } |
|
293 | 293 | }, |
|
294 | 294 | |
|
295 | 295 | addObservers: function(element) { |
|
296 | 296 | Event.observe(element, "mouseover", this.onHover.bindAsEventListener(this)); |
|
297 | 297 | Event.observe(element, "click", this.onClick.bindAsEventListener(this)); |
|
298 | 298 | }, |
|
299 | 299 | |
|
300 | 300 | onObserverEvent: function() { |
|
301 | 301 |
this.changed = false; |
|
302 | 302 | this.tokenBounds = null; |
|
303 | 303 | if(this.getToken().length>=this.options.minChars) { |
|
304 | 304 | this.getUpdatedChoices(); |
|
305 | 305 | } else { |
|
306 | 306 | this.active = false; |
|
307 | 307 | this.hide(); |
|
308 | 308 | } |
|
309 | 309 | this.oldElementValue = this.element.value; |
|
310 | 310 | }, |
|
311 | 311 | |
|
312 | 312 | getToken: function() { |
|
313 | 313 | var bounds = this.getTokenBounds(); |
|
314 | 314 | return this.element.value.substring(bounds[0], bounds[1]).strip(); |
@@ -364,600 +364,600 | |||
|
364 | 364 | new Ajax.Request(this.url, this.options); |
|
365 | 365 | }, |
|
366 | 366 | |
|
367 | 367 | onComplete: function(request) { |
|
368 | 368 | this.updateChoices(request.responseText); |
|
369 | 369 | } |
|
370 | 370 | }); |
|
371 | 371 | |
|
372 | 372 | // The local array autocompleter. Used when you'd prefer to |
|
373 | 373 | // inject an array of autocompletion options into the page, rather |
|
374 | 374 | // than sending out Ajax queries, which can be quite slow sometimes. |
|
375 | 375 | // |
|
376 | 376 | // The constructor takes four parameters. The first two are, as usual, |
|
377 | 377 | // the id of the monitored textbox, and id of the autocompletion menu. |
|
378 | 378 | // The third is the array you want to autocomplete from, and the fourth |
|
379 | 379 | // is the options block. |
|
380 | 380 | // |
|
381 | 381 | // Extra local autocompletion options: |
|
382 | 382 | // - choices - How many autocompletion choices to offer |
|
383 | 383 | // |
|
384 | 384 | // - partialSearch - If false, the autocompleter will match entered |
|
385 | 385 |
// text only at the beginning of strings in the |
|
386 | 386 | // autocomplete array. Defaults to true, which will |
|
387 | 387 | // match text at the beginning of any *word* in the |
|
388 | 388 | // strings in the autocomplete array. If you want to |
|
389 | 389 | // search anywhere in the string, additionally set |
|
390 | 390 | // the option fullSearch to true (default: off). |
|
391 | 391 | // |
|
392 | 392 | // - fullSsearch - Search anywhere in autocomplete array strings. |
|
393 | 393 | // |
|
394 | 394 | // - partialChars - How many characters to enter before triggering |
|
395 | 395 | // a partial match (unlike minChars, which defines |
|
396 | 396 | // how many characters are required to do any match |
|
397 | 397 | // at all). Defaults to 2. |
|
398 | 398 | // |
|
399 | 399 | // - ignoreCase - Whether to ignore case when autocompleting. |
|
400 | 400 | // Defaults to true. |
|
401 | 401 | // |
|
402 | 402 |
// It's possible to pass in a custom function as the 'selector' |
|
403 | 403 | // option, if you prefer to write your own autocompletion logic. |
|
404 | 404 | // In that case, the other options above will not apply unless |
|
405 | 405 | // you support them. |
|
406 | 406 | |
|
407 | 407 | Autocompleter.Local = Class.create(Autocompleter.Base, { |
|
408 | 408 | initialize: function(element, update, array, options) { |
|
409 | 409 | this.baseInitialize(element, update, options); |
|
410 | 410 | this.options.array = array; |
|
411 | 411 | }, |
|
412 | 412 | |
|
413 | 413 | getUpdatedChoices: function() { |
|
414 | 414 | this.updateChoices(this.options.selector(this)); |
|
415 | 415 | }, |
|
416 | 416 | |
|
417 | 417 | setOptions: function(options) { |
|
418 | 418 | this.options = Object.extend({ |
|
419 | 419 | choices: 10, |
|
420 | 420 | partialSearch: true, |
|
421 | 421 | partialChars: 2, |
|
422 | 422 | ignoreCase: true, |
|
423 | 423 | fullSearch: false, |
|
424 | 424 | selector: function(instance) { |
|
425 | 425 | var ret = []; // Beginning matches |
|
426 | 426 | var partial = []; // Inside matches |
|
427 | 427 | var entry = instance.getToken(); |
|
428 | 428 | var count = 0; |
|
429 | 429 | |
|
430 | 430 |
for (var i = 0; i < instance.options.array.length && |
|
431 | 431 |
ret.length < instance.options.choices ; i++) { |
|
432 | 432 | |
|
433 | 433 | var elem = instance.options.array[i]; |
|
434 | 434 |
var foundPos = instance.options.ignoreCase ? |
|
435 | 435 |
elem.toLowerCase().indexOf(entry.toLowerCase()) : |
|
436 | 436 | elem.indexOf(entry); |
|
437 | 437 | |
|
438 | 438 | while (foundPos != -1) { |
|
439 | 439 |
if (foundPos == 0 && elem.length != entry.length) { |
|
440 | 440 |
ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" + |
|
441 | 441 | elem.substr(entry.length) + "</li>"); |
|
442 | 442 | break; |
|
443 | 443 |
} else if (entry.length >= instance.options.partialChars && |
|
444 | 444 | instance.options.partialSearch && foundPos != -1) { |
|
445 | 445 | if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) { |
|
446 | 446 | partial.push("<li>" + elem.substr(0, foundPos) + "<strong>" + |
|
447 | 447 | elem.substr(foundPos, entry.length) + "</strong>" + elem.substr( |
|
448 | 448 | foundPos + entry.length) + "</li>"); |
|
449 | 449 | break; |
|
450 | 450 | } |
|
451 | 451 | } |
|
452 | 452 | |
|
453 | 453 |
foundPos = instance.options.ignoreCase ? |
|
454 | 454 |
elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) : |
|
455 | 455 | elem.indexOf(entry, foundPos + 1); |
|
456 | 456 | |
|
457 | 457 | } |
|
458 | 458 | } |
|
459 | 459 | if (partial.length) |
|
460 | - ret = ret.concat(partial.slice(0, instance.options.choices - ret.length)) | |
|
460 | + ret = ret.concat(partial.slice(0, instance.options.choices - ret.length)); | |
|
461 | 461 | return "<ul>" + ret.join('') + "</ul>"; |
|
462 | 462 | } |
|
463 | 463 | }, options || { }); |
|
464 | 464 | } |
|
465 | 465 | }); |
|
466 | 466 | |
|
467 | 467 | // AJAX in-place editor and collection editor |
|
468 | 468 | // Full rewrite by Christophe Porteneuve <tdd@tddsworld.com> (April 2007). |
|
469 | 469 | |
|
470 | 470 | // Use this if you notice weird scrolling problems on some browsers, |
|
471 | 471 | // the DOM might be a bit confused when this gets called so do this |
|
472 | 472 | // waits 1 ms (with setTimeout) until it does the activation |
|
473 | 473 | Field.scrollFreeActivate = function(field) { |
|
474 | 474 | setTimeout(function() { |
|
475 | 475 | Field.activate(field); |
|
476 | 476 | }, 1); |
|
477 | - } | |
|
477 | + }; | |
|
478 | 478 | |
|
479 | 479 | Ajax.InPlaceEditor = Class.create({ |
|
480 | 480 | initialize: function(element, url, options) { |
|
481 | 481 | this.url = url; |
|
482 | 482 | this.element = element = $(element); |
|
483 | 483 | this.prepareOptions(); |
|
484 | 484 | this._controls = { }; |
|
485 | 485 | arguments.callee.dealWithDeprecatedOptions(options); // DEPRECATION LAYER!!! |
|
486 | 486 | Object.extend(this.options, options || { }); |
|
487 | 487 | if (!this.options.formId && this.element.id) { |
|
488 | 488 | this.options.formId = this.element.id + '-inplaceeditor'; |
|
489 | 489 | if ($(this.options.formId)) |
|
490 | 490 | this.options.formId = ''; |
|
491 | 491 | } |
|
492 | 492 | if (this.options.externalControl) |
|
493 | 493 | this.options.externalControl = $(this.options.externalControl); |
|
494 | 494 | if (!this.options.externalControl) |
|
495 | 495 | this.options.externalControlOnly = false; |
|
496 | 496 | this._originalBackground = this.element.getStyle('background-color') || 'transparent'; |
|
497 | 497 | this.element.title = this.options.clickToEditText; |
|
498 | 498 | this._boundCancelHandler = this.handleFormCancellation.bind(this); |
|
499 | 499 | this._boundComplete = (this.options.onComplete || Prototype.emptyFunction).bind(this); |
|
500 | 500 | this._boundFailureHandler = this.handleAJAXFailure.bind(this); |
|
501 | 501 | this._boundSubmitHandler = this.handleFormSubmission.bind(this); |
|
502 | 502 | this._boundWrapperHandler = this.wrapUp.bind(this); |
|
503 | 503 | this.registerListeners(); |
|
504 | 504 | }, |
|
505 | 505 | checkForEscapeOrReturn: function(e) { |
|
506 | 506 | if (!this._editing || e.ctrlKey || e.altKey || e.shiftKey) return; |
|
507 | 507 | if (Event.KEY_ESC == e.keyCode) |
|
508 | 508 | this.handleFormCancellation(e); |
|
509 | 509 | else if (Event.KEY_RETURN == e.keyCode) |
|
510 | 510 | this.handleFormSubmission(e); |
|
511 | 511 | }, |
|
512 | 512 | createControl: function(mode, handler, extraClasses) { |
|
513 | 513 | var control = this.options[mode + 'Control']; |
|
514 | 514 | var text = this.options[mode + 'Text']; |
|
515 | 515 | if ('button' == control) { |
|
516 | 516 | var btn = document.createElement('input'); |
|
517 | 517 | btn.type = 'submit'; |
|
518 | 518 | btn.value = text; |
|
519 | 519 | btn.className = 'editor_' + mode + '_button'; |
|
520 | 520 | if ('cancel' == mode) |
|
521 | 521 | btn.onclick = this._boundCancelHandler; |
|
522 | 522 | this._form.appendChild(btn); |
|
523 | 523 | this._controls[mode] = btn; |
|
524 | 524 | } else if ('link' == control) { |
|
525 | 525 | var link = document.createElement('a'); |
|
526 | 526 | link.href = '#'; |
|
527 | 527 | link.appendChild(document.createTextNode(text)); |
|
528 | 528 | link.onclick = 'cancel' == mode ? this._boundCancelHandler : this._boundSubmitHandler; |
|
529 | 529 | link.className = 'editor_' + mode + '_link'; |
|
530 | 530 | if (extraClasses) |
|
531 | 531 | link.className += ' ' + extraClasses; |
|
532 | 532 | this._form.appendChild(link); |
|
533 | 533 | this._controls[mode] = link; |
|
534 | 534 | } |
|
535 | 535 | }, |
|
536 | 536 | createEditField: function() { |
|
537 | 537 | var text = (this.options.loadTextURL ? this.options.loadingText : this.getText()); |
|
538 | 538 | var fld; |
|
539 | 539 | if (1 >= this.options.rows && !/\r|\n/.test(this.getText())) { |
|
540 | 540 | fld = document.createElement('input'); |
|
541 | 541 | fld.type = 'text'; |
|
542 | 542 | var size = this.options.size || this.options.cols || 0; |
|
543 | 543 | if (0 < size) fld.size = size; |
|
544 | 544 | } else { |
|
545 | 545 | fld = document.createElement('textarea'); |
|
546 | 546 | fld.rows = (1 >= this.options.rows ? this.options.autoRows : this.options.rows); |
|
547 | 547 | fld.cols = this.options.cols || 40; |
|
548 | 548 | } |
|
549 | 549 | fld.name = this.options.paramName; |
|
550 | 550 | fld.value = text; // No HTML breaks conversion anymore |
|
551 | 551 | fld.className = 'editor_field'; |
|
552 | 552 | if (this.options.submitOnBlur) |
|
553 | 553 | fld.onblur = this._boundSubmitHandler; |
|
554 | 554 | this._controls.editor = fld; |
|
555 | 555 | if (this.options.loadTextURL) |
|
556 | 556 | this.loadExternalText(); |
|
557 | 557 | this._form.appendChild(this._controls.editor); |
|
558 | 558 | }, |
|
559 | 559 | createForm: function() { |
|
560 | 560 | var ipe = this; |
|
561 | 561 | function addText(mode, condition) { |
|
562 | 562 | var text = ipe.options['text' + mode + 'Controls']; |
|
563 | 563 | if (!text || condition === false) return; |
|
564 | 564 | ipe._form.appendChild(document.createTextNode(text)); |
|
565 | 565 | }; |
|
566 | 566 | this._form = $(document.createElement('form')); |
|
567 | 567 | this._form.id = this.options.formId; |
|
568 | 568 | this._form.addClassName(this.options.formClassName); |
|
569 | 569 | this._form.onsubmit = this._boundSubmitHandler; |
|
570 | 570 | this.createEditField(); |
|
571 | 571 | if ('textarea' == this._controls.editor.tagName.toLowerCase()) |
|
572 | 572 | this._form.appendChild(document.createElement('br')); |
|
573 | 573 | if (this.options.onFormCustomization) |
|
574 | 574 | this.options.onFormCustomization(this, this._form); |
|
575 | 575 | addText('Before', this.options.okControl || this.options.cancelControl); |
|
576 | 576 | this.createControl('ok', this._boundSubmitHandler); |
|
577 | 577 | addText('Between', this.options.okControl && this.options.cancelControl); |
|
578 | 578 | this.createControl('cancel', this._boundCancelHandler, 'editor_cancel'); |
|
579 | 579 | addText('After', this.options.okControl || this.options.cancelControl); |
|
580 | 580 | }, |
|
581 | 581 | destroy: function() { |
|
582 | 582 | if (this._oldInnerHTML) |
|
583 | 583 | this.element.innerHTML = this._oldInnerHTML; |
|
584 | 584 | this.leaveEditMode(); |
|
585 | 585 | this.unregisterListeners(); |
|
586 | 586 | }, |
|
587 | 587 | enterEditMode: function(e) { |
|
588 | 588 | if (this._saving || this._editing) return; |
|
589 | 589 | this._editing = true; |
|
590 | 590 | this.triggerCallback('onEnterEditMode'); |
|
591 | 591 | if (this.options.externalControl) |
|
592 | 592 | this.options.externalControl.hide(); |
|
593 | 593 | this.element.hide(); |
|
594 | 594 | this.createForm(); |
|
595 | 595 | this.element.parentNode.insertBefore(this._form, this.element); |
|
596 | 596 | if (!this.options.loadTextURL) |
|
597 | 597 | this.postProcessEditField(); |
|
598 | 598 | if (e) Event.stop(e); |
|
599 | 599 | }, |
|
600 | 600 | enterHover: function(e) { |
|
601 | 601 | if (this.options.hoverClassName) |
|
602 | 602 | this.element.addClassName(this.options.hoverClassName); |
|
603 | 603 | if (this._saving) return; |
|
604 | 604 | this.triggerCallback('onEnterHover'); |
|
605 | 605 | }, |
|
606 | 606 | getText: function() { |
|
607 | - return this.element.innerHTML; | |
|
607 | + return this.element.innerHTML.unescapeHTML(); | |
|
608 | 608 | }, |
|
609 | 609 | handleAJAXFailure: function(transport) { |
|
610 | 610 | this.triggerCallback('onFailure', transport); |
|
611 | 611 | if (this._oldInnerHTML) { |
|
612 | 612 | this.element.innerHTML = this._oldInnerHTML; |
|
613 | 613 | this._oldInnerHTML = null; |
|
614 | 614 | } |
|
615 | 615 | }, |
|
616 | 616 | handleFormCancellation: function(e) { |
|
617 | 617 | this.wrapUp(); |
|
618 | 618 | if (e) Event.stop(e); |
|
619 | 619 | }, |
|
620 | 620 | handleFormSubmission: function(e) { |
|
621 | 621 | var form = this._form; |
|
622 | 622 | var value = $F(this._controls.editor); |
|
623 | 623 | this.prepareSubmission(); |
|
624 | 624 | var params = this.options.callback(form, value) || ''; |
|
625 | 625 | if (Object.isString(params)) |
|
626 | 626 | params = params.toQueryParams(); |
|
627 | 627 | params.editorId = this.element.id; |
|
628 | 628 | if (this.options.htmlResponse) { |
|
629 | 629 | var options = Object.extend({ evalScripts: true }, this.options.ajaxOptions); |
|
630 | 630 | Object.extend(options, { |
|
631 | 631 | parameters: params, |
|
632 | 632 | onComplete: this._boundWrapperHandler, |
|
633 | 633 | onFailure: this._boundFailureHandler |
|
634 | 634 | }); |
|
635 | 635 | new Ajax.Updater({ success: this.element }, this.url, options); |
|
636 | 636 | } else { |
|
637 | 637 | var options = Object.extend({ method: 'get' }, this.options.ajaxOptions); |
|
638 | 638 | Object.extend(options, { |
|
639 | 639 | parameters: params, |
|
640 | 640 | onComplete: this._boundWrapperHandler, |
|
641 | 641 | onFailure: this._boundFailureHandler |
|
642 | 642 | }); |
|
643 | 643 | new Ajax.Request(this.url, options); |
|
644 | 644 | } |
|
645 | 645 | if (e) Event.stop(e); |
|
646 | 646 | }, |
|
647 | 647 | leaveEditMode: function() { |
|
648 | 648 | this.element.removeClassName(this.options.savingClassName); |
|
649 | 649 | this.removeForm(); |
|
650 | 650 | this.leaveHover(); |
|
651 | 651 | this.element.style.backgroundColor = this._originalBackground; |
|
652 | 652 | this.element.show(); |
|
653 | 653 | if (this.options.externalControl) |
|
654 | 654 | this.options.externalControl.show(); |
|
655 | 655 | this._saving = false; |
|
656 | 656 | this._editing = false; |
|
657 | 657 | this._oldInnerHTML = null; |
|
658 | 658 | this.triggerCallback('onLeaveEditMode'); |
|
659 | 659 | }, |
|
660 | 660 | leaveHover: function(e) { |
|
661 | 661 | if (this.options.hoverClassName) |
|
662 | 662 | this.element.removeClassName(this.options.hoverClassName); |
|
663 | 663 | if (this._saving) return; |
|
664 | 664 | this.triggerCallback('onLeaveHover'); |
|
665 | 665 | }, |
|
666 | 666 | loadExternalText: function() { |
|
667 | 667 | this._form.addClassName(this.options.loadingClassName); |
|
668 | 668 | this._controls.editor.disabled = true; |
|
669 | 669 | var options = Object.extend({ method: 'get' }, this.options.ajaxOptions); |
|
670 | 670 | Object.extend(options, { |
|
671 | 671 | parameters: 'editorId=' + encodeURIComponent(this.element.id), |
|
672 | 672 | onComplete: Prototype.emptyFunction, |
|
673 | 673 | onSuccess: function(transport) { |
|
674 | 674 | this._form.removeClassName(this.options.loadingClassName); |
|
675 | 675 | var text = transport.responseText; |
|
676 | 676 | if (this.options.stripLoadedTextTags) |
|
677 | 677 | text = text.stripTags(); |
|
678 | 678 | this._controls.editor.value = text; |
|
679 | 679 | this._controls.editor.disabled = false; |
|
680 | 680 | this.postProcessEditField(); |
|
681 | 681 | }.bind(this), |
|
682 | 682 | onFailure: this._boundFailureHandler |
|
683 | 683 | }); |
|
684 | 684 | new Ajax.Request(this.options.loadTextURL, options); |
|
685 | 685 | }, |
|
686 | 686 | postProcessEditField: function() { |
|
687 | 687 | var fpc = this.options.fieldPostCreation; |
|
688 | 688 | if (fpc) |
|
689 | 689 | $(this._controls.editor)['focus' == fpc ? 'focus' : 'activate'](); |
|
690 | 690 | }, |
|
691 | 691 | prepareOptions: function() { |
|
692 | 692 | this.options = Object.clone(Ajax.InPlaceEditor.DefaultOptions); |
|
693 | 693 | Object.extend(this.options, Ajax.InPlaceEditor.DefaultCallbacks); |
|
694 | 694 | [this._extraDefaultOptions].flatten().compact().each(function(defs) { |
|
695 | 695 | Object.extend(this.options, defs); |
|
696 | 696 | }.bind(this)); |
|
697 | 697 | }, |
|
698 | 698 | prepareSubmission: function() { |
|
699 | 699 | this._saving = true; |
|
700 | 700 | this.removeForm(); |
|
701 | 701 | this.leaveHover(); |
|
702 | 702 | this.showSaving(); |
|
703 | 703 | }, |
|
704 | 704 | registerListeners: function() { |
|
705 | 705 | this._listeners = { }; |
|
706 | 706 | var listener; |
|
707 | 707 | $H(Ajax.InPlaceEditor.Listeners).each(function(pair) { |
|
708 | 708 | listener = this[pair.value].bind(this); |
|
709 | 709 | this._listeners[pair.key] = listener; |
|
710 | 710 | if (!this.options.externalControlOnly) |
|
711 | 711 | this.element.observe(pair.key, listener); |
|
712 | 712 | if (this.options.externalControl) |
|
713 | 713 | this.options.externalControl.observe(pair.key, listener); |
|
714 | 714 | }.bind(this)); |
|
715 | 715 | }, |
|
716 | 716 | removeForm: function() { |
|
717 | 717 | if (!this._form) return; |
|
718 | 718 | this._form.remove(); |
|
719 | 719 | this._form = null; |
|
720 | 720 | this._controls = { }; |
|
721 | 721 | }, |
|
722 | 722 | showSaving: function() { |
|
723 | 723 | this._oldInnerHTML = this.element.innerHTML; |
|
724 | 724 | this.element.innerHTML = this.options.savingText; |
|
725 | 725 | this.element.addClassName(this.options.savingClassName); |
|
726 | 726 | this.element.style.backgroundColor = this._originalBackground; |
|
727 | 727 | this.element.show(); |
|
728 | 728 | }, |
|
729 | 729 | triggerCallback: function(cbName, arg) { |
|
730 | 730 | if ('function' == typeof this.options[cbName]) { |
|
731 | 731 | this.options[cbName](this, arg); |
|
732 | 732 | } |
|
733 | 733 | }, |
|
734 | 734 | unregisterListeners: function() { |
|
735 | 735 | $H(this._listeners).each(function(pair) { |
|
736 | 736 | if (!this.options.externalControlOnly) |
|
737 | 737 | this.element.stopObserving(pair.key, pair.value); |
|
738 | 738 | if (this.options.externalControl) |
|
739 | 739 | this.options.externalControl.stopObserving(pair.key, pair.value); |
|
740 | 740 | }.bind(this)); |
|
741 | 741 | }, |
|
742 | 742 | wrapUp: function(transport) { |
|
743 | 743 | this.leaveEditMode(); |
|
744 | 744 | // Can't use triggerCallback due to backward compatibility: requires |
|
745 | 745 | // binding + direct element |
|
746 | 746 | this._boundComplete(transport, this.element); |
|
747 | 747 | } |
|
748 | 748 | }); |
|
749 | 749 | |
|
750 | 750 | Object.extend(Ajax.InPlaceEditor.prototype, { |
|
751 | 751 | dispose: Ajax.InPlaceEditor.prototype.destroy |
|
752 | 752 | }); |
|
753 | 753 | |
|
754 | 754 | Ajax.InPlaceCollectionEditor = Class.create(Ajax.InPlaceEditor, { |
|
755 | 755 | initialize: function($super, element, url, options) { |
|
756 | 756 | this._extraDefaultOptions = Ajax.InPlaceCollectionEditor.DefaultOptions; |
|
757 | 757 | $super(element, url, options); |
|
758 | 758 | }, |
|
759 | 759 | |
|
760 | 760 | createEditField: function() { |
|
761 | 761 | var list = document.createElement('select'); |
|
762 | 762 | list.name = this.options.paramName; |
|
763 | 763 | list.size = 1; |
|
764 | 764 | this._controls.editor = list; |
|
765 | 765 | this._collection = this.options.collection || []; |
|
766 | 766 | if (this.options.loadCollectionURL) |
|
767 | 767 | this.loadCollection(); |
|
768 | 768 | else |
|
769 | 769 | this.checkForExternalText(); |
|
770 | 770 | this._form.appendChild(this._controls.editor); |
|
771 | 771 | }, |
|
772 | 772 | |
|
773 | 773 | loadCollection: function() { |
|
774 | 774 | this._form.addClassName(this.options.loadingClassName); |
|
775 | 775 | this.showLoadingText(this.options.loadingCollectionText); |
|
776 | 776 | var options = Object.extend({ method: 'get' }, this.options.ajaxOptions); |
|
777 | 777 | Object.extend(options, { |
|
778 | 778 | parameters: 'editorId=' + encodeURIComponent(this.element.id), |
|
779 | 779 | onComplete: Prototype.emptyFunction, |
|
780 | 780 | onSuccess: function(transport) { |
|
781 | 781 | var js = transport.responseText.strip(); |
|
782 | 782 | if (!/^\[.*\]$/.test(js)) // TODO: improve sanity check |
|
783 |
- throw |
|
|
783 | + throw('Server returned an invalid collection representation.'); | |
|
784 | 784 | this._collection = eval(js); |
|
785 | 785 | this.checkForExternalText(); |
|
786 | 786 | }.bind(this), |
|
787 | 787 | onFailure: this.onFailure |
|
788 | 788 | }); |
|
789 | 789 | new Ajax.Request(this.options.loadCollectionURL, options); |
|
790 | 790 | }, |
|
791 | 791 | |
|
792 | 792 | showLoadingText: function(text) { |
|
793 | 793 | this._controls.editor.disabled = true; |
|
794 | 794 | var tempOption = this._controls.editor.firstChild; |
|
795 | 795 | if (!tempOption) { |
|
796 | 796 | tempOption = document.createElement('option'); |
|
797 | 797 | tempOption.value = ''; |
|
798 | 798 | this._controls.editor.appendChild(tempOption); |
|
799 | 799 | tempOption.selected = true; |
|
800 | 800 | } |
|
801 | 801 | tempOption.update((text || '').stripScripts().stripTags()); |
|
802 | 802 | }, |
|
803 | 803 | |
|
804 | 804 | checkForExternalText: function() { |
|
805 | 805 | this._text = this.getText(); |
|
806 | 806 | if (this.options.loadTextURL) |
|
807 | 807 | this.loadExternalText(); |
|
808 | 808 | else |
|
809 | 809 | this.buildOptionList(); |
|
810 | 810 | }, |
|
811 | 811 | |
|
812 | 812 | loadExternalText: function() { |
|
813 | 813 | this.showLoadingText(this.options.loadingText); |
|
814 | 814 | var options = Object.extend({ method: 'get' }, this.options.ajaxOptions); |
|
815 | 815 | Object.extend(options, { |
|
816 | 816 | parameters: 'editorId=' + encodeURIComponent(this.element.id), |
|
817 | 817 | onComplete: Prototype.emptyFunction, |
|
818 | 818 | onSuccess: function(transport) { |
|
819 | 819 | this._text = transport.responseText.strip(); |
|
820 | 820 | this.buildOptionList(); |
|
821 | 821 | }.bind(this), |
|
822 | 822 | onFailure: this.onFailure |
|
823 | 823 | }); |
|
824 | 824 | new Ajax.Request(this.options.loadTextURL, options); |
|
825 | 825 | }, |
|
826 | 826 | |
|
827 | 827 | buildOptionList: function() { |
|
828 | 828 | this._form.removeClassName(this.options.loadingClassName); |
|
829 | 829 | this._collection = this._collection.map(function(entry) { |
|
830 | 830 | return 2 === entry.length ? entry : [entry, entry].flatten(); |
|
831 | 831 | }); |
|
832 | 832 | var marker = ('value' in this.options) ? this.options.value : this._text; |
|
833 | 833 | var textFound = this._collection.any(function(entry) { |
|
834 | 834 | return entry[0] == marker; |
|
835 | 835 | }.bind(this)); |
|
836 | 836 | this._controls.editor.update(''); |
|
837 | 837 | var option; |
|
838 | 838 | this._collection.each(function(entry, index) { |
|
839 | 839 | option = document.createElement('option'); |
|
840 | 840 | option.value = entry[0]; |
|
841 | 841 | option.selected = textFound ? entry[0] == marker : 0 == index; |
|
842 | 842 | option.appendChild(document.createTextNode(entry[1])); |
|
843 | 843 | this._controls.editor.appendChild(option); |
|
844 | 844 | }.bind(this)); |
|
845 | 845 | this._controls.editor.disabled = false; |
|
846 | 846 | Field.scrollFreeActivate(this._controls.editor); |
|
847 | 847 | } |
|
848 | 848 | }); |
|
849 | 849 | |
|
850 | 850 | //**** DEPRECATION LAYER FOR InPlace[Collection]Editor! **** |
|
851 | 851 | //**** This only exists for a while, in order to let **** |
|
852 | 852 | //**** users adapt to the new API. Read up on the new **** |
|
853 | 853 | //**** API and convert your code to it ASAP! **** |
|
854 | 854 | |
|
855 | 855 | Ajax.InPlaceEditor.prototype.initialize.dealWithDeprecatedOptions = function(options) { |
|
856 | 856 | if (!options) return; |
|
857 | 857 | function fallback(name, expr) { |
|
858 | 858 | if (name in options || expr === undefined) return; |
|
859 | 859 | options[name] = expr; |
|
860 | 860 | }; |
|
861 | 861 | fallback('cancelControl', (options.cancelLink ? 'link' : (options.cancelButton ? 'button' : |
|
862 | 862 | options.cancelLink == options.cancelButton == false ? false : undefined))); |
|
863 | 863 | fallback('okControl', (options.okLink ? 'link' : (options.okButton ? 'button' : |
|
864 | 864 | options.okLink == options.okButton == false ? false : undefined))); |
|
865 | 865 | fallback('highlightColor', options.highlightcolor); |
|
866 | 866 | fallback('highlightEndColor', options.highlightendcolor); |
|
867 | 867 | }; |
|
868 | 868 | |
|
869 | 869 | Object.extend(Ajax.InPlaceEditor, { |
|
870 | 870 | DefaultOptions: { |
|
871 | 871 | ajaxOptions: { }, |
|
872 | 872 | autoRows: 3, // Use when multi-line w/ rows == 1 |
|
873 | 873 | cancelControl: 'link', // 'link'|'button'|false |
|
874 | 874 | cancelText: 'cancel', |
|
875 | 875 | clickToEditText: 'Click to edit', |
|
876 | 876 | externalControl: null, // id|elt |
|
877 | 877 | externalControlOnly: false, |
|
878 | 878 | fieldPostCreation: 'activate', // 'activate'|'focus'|false |
|
879 | 879 | formClassName: 'inplaceeditor-form', |
|
880 | 880 | formId: null, // id|elt |
|
881 | 881 | highlightColor: '#ffff99', |
|
882 | 882 | highlightEndColor: '#ffffff', |
|
883 | 883 | hoverClassName: '', |
|
884 | 884 | htmlResponse: true, |
|
885 | 885 | loadingClassName: 'inplaceeditor-loading', |
|
886 | 886 | loadingText: 'Loading...', |
|
887 | 887 | okControl: 'button', // 'link'|'button'|false |
|
888 | 888 | okText: 'ok', |
|
889 | 889 | paramName: 'value', |
|
890 | 890 | rows: 1, // If 1 and multi-line, uses autoRows |
|
891 | 891 | savingClassName: 'inplaceeditor-saving', |
|
892 | 892 | savingText: 'Saving...', |
|
893 | 893 | size: 0, |
|
894 | 894 | stripLoadedTextTags: false, |
|
895 | 895 | submitOnBlur: false, |
|
896 | 896 | textAfterControls: '', |
|
897 | 897 | textBeforeControls: '', |
|
898 | 898 | textBetweenControls: '' |
|
899 | 899 | }, |
|
900 | 900 | DefaultCallbacks: { |
|
901 | 901 | callback: function(form) { |
|
902 | 902 | return Form.serialize(form); |
|
903 | 903 | }, |
|
904 | 904 | onComplete: function(transport, element) { |
|
905 | 905 | // For backward compatibility, this one is bound to the IPE, and passes |
|
906 | 906 | // the element directly. It was too often customized, so we don't break it. |
|
907 | 907 | new Effect.Highlight(element, { |
|
908 | 908 | startcolor: this.options.highlightColor, keepBackgroundImage: true }); |
|
909 | 909 | }, |
|
910 | 910 | onEnterEditMode: null, |
|
911 | 911 | onEnterHover: function(ipe) { |
|
912 | 912 | ipe.element.style.backgroundColor = ipe.options.highlightColor; |
|
913 | 913 | if (ipe._effect) |
|
914 | 914 | ipe._effect.cancel(); |
|
915 | 915 | }, |
|
916 | 916 | onFailure: function(transport, ipe) { |
|
917 | 917 | alert('Error communication with the server: ' + transport.responseText.stripTags()); |
|
918 | 918 | }, |
|
919 | 919 | onFormCustomization: null, // Takes the IPE and its generated form, after editor, before controls. |
|
920 | 920 | onLeaveEditMode: null, |
|
921 | 921 | onLeaveHover: function(ipe) { |
|
922 | 922 | ipe._effect = new Effect.Highlight(ipe.element, { |
|
923 | 923 | startcolor: ipe.options.highlightColor, endcolor: ipe.options.highlightEndColor, |
|
924 | 924 | restorecolor: ipe._originalBackground, keepBackgroundImage: true |
|
925 | 925 | }); |
|
926 | 926 | } |
|
927 | 927 | }, |
|
928 | 928 | Listeners: { |
|
929 | 929 | click: 'enterEditMode', |
|
930 | 930 | keydown: 'checkForEscapeOrReturn', |
|
931 | 931 | mouseover: 'enterHover', |
|
932 | 932 | mouseout: 'leaveHover' |
|
933 | 933 | } |
|
934 | 934 | }); |
|
935 | 935 | |
|
936 | 936 | Ajax.InPlaceCollectionEditor.DefaultOptions = { |
|
937 | 937 | loadingCollectionText: 'Loading options...' |
|
938 | 938 | }; |
|
939 | 939 | |
|
940 | 940 |
// Delayed observer, like Form.Element.Observer, |
|
941 | 941 | // but waits for delay after last key input |
|
942 | 942 | // Ideal for live-search fields |
|
943 | 943 | |
|
944 | 944 | Form.Element.DelayedObserver = Class.create({ |
|
945 | 945 | initialize: function(element, delay, callback) { |
|
946 | 946 | this.delay = delay || 0.5; |
|
947 | 947 | this.element = $(element); |
|
948 | 948 | this.callback = callback; |
|
949 | 949 | this.timer = null; |
|
950 | 950 |
this.lastValue = $F(this.element); |
|
951 | 951 | Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this)); |
|
952 | 952 | }, |
|
953 | 953 | delayedListener: function(event) { |
|
954 | 954 | if(this.lastValue == $F(this.element)) return; |
|
955 | 955 | if(this.timer) clearTimeout(this.timer); |
|
956 | 956 | this.timer = setTimeout(this.onTimerEvent.bind(this), this.delay * 1000); |
|
957 | 957 | this.lastValue = $F(this.element); |
|
958 | 958 | }, |
|
959 | 959 | onTimerEvent: function() { |
|
960 | 960 | this.timer = null; |
|
961 | 961 | this.callback(this.element, $F(this.element)); |
|
962 | 962 | } |
|
963 |
- }); |
|
|
963 | + }); No newline at end of file |
@@ -1,972 +1,973 | |||
|
1 | 1 | // Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) |
|
2 |
- // (c) 2005-200 |
|
|
2 | + // (c) 2005-2008 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz) | |
|
3 | 3 |
// |
|
4 | 4 | // script.aculo.us is freely distributable under the terms of an MIT-style license. |
|
5 | 5 | // For details, see the script.aculo.us web site: http://script.aculo.us/ |
|
6 | 6 | |
|
7 | 7 | if(Object.isUndefined(Effect)) |
|
8 | 8 | throw("dragdrop.js requires including script.aculo.us' effects.js library"); |
|
9 | 9 | |
|
10 | 10 | var Droppables = { |
|
11 | 11 | drops: [], |
|
12 | 12 | |
|
13 | 13 | remove: function(element) { |
|
14 | 14 | this.drops = this.drops.reject(function(d) { return d.element==$(element) }); |
|
15 | 15 | }, |
|
16 | 16 | |
|
17 | 17 | add: function(element) { |
|
18 | 18 | element = $(element); |
|
19 | 19 | var options = Object.extend({ |
|
20 | 20 | greedy: true, |
|
21 | 21 | hoverclass: null, |
|
22 | 22 | tree: false |
|
23 | 23 | }, arguments[1] || { }); |
|
24 | 24 | |
|
25 | 25 | // cache containers |
|
26 | 26 | if(options.containment) { |
|
27 | 27 | options._containers = []; |
|
28 | 28 | var containment = options.containment; |
|
29 | 29 | if(Object.isArray(containment)) { |
|
30 | 30 | containment.each( function(c) { options._containers.push($(c)) }); |
|
31 | 31 | } else { |
|
32 | 32 | options._containers.push($(containment)); |
|
33 | 33 | } |
|
34 | 34 | } |
|
35 | 35 | |
|
36 | 36 | if(options.accept) options.accept = [options.accept].flatten(); |
|
37 | 37 | |
|
38 | 38 | Element.makePositioned(element); // fix IE |
|
39 | 39 | options.element = element; |
|
40 | 40 | |
|
41 | 41 | this.drops.push(options); |
|
42 | 42 | }, |
|
43 | 43 | |
|
44 | 44 | findDeepestChild: function(drops) { |
|
45 | 45 | deepest = drops[0]; |
|
46 | 46 | |
|
47 | 47 | for (i = 1; i < drops.length; ++i) |
|
48 | 48 | if (Element.isParent(drops[i].element, deepest.element)) |
|
49 | 49 | deepest = drops[i]; |
|
50 | 50 | |
|
51 | 51 | return deepest; |
|
52 | 52 | }, |
|
53 | 53 | |
|
54 | 54 | isContained: function(element, drop) { |
|
55 | 55 | var containmentNode; |
|
56 | 56 | if(drop.tree) { |
|
57 | 57 |
containmentNode = element.treeNode; |
|
58 | 58 | } else { |
|
59 | 59 | containmentNode = element.parentNode; |
|
60 | 60 | } |
|
61 | 61 | return drop._containers.detect(function(c) { return containmentNode == c }); |
|
62 | 62 | }, |
|
63 | 63 | |
|
64 | 64 | isAffected: function(point, element, drop) { |
|
65 | 65 | return ( |
|
66 | 66 | (drop.element!=element) && |
|
67 | 67 | ((!drop._containers) || |
|
68 | 68 | this.isContained(element, drop)) && |
|
69 | 69 | ((!drop.accept) || |
|
70 | 70 |
(Element.classNames(element).detect( |
|
71 | 71 | function(v) { return drop.accept.include(v) } ) )) && |
|
72 | 72 | Position.within(drop.element, point[0], point[1]) ); |
|
73 | 73 | }, |
|
74 | 74 | |
|
75 | 75 | deactivate: function(drop) { |
|
76 | 76 | if(drop.hoverclass) |
|
77 | 77 | Element.removeClassName(drop.element, drop.hoverclass); |
|
78 | 78 | this.last_active = null; |
|
79 | 79 | }, |
|
80 | 80 | |
|
81 | 81 | activate: function(drop) { |
|
82 | 82 | if(drop.hoverclass) |
|
83 | 83 | Element.addClassName(drop.element, drop.hoverclass); |
|
84 | 84 | this.last_active = drop; |
|
85 | 85 | }, |
|
86 | 86 | |
|
87 | 87 | show: function(point, element) { |
|
88 | 88 | if(!this.drops.length) return; |
|
89 | 89 | var drop, affected = []; |
|
90 | 90 | |
|
91 | 91 | this.drops.each( function(drop) { |
|
92 | 92 | if(Droppables.isAffected(point, element, drop)) |
|
93 | 93 | affected.push(drop); |
|
94 | 94 | }); |
|
95 | 95 | |
|
96 | 96 | if(affected.length>0) |
|
97 | 97 | drop = Droppables.findDeepestChild(affected); |
|
98 | 98 | |
|
99 | 99 | if(this.last_active && this.last_active != drop) this.deactivate(this.last_active); |
|
100 | 100 | if (drop) { |
|
101 | 101 | Position.within(drop.element, point[0], point[1]); |
|
102 | 102 | if(drop.onHover) |
|
103 | 103 | drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element)); |
|
104 | 104 | |
|
105 | 105 | if (drop != this.last_active) Droppables.activate(drop); |
|
106 | 106 | } |
|
107 | 107 | }, |
|
108 | 108 | |
|
109 | 109 | fire: function(event, element) { |
|
110 | 110 | if(!this.last_active) return; |
|
111 | 111 | Position.prepare(); |
|
112 | 112 | |
|
113 | 113 | if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active)) |
|
114 | 114 | if (this.last_active.onDrop) { |
|
115 | 115 |
this.last_active.onDrop(element, this.last_active.element, event); |
|
116 | 116 |
return true; |
|
117 | 117 | } |
|
118 | 118 | }, |
|
119 | 119 | |
|
120 | 120 | reset: function() { |
|
121 | 121 | if(this.last_active) |
|
122 | 122 | this.deactivate(this.last_active); |
|
123 | 123 | } |
|
124 | - } | |
|
124 | + }; | |
|
125 | 125 | |
|
126 | 126 | var Draggables = { |
|
127 | 127 | drags: [], |
|
128 | 128 | observers: [], |
|
129 | 129 | |
|
130 | 130 | register: function(draggable) { |
|
131 | 131 | if(this.drags.length == 0) { |
|
132 | 132 | this.eventMouseUp = this.endDrag.bindAsEventListener(this); |
|
133 | 133 | this.eventMouseMove = this.updateDrag.bindAsEventListener(this); |
|
134 | 134 | this.eventKeypress = this.keyPress.bindAsEventListener(this); |
|
135 | 135 | |
|
136 | 136 | Event.observe(document, "mouseup", this.eventMouseUp); |
|
137 | 137 | Event.observe(document, "mousemove", this.eventMouseMove); |
|
138 | 138 | Event.observe(document, "keypress", this.eventKeypress); |
|
139 | 139 | } |
|
140 | 140 | this.drags.push(draggable); |
|
141 | 141 | }, |
|
142 | 142 | |
|
143 | 143 | unregister: function(draggable) { |
|
144 | 144 | this.drags = this.drags.reject(function(d) { return d==draggable }); |
|
145 | 145 | if(this.drags.length == 0) { |
|
146 | 146 | Event.stopObserving(document, "mouseup", this.eventMouseUp); |
|
147 | 147 | Event.stopObserving(document, "mousemove", this.eventMouseMove); |
|
148 | 148 | Event.stopObserving(document, "keypress", this.eventKeypress); |
|
149 | 149 | } |
|
150 | 150 | }, |
|
151 | 151 | |
|
152 | 152 | activate: function(draggable) { |
|
153 | 153 |
if(draggable.options.delay) { |
|
154 | 154 |
this._timeout = setTimeout(function() { |
|
155 | 155 |
Draggables._timeout = null; |
|
156 | 156 |
window.focus(); |
|
157 | 157 |
Draggables.activeDraggable = draggable; |
|
158 | 158 |
}.bind(this), draggable.options.delay); |
|
159 | 159 | } else { |
|
160 | 160 | window.focus(); // allows keypress events if window isn't currently focused, fails for Safari |
|
161 | 161 | this.activeDraggable = draggable; |
|
162 | 162 | } |
|
163 | 163 | }, |
|
164 | 164 | |
|
165 | 165 | deactivate: function() { |
|
166 | 166 | this.activeDraggable = null; |
|
167 | 167 | }, |
|
168 | 168 | |
|
169 | 169 | updateDrag: function(event) { |
|
170 | 170 | if(!this.activeDraggable) return; |
|
171 | 171 | var pointer = [Event.pointerX(event), Event.pointerY(event)]; |
|
172 | 172 | // Mozilla-based browsers fire successive mousemove events with |
|
173 | 173 | // the same coordinates, prevent needless redrawing (moz bug?) |
|
174 | 174 | if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return; |
|
175 | 175 | this._lastPointer = pointer; |
|
176 | 176 | |
|
177 | 177 | this.activeDraggable.updateDrag(event, pointer); |
|
178 | 178 | }, |
|
179 | 179 | |
|
180 | 180 | endDrag: function(event) { |
|
181 | 181 |
if(this._timeout) { |
|
182 | 182 |
clearTimeout(this._timeout); |
|
183 | 183 |
this._timeout = null; |
|
184 | 184 | } |
|
185 | 185 | if(!this.activeDraggable) return; |
|
186 | 186 | this._lastPointer = null; |
|
187 | 187 | this.activeDraggable.endDrag(event); |
|
188 | 188 | this.activeDraggable = null; |
|
189 | 189 | }, |
|
190 | 190 | |
|
191 | 191 | keyPress: function(event) { |
|
192 | 192 | if(this.activeDraggable) |
|
193 | 193 | this.activeDraggable.keyPress(event); |
|
194 | 194 | }, |
|
195 | 195 | |
|
196 | 196 | addObserver: function(observer) { |
|
197 | 197 | this.observers.push(observer); |
|
198 | 198 | this._cacheObserverCallbacks(); |
|
199 | 199 | }, |
|
200 | 200 | |
|
201 | 201 | removeObserver: function(element) { // element instead of observer fixes mem leaks |
|
202 | 202 | this.observers = this.observers.reject( function(o) { return o.element==element }); |
|
203 | 203 | this._cacheObserverCallbacks(); |
|
204 | 204 | }, |
|
205 | 205 | |
|
206 | 206 | notify: function(eventName, draggable, event) { // 'onStart', 'onEnd', 'onDrag' |
|
207 | 207 | if(this[eventName+'Count'] > 0) |
|
208 | 208 | this.observers.each( function(o) { |
|
209 | 209 | if(o[eventName]) o[eventName](eventName, draggable, event); |
|
210 | 210 | }); |
|
211 | 211 | if(draggable.options[eventName]) draggable.options[eventName](draggable, event); |
|
212 | 212 | }, |
|
213 | 213 | |
|
214 | 214 | _cacheObserverCallbacks: function() { |
|
215 | 215 | ['onStart','onEnd','onDrag'].each( function(eventName) { |
|
216 | 216 | Draggables[eventName+'Count'] = Draggables.observers.select( |
|
217 | 217 | function(o) { return o[eventName]; } |
|
218 | 218 | ).length; |
|
219 | 219 | }); |
|
220 | 220 | } |
|
221 | - } | |
|
221 | + }; | |
|
222 | 222 | |
|
223 | 223 |
|
|
224 | 224 | |
|
225 | 225 | var Draggable = Class.create({ |
|
226 | 226 | initialize: function(element) { |
|
227 | 227 | var defaults = { |
|
228 | 228 | handle: false, |
|
229 | 229 | reverteffect: function(element, top_offset, left_offset) { |
|
230 | 230 | var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02; |
|
231 | 231 | new Effect.Move(element, { x: -left_offset, y: -top_offset, duration: dur, |
|
232 | 232 | queue: {scope:'_draggable', position:'end'} |
|
233 | 233 | }); |
|
234 | 234 | }, |
|
235 | 235 | endeffect: function(element) { |
|
236 | 236 | var toOpacity = Object.isNumber(element._opacity) ? element._opacity : 1.0; |
|
237 | 237 |
new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity, |
|
238 | 238 | queue: {scope:'_draggable', position:'end'}, |
|
239 | 239 |
afterFinish: function(){ |
|
240 | 240 |
Draggable._dragging[element] = false |
|
241 | 241 | } |
|
242 | 242 |
}); |
|
243 | 243 | }, |
|
244 | 244 | zindex: 1000, |
|
245 | 245 | revert: false, |
|
246 | 246 | quiet: false, |
|
247 | 247 | scroll: false, |
|
248 | 248 | scrollSensitivity: 20, |
|
249 | 249 | scrollSpeed: 15, |
|
250 | 250 | snap: false, // false, or xy or [x,y] or function(x,y){ return [x,y] } |
|
251 | 251 | delay: 0 |
|
252 | 252 | }; |
|
253 | 253 | |
|
254 | 254 | if(!arguments[1] || Object.isUndefined(arguments[1].endeffect)) |
|
255 | 255 | Object.extend(defaults, { |
|
256 | 256 | starteffect: function(element) { |
|
257 | 257 | element._opacity = Element.getOpacity(element); |
|
258 | 258 | Draggable._dragging[element] = true; |
|
259 | 259 |
new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7}); |
|
260 | 260 | } |
|
261 | 261 | }); |
|
262 | 262 | |
|
263 | 263 | var options = Object.extend(defaults, arguments[1] || { }); |
|
264 | 264 | |
|
265 | 265 | this.element = $(element); |
|
266 | 266 | |
|
267 | 267 | if(options.handle && Object.isString(options.handle)) |
|
268 | 268 | this.handle = this.element.down('.'+options.handle, 0); |
|
269 | 269 | |
|
270 | 270 | if(!this.handle) this.handle = $(options.handle); |
|
271 | 271 | if(!this.handle) this.handle = this.element; |
|
272 | 272 | |
|
273 | 273 | if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) { |
|
274 | 274 | options.scroll = $(options.scroll); |
|
275 | 275 | this._isScrollChild = Element.childOf(this.element, options.scroll); |
|
276 | 276 | } |
|
277 | 277 | |
|
278 | 278 |
Element.makePositioned(this.element); // fix IE |
|
279 | 279 | |
|
280 | 280 | this.options = options; |
|
281 | 281 |
this.dragging = false; |
|
282 | 282 | |
|
283 | 283 | this.eventMouseDown = this.initDrag.bindAsEventListener(this); |
|
284 | 284 | Event.observe(this.handle, "mousedown", this.eventMouseDown); |
|
285 | 285 | |
|
286 | 286 | Draggables.register(this); |
|
287 | 287 | }, |
|
288 | 288 | |
|
289 | 289 | destroy: function() { |
|
290 | 290 | Event.stopObserving(this.handle, "mousedown", this.eventMouseDown); |
|
291 | 291 | Draggables.unregister(this); |
|
292 | 292 | }, |
|
293 | 293 | |
|
294 | 294 | currentDelta: function() { |
|
295 | 295 | return([ |
|
296 | 296 | parseInt(Element.getStyle(this.element,'left') || '0'), |
|
297 | 297 | parseInt(Element.getStyle(this.element,'top') || '0')]); |
|
298 | 298 | }, |
|
299 | 299 | |
|
300 | 300 | initDrag: function(event) { |
|
301 | 301 | if(!Object.isUndefined(Draggable._dragging[this.element]) && |
|
302 | 302 | Draggable._dragging[this.element]) return; |
|
303 | 303 |
if(Event.isLeftClick(event)) { |
|
304 | 304 | // abort on form elements, fixes a Firefox issue |
|
305 | 305 | var src = Event.element(event); |
|
306 | 306 | if((tag_name = src.tagName.toUpperCase()) && ( |
|
307 | 307 | tag_name=='INPUT' || |
|
308 | 308 | tag_name=='SELECT' || |
|
309 | 309 | tag_name=='OPTION' || |
|
310 | 310 | tag_name=='BUTTON' || |
|
311 | 311 | tag_name=='TEXTAREA')) return; |
|
312 | 312 | |
|
313 | 313 | var pointer = [Event.pointerX(event), Event.pointerY(event)]; |
|
314 | 314 | var pos = Position.cumulativeOffset(this.element); |
|
315 | 315 | this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) }); |
|
316 | 316 | |
|
317 | 317 | Draggables.activate(this); |
|
318 | 318 | Event.stop(event); |
|
319 | 319 | } |
|
320 | 320 | }, |
|
321 | 321 | |
|
322 | 322 | startDrag: function(event) { |
|
323 | 323 | this.dragging = true; |
|
324 | 324 | if(!this.delta) |
|
325 | 325 | this.delta = this.currentDelta(); |
|
326 | 326 | |
|
327 | 327 | if(this.options.zindex) { |
|
328 | 328 | this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0); |
|
329 | 329 | this.element.style.zIndex = this.options.zindex; |
|
330 | 330 | } |
|
331 | 331 | |
|
332 | 332 | if(this.options.ghosting) { |
|
333 | 333 | this._clone = this.element.cloneNode(true); |
|
334 |
- this |
|
|
335 |
- if (!this. |
|
|
334 | + this._originallyAbsolute = (this.element.getStyle('position') == 'absolute'); | |
|
335 | + if (!this._originallyAbsolute) | |
|
336 | 336 | Position.absolutize(this.element); |
|
337 | 337 | this.element.parentNode.insertBefore(this._clone, this.element); |
|
338 | 338 | } |
|
339 | 339 | |
|
340 | 340 | if(this.options.scroll) { |
|
341 | 341 | if (this.options.scroll == window) { |
|
342 | 342 | var where = this._getWindowScroll(this.options.scroll); |
|
343 | 343 | this.originalScrollLeft = where.left; |
|
344 | 344 | this.originalScrollTop = where.top; |
|
345 | 345 | } else { |
|
346 | 346 | this.originalScrollLeft = this.options.scroll.scrollLeft; |
|
347 | 347 | this.originalScrollTop = this.options.scroll.scrollTop; |
|
348 | 348 | } |
|
349 | 349 | } |
|
350 | 350 | |
|
351 | 351 | Draggables.notify('onStart', this, event); |
|
352 | 352 | |
|
353 | 353 | if(this.options.starteffect) this.options.starteffect(this.element); |
|
354 | 354 | }, |
|
355 | 355 | |
|
356 | 356 | updateDrag: function(event, pointer) { |
|
357 | 357 | if(!this.dragging) this.startDrag(event); |
|
358 | 358 | |
|
359 | 359 | if(!this.options.quiet){ |
|
360 | 360 | Position.prepare(); |
|
361 | 361 | Droppables.show(pointer, this.element); |
|
362 | 362 | } |
|
363 | 363 | |
|
364 | 364 | Draggables.notify('onDrag', this, event); |
|
365 | 365 | |
|
366 | 366 | this.draw(pointer); |
|
367 | 367 | if(this.options.change) this.options.change(this); |
|
368 | 368 | |
|
369 | 369 | if(this.options.scroll) { |
|
370 | 370 | this.stopScrolling(); |
|
371 | 371 | |
|
372 | 372 | var p; |
|
373 | 373 | if (this.options.scroll == window) { |
|
374 | 374 | with(this._getWindowScroll(this.options.scroll)) { p = [ left, top, left+width, top+height ]; } |
|
375 | 375 | } else { |
|
376 | 376 | p = Position.page(this.options.scroll); |
|
377 | 377 | p[0] += this.options.scroll.scrollLeft + Position.deltaX; |
|
378 | 378 | p[1] += this.options.scroll.scrollTop + Position.deltaY; |
|
379 | 379 | p.push(p[0]+this.options.scroll.offsetWidth); |
|
380 | 380 | p.push(p[1]+this.options.scroll.offsetHeight); |
|
381 | 381 | } |
|
382 | 382 | var speed = [0,0]; |
|
383 | 383 | if(pointer[0] < (p[0]+this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[0]+this.options.scrollSensitivity); |
|
384 | 384 | if(pointer[1] < (p[1]+this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[1]+this.options.scrollSensitivity); |
|
385 | 385 | if(pointer[0] > (p[2]-this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[2]-this.options.scrollSensitivity); |
|
386 | 386 | if(pointer[1] > (p[3]-this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[3]-this.options.scrollSensitivity); |
|
387 | 387 | this.startScrolling(speed); |
|
388 | 388 | } |
|
389 | 389 | |
|
390 | 390 | // fix AppleWebKit rendering |
|
391 | 391 | if(Prototype.Browser.WebKit) window.scrollBy(0,0); |
|
392 | 392 | |
|
393 | 393 | Event.stop(event); |
|
394 | 394 | }, |
|
395 | 395 | |
|
396 | 396 | finishDrag: function(event, success) { |
|
397 | 397 | this.dragging = false; |
|
398 | 398 | |
|
399 | 399 | if(this.options.quiet){ |
|
400 | 400 | Position.prepare(); |
|
401 | 401 | var pointer = [Event.pointerX(event), Event.pointerY(event)]; |
|
402 | 402 | Droppables.show(pointer, this.element); |
|
403 | 403 | } |
|
404 | 404 | |
|
405 | 405 | if(this.options.ghosting) { |
|
406 |
- if (!this. |
|
|
406 | + if (!this._originallyAbsolute) | |
|
407 | 407 | Position.relativize(this.element); |
|
408 |
- delete this. |
|
|
408 | + delete this._originallyAbsolute; | |
|
409 | 409 | Element.remove(this._clone); |
|
410 | 410 | this._clone = null; |
|
411 | 411 | } |
|
412 | 412 | |
|
413 | 413 |
var dropped = false; |
|
414 | 414 |
if(success) { |
|
415 | 415 |
dropped = Droppables.fire(event, this.element); |
|
416 | 416 |
if (!dropped) dropped = false; |
|
417 | 417 | } |
|
418 | 418 | if(dropped && this.options.onDropped) this.options.onDropped(this.element); |
|
419 | 419 | Draggables.notify('onEnd', this, event); |
|
420 | 420 | |
|
421 | 421 | var revert = this.options.revert; |
|
422 | 422 | if(revert && Object.isFunction(revert)) revert = revert(this.element); |
|
423 | 423 | |
|
424 | 424 | var d = this.currentDelta(); |
|
425 | 425 | if(revert && this.options.reverteffect) { |
|
426 | 426 | if (dropped == 0 || revert != 'failure') |
|
427 | 427 | this.options.reverteffect(this.element, |
|
428 | 428 | d[1]-this.delta[1], d[0]-this.delta[0]); |
|
429 | 429 | } else { |
|
430 | 430 | this.delta = d; |
|
431 | 431 | } |
|
432 | 432 | |
|
433 | 433 | if(this.options.zindex) |
|
434 | 434 | this.element.style.zIndex = this.originalZ; |
|
435 | 435 | |
|
436 | 436 |
if(this.options.endeffect) |
|
437 | 437 | this.options.endeffect(this.element); |
|
438 | 438 | |
|
439 | 439 | Draggables.deactivate(this); |
|
440 | 440 | Droppables.reset(); |
|
441 | 441 | }, |
|
442 | 442 | |
|
443 | 443 | keyPress: function(event) { |
|
444 | 444 | if(event.keyCode!=Event.KEY_ESC) return; |
|
445 | 445 | this.finishDrag(event, false); |
|
446 | 446 | Event.stop(event); |
|
447 | 447 | }, |
|
448 | 448 | |
|
449 | 449 | endDrag: function(event) { |
|
450 | 450 | if(!this.dragging) return; |
|
451 | 451 | this.stopScrolling(); |
|
452 | 452 | this.finishDrag(event, true); |
|
453 | 453 | Event.stop(event); |
|
454 | 454 | }, |
|
455 | 455 | |
|
456 | 456 | draw: function(point) { |
|
457 | 457 | var pos = Position.cumulativeOffset(this.element); |
|
458 | 458 | if(this.options.ghosting) { |
|
459 | 459 | var r = Position.realOffset(this.element); |
|
460 | 460 | pos[0] += r[0] - Position.deltaX; pos[1] += r[1] - Position.deltaY; |
|
461 | 461 | } |
|
462 | 462 | |
|
463 | 463 | var d = this.currentDelta(); |
|
464 | 464 | pos[0] -= d[0]; pos[1] -= d[1]; |
|
465 | 465 | |
|
466 | 466 | if(this.options.scroll && (this.options.scroll != window && this._isScrollChild)) { |
|
467 | 467 | pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft; |
|
468 | 468 | pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop; |
|
469 | 469 | } |
|
470 | 470 | |
|
471 | 471 |
var p = [0,1].map(function(i){ |
|
472 | 472 |
return (point[i]-pos[i]-this.offset[i]) |
|
473 | 473 | }.bind(this)); |
|
474 | 474 | |
|
475 | 475 | if(this.options.snap) { |
|
476 | 476 | if(Object.isFunction(this.options.snap)) { |
|
477 | 477 | p = this.options.snap(p[0],p[1],this); |
|
478 | 478 | } else { |
|
479 | 479 | if(Object.isArray(this.options.snap)) { |
|
480 | 480 | p = p.map( function(v, i) { |
|
481 | - return (v/this.options.snap[i]).round()*this.options.snap[i] }.bind(this)) | |
|
481 | + return (v/this.options.snap[i]).round()*this.options.snap[i] }.bind(this)); | |
|
482 | 482 | } else { |
|
483 | 483 | p = p.map( function(v) { |
|
484 | - return (v/this.options.snap).round()*this.options.snap }.bind(this)) | |
|
484 | + return (v/this.options.snap).round()*this.options.snap }.bind(this)); | |
|
485 | 485 | } |
|
486 | 486 | }} |
|
487 | 487 | |
|
488 | 488 | var style = this.element.style; |
|
489 | 489 | if((!this.options.constraint) || (this.options.constraint=='horizontal')) |
|
490 | 490 | style.left = p[0] + "px"; |
|
491 | 491 | if((!this.options.constraint) || (this.options.constraint=='vertical')) |
|
492 | 492 | style.top = p[1] + "px"; |
|
493 | 493 | |
|
494 | 494 | if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering |
|
495 | 495 | }, |
|
496 | 496 | |
|
497 | 497 | stopScrolling: function() { |
|
498 | 498 | if(this.scrollInterval) { |
|
499 | 499 | clearInterval(this.scrollInterval); |
|
500 | 500 | this.scrollInterval = null; |
|
501 | 501 | Draggables._lastScrollPointer = null; |
|
502 | 502 | } |
|
503 | 503 | }, |
|
504 | 504 | |
|
505 | 505 | startScrolling: function(speed) { |
|
506 | 506 | if(!(speed[0] || speed[1])) return; |
|
507 | 507 | this.scrollSpeed = [speed[0]*this.options.scrollSpeed,speed[1]*this.options.scrollSpeed]; |
|
508 | 508 | this.lastScrolled = new Date(); |
|
509 | 509 | this.scrollInterval = setInterval(this.scroll.bind(this), 10); |
|
510 | 510 | }, |
|
511 | 511 | |
|
512 | 512 | scroll: function() { |
|
513 | 513 | var current = new Date(); |
|
514 | 514 | var delta = current - this.lastScrolled; |
|
515 | 515 | this.lastScrolled = current; |
|
516 | 516 | if(this.options.scroll == window) { |
|
517 | 517 | with (this._getWindowScroll(this.options.scroll)) { |
|
518 | 518 | if (this.scrollSpeed[0] || this.scrollSpeed[1]) { |
|
519 | 519 | var d = delta / 1000; |
|
520 | 520 | this.options.scroll.scrollTo( left + d*this.scrollSpeed[0], top + d*this.scrollSpeed[1] ); |
|
521 | 521 | } |
|
522 | 522 | } |
|
523 | 523 | } else { |
|
524 | 524 | this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000; |
|
525 | 525 | this.options.scroll.scrollTop += this.scrollSpeed[1] * delta / 1000; |
|
526 | 526 | } |
|
527 | 527 | |
|
528 | 528 | Position.prepare(); |
|
529 | 529 | Droppables.show(Draggables._lastPointer, this.element); |
|
530 | 530 | Draggables.notify('onDrag', this); |
|
531 | 531 | if (this._isScrollChild) { |
|
532 | 532 | Draggables._lastScrollPointer = Draggables._lastScrollPointer || $A(Draggables._lastPointer); |
|
533 | 533 | Draggables._lastScrollPointer[0] += this.scrollSpeed[0] * delta / 1000; |
|
534 | 534 | Draggables._lastScrollPointer[1] += this.scrollSpeed[1] * delta / 1000; |
|
535 | 535 | if (Draggables._lastScrollPointer[0] < 0) |
|
536 | 536 | Draggables._lastScrollPointer[0] = 0; |
|
537 | 537 | if (Draggables._lastScrollPointer[1] < 0) |
|
538 | 538 | Draggables._lastScrollPointer[1] = 0; |
|
539 | 539 | this.draw(Draggables._lastScrollPointer); |
|
540 | 540 | } |
|
541 | 541 | |
|
542 | 542 | if(this.options.change) this.options.change(this); |
|
543 | 543 | }, |
|
544 | 544 | |
|
545 | 545 | _getWindowScroll: function(w) { |
|
546 | 546 | var T, L, W, H; |
|
547 | 547 | with (w.document) { |
|
548 | 548 | if (w.document.documentElement && documentElement.scrollTop) { |
|
549 | 549 | T = documentElement.scrollTop; |
|
550 | 550 | L = documentElement.scrollLeft; |
|
551 | 551 | } else if (w.document.body) { |
|
552 | 552 | T = body.scrollTop; |
|
553 | 553 | L = body.scrollLeft; |
|
554 | 554 | } |
|
555 | 555 | if (w.innerWidth) { |
|
556 | 556 | W = w.innerWidth; |
|
557 | 557 | H = w.innerHeight; |
|
558 | 558 | } else if (w.document.documentElement && documentElement.clientWidth) { |
|
559 | 559 | W = documentElement.clientWidth; |
|
560 | 560 | H = documentElement.clientHeight; |
|
561 | 561 | } else { |
|
562 | 562 | W = body.offsetWidth; |
|
563 | - H = body.offsetHeight | |
|
563 | + H = body.offsetHeight; | |
|
564 | 564 | } |
|
565 | 565 | } |
|
566 | 566 | return { top: T, left: L, width: W, height: H }; |
|
567 | 567 | } |
|
568 | 568 | }); |
|
569 | 569 | |
|
570 | 570 | Draggable._dragging = { }; |
|
571 | 571 | |
|
572 | 572 | /*--------------------------------------------------------------------------*/ |
|
573 | 573 | |
|
574 | 574 | var SortableObserver = Class.create({ |
|
575 | 575 | initialize: function(element, observer) { |
|
576 | 576 | this.element = $(element); |
|
577 | 577 | this.observer = observer; |
|
578 | 578 | this.lastValue = Sortable.serialize(this.element); |
|
579 | 579 | }, |
|
580 | 580 | |
|
581 | 581 | onStart: function() { |
|
582 | 582 | this.lastValue = Sortable.serialize(this.element); |
|
583 | 583 | }, |
|
584 | 584 | |
|
585 | 585 | onEnd: function() { |
|
586 | 586 | Sortable.unmark(); |
|
587 | 587 | if(this.lastValue != Sortable.serialize(this.element)) |
|
588 | 588 | this.observer(this.element) |
|
589 | 589 | } |
|
590 | 590 | }); |
|
591 | 591 | |
|
592 | 592 | var Sortable = { |
|
593 | 593 | SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/, |
|
594 | 594 | |
|
595 | 595 | sortables: { }, |
|
596 | 596 | |
|
597 | 597 | _findRootElement: function(element) { |
|
598 | 598 |
while (element.tagName.toUpperCase() != "BODY") { |
|
599 | 599 | if(element.id && Sortable.sortables[element.id]) return element; |
|
600 | 600 | element = element.parentNode; |
|
601 | 601 | } |
|
602 | 602 | }, |
|
603 | 603 | |
|
604 | 604 | options: function(element) { |
|
605 | 605 | element = Sortable._findRootElement($(element)); |
|
606 | 606 | if(!element) return; |
|
607 | 607 | return Sortable.sortables[element.id]; |
|
608 | 608 | }, |
|
609 | 609 | |
|
610 | 610 | destroy: function(element){ |
|
611 | - var s = Sortable.options(element); | |
|
611 | + element = $(element); | |
|
612 | + var s = Sortable.sortables[element.id]; | |
|
612 | 613 | |
|
613 | 614 | if(s) { |
|
614 | 615 | Draggables.removeObserver(s.element); |
|
615 | 616 | s.droppables.each(function(d){ Droppables.remove(d) }); |
|
616 | 617 | s.draggables.invoke('destroy'); |
|
617 | 618 | |
|
618 | 619 | delete Sortable.sortables[s.element.id]; |
|
619 | 620 | } |
|
620 | 621 | }, |
|
621 | 622 | |
|
622 | 623 | create: function(element) { |
|
623 | 624 | element = $(element); |
|
624 | 625 |
var options = Object.extend({ |
|
625 | 626 | element: element, |
|
626 | 627 | tag: 'li', // assumes li children, override with tag: 'tagname' |
|
627 | 628 | dropOnEmpty: false, |
|
628 | 629 | tree: false, |
|
629 | 630 | treeTag: 'ul', |
|
630 | 631 | overlap: 'vertical', // one of 'vertical', 'horizontal' |
|
631 | 632 | constraint: 'vertical', // one of 'vertical', 'horizontal', false |
|
632 | 633 | containment: element, // also takes array of elements (or id's); or false |
|
633 | 634 | handle: false, // or a CSS class |
|
634 | 635 | only: false, |
|
635 | 636 | delay: 0, |
|
636 | 637 | hoverclass: null, |
|
637 | 638 | ghosting: false, |
|
638 | 639 |
quiet: false, |
|
639 | 640 | scroll: false, |
|
640 | 641 | scrollSensitivity: 20, |
|
641 | 642 | scrollSpeed: 15, |
|
642 | 643 | format: this.SERIALIZE_RULE, |
|
643 | 644 | |
|
644 | 645 |
// these take arrays of elements or ids and can be |
|
645 | 646 | // used for better initialization performance |
|
646 | 647 | elements: false, |
|
647 | 648 | handles: false, |
|
648 | 649 | |
|
649 | 650 | onChange: Prototype.emptyFunction, |
|
650 | 651 | onUpdate: Prototype.emptyFunction |
|
651 | 652 | }, arguments[1] || { }); |
|
652 | 653 | |
|
653 | 654 | // clear any old sortable with same element |
|
654 | 655 | this.destroy(element); |
|
655 | 656 | |
|
656 | 657 | // build options for the draggables |
|
657 | 658 | var options_for_draggable = { |
|
658 | 659 | revert: true, |
|
659 | 660 | quiet: options.quiet, |
|
660 | 661 | scroll: options.scroll, |
|
661 | 662 | scrollSpeed: options.scrollSpeed, |
|
662 | 663 | scrollSensitivity: options.scrollSensitivity, |
|
663 | 664 | delay: options.delay, |
|
664 | 665 | ghosting: options.ghosting, |
|
665 | 666 | constraint: options.constraint, |
|
666 | 667 | handle: options.handle }; |
|
667 | 668 | |
|
668 | 669 | if(options.starteffect) |
|
669 | 670 | options_for_draggable.starteffect = options.starteffect; |
|
670 | 671 | |
|
671 | 672 | if(options.reverteffect) |
|
672 | 673 | options_for_draggable.reverteffect = options.reverteffect; |
|
673 | 674 | else |
|
674 | 675 | if(options.ghosting) options_for_draggable.reverteffect = function(element) { |
|
675 | 676 | element.style.top = 0; |
|
676 | 677 | element.style.left = 0; |
|
677 | 678 | }; |
|
678 | 679 | |
|
679 | 680 | if(options.endeffect) |
|
680 | 681 | options_for_draggable.endeffect = options.endeffect; |
|
681 | 682 | |
|
682 | 683 | if(options.zindex) |
|
683 | 684 | options_for_draggable.zindex = options.zindex; |
|
684 | 685 | |
|
685 | 686 |
// build options for the droppables |
|
686 | 687 | var options_for_droppable = { |
|
687 | 688 | overlap: options.overlap, |
|
688 | 689 | containment: options.containment, |
|
689 | 690 | tree: options.tree, |
|
690 | 691 | hoverclass: options.hoverclass, |
|
691 | 692 | onHover: Sortable.onHover |
|
692 | - } | |
|
693 | + }; | |
|
693 | 694 | |
|
694 | 695 | var options_for_tree = { |
|
695 | 696 | onHover: Sortable.onEmptyHover, |
|
696 | 697 | overlap: options.overlap, |
|
697 | 698 | containment: options.containment, |
|
698 | 699 | hoverclass: options.hoverclass |
|
699 | - } | |
|
700 | + }; | |
|
700 | 701 | |
|
701 | 702 | // fix for gecko engine |
|
702 | 703 |
|
|
703 | 704 | |
|
704 | 705 | options.draggables = []; |
|
705 | 706 | options.droppables = []; |
|
706 | 707 | |
|
707 | 708 | // drop on empty handling |
|
708 | 709 | if(options.dropOnEmpty || options.tree) { |
|
709 | 710 | Droppables.add(element, options_for_tree); |
|
710 | 711 | options.droppables.push(element); |
|
711 | 712 | } |
|
712 | 713 | |
|
713 | 714 | (options.elements || this.findElements(element, options) || []).each( function(e,i) { |
|
714 | 715 | var handle = options.handles ? $(options.handles[i]) : |
|
715 | 716 |
(options.handle ? $(e).select('.' + options.handle)[0] : e); |
|
716 | 717 | options.draggables.push( |
|
717 | 718 | new Draggable(e, Object.extend(options_for_draggable, { handle: handle }))); |
|
718 | 719 | Droppables.add(e, options_for_droppable); |
|
719 | 720 | if(options.tree) e.treeNode = element; |
|
720 | 721 |
options.droppables.push(e); |
|
721 | 722 | }); |
|
722 | 723 | |
|
723 | 724 | if(options.tree) { |
|
724 | 725 | (Sortable.findTreeElements(element, options) || []).each( function(e) { |
|
725 | 726 | Droppables.add(e, options_for_tree); |
|
726 | 727 | e.treeNode = element; |
|
727 | 728 | options.droppables.push(e); |
|
728 | 729 | }); |
|
729 | 730 | } |
|
730 | 731 | |
|
731 | 732 | // keep reference |
|
732 | 733 | this.sortables[element.id] = options; |
|
733 | 734 | |
|
734 | 735 | // for onupdate |
|
735 | 736 | Draggables.addObserver(new SortableObserver(element, options.onUpdate)); |
|
736 | 737 | |
|
737 | 738 | }, |
|
738 | 739 | |
|
739 | 740 | // return all suitable-for-sortable elements in a guaranteed order |
|
740 | 741 | findElements: function(element, options) { |
|
741 | 742 | return Element.findChildren( |
|
742 | 743 | element, options.only, options.tree ? true : false, options.tag); |
|
743 | 744 | }, |
|
744 | 745 | |
|
745 | 746 | findTreeElements: function(element, options) { |
|
746 | 747 | return Element.findChildren( |
|
747 | 748 | element, options.only, options.tree ? true : false, options.treeTag); |
|
748 | 749 | }, |
|
749 | 750 | |
|
750 | 751 | onHover: function(element, dropon, overlap) { |
|
751 | 752 | if(Element.isParent(dropon, element)) return; |
|
752 | 753 | |
|
753 | 754 | if(overlap > .33 && overlap < .66 && Sortable.options(dropon).tree) { |
|
754 | 755 | return; |
|
755 | 756 | } else if(overlap>0.5) { |
|
756 | 757 | Sortable.mark(dropon, 'before'); |
|
757 | 758 | if(dropon.previousSibling != element) { |
|
758 | 759 | var oldParentNode = element.parentNode; |
|
759 | 760 | element.style.visibility = "hidden"; // fix gecko rendering |
|
760 | 761 | dropon.parentNode.insertBefore(element, dropon); |
|
761 | 762 |
if(dropon.parentNode!=oldParentNode) |
|
762 | 763 | Sortable.options(oldParentNode).onChange(element); |
|
763 | 764 | Sortable.options(dropon.parentNode).onChange(element); |
|
764 | 765 | } |
|
765 | 766 | } else { |
|
766 | 767 | Sortable.mark(dropon, 'after'); |
|
767 | 768 | var nextElement = dropon.nextSibling || null; |
|
768 | 769 | if(nextElement != element) { |
|
769 | 770 | var oldParentNode = element.parentNode; |
|
770 | 771 | element.style.visibility = "hidden"; // fix gecko rendering |
|
771 | 772 | dropon.parentNode.insertBefore(element, nextElement); |
|
772 | 773 |
if(dropon.parentNode!=oldParentNode) |
|
773 | 774 | Sortable.options(oldParentNode).onChange(element); |
|
774 | 775 | Sortable.options(dropon.parentNode).onChange(element); |
|
775 | 776 | } |
|
776 | 777 | } |
|
777 | 778 | }, |
|
778 | 779 | |
|
779 | 780 | onEmptyHover: function(element, dropon, overlap) { |
|
780 | 781 | var oldParentNode = element.parentNode; |
|
781 | 782 | var droponOptions = Sortable.options(dropon); |
|
782 | 783 | |
|
783 | 784 | if(!Element.isParent(dropon, element)) { |
|
784 | 785 | var index; |
|
785 | 786 | |
|
786 | 787 | var children = Sortable.findElements(dropon, {tag: droponOptions.tag, only: droponOptions.only}); |
|
787 | 788 | var child = null; |
|
788 | 789 | |
|
789 | 790 | if(children) { |
|
790 | 791 | var offset = Element.offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap); |
|
791 | 792 | |
|
792 | 793 | for (index = 0; index < children.length; index += 1) { |
|
793 | 794 | if (offset - Element.offsetSize (children[index], droponOptions.overlap) >= 0) { |
|
794 | 795 | offset -= Element.offsetSize (children[index], droponOptions.overlap); |
|
795 | 796 | } else if (offset - (Element.offsetSize (children[index], droponOptions.overlap) / 2) >= 0) { |
|
796 | 797 | child = index + 1 < children.length ? children[index + 1] : null; |
|
797 | 798 | break; |
|
798 | 799 | } else { |
|
799 | 800 | child = children[index]; |
|
800 | 801 | break; |
|
801 | 802 | } |
|
802 | 803 | } |
|
803 | 804 | } |
|
804 | 805 | |
|
805 | 806 | dropon.insertBefore(element, child); |
|
806 | 807 | |
|
807 | 808 | Sortable.options(oldParentNode).onChange(element); |
|
808 | 809 | droponOptions.onChange(element); |
|
809 | 810 | } |
|
810 | 811 | }, |
|
811 | 812 | |
|
812 | 813 | unmark: function() { |
|
813 | 814 | if(Sortable._marker) Sortable._marker.hide(); |
|
814 | 815 | }, |
|
815 | 816 | |
|
816 | 817 | mark: function(dropon, position) { |
|
817 | 818 | // mark on ghosting only |
|
818 | 819 | var sortable = Sortable.options(dropon.parentNode); |
|
819 | 820 |
if(sortable && !sortable.ghosting) return; |
|
820 | 821 | |
|
821 | 822 | if(!Sortable._marker) { |
|
822 | 823 |
Sortable._marker = |
|
823 | 824 | ($('dropmarker') || Element.extend(document.createElement('DIV'))). |
|
824 | 825 | hide().addClassName('dropmarker').setStyle({position:'absolute'}); |
|
825 | 826 | document.getElementsByTagName("body").item(0).appendChild(Sortable._marker); |
|
826 | 827 |
} |
|
827 | 828 | var offsets = Position.cumulativeOffset(dropon); |
|
828 | 829 | Sortable._marker.setStyle({left: offsets[0]+'px', top: offsets[1] + 'px'}); |
|
829 | 830 | |
|
830 | 831 | if(position=='after') |
|
831 | 832 |
if(sortable.overlap == 'horizontal') |
|
832 | 833 | Sortable._marker.setStyle({left: (offsets[0]+dropon.clientWidth) + 'px'}); |
|
833 | 834 | else |
|
834 | 835 | Sortable._marker.setStyle({top: (offsets[1]+dropon.clientHeight) + 'px'}); |
|
835 | 836 | |
|
836 | 837 | Sortable._marker.show(); |
|
837 | 838 | }, |
|
838 | 839 | |
|
839 | 840 | _tree: function(element, options, parent) { |
|
840 | 841 | var children = Sortable.findElements(element, options) || []; |
|
841 | 842 | |
|
842 | 843 | for (var i = 0; i < children.length; ++i) { |
|
843 | 844 | var match = children[i].id.match(options.format); |
|
844 | 845 | |
|
845 | 846 | if (!match) continue; |
|
846 | 847 | |
|
847 | 848 | var child = { |
|
848 | 849 | id: encodeURIComponent(match ? match[1] : null), |
|
849 | 850 | element: element, |
|
850 | 851 | parent: parent, |
|
851 | 852 | children: [], |
|
852 | 853 | position: parent.children.length, |
|
853 | 854 | container: $(children[i]).down(options.treeTag) |
|
854 | - } | |
|
855 | + }; | |
|
855 | 856 | |
|
856 | 857 | /* Get the element containing the children and recurse over it */ |
|
857 | 858 | if (child.container) |
|
858 | - this._tree(child.container, options, child) | |
|
859 | + this._tree(child.container, options, child); | |
|
859 | 860 | |
|
860 | 861 | parent.children.push (child); |
|
861 | 862 | } |
|
862 | 863 | |
|
863 | 864 |
return parent; |
|
864 | 865 | }, |
|
865 | 866 | |
|
866 | 867 | tree: function(element) { |
|
867 | 868 | element = $(element); |
|
868 | 869 | var sortableOptions = this.options(element); |
|
869 | 870 | var options = Object.extend({ |
|
870 | 871 | tag: sortableOptions.tag, |
|
871 | 872 | treeTag: sortableOptions.treeTag, |
|
872 | 873 | only: sortableOptions.only, |
|
873 | 874 | name: element.id, |
|
874 | 875 | format: sortableOptions.format |
|
875 | 876 | }, arguments[1] || { }); |
|
876 | 877 | |
|
877 | 878 | var root = { |
|
878 | 879 | id: null, |
|
879 | 880 | parent: null, |
|
880 | 881 | children: [], |
|
881 | 882 | container: element, |
|
882 | 883 | position: 0 |
|
883 | - } | |
|
884 | + }; | |
|
884 | 885 | |
|
885 | 886 | return Sortable._tree(element, options, root); |
|
886 | 887 | }, |
|
887 | 888 | |
|
888 | 889 | /* Construct a [i] index for a particular node */ |
|
889 | 890 | _constructIndex: function(node) { |
|
890 | 891 | var index = ''; |
|
891 | 892 | do { |
|
892 | 893 | if (node.id) index = '[' + node.position + ']' + index; |
|
893 | 894 | } while ((node = node.parent) != null); |
|
894 | 895 | return index; |
|
895 | 896 | }, |
|
896 | 897 | |
|
897 | 898 | sequence: function(element) { |
|
898 | 899 | element = $(element); |
|
899 | 900 | var options = Object.extend(this.options(element), arguments[1] || { }); |
|
900 | 901 | |
|
901 | 902 | return $(this.findElements(element, options) || []).map( function(item) { |
|
902 | 903 | return item.id.match(options.format) ? item.id.match(options.format)[1] : ''; |
|
903 | 904 | }); |
|
904 | 905 | }, |
|
905 | 906 | |
|
906 | 907 | setSequence: function(element, new_sequence) { |
|
907 | 908 | element = $(element); |
|
908 | 909 | var options = Object.extend(this.options(element), arguments[2] || { }); |
|
909 | 910 | |
|
910 | 911 | var nodeMap = { }; |
|
911 | 912 | this.findElements(element, options).each( function(n) { |
|
912 | 913 | if (n.id.match(options.format)) |
|
913 | 914 | nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode]; |
|
914 | 915 | n.parentNode.removeChild(n); |
|
915 | 916 | }); |
|
916 | 917 | |
|
917 | 918 | new_sequence.each(function(ident) { |
|
918 | 919 | var n = nodeMap[ident]; |
|
919 | 920 | if (n) { |
|
920 | 921 | n[1].appendChild(n[0]); |
|
921 | 922 | delete nodeMap[ident]; |
|
922 | 923 | } |
|
923 | 924 | }); |
|
924 | 925 | }, |
|
925 | 926 | |
|
926 | 927 | serialize: function(element) { |
|
927 | 928 | element = $(element); |
|
928 | 929 | var options = Object.extend(Sortable.options(element), arguments[1] || { }); |
|
929 | 930 | var name = encodeURIComponent( |
|
930 | 931 | (arguments[1] && arguments[1].name) ? arguments[1].name : element.id); |
|
931 | 932 | |
|
932 | 933 | if (options.tree) { |
|
933 | 934 | return Sortable.tree(element, arguments[1]).children.map( function (item) { |
|
934 | 935 |
return [name + Sortable._constructIndex(item) + "[id]=" + |
|
935 | 936 | encodeURIComponent(item.id)].concat(item.children.map(arguments.callee)); |
|
936 | 937 | }).flatten().join('&'); |
|
937 | 938 | } else { |
|
938 | 939 | return Sortable.sequence(element, arguments[1]).map( function(item) { |
|
939 | 940 | return name + "[]=" + encodeURIComponent(item); |
|
940 | 941 | }).join('&'); |
|
941 | 942 | } |
|
942 | 943 | } |
|
943 | - } | |
|
944 | + }; | |
|
944 | 945 | |
|
945 | 946 |
|
|
946 | 947 | Element.isParent = function(child, element) { |
|
947 | 948 | if (!child.parentNode || child == element) return false; |
|
948 | 949 | if (child.parentNode == element) return true; |
|
949 | 950 | return Element.isParent(child.parentNode, element); |
|
950 | - } | |
|
951 | + }; | |
|
951 | 952 | |
|
952 | 953 |
Element.findChildren = function(element, only, recursive, tagName) { |
|
953 | 954 | if(!element.hasChildNodes()) return null; |
|
954 | 955 | tagName = tagName.toUpperCase(); |
|
955 | 956 | if(only) only = [only].flatten(); |
|
956 | 957 | var elements = []; |
|
957 | 958 | $A(element.childNodes).each( function(e) { |
|
958 | 959 | if(e.tagName && e.tagName.toUpperCase()==tagName && |
|
959 | 960 | (!only || (Element.classNames(e).detect(function(v) { return only.include(v) })))) |
|
960 | 961 | elements.push(e); |
|
961 | 962 | if(recursive) { |
|
962 | 963 | var grandchildren = Element.findChildren(e, only, recursive, tagName); |
|
963 | 964 | if(grandchildren) elements.push(grandchildren); |
|
964 | 965 | } |
|
965 | 966 | }); |
|
966 | 967 | |
|
967 | 968 | return (elements.length>0 ? elements.flatten() : []); |
|
968 | - } | |
|
969 | + }; | |
|
969 | 970 | |
|
970 | 971 | Element.offsetSize = function (element, type) { |
|
971 | 972 | return element['offset' + ((type=='vertical' || type=='height') ? 'Height' : 'Width')]; |
|
972 | - } | |
|
973 | + }; No newline at end of file |
@@ -1,359 +1,366 | |||
|
1 | 1 | // Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) |
|
2 | 2 | // Contributors: |
|
3 | 3 | // Justin Palmer (http://encytemedia.com/) |
|
4 | 4 | // Mark Pilgrim (http://diveintomark.org/) |
|
5 | 5 | // Martin Bialasinki |
|
6 | 6 |
// |
|
7 | 7 | // script.aculo.us is freely distributable under the terms of an MIT-style license. |
|
8 | 8 |
// For details, see the script.aculo.us web site: http://script.aculo.us/ |
|
9 | 9 | |
|
10 | 10 |
// converts rgb() and #xxx to #xxxxxx format, |
|
11 | 11 |
// returns self (or first argument) if not convertable |
|
12 | 12 |
String.prototype.parseColor = function() { |
|
13 | 13 | var color = '#'; |
|
14 | 14 |
if (this.slice(0,4) == 'rgb(') { |
|
15 | 15 |
var cols = this.slice(4,this.length-1).split(','); |
|
16 | 16 |
var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3); |
|
17 | 17 |
} else { |
|
18 | 18 |
if (this.slice(0,1) == '#') { |
|
19 | 19 |
if (this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase(); |
|
20 | 20 |
if (this.length==7) color = this.toLowerCase(); |
|
21 | 21 |
} |
|
22 | 22 |
} |
|
23 | 23 |
return (color.length==7 ? color : (arguments[0] || this)); |
|
24 | 24 | }; |
|
25 | 25 | |
|
26 | 26 | /*--------------------------------------------------------------------------*/ |
|
27 | 27 | |
|
28 | 28 |
Element.collectTextNodes = function(element) { |
|
29 | 29 | return $A($(element).childNodes).collect( function(node) { |
|
30 | 30 |
return (node.nodeType==3 ? node.nodeValue : |
|
31 | 31 | (node.hasChildNodes() ? Element.collectTextNodes(node) : '')); |
|
32 | 32 | }).flatten().join(''); |
|
33 | 33 | }; |
|
34 | 34 | |
|
35 | 35 |
Element.collectTextNodesIgnoreClass = function(element, className) { |
|
36 | 36 | return $A($(element).childNodes).collect( function(node) { |
|
37 | 37 |
return (node.nodeType==3 ? node.nodeValue : |
|
38 | 38 |
((node.hasChildNodes() && !Element.hasClassName(node,className)) ? |
|
39 | 39 | Element.collectTextNodesIgnoreClass(node, className) : '')); |
|
40 | 40 | }).flatten().join(''); |
|
41 | 41 | }; |
|
42 | 42 | |
|
43 | 43 | Element.setContentZoom = function(element, percent) { |
|
44 | 44 |
element = $(element); |
|
45 | 45 |
element.setStyle({fontSize: (percent/100) + 'em'}); |
|
46 | 46 | if (Prototype.Browser.WebKit) window.scrollBy(0,0); |
|
47 | 47 | return element; |
|
48 | 48 | }; |
|
49 | 49 | |
|
50 | 50 | Element.getInlineOpacity = function(element){ |
|
51 | 51 | return $(element).style.opacity || ''; |
|
52 | 52 | }; |
|
53 | 53 | |
|
54 | 54 | Element.forceRerendering = function(element) { |
|
55 | 55 | try { |
|
56 | 56 | element = $(element); |
|
57 | 57 | var n = document.createTextNode(' '); |
|
58 | 58 | element.appendChild(n); |
|
59 | 59 | element.removeChild(n); |
|
60 | 60 | } catch(e) { } |
|
61 | 61 | }; |
|
62 | 62 | |
|
63 | 63 | /*--------------------------------------------------------------------------*/ |
|
64 | 64 | |
|
65 | 65 | var Effect = { |
|
66 | 66 | _elementDoesNotExistError: { |
|
67 | 67 | name: 'ElementDoesNotExistError', |
|
68 | 68 | message: 'The specified DOM element does not exist, but is required for this effect to operate' |
|
69 | 69 | }, |
|
70 | 70 | Transitions: { |
|
71 | 71 | linear: Prototype.K, |
|
72 | 72 | sinoidal: function(pos) { |
|
73 |
- return (-Math.cos(pos*Math.PI)/2) + |
|
|
73 | + return (-Math.cos(pos*Math.PI)/2) + .5; | |
|
74 | 74 | }, |
|
75 | 75 | reverse: function(pos) { |
|
76 | 76 | return 1-pos; |
|
77 | 77 | }, |
|
78 | 78 | flicker: function(pos) { |
|
79 |
- var pos = ((-Math.cos(pos*Math.PI)/4) + |
|
|
79 | + var pos = ((-Math.cos(pos*Math.PI)/4) + .75) + Math.random()/4; | |
|
80 | 80 | return pos > 1 ? 1 : pos; |
|
81 | 81 | }, |
|
82 | 82 | wobble: function(pos) { |
|
83 |
- return (-Math.cos(pos*Math.PI*(9*pos))/2) + |
|
|
83 | + return (-Math.cos(pos*Math.PI*(9*pos))/2) + .5; | |
|
84 | 84 | }, |
|
85 | 85 |
pulse: function(pos, pulses) { |
|
86 | - pulses = pulses || 5; | |
|
87 | - return ( | |
|
88 | - ((pos % (1/pulses)) * pulses).round() == 0 ? | |
|
89 | - ((pos * pulses * 2) - (pos * pulses * 2).floor()) : | |
|
90 | - 1 - ((pos * pulses * 2) - (pos * pulses * 2).floor()) | |
|
91 | - ); | |
|
86 | + return (-Math.cos((pos*((pulses||5)-.5)*2)*Math.PI)/2) + .5; | |
|
92 | 87 | }, |
|
93 | 88 |
spring: function(pos) { |
|
94 | 89 |
return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6)); |
|
95 | 90 | }, |
|
96 | 91 | none: function(pos) { |
|
97 | 92 | return 0; |
|
98 | 93 | }, |
|
99 | 94 | full: function(pos) { |
|
100 | 95 | return 1; |
|
101 | 96 | } |
|
102 | 97 | }, |
|
103 | 98 | DefaultOptions: { |
|
104 | 99 | duration: 1.0, // seconds |
|
105 | 100 | fps: 100, // 100= assume 66fps max. |
|
106 | 101 | sync: false, // true for combining |
|
107 | 102 | from: 0.0, |
|
108 | 103 | to: 1.0, |
|
109 | 104 | delay: 0.0, |
|
110 | 105 | queue: 'parallel' |
|
111 | 106 | }, |
|
112 | 107 | tagifyText: function(element) { |
|
113 | 108 | var tagifyStyle = 'position:relative'; |
|
114 | 109 | if (Prototype.Browser.IE) tagifyStyle += ';zoom:1'; |
|
115 | 110 | |
|
116 | 111 | element = $(element); |
|
117 | 112 | $A(element.childNodes).each( function(child) { |
|
118 | 113 | if (child.nodeType==3) { |
|
119 | 114 | child.nodeValue.toArray().each( function(character) { |
|
120 | 115 | element.insertBefore( |
|
121 | 116 | new Element('span', {style: tagifyStyle}).update( |
|
122 | 117 |
character == ' ' ? String.fromCharCode(160) : character), |
|
123 | 118 | child); |
|
124 | 119 | }); |
|
125 | 120 | Element.remove(child); |
|
126 | 121 | } |
|
127 | 122 | }); |
|
128 | 123 | }, |
|
129 | 124 | multiple: function(element, effect) { |
|
130 | 125 | var elements; |
|
131 | 126 |
if (((typeof element == 'object') || |
|
132 | 127 |
Object.isFunction(element)) && |
|
133 | 128 | (element.length)) |
|
134 | 129 | elements = element; |
|
135 | 130 | else |
|
136 | 131 | elements = $(element).childNodes; |
|
137 | 132 | |
|
138 | 133 | var options = Object.extend({ |
|
139 | 134 | speed: 0.1, |
|
140 | 135 | delay: 0.0 |
|
141 | 136 | }, arguments[2] || { }); |
|
142 | 137 | var masterDelay = options.delay; |
|
143 | 138 | |
|
144 | 139 | $A(elements).each( function(element, index) { |
|
145 | 140 | new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay })); |
|
146 | 141 | }); |
|
147 | 142 | }, |
|
148 | 143 | PAIRS: { |
|
149 | 144 | 'slide': ['SlideDown','SlideUp'], |
|
150 | 145 | 'blind': ['BlindDown','BlindUp'], |
|
151 | 146 | 'appear': ['Appear','Fade'] |
|
152 | 147 | }, |
|
153 | 148 | toggle: function(element, effect) { |
|
154 | 149 | element = $(element); |
|
155 | 150 | effect = (effect || 'appear').toLowerCase(); |
|
156 | 151 | var options = Object.extend({ |
|
157 | 152 | queue: { position:'end', scope:(element.id || 'global'), limit: 1 } |
|
158 | 153 | }, arguments[2] || { }); |
|
159 | 154 |
Effect[element.visible() ? |
|
160 | 155 | Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options); |
|
161 | 156 | } |
|
162 | 157 | }; |
|
163 | 158 | |
|
164 | 159 | Effect.DefaultOptions.transition = Effect.Transitions.sinoidal; |
|
165 | 160 | |
|
166 | 161 | /* ------------- core effects ------------- */ |
|
167 | 162 | |
|
168 | 163 | Effect.ScopedQueue = Class.create(Enumerable, { |
|
169 | 164 | initialize: function() { |
|
170 | 165 | this.effects = []; |
|
171 | 166 |
this.interval = null; |
|
172 | 167 | }, |
|
173 | 168 | _each: function(iterator) { |
|
174 | 169 | this.effects._each(iterator); |
|
175 | 170 | }, |
|
176 | 171 | add: function(effect) { |
|
177 | 172 | var timestamp = new Date().getTime(); |
|
178 | 173 | |
|
179 | 174 |
var position = Object.isString(effect.options.queue) ? |
|
180 | 175 | effect.options.queue : effect.options.queue.position; |
|
181 | 176 | |
|
182 | 177 | switch(position) { |
|
183 | 178 | case 'front': |
|
184 | 179 |
// move unstarted effects after this effect |
|
185 | 180 | this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) { |
|
186 | 181 | e.startOn += effect.finishOn; |
|
187 | 182 | e.finishOn += effect.finishOn; |
|
188 | 183 | }); |
|
189 | 184 | break; |
|
190 | 185 | case 'with-last': |
|
191 | 186 | timestamp = this.effects.pluck('startOn').max() || timestamp; |
|
192 | 187 | break; |
|
193 | 188 | case 'end': |
|
194 | 189 | // start effect after last queued effect has finished |
|
195 | 190 | timestamp = this.effects.pluck('finishOn').max() || timestamp; |
|
196 | 191 | break; |
|
197 | 192 | } |
|
198 | 193 | |
|
199 | 194 | effect.startOn += timestamp; |
|
200 | 195 | effect.finishOn += timestamp; |
|
201 | 196 | |
|
202 | 197 | if (!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit)) |
|
203 | 198 | this.effects.push(effect); |
|
204 | 199 | |
|
205 | 200 | if (!this.interval) |
|
206 | 201 | this.interval = setInterval(this.loop.bind(this), 15); |
|
207 | 202 | }, |
|
208 | 203 | remove: function(effect) { |
|
209 | 204 | this.effects = this.effects.reject(function(e) { return e==effect }); |
|
210 | 205 | if (this.effects.length == 0) { |
|
211 | 206 | clearInterval(this.interval); |
|
212 | 207 | this.interval = null; |
|
213 | 208 | } |
|
214 | 209 | }, |
|
215 | 210 | loop: function() { |
|
216 | 211 | var timePos = new Date().getTime(); |
|
217 | 212 |
for(var i=0, len=this.effects.length;i<len;i++) |
|
218 | 213 | this.effects[i] && this.effects[i].loop(timePos); |
|
219 | 214 | } |
|
220 | 215 | }); |
|
221 | 216 | |
|
222 | 217 | Effect.Queues = { |
|
223 | 218 | instances: $H(), |
|
224 | 219 | get: function(queueName) { |
|
225 | 220 | if (!Object.isString(queueName)) return queueName; |
|
226 | 221 | |
|
227 | 222 | return this.instances.get(queueName) || |
|
228 | 223 | this.instances.set(queueName, new Effect.ScopedQueue()); |
|
229 | 224 | } |
|
230 | 225 | }; |
|
231 | 226 | Effect.Queue = Effect.Queues.get('global'); |
|
232 | 227 | |
|
233 | 228 | Effect.Base = Class.create({ |
|
234 | 229 | position: null, |
|
235 | 230 | start: function(options) { |
|
236 | 231 | function codeForEvent(options,eventName){ |
|
237 | 232 | return ( |
|
238 | 233 | (options[eventName+'Internal'] ? 'this.options.'+eventName+'Internal(this);' : '') + |
|
239 | 234 | (options[eventName] ? 'this.options.'+eventName+'(this);' : '') |
|
240 | 235 | ); |
|
241 | 236 | } |
|
242 | 237 | if (options && options.transition === false) options.transition = Effect.Transitions.linear; |
|
243 | 238 | this.options = Object.extend(Object.extend({ },Effect.DefaultOptions), options || { }); |
|
244 | 239 | this.currentFrame = 0; |
|
245 | 240 | this.state = 'idle'; |
|
246 | 241 | this.startOn = this.options.delay*1000; |
|
247 | 242 | this.finishOn = this.startOn+(this.options.duration*1000); |
|
248 | 243 | this.fromToDelta = this.options.to-this.options.from; |
|
249 | 244 | this.totalTime = this.finishOn-this.startOn; |
|
250 | 245 | this.totalFrames = this.options.fps*this.options.duration; |
|
251 | 246 | |
|
252 |
- |
|
|
253 | - 'if (this.state=="idle"){this.state="running";'+ | |
|
254 | - codeForEvent(this.options,'beforeSetup')+ | |
|
255 | - (this.setup ? 'this.setup();':'')+ | |
|
256 | - codeForEvent(this.options,'afterSetup')+ | |
|
257 | - '};if (this.state=="running"){'+ | |
|
258 | - 'pos=this.options.transition(pos)*'+this.fromToDelta+'+'+this.options.from+';'+ | |
|
259 | - 'this.position=pos;'+ | |
|
260 | - codeForEvent(this.options,'beforeUpdate')+ | |
|
261 | - (this.update ? 'this.update(pos);':'')+ | |
|
262 | - codeForEvent(this.options,'afterUpdate')+ | |
|
263 | - '}}'); | |
|
247 | + this.render = (function() { | |
|
248 | + function dispatch(effect, eventName) { | |
|
249 | + if (effect.options[eventName + 'Internal']) | |
|
250 | + effect.options[eventName + 'Internal'](effect); | |
|
251 | + if (effect.options[eventName]) | |
|
252 | + effect.options[eventName](effect); | |
|
253 | + } | |
|
254 | + | |
|
255 | + return function(pos) { | |
|
256 | + if (this.state === "idle") { | |
|
257 | + this.state = "running"; | |
|
258 | + dispatch(this, 'beforeSetup'); | |
|
259 | + if (this.setup) this.setup(); | |
|
260 | + dispatch(this, 'afterSetup'); | |
|
261 | + } | |
|
262 | + if (this.state === "running") { | |
|
263 | + pos = (this.options.transition(pos) * this.fromToDelta) + this.options.from; | |
|
264 | + this.position = pos; | |
|
265 | + dispatch(this, 'beforeUpdate'); | |
|
266 | + if (this.update) this.update(pos); | |
|
267 | + dispatch(this, 'afterUpdate'); | |
|
268 | + } | |
|
269 | + }; | |
|
270 | + })(); | |
|
264 | 271 | |
|
265 | 272 | this.event('beforeStart'); |
|
266 | 273 | if (!this.options.sync) |
|
267 | 274 |
Effect.Queues.get(Object.isString(this.options.queue) ? |
|
268 | 275 | 'global' : this.options.queue.scope).add(this); |
|
269 | 276 | }, |
|
270 | 277 | loop: function(timePos) { |
|
271 | 278 | if (timePos >= this.startOn) { |
|
272 | 279 | if (timePos >= this.finishOn) { |
|
273 | 280 | this.render(1.0); |
|
274 | 281 | this.cancel(); |
|
275 | 282 | this.event('beforeFinish'); |
|
276 | 283 |
if (this.finish) this.finish(); |
|
277 | 284 | this.event('afterFinish'); |
|
278 | 285 |
return; |
|
279 | 286 | } |
|
280 | 287 | var pos = (timePos - this.startOn) / this.totalTime, |
|
281 | 288 | frame = (pos * this.totalFrames).round(); |
|
282 | 289 | if (frame > this.currentFrame) { |
|
283 | 290 | this.render(pos); |
|
284 | 291 | this.currentFrame = frame; |
|
285 | 292 | } |
|
286 | 293 | } |
|
287 | 294 | }, |
|
288 | 295 | cancel: function() { |
|
289 | 296 | if (!this.options.sync) |
|
290 | 297 |
Effect.Queues.get(Object.isString(this.options.queue) ? |
|
291 | 298 | 'global' : this.options.queue.scope).remove(this); |
|
292 | 299 | this.state = 'finished'; |
|
293 | 300 | }, |
|
294 | 301 | event: function(eventName) { |
|
295 | 302 | if (this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this); |
|
296 | 303 | if (this.options[eventName]) this.options[eventName](this); |
|
297 | 304 | }, |
|
298 | 305 | inspect: function() { |
|
299 | 306 | var data = $H(); |
|
300 | 307 | for(property in this) |
|
301 | 308 | if (!Object.isFunction(this[property])) data.set(property, this[property]); |
|
302 | 309 | return '#<Effect:' + data.inspect() + ',options:' + $H(this.options).inspect() + '>'; |
|
303 | 310 | } |
|
304 | 311 | }); |
|
305 | 312 | |
|
306 | 313 | Effect.Parallel = Class.create(Effect.Base, { |
|
307 | 314 | initialize: function(effects) { |
|
308 | 315 | this.effects = effects || []; |
|
309 | 316 | this.start(arguments[1]); |
|
310 | 317 | }, |
|
311 | 318 | update: function(position) { |
|
312 | 319 | this.effects.invoke('render', position); |
|
313 | 320 | }, |
|
314 | 321 | finish: function(position) { |
|
315 | 322 | this.effects.each( function(effect) { |
|
316 | 323 | effect.render(1.0); |
|
317 | 324 | effect.cancel(); |
|
318 | 325 | effect.event('beforeFinish'); |
|
319 | 326 | if (effect.finish) effect.finish(position); |
|
320 | 327 | effect.event('afterFinish'); |
|
321 | 328 | }); |
|
322 | 329 | } |
|
323 | 330 | }); |
|
324 | 331 | |
|
325 | 332 | Effect.Tween = Class.create(Effect.Base, { |
|
326 | 333 | initialize: function(object, from, to) { |
|
327 | 334 | object = Object.isString(object) ? $(object) : object; |
|
328 | 335 |
var args = $A(arguments), method = args.last(), |
|
329 | 336 | options = args.length == 5 ? args[3] : null; |
|
330 | 337 | this.method = Object.isFunction(method) ? method.bind(object) : |
|
331 | 338 |
Object.isFunction(object[method]) ? object[method].bind(object) : |
|
332 | 339 | function(value) { object[method] = value }; |
|
333 | 340 | this.start(Object.extend({ from: from, to: to }, options || { })); |
|
334 | 341 | }, |
|
335 | 342 | update: function(position) { |
|
336 | 343 | this.method(position); |
|
337 | 344 | } |
|
338 | 345 | }); |
|
339 | 346 | |
|
340 | 347 | Effect.Event = Class.create(Effect.Base, { |
|
341 | 348 | initialize: function() { |
|
342 | 349 | this.start(Object.extend({ duration: 0 }, arguments[0] || { })); |
|
343 | 350 | }, |
|
344 | 351 | update: Prototype.emptyFunction |
|
345 | 352 | }); |
|
346 | 353 | |
|
347 | 354 | Effect.Opacity = Class.create(Effect.Base, { |
|
348 | 355 | initialize: function(element) { |
|
349 | 356 | this.element = $(element); |
|
350 | 357 | if (!this.element) throw(Effect._elementDoesNotExistError); |
|
351 | 358 | // make this work on IE on elements without 'layout' |
|
352 | 359 | if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout)) |
|
353 | 360 | this.element.setStyle({zoom: 1}); |
|
354 | 361 | var options = Object.extend({ |
|
355 | 362 | from: this.element.getOpacity() || 0.0, |
|
356 | 363 | to: 1.0 |
|
357 | 364 | }, arguments[1] || { }); |
|
358 | 365 | this.start(options); |
|
359 | 366 | }, |
@@ -415,706 +422,707 | |||
|
415 | 422 | this.restoreAfterFinish = this.options.restoreAfterFinish || false; |
|
416 | 423 | this.elementPositioning = this.element.getStyle('position'); |
|
417 | 424 | |
|
418 | 425 | this.originalStyle = { }; |
|
419 | 426 | ['top','left','width','height','fontSize'].each( function(k) { |
|
420 | 427 | this.originalStyle[k] = this.element.style[k]; |
|
421 | 428 | }.bind(this)); |
|
422 | 429 | |
|
423 | 430 | this.originalTop = this.element.offsetTop; |
|
424 | 431 | this.originalLeft = this.element.offsetLeft; |
|
425 | 432 | |
|
426 | 433 | var fontSize = this.element.getStyle('font-size') || '100%'; |
|
427 | 434 | ['em','px','%','pt'].each( function(fontSizeType) { |
|
428 | 435 | if (fontSize.indexOf(fontSizeType)>0) { |
|
429 | 436 | this.fontSize = parseFloat(fontSize); |
|
430 | 437 | this.fontSizeType = fontSizeType; |
|
431 | 438 | } |
|
432 | 439 | }.bind(this)); |
|
433 | 440 | |
|
434 | 441 | this.factor = (this.options.scaleTo - this.options.scaleFrom)/100; |
|
435 | 442 | |
|
436 | 443 | this.dims = null; |
|
437 | 444 | if (this.options.scaleMode=='box') |
|
438 | 445 | this.dims = [this.element.offsetHeight, this.element.offsetWidth]; |
|
439 | 446 | if (/^content/.test(this.options.scaleMode)) |
|
440 | 447 | this.dims = [this.element.scrollHeight, this.element.scrollWidth]; |
|
441 | 448 | if (!this.dims) |
|
442 | 449 | this.dims = [this.options.scaleMode.originalHeight, |
|
443 | 450 | this.options.scaleMode.originalWidth]; |
|
444 | 451 | }, |
|
445 | 452 | update: function(position) { |
|
446 | 453 | var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position); |
|
447 | 454 | if (this.options.scaleContent && this.fontSize) |
|
448 | 455 | this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType }); |
|
449 | 456 | this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale); |
|
450 | 457 | }, |
|
451 | 458 | finish: function(position) { |
|
452 | 459 | if (this.restoreAfterFinish) this.element.setStyle(this.originalStyle); |
|
453 | 460 | }, |
|
454 | 461 | setDimensions: function(height, width) { |
|
455 | 462 | var d = { }; |
|
456 | 463 | if (this.options.scaleX) d.width = width.round() + 'px'; |
|
457 | 464 | if (this.options.scaleY) d.height = height.round() + 'px'; |
|
458 | 465 | if (this.options.scaleFromCenter) { |
|
459 | 466 | var topd = (height - this.dims[0])/2; |
|
460 | 467 | var leftd = (width - this.dims[1])/2; |
|
461 | 468 | if (this.elementPositioning == 'absolute') { |
|
462 | 469 | if (this.options.scaleY) d.top = this.originalTop-topd + 'px'; |
|
463 | 470 | if (this.options.scaleX) d.left = this.originalLeft-leftd + 'px'; |
|
464 | 471 | } else { |
|
465 | 472 | if (this.options.scaleY) d.top = -topd + 'px'; |
|
466 | 473 | if (this.options.scaleX) d.left = -leftd + 'px'; |
|
467 | 474 | } |
|
468 | 475 | } |
|
469 | 476 | this.element.setStyle(d); |
|
470 | 477 | } |
|
471 | 478 | }); |
|
472 | 479 | |
|
473 | 480 | Effect.Highlight = Class.create(Effect.Base, { |
|
474 | 481 | initialize: function(element) { |
|
475 | 482 | this.element = $(element); |
|
476 | 483 | if (!this.element) throw(Effect._elementDoesNotExistError); |
|
477 | 484 | var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || { }); |
|
478 | 485 | this.start(options); |
|
479 | 486 | }, |
|
480 | 487 | setup: function() { |
|
481 | 488 | // Prevent executing on elements not in the layout flow |
|
482 | 489 | if (this.element.getStyle('display')=='none') { this.cancel(); return; } |
|
483 | 490 | // Disable background image during the effect |
|
484 | 491 | this.oldStyle = { }; |
|
485 | 492 | if (!this.options.keepBackgroundImage) { |
|
486 | 493 | this.oldStyle.backgroundImage = this.element.getStyle('background-image'); |
|
487 | 494 | this.element.setStyle({backgroundImage: 'none'}); |
|
488 | 495 | } |
|
489 | 496 | if (!this.options.endcolor) |
|
490 | 497 | this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff'); |
|
491 | 498 | if (!this.options.restorecolor) |
|
492 | 499 | this.options.restorecolor = this.element.getStyle('background-color'); |
|
493 | 500 | // init color calculations |
|
494 | 501 | this._base = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this)); |
|
495 | 502 | this._delta = $R(0,2).map(function(i){ return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this)); |
|
496 | 503 | }, |
|
497 | 504 | update: function(position) { |
|
498 | 505 | this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){ |
|
499 | 506 | return m+((this._base[i]+(this._delta[i]*position)).round().toColorPart()); }.bind(this)) }); |
|
500 | 507 | }, |
|
501 | 508 | finish: function() { |
|
502 | 509 | this.element.setStyle(Object.extend(this.oldStyle, { |
|
503 | 510 | backgroundColor: this.options.restorecolor |
|
504 | 511 | })); |
|
505 | 512 | } |
|
506 | 513 | }); |
|
507 | 514 | |
|
508 | 515 | Effect.ScrollTo = function(element) { |
|
509 | 516 | var options = arguments[1] || { }, |
|
510 | 517 |
|
|
511 |
- |
|
|
512 | - max = (window.height || document.body.scrollHeight) - document.viewport.getHeight(); | |
|
518 | + elementOffsets = $(element).cumulativeOffset(); | |
|
513 | 519 | |
|
514 | 520 | if (options.offset) elementOffsets[1] += options.offset; |
|
515 | 521 | |
|
516 | 522 | return new Effect.Tween(null, |
|
517 | 523 | scrollOffsets.top, |
|
518 | - elementOffsets[1] > max ? max : elementOffsets[1], | |
|
524 | + elementOffsets[1], | |
|
519 | 525 | options, |
|
520 | - function(p){ scrollTo(scrollOffsets.left, p.round()) } | |
|
526 | + function(p){ scrollTo(scrollOffsets.left, p.round()); } | |
|
521 | 527 | ); |
|
522 | 528 | }; |
|
523 | 529 | |
|
524 | 530 | /* ------------- combination effects ------------- */ |
|
525 | 531 | |
|
526 | 532 | Effect.Fade = function(element) { |
|
527 | 533 | element = $(element); |
|
528 | 534 | var oldOpacity = element.getInlineOpacity(); |
|
529 | 535 | var options = Object.extend({ |
|
530 | 536 | from: element.getOpacity() || 1.0, |
|
531 | 537 | to: 0.0, |
|
532 | 538 |
afterFinishInternal: function(effect) { |
|
533 | 539 | if (effect.options.to!=0) return; |
|
534 | 540 |
effect.element.hide().setStyle({opacity: oldOpacity}); |
|
535 | 541 | } |
|
536 | 542 | }, arguments[1] || { }); |
|
537 | 543 | return new Effect.Opacity(element,options); |
|
538 | 544 | }; |
|
539 | 545 | |
|
540 | 546 | Effect.Appear = function(element) { |
|
541 | 547 | element = $(element); |
|
542 | 548 | var options = Object.extend({ |
|
543 | 549 | from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0), |
|
544 | 550 | to: 1.0, |
|
545 | 551 | // force Safari to render floated elements properly |
|
546 | 552 | afterFinishInternal: function(effect) { |
|
547 | 553 | effect.element.forceRerendering(); |
|
548 | 554 | }, |
|
549 | 555 | beforeSetup: function(effect) { |
|
550 | 556 |
effect.element.setOpacity(effect.options.from).show(); |
|
551 | 557 | }}, arguments[1] || { }); |
|
552 | 558 | return new Effect.Opacity(element,options); |
|
553 | 559 | }; |
|
554 | 560 | |
|
555 | 561 | Effect.Puff = function(element) { |
|
556 | 562 | element = $(element); |
|
557 | 563 |
var oldStyle = { |
|
558 | 564 |
opacity: element.getInlineOpacity(), |
|
559 | 565 | position: element.getStyle('position'), |
|
560 | 566 | top: element.style.top, |
|
561 | 567 | left: element.style.left, |
|
562 | 568 | width: element.style.width, |
|
563 | 569 | height: element.style.height |
|
564 | 570 | }; |
|
565 | 571 | return new Effect.Parallel( |
|
566 | 572 |
[ new Effect.Scale(element, 200, |
|
567 | 573 |
{ sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }), |
|
568 | 574 |
new Effect.Opacity(element, { sync: true, to: 0.0 } ) ], |
|
569 | 575 |
Object.extend({ duration: 1.0, |
|
570 | 576 | beforeSetupInternal: function(effect) { |
|
571 | - Position.absolutize(effect.effects[0].element) | |
|
577 | + Position.absolutize(effect.effects[0].element); | |
|
572 | 578 | }, |
|
573 | 579 | afterFinishInternal: function(effect) { |
|
574 | 580 | effect.effects[0].element.hide().setStyle(oldStyle); } |
|
575 | 581 | }, arguments[1] || { }) |
|
576 | 582 | ); |
|
577 | 583 | }; |
|
578 | 584 | |
|
579 | 585 | Effect.BlindUp = function(element) { |
|
580 | 586 | element = $(element); |
|
581 | 587 | element.makeClipping(); |
|
582 | 588 | return new Effect.Scale(element, 0, |
|
583 | 589 |
Object.extend({ scaleContent: false, |
|
584 | 590 |
scaleX: false, |
|
585 | 591 | restoreAfterFinish: true, |
|
586 | 592 | afterFinishInternal: function(effect) { |
|
587 | 593 | effect.element.hide().undoClipping(); |
|
588 | 594 |
} |
|
589 | 595 | }, arguments[1] || { }) |
|
590 | 596 | ); |
|
591 | 597 | }; |
|
592 | 598 | |
|
593 | 599 | Effect.BlindDown = function(element) { |
|
594 | 600 | element = $(element); |
|
595 | 601 | var elementDimensions = element.getDimensions(); |
|
596 | 602 |
return new Effect.Scale(element, 100, Object.extend({ |
|
597 | 603 |
scaleContent: false, |
|
598 | 604 | scaleX: false, |
|
599 | 605 | scaleFrom: 0, |
|
600 | 606 | scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width}, |
|
601 | 607 | restoreAfterFinish: true, |
|
602 | 608 | afterSetup: function(effect) { |
|
603 | 609 |
effect.element.makeClipping().setStyle({height: '0px'}).show(); |
|
604 | 610 |
}, |
|
605 | 611 | afterFinishInternal: function(effect) { |
|
606 | 612 | effect.element.undoClipping(); |
|
607 | 613 | } |
|
608 | 614 | }, arguments[1] || { })); |
|
609 | 615 | }; |
|
610 | 616 | |
|
611 | 617 | Effect.SwitchOff = function(element) { |
|
612 | 618 | element = $(element); |
|
613 | 619 | var oldOpacity = element.getInlineOpacity(); |
|
614 | 620 | return new Effect.Appear(element, Object.extend({ |
|
615 | 621 | duration: 0.4, |
|
616 | 622 | from: 0, |
|
617 | 623 | transition: Effect.Transitions.flicker, |
|
618 | 624 | afterFinishInternal: function(effect) { |
|
619 | 625 |
new Effect.Scale(effect.element, 1, { |
|
620 | 626 | duration: 0.3, scaleFromCenter: true, |
|
621 | 627 | scaleX: false, scaleContent: false, restoreAfterFinish: true, |
|
622 | 628 |
beforeSetup: function(effect) { |
|
623 | 629 | effect.element.makePositioned().makeClipping(); |
|
624 | 630 | }, |
|
625 | 631 | afterFinishInternal: function(effect) { |
|
626 | 632 | effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity}); |
|
627 | 633 | } |
|
628 | - }) | |
|
634 | + }); | |
|
629 | 635 | } |
|
630 | 636 | }, arguments[1] || { })); |
|
631 | 637 | }; |
|
632 | 638 | |
|
633 | 639 | Effect.DropOut = function(element) { |
|
634 | 640 | element = $(element); |
|
635 | 641 | var oldStyle = { |
|
636 | 642 | top: element.getStyle('top'), |
|
637 | 643 | left: element.getStyle('left'), |
|
638 | 644 | opacity: element.getInlineOpacity() }; |
|
639 | 645 | return new Effect.Parallel( |
|
640 | 646 |
[ new Effect.Move(element, {x: 0, y: 100, sync: true }), |
|
641 | 647 | new Effect.Opacity(element, { sync: true, to: 0.0 }) ], |
|
642 | 648 | Object.extend( |
|
643 | 649 | { duration: 0.5, |
|
644 | 650 | beforeSetup: function(effect) { |
|
645 | 651 |
effect.effects[0].element.makePositioned(); |
|
646 | 652 | }, |
|
647 | 653 | afterFinishInternal: function(effect) { |
|
648 | 654 | effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle); |
|
649 | 655 |
} |
|
650 | 656 | }, arguments[1] || { })); |
|
651 | 657 | }; |
|
652 | 658 | |
|
653 | 659 | Effect.Shake = function(element) { |
|
654 | 660 | element = $(element); |
|
655 | 661 | var options = Object.extend({ |
|
656 | 662 | distance: 20, |
|
657 | 663 | duration: 0.5 |
|
658 | 664 | }, arguments[1] || {}); |
|
659 | 665 | var distance = parseFloat(options.distance); |
|
660 | 666 | var split = parseFloat(options.duration) / 10.0; |
|
661 | 667 | var oldStyle = { |
|
662 | 668 | top: element.getStyle('top'), |
|
663 | 669 | left: element.getStyle('left') }; |
|
664 | 670 | return new Effect.Move(element, |
|
665 | 671 | { x: distance, y: 0, duration: split, afterFinishInternal: function(effect) { |
|
666 | 672 | new Effect.Move(effect.element, |
|
667 | 673 | { x: -distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) { |
|
668 | 674 | new Effect.Move(effect.element, |
|
669 | 675 | { x: distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) { |
|
670 | 676 | new Effect.Move(effect.element, |
|
671 | 677 | { x: -distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) { |
|
672 | 678 | new Effect.Move(effect.element, |
|
673 | 679 | { x: distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) { |
|
674 | 680 | new Effect.Move(effect.element, |
|
675 | 681 | { x: -distance, y: 0, duration: split, afterFinishInternal: function(effect) { |
|
676 | 682 | effect.element.undoPositioned().setStyle(oldStyle); |
|
677 | - }}) }}) }}) }}) }}) }}); | |
|
683 | + }}); }}); }}); }}); }}); }}); | |
|
678 | 684 | }; |
|
679 | 685 | |
|
680 | 686 | Effect.SlideDown = function(element) { |
|
681 | 687 | element = $(element).cleanWhitespace(); |
|
682 | 688 | // SlideDown need to have the content of the element wrapped in a container element with fixed height! |
|
683 | 689 | var oldInnerBottom = element.down().getStyle('bottom'); |
|
684 | 690 | var elementDimensions = element.getDimensions(); |
|
685 | 691 |
return new Effect.Scale(element, 100, Object.extend({ |
|
686 | 692 |
scaleContent: false, |
|
687 | 693 |
scaleX: false, |
|
688 | 694 | scaleFrom: window.opera ? 0 : 1, |
|
689 | 695 | scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width}, |
|
690 | 696 | restoreAfterFinish: true, |
|
691 | 697 | afterSetup: function(effect) { |
|
692 | 698 | effect.element.makePositioned(); |
|
693 | 699 | effect.element.down().makePositioned(); |
|
694 | 700 | if (window.opera) effect.element.setStyle({top: ''}); |
|
695 | 701 |
effect.element.makeClipping().setStyle({height: '0px'}).show(); |
|
696 | 702 | }, |
|
697 | 703 | afterUpdateInternal: function(effect) { |
|
698 | 704 | effect.element.down().setStyle({bottom: |
|
699 | 705 |
(effect.dims[0] - effect.element.clientHeight) + 'px' }); |
|
700 | 706 | }, |
|
701 | 707 | afterFinishInternal: function(effect) { |
|
702 | 708 | effect.element.undoClipping().undoPositioned(); |
|
703 | 709 | effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); } |
|
704 | 710 | }, arguments[1] || { }) |
|
705 | 711 | ); |
|
706 | 712 | }; |
|
707 | 713 | |
|
708 | 714 | Effect.SlideUp = function(element) { |
|
709 | 715 | element = $(element).cleanWhitespace(); |
|
710 | 716 | var oldInnerBottom = element.down().getStyle('bottom'); |
|
711 | 717 | var elementDimensions = element.getDimensions(); |
|
712 | 718 | return new Effect.Scale(element, window.opera ? 0 : 1, |
|
713 | 719 |
Object.extend({ scaleContent: false, |
|
714 | 720 |
scaleX: false, |
|
715 | 721 | scaleMode: 'box', |
|
716 | 722 | scaleFrom: 100, |
|
717 | 723 | scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width}, |
|
718 | 724 | restoreAfterFinish: true, |
|
719 | 725 | afterSetup: function(effect) { |
|
720 | 726 | effect.element.makePositioned(); |
|
721 | 727 | effect.element.down().makePositioned(); |
|
722 | 728 | if (window.opera) effect.element.setStyle({top: ''}); |
|
723 | 729 | effect.element.makeClipping().show(); |
|
724 | 730 |
}, |
|
725 | 731 | afterUpdateInternal: function(effect) { |
|
726 | 732 | effect.element.down().setStyle({bottom: |
|
727 | 733 | (effect.dims[0] - effect.element.clientHeight) + 'px' }); |
|
728 | 734 | }, |
|
729 | 735 | afterFinishInternal: function(effect) { |
|
730 | 736 | effect.element.hide().undoClipping().undoPositioned(); |
|
731 | 737 | effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); |
|
732 | 738 | } |
|
733 | 739 | }, arguments[1] || { }) |
|
734 | 740 | ); |
|
735 | 741 | }; |
|
736 | 742 | |
|
737 | 743 |
// Bug in opera makes the TD containing this element expand for a instance after finish |
|
738 | 744 | Effect.Squish = function(element) { |
|
739 | 745 |
return new Effect.Scale(element, window.opera ? 1 : 0, { |
|
740 | 746 | restoreAfterFinish: true, |
|
741 | 747 | beforeSetup: function(effect) { |
|
742 | 748 |
effect.element.makeClipping(); |
|
743 | 749 |
}, |
|
744 | 750 | afterFinishInternal: function(effect) { |
|
745 | 751 |
effect.element.hide().undoClipping(); |
|
746 | 752 | } |
|
747 | 753 | }); |
|
748 | 754 | }; |
|
749 | 755 | |
|
750 | 756 | Effect.Grow = function(element) { |
|
751 | 757 | element = $(element); |
|
752 | 758 | var options = Object.extend({ |
|
753 | 759 | direction: 'center', |
|
754 | 760 | moveTransition: Effect.Transitions.sinoidal, |
|
755 | 761 | scaleTransition: Effect.Transitions.sinoidal, |
|
756 | 762 | opacityTransition: Effect.Transitions.full |
|
757 | 763 | }, arguments[1] || { }); |
|
758 | 764 | var oldStyle = { |
|
759 | 765 | top: element.style.top, |
|
760 | 766 | left: element.style.left, |
|
761 | 767 | height: element.style.height, |
|
762 | 768 | width: element.style.width, |
|
763 | 769 | opacity: element.getInlineOpacity() }; |
|
764 | 770 | |
|
765 | 771 |
var dims = element.getDimensions(); |
|
766 | 772 | var initialMoveX, initialMoveY; |
|
767 | 773 | var moveX, moveY; |
|
768 | 774 | |
|
769 | 775 | switch (options.direction) { |
|
770 | 776 | case 'top-left': |
|
771 | 777 |
initialMoveX = initialMoveY = moveX = moveY = 0; |
|
772 | 778 | break; |
|
773 | 779 | case 'top-right': |
|
774 | 780 | initialMoveX = dims.width; |
|
775 | 781 | initialMoveY = moveY = 0; |
|
776 | 782 | moveX = -dims.width; |
|
777 | 783 | break; |
|
778 | 784 | case 'bottom-left': |
|
779 | 785 | initialMoveX = moveX = 0; |
|
780 | 786 | initialMoveY = dims.height; |
|
781 | 787 | moveY = -dims.height; |
|
782 | 788 | break; |
|
783 | 789 | case 'bottom-right': |
|
784 | 790 | initialMoveX = dims.width; |
|
785 | 791 | initialMoveY = dims.height; |
|
786 | 792 | moveX = -dims.width; |
|
787 | 793 | moveY = -dims.height; |
|
788 | 794 | break; |
|
789 | 795 | case 'center': |
|
790 | 796 | initialMoveX = dims.width / 2; |
|
791 | 797 | initialMoveY = dims.height / 2; |
|
792 | 798 | moveX = -dims.width / 2; |
|
793 | 799 | moveY = -dims.height / 2; |
|
794 | 800 | break; |
|
795 | 801 | } |
|
796 | 802 | |
|
797 | 803 | return new Effect.Move(element, { |
|
798 | 804 | x: initialMoveX, |
|
799 | 805 | y: initialMoveY, |
|
800 | 806 |
duration: 0.01, |
|
801 | 807 | beforeSetup: function(effect) { |
|
802 | 808 | effect.element.hide().makeClipping().makePositioned(); |
|
803 | 809 | }, |
|
804 | 810 | afterFinishInternal: function(effect) { |
|
805 | 811 | new Effect.Parallel( |
|
806 | 812 | [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }), |
|
807 | 813 | new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }), |
|
808 | 814 | new Effect.Scale(effect.element, 100, { |
|
809 | 815 |
scaleMode: { originalHeight: dims.height, originalWidth: dims.width }, |
|
810 | 816 | sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true}) |
|
811 | 817 | ], Object.extend({ |
|
812 | 818 | beforeSetup: function(effect) { |
|
813 | 819 |
effect.effects[0].element.setStyle({height: '0px'}).show(); |
|
814 | 820 | }, |
|
815 | 821 | afterFinishInternal: function(effect) { |
|
816 | 822 |
effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle); |
|
817 | 823 | } |
|
818 | 824 | }, options) |
|
819 | - ) | |
|
825 | + ); | |
|
820 | 826 | } |
|
821 | 827 | }); |
|
822 | 828 | }; |
|
823 | 829 | |
|
824 | 830 | Effect.Shrink = function(element) { |
|
825 | 831 | element = $(element); |
|
826 | 832 | var options = Object.extend({ |
|
827 | 833 | direction: 'center', |
|
828 | 834 | moveTransition: Effect.Transitions.sinoidal, |
|
829 | 835 | scaleTransition: Effect.Transitions.sinoidal, |
|
830 | 836 | opacityTransition: Effect.Transitions.none |
|
831 | 837 | }, arguments[1] || { }); |
|
832 | 838 | var oldStyle = { |
|
833 | 839 | top: element.style.top, |
|
834 | 840 | left: element.style.left, |
|
835 | 841 | height: element.style.height, |
|
836 | 842 | width: element.style.width, |
|
837 | 843 | opacity: element.getInlineOpacity() }; |
|
838 | 844 | |
|
839 | 845 | var dims = element.getDimensions(); |
|
840 | 846 | var moveX, moveY; |
|
841 | 847 | |
|
842 | 848 | switch (options.direction) { |
|
843 | 849 | case 'top-left': |
|
844 | 850 | moveX = moveY = 0; |
|
845 | 851 | break; |
|
846 | 852 | case 'top-right': |
|
847 | 853 | moveX = dims.width; |
|
848 | 854 | moveY = 0; |
|
849 | 855 | break; |
|
850 | 856 | case 'bottom-left': |
|
851 | 857 | moveX = 0; |
|
852 | 858 | moveY = dims.height; |
|
853 | 859 | break; |
|
854 | 860 | case 'bottom-right': |
|
855 | 861 | moveX = dims.width; |
|
856 | 862 | moveY = dims.height; |
|
857 | 863 | break; |
|
858 | 864 |
case 'center': |
|
859 | 865 | moveX = dims.width / 2; |
|
860 | 866 | moveY = dims.height / 2; |
|
861 | 867 | break; |
|
862 | 868 | } |
|
863 | 869 | |
|
864 | 870 | return new Effect.Parallel( |
|
865 | 871 | [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }), |
|
866 | 872 | new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}), |
|
867 | 873 | new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }) |
|
868 | 874 |
], Object.extend({ |
|
869 | 875 | beforeStartInternal: function(effect) { |
|
870 | 876 |
effect.effects[0].element.makePositioned().makeClipping(); |
|
871 | 877 | }, |
|
872 | 878 | afterFinishInternal: function(effect) { |
|
873 | 879 | effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); } |
|
874 | 880 | }, options) |
|
875 | 881 | ); |
|
876 | 882 | }; |
|
877 | 883 | |
|
878 | 884 | Effect.Pulsate = function(element) { |
|
879 | 885 | element = $(element); |
|
880 |
- var options = arguments[1] || { } |
|
|
881 |
- |
|
|
882 |
- |
|
|
883 | - var reverser = function(pos){ return transition(1-Effect.Transitions.pulse(pos, options.pulses)) }; | |
|
884 | - reverser.bind(transition); | |
|
886 | + var options = arguments[1] || { }, | |
|
887 | + oldOpacity = element.getInlineOpacity(), | |
|
888 | + transition = options.transition || Effect.Transitions.linear, | |
|
889 | + reverser = function(pos){ | |
|
890 | + return 1 - transition((-Math.cos((pos*(options.pulses||5)*2)*Math.PI)/2) + .5); | |
|
891 | + }; | |
|
892 | + | |
|
885 | 893 |
return new Effect.Opacity(element, |
|
886 | 894 | Object.extend(Object.extend({ duration: 2.0, from: 0, |
|
887 | 895 | afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); } |
|
888 | 896 | }, options), {transition: reverser})); |
|
889 | 897 | }; |
|
890 | 898 | |
|
891 | 899 | Effect.Fold = function(element) { |
|
892 | 900 | element = $(element); |
|
893 | 901 | var oldStyle = { |
|
894 | 902 | top: element.style.top, |
|
895 | 903 | left: element.style.left, |
|
896 | 904 | width: element.style.width, |
|
897 | 905 | height: element.style.height }; |
|
898 | 906 | element.makeClipping(); |
|
899 | 907 |
return new Effect.Scale(element, 5, Object.extend({ |
|
900 | 908 | scaleContent: false, |
|
901 | 909 | scaleX: false, |
|
902 | 910 | afterFinishInternal: function(effect) { |
|
903 | 911 |
new Effect.Scale(element, 1, { |
|
904 | 912 |
scaleContent: false, |
|
905 | 913 | scaleY: false, |
|
906 | 914 | afterFinishInternal: function(effect) { |
|
907 | 915 | effect.element.hide().undoClipping().setStyle(oldStyle); |
|
908 | 916 | } }); |
|
909 | 917 | }}, arguments[1] || { })); |
|
910 | 918 | }; |
|
911 | 919 | |
|
912 | 920 | Effect.Morph = Class.create(Effect.Base, { |
|
913 | 921 | initialize: function(element) { |
|
914 | 922 | this.element = $(element); |
|
915 | 923 | if (!this.element) throw(Effect._elementDoesNotExistError); |
|
916 | 924 | var options = Object.extend({ |
|
917 | 925 | style: { } |
|
918 | 926 | }, arguments[1] || { }); |
|
919 | 927 | |
|
920 | 928 | if (!Object.isString(options.style)) this.style = $H(options.style); |
|
921 | 929 | else { |
|
922 | 930 | if (options.style.include(':')) |
|
923 | 931 | this.style = options.style.parseStyle(); |
|
924 | 932 | else { |
|
925 | 933 | this.element.addClassName(options.style); |
|
926 | 934 | this.style = $H(this.element.getStyles()); |
|
927 | 935 | this.element.removeClassName(options.style); |
|
928 | 936 | var css = this.element.getStyles(); |
|
929 | 937 | this.style = this.style.reject(function(style) { |
|
930 | 938 | return style.value == css[style.key]; |
|
931 | 939 | }); |
|
932 | 940 | options.afterFinishInternal = function(effect) { |
|
933 | 941 | effect.element.addClassName(effect.options.style); |
|
934 | 942 | effect.transforms.each(function(transform) { |
|
935 | 943 | effect.element.style[transform.style] = ''; |
|
936 | 944 | }); |
|
937 | - } | |
|
945 | + }; | |
|
938 | 946 | } |
|
939 | 947 | } |
|
940 | 948 | this.start(options); |
|
941 | 949 | }, |
|
942 | 950 | |
|
943 | 951 | setup: function(){ |
|
944 | 952 | function parseColor(color){ |
|
945 | 953 | if (!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff'; |
|
946 | 954 | color = color.parseColor(); |
|
947 | 955 | return $R(0,2).map(function(i){ |
|
948 |
- return parseInt( color.slice(i*2+1,i*2+3), 16 ) |
|
|
956 | + return parseInt( color.slice(i*2+1,i*2+3), 16 ); | |
|
949 | 957 | }); |
|
950 | 958 | } |
|
951 | 959 | this.transforms = this.style.map(function(pair){ |
|
952 | 960 | var property = pair[0], value = pair[1], unit = null; |
|
953 | 961 | |
|
954 | 962 | if (value.parseColor('#zzzzzz') != '#zzzzzz') { |
|
955 | 963 | value = value.parseColor(); |
|
956 | 964 | unit = 'color'; |
|
957 | 965 | } else if (property == 'opacity') { |
|
958 | 966 | value = parseFloat(value); |
|
959 | 967 | if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout)) |
|
960 | 968 | this.element.setStyle({zoom: 1}); |
|
961 | 969 | } else if (Element.CSS_LENGTH.test(value)) { |
|
962 | 970 | var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/); |
|
963 | 971 | value = parseFloat(components[1]); |
|
964 | 972 | unit = (components.length == 3) ? components[2] : null; |
|
965 | 973 | } |
|
966 | 974 | |
|
967 | 975 | var originalValue = this.element.getStyle(property); |
|
968 | 976 |
return { |
|
969 | 977 |
style: property.camelize(), |
|
970 | 978 |
originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0), |
|
971 | 979 | targetValue: unit=='color' ? parseColor(value) : value, |
|
972 | 980 | unit: unit |
|
973 | 981 | }; |
|
974 | 982 | }.bind(this)).reject(function(transform){ |
|
975 | 983 | return ( |
|
976 | 984 | (transform.originalValue == transform.targetValue) || |
|
977 | 985 | ( |
|
978 | 986 | transform.unit != 'color' && |
|
979 | 987 | (isNaN(transform.originalValue) || isNaN(transform.targetValue)) |
|
980 | 988 | ) |
|
981 | - ) | |
|
989 | + ); | |
|
982 | 990 | }); |
|
983 | 991 | }, |
|
984 | 992 | update: function(position) { |
|
985 | 993 | var style = { }, transform, i = this.transforms.length; |
|
986 | 994 | while(i--) |
|
987 | 995 |
style[(transform = this.transforms[i]).style] = |
|
988 | 996 | transform.unit=='color' ? '#'+ |
|
989 | 997 | (Math.round(transform.originalValue[0]+ |
|
990 | 998 | (transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart() + |
|
991 | 999 | (Math.round(transform.originalValue[1]+ |
|
992 | 1000 | (transform.targetValue[1]-transform.originalValue[1])*position)).toColorPart() + |
|
993 | 1001 | (Math.round(transform.originalValue[2]+ |
|
994 | 1002 | (transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() : |
|
995 | 1003 | (transform.originalValue + |
|
996 | 1004 |
(transform.targetValue - transform.originalValue) * position).toFixed(3) + |
|
997 | 1005 | (transform.unit === null ? '' : transform.unit); |
|
998 | 1006 | this.element.setStyle(style, true); |
|
999 | 1007 | } |
|
1000 | 1008 | }); |
|
1001 | 1009 | |
|
1002 | 1010 | Effect.Transform = Class.create({ |
|
1003 | 1011 | initialize: function(tracks){ |
|
1004 | 1012 | this.tracks = []; |
|
1005 | 1013 | this.options = arguments[1] || { }; |
|
1006 | 1014 | this.addTracks(tracks); |
|
1007 | 1015 | }, |
|
1008 | 1016 | addTracks: function(tracks){ |
|
1009 | 1017 | tracks.each(function(track){ |
|
1010 | 1018 | track = $H(track); |
|
1011 | 1019 | var data = track.values().first(); |
|
1012 | 1020 | this.tracks.push($H({ |
|
1013 | 1021 | ids: track.keys().first(), |
|
1014 | 1022 | effect: Effect.Morph, |
|
1015 | 1023 | options: { style: data } |
|
1016 | 1024 | })); |
|
1017 | 1025 | }.bind(this)); |
|
1018 | 1026 | return this; |
|
1019 | 1027 | }, |
|
1020 | 1028 | play: function(){ |
|
1021 | 1029 | return new Effect.Parallel( |
|
1022 | 1030 | this.tracks.map(function(track){ |
|
1023 | 1031 | var ids = track.get('ids'), effect = track.get('effect'), options = track.get('options'); |
|
1024 | 1032 | var elements = [$(ids) || $$(ids)].flatten(); |
|
1025 | 1033 | return elements.map(function(e){ return new effect(e, Object.extend({ sync:true }, options)) }); |
|
1026 | 1034 | }).flatten(), |
|
1027 | 1035 | this.options |
|
1028 | 1036 | ); |
|
1029 | 1037 | } |
|
1030 | 1038 | }); |
|
1031 | 1039 | |
|
1032 | 1040 | Element.CSS_PROPERTIES = $w( |
|
1033 | 1041 |
'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' + |
|
1034 | 1042 | 'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' + |
|
1035 | 1043 | 'borderRightColor borderRightStyle borderRightWidth borderSpacing ' + |
|
1036 | 1044 | 'borderTopColor borderTopStyle borderTopWidth bottom clip color ' + |
|
1037 | 1045 | 'fontSize fontWeight height left letterSpacing lineHeight ' + |
|
1038 | 1046 | 'marginBottom marginLeft marginRight marginTop markerOffset maxHeight '+ |
|
1039 | 1047 | 'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' + |
|
1040 | 1048 | 'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' + |
|
1041 | 1049 | 'right textIndent top width wordSpacing zIndex'); |
|
1042 | 1050 | |
|
1043 | 1051 | Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/; |
|
1044 | 1052 | |
|
1045 | 1053 | String.__parseStyleElement = document.createElement('div'); |
|
1046 | 1054 | String.prototype.parseStyle = function(){ |
|
1047 | 1055 | var style, styleRules = $H(); |
|
1048 | 1056 | if (Prototype.Browser.WebKit) |
|
1049 | 1057 | style = new Element('div',{style:this}).style; |
|
1050 | 1058 | else { |
|
1051 | 1059 | String.__parseStyleElement.innerHTML = '<div style="' + this + '"></div>'; |
|
1052 | 1060 | style = String.__parseStyleElement.childNodes[0].style; |
|
1053 | 1061 | } |
|
1054 | 1062 | |
|
1055 | 1063 | Element.CSS_PROPERTIES.each(function(property){ |
|
1056 | 1064 |
if (style[property]) styleRules.set(property, style[property]); |
|
1057 | 1065 | }); |
|
1058 | 1066 | |
|
1059 | 1067 | if (Prototype.Browser.IE && this.include('opacity')) |
|
1060 | 1068 | styleRules.set('opacity', this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1]); |
|
1061 | 1069 | |
|
1062 | 1070 | return styleRules; |
|
1063 | 1071 | }; |
|
1064 | 1072 | |
|
1065 | 1073 | if (document.defaultView && document.defaultView.getComputedStyle) { |
|
1066 | 1074 | Element.getStyles = function(element) { |
|
1067 | 1075 | var css = document.defaultView.getComputedStyle($(element), null); |
|
1068 | 1076 | return Element.CSS_PROPERTIES.inject({ }, function(styles, property) { |
|
1069 | 1077 | styles[property] = css[property]; |
|
1070 | 1078 | return styles; |
|
1071 | 1079 | }); |
|
1072 | 1080 | }; |
|
1073 | 1081 | } else { |
|
1074 | 1082 | Element.getStyles = function(element) { |
|
1075 | 1083 | element = $(element); |
|
1076 | 1084 | var css = element.currentStyle, styles; |
|
1077 |
- styles = Element.CSS_PROPERTIES.inject({ }, function( |
|
|
1078 |
- |
|
|
1079 |
- return |
|
|
1085 | + styles = Element.CSS_PROPERTIES.inject({ }, function(results, property) { | |
|
1086 | + results[property] = css[property]; | |
|
1087 | + return results; | |
|
1080 | 1088 | }); |
|
1081 |
- if (!styles.opacity) styles. |
|
|
1089 | + if (!styles.opacity) styles.opacity = element.getOpacity(); | |
|
1082 | 1090 | return styles; |
|
1083 | 1091 | }; |
|
1084 |
- } |
|
|
1092 | + } | |
|
1085 | 1093 | |
|
1086 | 1094 | Effect.Methods = { |
|
1087 | 1095 | morph: function(element, style) { |
|
1088 | 1096 | element = $(element); |
|
1089 | 1097 | new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || { })); |
|
1090 | 1098 | return element; |
|
1091 | 1099 | }, |
|
1092 | 1100 | visualEffect: function(element, effect, options) { |
|
1093 | - element = $(element) | |
|
1101 | + element = $(element); | |
|
1094 | 1102 | var s = effect.dasherize().camelize(), klass = s.charAt(0).toUpperCase() + s.substring(1); |
|
1095 | 1103 | new Effect[klass](element, options); |
|
1096 | 1104 | return element; |
|
1097 | 1105 | }, |
|
1098 | 1106 | highlight: function(element, options) { |
|
1099 | 1107 | element = $(element); |
|
1100 | 1108 | new Effect.Highlight(element, options); |
|
1101 | 1109 | return element; |
|
1102 | 1110 | } |
|
1103 | 1111 | }; |
|
1104 | 1112 | |
|
1105 | 1113 | $w('fade appear grow shrink fold blindUp blindDown slideUp slideDown '+ |
|
1106 | 1114 | 'pulsate shake puff squish switchOff dropOut').each( |
|
1107 | 1115 |
function(effect) { |
|
1108 | 1116 | Effect.Methods[effect] = function(element, options){ |
|
1109 | 1117 | element = $(element); |
|
1110 | 1118 | Effect[effect.charAt(0).toUpperCase() + effect.substring(1)](element, options); |
|
1111 | 1119 | return element; |
|
1112 | - } | |
|
1120 | + }; | |
|
1113 | 1121 | } |
|
1114 | 1122 | ); |
|
1115 | 1123 | |
|
1116 | 1124 |
$w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each( |
|
1117 | 1125 | function(f) { Effect.Methods[f] = Element[f]; } |
|
1118 | 1126 | ); |
|
1119 | 1127 | |
|
1120 |
- Element.addMethods(Effect.Methods); |
|
|
1128 | + Element.addMethods(Effect.Methods); No newline at end of file |
modified file |
You need to be logged in to leave comments.
Login now