The requested changes are too big and content was truncated. Show full diff
@@ -28,11 +28,11 ContextMenu.prototype = { | |||||
28 | RightClick: function(e) { |
|
28 | RightClick: function(e) { | |
29 | this.hideMenu(); |
|
29 | this.hideMenu(); | |
30 | // do not show the context menu on links |
|
30 | // do not show the context menu on links | |
31 | if (Event.findElement(e, 'a') != document) { return; } |
|
31 | if (Event.findElement(e, 'a') != document && Event.findElement(e, 'a') != undefined) { return; } | |
32 | // right-click simulated by Alt+Click with Opera |
|
32 | // right-click simulated by Alt+Click with Opera | |
33 | if (window.opera && !e.altKey) { return; } |
|
33 | if (window.opera && !e.altKey) { return; } | |
34 | var tr = Event.findElement(e, 'tr'); |
|
34 | var tr = Event.findElement(e, 'tr'); | |
35 |
if |
|
35 | if (tr == document || tr == undefined || !tr.hasClassName('hascontextmenu')) { return; } | |
36 | Event.stop(e); |
|
36 | Event.stop(e); | |
37 | if (!this.isSelected(tr)) { |
|
37 | if (!this.isSelected(tr)) { | |
38 | this.unselectAll(); |
|
38 | this.unselectAll(); | |
@@ -44,14 +44,14 ContextMenu.prototype = { | |||||
44 |
|
44 | |||
45 | Click: function(e) { |
|
45 | Click: function(e) { | |
46 | this.hideMenu(); |
|
46 | this.hideMenu(); | |
47 | if (Event.findElement(e, 'a') != document) { return; } |
|
47 | if (Event.findElement(e, 'a') != document && Event.findElement(e, 'a') != undefined ) { return; } | |
48 | if (window.opera && e.altKey) { return; } |
|
48 | if (window.opera && e.altKey) { return; } | |
49 | if (Event.isLeftClick(e) || (navigator.appVersion.match(/\bMSIE\b/))) { |
|
49 | if (Event.isLeftClick(e) || (navigator.appVersion.match(/\bMSIE\b/))) { | |
50 | var tr = Event.findElement(e, 'tr'); |
|
50 | var tr = Event.findElement(e, 'tr'); | |
51 | if (tr!=document && tr.hasClassName('hascontextmenu')) { |
|
51 | if (tr!=document && tr.hasClassName('hascontextmenu')) { | |
52 | // a row was clicked, check if the click was on checkbox |
|
52 | // a row was clicked, check if the click was on checkbox | |
53 | var box = Event.findElement(e, 'input'); |
|
53 | var box = Event.findElement(e, 'input'); | |
54 | if (box!=document) { |
|
54 | if (box!=document && box!=undefined) { | |
55 | // a checkbox may be clicked |
|
55 | // a checkbox may be clicked | |
56 | if (box.checked) { |
|
56 | if (box.checked) { | |
57 | tr.addClassName('context-menu-selection'); |
|
57 | tr.addClassName('context-menu-selection'); |
This diff has been collapsed as it changes many lines, (838 lines changed) Show them Hide them | |||||
@@ -1,6 +1,6 | |||||
1 |
// Copyright (c) 2005 |
|
1 | // Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) | |
2 |
// (c) 2005 |
|
2 | // (c) 2005-2007 Ivan Krstic (http://blogs.law.harvard.edu/ivan) | |
3 |
// (c) 2005 |
|
3 | // (c) 2005-2007 Jon Tirsen (http://www.tirsen.com) | |
4 | // Contributors: |
|
4 | // Contributors: | |
5 | // Richard Livsey |
|
5 | // Richard Livsey | |
6 | // Rahul Bhargava |
|
6 | // Rahul Bhargava | |
@@ -37,22 +37,23 | |||||
37 | if(typeof Effect == 'undefined') |
|
37 | if(typeof Effect == 'undefined') | |
38 | throw("controls.js requires including script.aculo.us' effects.js library"); |
|
38 | throw("controls.js requires including script.aculo.us' effects.js library"); | |
39 |
|
39 | |||
40 | var Autocompleter = {} |
|
40 | var Autocompleter = { } | |
41 |
Autocompleter.Base = |
|
41 | Autocompleter.Base = Class.create({ | |
42 | Autocompleter.Base.prototype = { |
|
|||
43 | baseInitialize: function(element, update, options) { |
|
42 | baseInitialize: function(element, update, options) { | |
44 |
|
|
43 | element = $(element) | |
|
44 | this.element = element; | |||
45 | this.update = $(update); |
|
45 | this.update = $(update); | |
46 | this.hasFocus = false; |
|
46 | this.hasFocus = false; | |
47 | this.changed = false; |
|
47 | this.changed = false; | |
48 | this.active = false; |
|
48 | this.active = false; | |
49 | this.index = 0; |
|
49 | this.index = 0; | |
50 | this.entryCount = 0; |
|
50 | this.entryCount = 0; | |
|
51 | this.oldElementValue = this.element.value; | |||
51 |
|
52 | |||
52 | if(this.setOptions) |
|
53 | if(this.setOptions) | |
53 | this.setOptions(options); |
|
54 | this.setOptions(options); | |
54 | else |
|
55 | else | |
55 | this.options = options || {}; |
|
56 | this.options = options || { }; | |
56 |
|
57 | |||
57 | this.options.paramName = this.options.paramName || this.element.name; |
|
58 | this.options.paramName = this.options.paramName || this.element.name; | |
58 | this.options.tokens = this.options.tokens || []; |
|
59 | this.options.tokens = this.options.tokens || []; | |
@@ -74,6 +75,9 Autocompleter.Base.prototype = { | |||||
74 |
|
75 | |||
75 | if(typeof(this.options.tokens) == 'string') |
|
76 | if(typeof(this.options.tokens) == 'string') | |
76 | this.options.tokens = new Array(this.options.tokens); |
|
77 | this.options.tokens = new Array(this.options.tokens); | |
|
78 | // Force carriage returns as token delimiters anyway | |||
|
79 | if (!this.options.tokens.include('\n')) | |||
|
80 | this.options.tokens.push('\n'); | |||
77 |
|
81 | |||
78 | this.observer = null; |
|
82 | this.observer = null; | |
79 |
|
83 | |||
@@ -81,15 +85,14 Autocompleter.Base.prototype = { | |||||
81 |
|
85 | |||
82 | Element.hide(this.update); |
|
86 | Element.hide(this.update); | |
83 |
|
87 | |||
84 |
Event.observe(this.element, |
|
88 | Event.observe(this.element, 'blur', this.onBlur.bindAsEventListener(this)); | |
85 |
Event.observe(this.element, |
|
89 | Event.observe(this.element, 'keydown', this.onKeyPress.bindAsEventListener(this)); | |
86 | }, |
|
90 | }, | |
87 |
|
91 | |||
88 | show: function() { |
|
92 | show: function() { | |
89 | if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update); |
|
93 | if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update); | |
90 | if(!this.iefix && |
|
94 | if(!this.iefix && | |
91 | (navigator.appVersion.indexOf('MSIE')>0) && |
|
95 | (Prototype.Browser.IE) && | |
92 | (navigator.userAgent.indexOf('Opera')<0) && |
|
|||
93 | (Element.getStyle(this.update, 'position')=='absolute')) { |
|
96 | (Element.getStyle(this.update, 'position')=='absolute')) { | |
94 | new Insertion.After(this.update, |
|
97 | new Insertion.After(this.update, | |
95 | '<iframe id="' + this.update.id + '_iefix" '+ |
|
98 | '<iframe id="' + this.update.id + '_iefix" '+ | |
@@ -139,17 +142,17 Autocompleter.Base.prototype = { | |||||
139 | case Event.KEY_UP: |
|
142 | case Event.KEY_UP: | |
140 | this.markPrevious(); |
|
143 | this.markPrevious(); | |
141 | this.render(); |
|
144 | this.render(); | |
142 | if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event); |
|
145 | Event.stop(event); | |
143 | return; |
|
146 | return; | |
144 | case Event.KEY_DOWN: |
|
147 | case Event.KEY_DOWN: | |
145 | this.markNext(); |
|
148 | this.markNext(); | |
146 | this.render(); |
|
149 | this.render(); | |
147 | if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event); |
|
150 | Event.stop(event); | |
148 | return; |
|
151 | return; | |
149 | } |
|
152 | } | |
150 | else |
|
153 | else | |
151 | if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN || |
|
154 | if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN || | |
152 |
( |
|
155 | (Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return; | |
153 |
|
156 | |||
154 | this.changed = true; |
|
157 | this.changed = true; | |
155 | this.hasFocus = true; |
|
158 | this.hasFocus = true; | |
@@ -195,7 +198,6 Autocompleter.Base.prototype = { | |||||
195 | this.index==i ? |
|
198 | this.index==i ? | |
196 | Element.addClassName(this.getEntry(i),"selected") : |
|
199 | Element.addClassName(this.getEntry(i),"selected") : | |
197 | Element.removeClassName(this.getEntry(i),"selected"); |
|
200 | Element.removeClassName(this.getEntry(i),"selected"); | |
198 |
|
||||
199 | if(this.hasFocus) { |
|
201 | if(this.hasFocus) { | |
200 | this.show(); |
|
202 | this.show(); | |
201 | this.active = true; |
|
203 | this.active = true; | |
@@ -238,21 +240,22 Autocompleter.Base.prototype = { | |||||
238 | } |
|
240 | } | |
239 | var value = ''; |
|
241 | var value = ''; | |
240 | if (this.options.select) { |
|
242 | if (this.options.select) { | |
241 |
var nodes = |
|
243 | var nodes = $(selectedElement).select('.' + this.options.select) || []; | |
242 | if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select); |
|
244 | if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select); | |
243 | } else |
|
245 | } else | |
244 | value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal'); |
|
246 | value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal'); | |
245 |
|
247 | |||
246 |
var |
|
248 | var bounds = this.getTokenBounds(); | |
247 |
if ( |
|
249 | if (bounds[0] != -1) { | |
248 |
var newValue = this.element.value.substr(0, |
|
250 | var newValue = this.element.value.substr(0, bounds[0]); | |
249 |
var whitespace = this.element.value.substr( |
|
251 | var whitespace = this.element.value.substr(bounds[0]).match(/^\s+/); | |
250 | if (whitespace) |
|
252 | if (whitespace) | |
251 | newValue += whitespace[0]; |
|
253 | newValue += whitespace[0]; | |
252 | this.element.value = newValue + value; |
|
254 | this.element.value = newValue + value + this.element.value.substr(bounds[1]); | |
253 | } else { |
|
255 | } else { | |
254 | this.element.value = value; |
|
256 | this.element.value = value; | |
255 | } |
|
257 | } | |
|
258 | this.oldElementValue = this.element.value; | |||
256 | this.element.focus(); |
|
259 | this.element.focus(); | |
257 |
|
260 | |||
258 | if (this.options.afterUpdateElement) |
|
261 | if (this.options.afterUpdateElement) | |
@@ -296,39 +299,48 Autocompleter.Base.prototype = { | |||||
296 |
|
299 | |||
297 | onObserverEvent: function() { |
|
300 | onObserverEvent: function() { | |
298 | this.changed = false; |
|
301 | this.changed = false; | |
|
302 | this.tokenBounds = null; | |||
299 | if(this.getToken().length>=this.options.minChars) { |
|
303 | if(this.getToken().length>=this.options.minChars) { | |
300 | this.startIndicator(); |
|
|||
301 | this.getUpdatedChoices(); |
|
304 | this.getUpdatedChoices(); | |
302 | } else { |
|
305 | } else { | |
303 | this.active = false; |
|
306 | this.active = false; | |
304 | this.hide(); |
|
307 | this.hide(); | |
305 | } |
|
308 | } | |
|
309 | this.oldElementValue = this.element.value; | |||
306 | }, |
|
310 | }, | |
307 |
|
311 | |||
308 | getToken: function() { |
|
312 | getToken: function() { | |
309 |
var |
|
313 | var bounds = this.getTokenBounds(); | |
310 | if (tokenPos != -1) |
|
314 | return this.element.value.substring(bounds[0], bounds[1]).strip(); | |
311 | var ret = this.element.value.substr(tokenPos + 1).replace(/^\s+/,'').replace(/\s+$/,''); |
|
315 | }, | |
312 | else |
|
316 | ||
313 | var ret = this.element.value; |
|
317 | getTokenBounds: function() { | |
314 |
|
318 | if (null != this.tokenBounds) return this.tokenBounds; | ||
315 | return /\n/.test(ret) ? '' : ret; |
|
319 | var value = this.element.value; | |
316 | }, |
|
320 | if (value.strip().empty()) return [-1, 0]; | |
317 |
|
321 | var diff = arguments.callee.getFirstDifferencePos(value, this.oldElementValue); | ||
318 | findLastToken: function() { |
|
322 | var offset = (diff == this.oldElementValue.length ? 1 : 0); | |
319 | var lastTokenPos = -1; |
|
323 | var prevTokenPos = -1, nextTokenPos = value.length; | |
320 |
|
324 | var tp; | ||
321 |
for (var i=0 |
|
325 | for (var index = 0, l = this.options.tokens.length; index < l; ++index) { | |
322 |
|
|
326 | tp = value.lastIndexOf(this.options.tokens[index], diff + offset - 1); | |
323 | if (thisTokenPos > lastTokenPos) |
|
327 | if (tp > prevTokenPos) prevTokenPos = tp; | |
324 | lastTokenPos = thisTokenPos; |
|
328 | tp = value.indexOf(this.options.tokens[index], diff + offset); | |
|
329 | if (-1 != tp && tp < nextTokenPos) nextTokenPos = tp; | |||
325 | } |
|
330 | } | |
326 | return lastTokenPos; |
|
331 | return (this.tokenBounds = [prevTokenPos + 1, nextTokenPos]); | |
327 | } |
|
332 | } | |
328 | } |
|
333 | }); | |
|
334 | ||||
|
335 | Autocompleter.Base.prototype.getTokenBounds.getFirstDifferencePos = function(newS, oldS) { | |||
|
336 | var boundary = Math.min(newS.length, oldS.length); | |||
|
337 | for (var index = 0; index < boundary; ++index) | |||
|
338 | if (newS[index] != oldS[index]) | |||
|
339 | return index; | |||
|
340 | return boundary; | |||
|
341 | }; | |||
329 |
|
342 | |||
330 |
Ajax.Autocompleter = Class.create( |
|
343 | Ajax.Autocompleter = Class.create(Autocompleter.Base, { | |
331 | Object.extend(Object.extend(Ajax.Autocompleter.prototype, Autocompleter.Base.prototype), { |
|
|||
332 | initialize: function(element, update, url, options) { |
|
344 | initialize: function(element, update, url, options) { | |
333 | this.baseInitialize(element, update, options); |
|
345 | this.baseInitialize(element, update, options); | |
334 | this.options.asynchronous = true; |
|
346 | this.options.asynchronous = true; | |
@@ -338,7 +350,9 Object.extend(Object.extend(Ajax.Autocompleter.prototype, Autocompleter.Base.pro | |||||
338 | }, |
|
350 | }, | |
339 |
|
351 | |||
340 | getUpdatedChoices: function() { |
|
352 | getUpdatedChoices: function() { | |
341 | entry = encodeURIComponent(this.options.paramName) + '=' + |
|
353 | this.startIndicator(); | |
|
354 | ||||
|
355 | var entry = encodeURIComponent(this.options.paramName) + '=' + | |||
342 | encodeURIComponent(this.getToken()); |
|
356 | encodeURIComponent(this.getToken()); | |
343 |
|
357 | |||
344 | this.options.parameters = this.options.callback ? |
|
358 | this.options.parameters = this.options.callback ? | |
@@ -346,14 +360,13 Object.extend(Object.extend(Ajax.Autocompleter.prototype, Autocompleter.Base.pro | |||||
346 |
|
360 | |||
347 | if(this.options.defaultParams) |
|
361 | if(this.options.defaultParams) | |
348 | this.options.parameters += '&' + this.options.defaultParams; |
|
362 | this.options.parameters += '&' + this.options.defaultParams; | |
349 |
|
363 | |||
350 | new Ajax.Request(this.url, this.options); |
|
364 | new Ajax.Request(this.url, this.options); | |
351 | }, |
|
365 | }, | |
352 |
|
366 | |||
353 | onComplete: function(request) { |
|
367 | onComplete: function(request) { | |
354 | this.updateChoices(request.responseText); |
|
368 | this.updateChoices(request.responseText); | |
355 | } |
|
369 | } | |
356 |
|
||||
357 | }); |
|
370 | }); | |
358 |
|
371 | |||
359 | // The local array autocompleter. Used when you'd prefer to |
|
372 | // The local array autocompleter. Used when you'd prefer to | |
@@ -391,8 +404,7 Object.extend(Object.extend(Ajax.Autocompleter.prototype, Autocompleter.Base.pro | |||||
391 | // In that case, the other options above will not apply unless |
|
404 | // In that case, the other options above will not apply unless | |
392 | // you support them. |
|
405 | // you support them. | |
393 |
|
406 | |||
394 |
Autocompleter.Local = Class.create( |
|
407 | Autocompleter.Local = Class.create(Autocompleter.Base, { | |
395 | Autocompleter.Local.prototype = Object.extend(new Autocompleter.Base(), { |
|
|||
396 | initialize: function(element, update, array, options) { |
|
408 | initialize: function(element, update, array, options) { | |
397 | this.baseInitialize(element, update, options); |
|
409 | this.baseInitialize(element, update, options); | |
398 | this.options.array = array; |
|
410 | this.options.array = array; | |
@@ -448,13 +460,12 Autocompleter.Local.prototype = Object.extend(new Autocompleter.Base(), { | |||||
448 | ret = ret.concat(partial.slice(0, instance.options.choices - ret.length)) |
|
460 | ret = ret.concat(partial.slice(0, instance.options.choices - ret.length)) | |
449 | return "<ul>" + ret.join('') + "</ul>"; |
|
461 | return "<ul>" + ret.join('') + "</ul>"; | |
450 | } |
|
462 | } | |
451 | }, options || {}); |
|
463 | }, options || { }); | |
452 | } |
|
464 | } | |
453 | }); |
|
465 | }); | |
454 |
|
466 | |||
455 | // AJAX in-place editor |
|
467 | // AJAX in-place editor and collection editor | |
456 | // |
|
468 | // Full rewrite by Christophe Porteneuve <tdd@tddsworld.com> (April 2007). | |
457 | // see documentation on http://wiki.script.aculo.us/scriptaculous/show/Ajax.InPlaceEditor |
|
|||
458 |
|
469 | |||
459 | // Use this if you notice weird scrolling problems on some browsers, |
|
470 | // Use this if you notice weird scrolling problems on some browsers, | |
460 | // the DOM might be a bit confused when this gets called so do this |
|
471 | // the DOM might be a bit confused when this gets called so do this | |
@@ -465,353 +476,472 Field.scrollFreeActivate = function(field) { | |||||
465 | }, 1); |
|
476 | }, 1); | |
466 | } |
|
477 | } | |
467 |
|
478 | |||
468 |
Ajax.InPlaceEditor = Class.create( |
|
479 | Ajax.InPlaceEditor = Class.create({ | |
469 | Ajax.InPlaceEditor.defaultHighlightColor = "#FFFF99"; |
|
|||
470 | Ajax.InPlaceEditor.prototype = { |
|
|||
471 | initialize: function(element, url, options) { |
|
480 | initialize: function(element, url, options) { | |
472 | this.url = url; |
|
481 | this.url = url; | |
473 | this.element = $(element); |
|
482 | this.element = element = $(element); | |
474 |
|
483 | this.prepareOptions(); | ||
475 | this.options = Object.extend({ |
|
484 | this._controls = { }; | |
476 | paramName: "value", |
|
485 | arguments.callee.dealWithDeprecatedOptions(options); // DEPRECATION LAYER!!! | |
477 | okButton: true, |
|
486 | Object.extend(this.options, options || { }); | |
478 | okText: "ok", |
|
487 | if (!this.options.formId && this.element.id) { | |
479 | cancelLink: true, |
|
488 | this.options.formId = this.element.id + '-inplaceeditor'; | |
480 | cancelText: "cancel", |
|
489 | if ($(this.options.formId)) | |
481 | savingText: "Saving...", |
|
490 | this.options.formId = ''; | |
482 | clickToEditText: "Click to edit", |
|
|||
483 | okText: "ok", |
|
|||
484 | rows: 1, |
|
|||
485 | onComplete: function(transport, element) { |
|
|||
486 | new Effect.Highlight(element, {startcolor: this.options.highlightcolor}); |
|
|||
487 | }, |
|
|||
488 | onFailure: function(transport) { |
|
|||
489 | alert("Error communicating with the server: " + transport.responseText.stripTags()); |
|
|||
490 | }, |
|
|||
491 | callback: function(form) { |
|
|||
492 | return Form.serialize(form); |
|
|||
493 | }, |
|
|||
494 | handleLineBreaks: true, |
|
|||
495 | loadingText: 'Loading...', |
|
|||
496 | savingClassName: 'inplaceeditor-saving', |
|
|||
497 | loadingClassName: 'inplaceeditor-loading', |
|
|||
498 | formClassName: 'inplaceeditor-form', |
|
|||
499 | highlightcolor: Ajax.InPlaceEditor.defaultHighlightColor, |
|
|||
500 | highlightendcolor: "#FFFFFF", |
|
|||
501 | externalControl: null, |
|
|||
502 | submitOnBlur: false, |
|
|||
503 | ajaxOptions: {}, |
|
|||
504 | evalScripts: false |
|
|||
505 | }, options || {}); |
|
|||
506 |
|
||||
507 | if(!this.options.formId && this.element.id) { |
|
|||
508 | this.options.formId = this.element.id + "-inplaceeditor"; |
|
|||
509 | if ($(this.options.formId)) { |
|
|||
510 | // there's already a form with that name, don't specify an id |
|
|||
511 | this.options.formId = null; |
|
|||
512 | } |
|
|||
513 | } |
|
491 | } | |
514 |
|
492 | if (this.options.externalControl) | ||
515 | if (this.options.externalControl) { |
|
|||
516 | this.options.externalControl = $(this.options.externalControl); |
|
493 | this.options.externalControl = $(this.options.externalControl); | |
517 | } |
|
494 | if (!this.options.externalControl) | |
518 |
|
495 | this.options.externalControlOnly = false; | ||
519 |
this.originalBackground = |
|
496 | this._originalBackground = this.element.getStyle('background-color') || 'transparent'; | |
520 | if (!this.originalBackground) { |
|
|||
521 | this.originalBackground = "transparent"; |
|
|||
522 | } |
|
|||
523 |
|
||||
524 | this.element.title = this.options.clickToEditText; |
|
497 | this.element.title = this.options.clickToEditText; | |
525 |
|
498 | this._boundCancelHandler = this.handleFormCancellation.bind(this); | ||
526 | this.onclickListener = this.enterEditMode.bindAsEventListener(this); |
|
499 | this._boundComplete = (this.options.onComplete || Prototype.emptyFunction).bind(this); | |
527 | this.mouseoverListener = this.enterHover.bindAsEventListener(this); |
|
500 | this._boundFailureHandler = this.handleAJAXFailure.bind(this); | |
528 | this.mouseoutListener = this.leaveHover.bindAsEventListener(this); |
|
501 | this._boundSubmitHandler = this.handleFormSubmission.bind(this); | |
529 | Event.observe(this.element, 'click', this.onclickListener); |
|
502 | this._boundWrapperHandler = this.wrapUp.bind(this); | |
530 | Event.observe(this.element, 'mouseover', this.mouseoverListener); |
|
503 | this.registerListeners(); | |
531 | Event.observe(this.element, 'mouseout', this.mouseoutListener); |
|
504 | }, | |
532 | if (this.options.externalControl) { |
|
505 | checkForEscapeOrReturn: function(e) { | |
533 | Event.observe(this.options.externalControl, 'click', this.onclickListener); |
|
506 | if (!this._editing || e.ctrlKey || e.altKey || e.shiftKey) return; | |
534 | Event.observe(this.options.externalControl, 'mouseover', this.mouseoverListener); |
|
507 | if (Event.KEY_ESC == e.keyCode) | |
535 | Event.observe(this.options.externalControl, 'mouseout', this.mouseoutListener); |
|
508 | this.handleFormCancellation(e); | |
|
509 | else if (Event.KEY_RETURN == e.keyCode) | |||
|
510 | this.handleFormSubmission(e); | |||
|
511 | }, | |||
|
512 | createControl: function(mode, handler, extraClasses) { | |||
|
513 | var control = this.options[mode + 'Control']; | |||
|
514 | var text = this.options[mode + 'Text']; | |||
|
515 | if ('button' == control) { | |||
|
516 | var btn = document.createElement('input'); | |||
|
517 | btn.type = 'submit'; | |||
|
518 | btn.value = text; | |||
|
519 | btn.className = 'editor_' + mode + '_button'; | |||
|
520 | if ('cancel' == mode) | |||
|
521 | btn.onclick = this._boundCancelHandler; | |||
|
522 | this._form.appendChild(btn); | |||
|
523 | this._controls[mode] = btn; | |||
|
524 | } else if ('link' == control) { | |||
|
525 | var link = document.createElement('a'); | |||
|
526 | link.href = '#'; | |||
|
527 | link.appendChild(document.createTextNode(text)); | |||
|
528 | link.onclick = 'cancel' == mode ? this._boundCancelHandler : this._boundSubmitHandler; | |||
|
529 | link.className = 'editor_' + mode + '_link'; | |||
|
530 | if (extraClasses) | |||
|
531 | link.className += ' ' + extraClasses; | |||
|
532 | this._form.appendChild(link); | |||
|
533 | this._controls[mode] = link; | |||
536 | } |
|
534 | } | |
537 | }, |
|
535 | }, | |
538 | enterEditMode: function(evt) { |
|
|||
539 | if (this.saving) return; |
|
|||
540 | if (this.editing) return; |
|
|||
541 | this.editing = true; |
|
|||
542 | this.onEnterEditMode(); |
|
|||
543 | if (this.options.externalControl) { |
|
|||
544 | Element.hide(this.options.externalControl); |
|
|||
545 | } |
|
|||
546 | Element.hide(this.element); |
|
|||
547 | this.createForm(); |
|
|||
548 | this.element.parentNode.insertBefore(this.form, this.element); |
|
|||
549 | if (!this.options.loadTextURL) Field.scrollFreeActivate(this.editField); |
|
|||
550 | // stop the event to avoid a page refresh in Safari |
|
|||
551 | if (evt) { |
|
|||
552 | Event.stop(evt); |
|
|||
553 | } |
|
|||
554 | return false; |
|
|||
555 | }, |
|
|||
556 | createForm: function() { |
|
|||
557 | this.form = document.createElement("form"); |
|
|||
558 | this.form.id = this.options.formId; |
|
|||
559 | Element.addClassName(this.form, this.options.formClassName) |
|
|||
560 | this.form.onsubmit = this.onSubmit.bind(this); |
|
|||
561 |
|
||||
562 | this.createEditField(); |
|
|||
563 |
|
||||
564 | if (this.options.textarea) { |
|
|||
565 | var br = document.createElement("br"); |
|
|||
566 | this.form.appendChild(br); |
|
|||
567 | } |
|
|||
568 |
|
||||
569 | if (this.options.okButton) { |
|
|||
570 | okButton = document.createElement("input"); |
|
|||
571 | okButton.type = "submit"; |
|
|||
572 | okButton.value = this.options.okText; |
|
|||
573 | okButton.className = 'editor_ok_button'; |
|
|||
574 | this.form.appendChild(okButton); |
|
|||
575 | } |
|
|||
576 |
|
||||
577 | if (this.options.cancelLink) { |
|
|||
578 | cancelLink = document.createElement("a"); |
|
|||
579 | cancelLink.href = "#"; |
|
|||
580 | cancelLink.appendChild(document.createTextNode(this.options.cancelText)); |
|
|||
581 | cancelLink.onclick = this.onclickCancel.bind(this); |
|
|||
582 | cancelLink.className = 'editor_cancel'; |
|
|||
583 | this.form.appendChild(cancelLink); |
|
|||
584 | } |
|
|||
585 | }, |
|
|||
586 | hasHTMLLineBreaks: function(string) { |
|
|||
587 | if (!this.options.handleLineBreaks) return false; |
|
|||
588 | return string.match(/<br/i) || string.match(/<p>/i); |
|
|||
589 | }, |
|
|||
590 | convertHTMLLineBreaks: function(string) { |
|
|||
591 | return string.replace(/<br>/gi, "\n").replace(/<br\/>/gi, "\n").replace(/<\/p>/gi, "\n").replace(/<p>/gi, ""); |
|
|||
592 | }, |
|
|||
593 | createEditField: function() { |
|
536 | createEditField: function() { | |
594 | var text; |
|
537 | var text = (this.options.loadTextURL ? this.options.loadingText : this.getText()); | |
595 | if(this.options.loadTextURL) { |
|
538 | var fld; | |
596 | text = this.options.loadingText; |
|
539 | if (1 >= this.options.rows && !/\r|\n/.test(this.getText())) { | |
597 | } else { |
|
540 | fld = document.createElement('input'); | |
598 | text = this.getText(); |
|
541 | fld.type = 'text'; | |
599 | } |
|
|||
600 |
|
||||
601 | var obj = this; |
|
|||
602 |
|
||||
603 | if (this.options.rows == 1 && !this.hasHTMLLineBreaks(text)) { |
|
|||
604 | this.options.textarea = false; |
|
|||
605 | var textField = document.createElement("input"); |
|
|||
606 | textField.obj = this; |
|
|||
607 | textField.type = "text"; |
|
|||
608 | textField.name = this.options.paramName; |
|
|||
609 | textField.value = text; |
|
|||
610 | textField.style.backgroundColor = this.options.highlightcolor; |
|
|||
611 | textField.className = 'editor_field'; |
|
|||
612 | var size = this.options.size || this.options.cols || 0; |
|
542 | var size = this.options.size || this.options.cols || 0; | |
613 |
if (size |
|
543 | if (0 < size) fld.size = size; | |
614 | if (this.options.submitOnBlur) |
|
|||
615 | textField.onblur = this.onSubmit.bind(this); |
|
|||
616 | this.editField = textField; |
|
|||
617 | } else { |
|
544 | } else { | |
618 | this.options.textarea = true; |
|
545 | fld = document.createElement('textarea'); | |
619 | var textArea = document.createElement("textarea"); |
|
546 | fld.rows = (1 >= this.options.rows ? this.options.autoRows : this.options.rows); | |
620 | textArea.obj = this; |
|
547 | fld.cols = this.options.cols || 40; | |
621 | textArea.name = this.options.paramName; |
|
|||
622 | textArea.value = this.convertHTMLLineBreaks(text); |
|
|||
623 | textArea.rows = this.options.rows; |
|
|||
624 | textArea.cols = this.options.cols || 40; |
|
|||
625 | textArea.className = 'editor_field'; |
|
|||
626 | if (this.options.submitOnBlur) |
|
|||
627 | textArea.onblur = this.onSubmit.bind(this); |
|
|||
628 | this.editField = textArea; |
|
|||
629 | } |
|
548 | } | |
630 |
|
549 | fld.name = this.options.paramName; | ||
631 | if(this.options.loadTextURL) { |
|
550 | fld.value = text; // No HTML breaks conversion anymore | |
|
551 | fld.className = 'editor_field'; | |||
|
552 | if (this.options.submitOnBlur) | |||
|
553 | fld.onblur = this._boundSubmitHandler; | |||
|
554 | this._controls.editor = fld; | |||
|
555 | if (this.options.loadTextURL) | |||
632 | this.loadExternalText(); |
|
556 | this.loadExternalText(); | |
633 | } |
|
557 | this._form.appendChild(this._controls.editor); | |
634 | this.form.appendChild(this.editField); |
|
558 | }, | |
|
559 | createForm: function() { | |||
|
560 | var ipe = this; | |||
|
561 | function addText(mode, condition) { | |||
|
562 | var text = ipe.options['text' + mode + 'Controls']; | |||
|
563 | if (!text || condition === false) return; | |||
|
564 | ipe._form.appendChild(document.createTextNode(text)); | |||
|
565 | }; | |||
|
566 | this._form = $(document.createElement('form')); | |||
|
567 | this._form.id = this.options.formId; | |||
|
568 | this._form.addClassName(this.options.formClassName); | |||
|
569 | this._form.onsubmit = this._boundSubmitHandler; | |||
|
570 | this.createEditField(); | |||
|
571 | if ('textarea' == this._controls.editor.tagName.toLowerCase()) | |||
|
572 | this._form.appendChild(document.createElement('br')); | |||
|
573 | if (this.options.onFormCustomization) | |||
|
574 | this.options.onFormCustomization(this, this._form); | |||
|
575 | addText('Before', this.options.okControl || this.options.cancelControl); | |||
|
576 | this.createControl('ok', this._boundSubmitHandler); | |||
|
577 | addText('Between', this.options.okControl && this.options.cancelControl); | |||
|
578 | this.createControl('cancel', this._boundCancelHandler, 'editor_cancel'); | |||
|
579 | addText('After', this.options.okControl || this.options.cancelControl); | |||
|
580 | }, | |||
|
581 | destroy: function() { | |||
|
582 | if (this._oldInnerHTML) | |||
|
583 | this.element.innerHTML = this._oldInnerHTML; | |||
|
584 | this.leaveEditMode(); | |||
|
585 | this.unregisterListeners(); | |||
|
586 | }, | |||
|
587 | enterEditMode: function(e) { | |||
|
588 | if (this._saving || this._editing) return; | |||
|
589 | this._editing = true; | |||
|
590 | this.triggerCallback('onEnterEditMode'); | |||
|
591 | if (this.options.externalControl) | |||
|
592 | this.options.externalControl.hide(); | |||
|
593 | this.element.hide(); | |||
|
594 | this.createForm(); | |||
|
595 | this.element.parentNode.insertBefore(this._form, this.element); | |||
|
596 | if (!this.options.loadTextURL) | |||
|
597 | this.postProcessEditField(); | |||
|
598 | if (e) Event.stop(e); | |||
|
599 | }, | |||
|
600 | enterHover: function(e) { | |||
|
601 | if (this.options.hoverClassName) | |||
|
602 | this.element.addClassName(this.options.hoverClassName); | |||
|
603 | if (this._saving) return; | |||
|
604 | this.triggerCallback('onEnterHover'); | |||
635 | }, |
|
605 | }, | |
636 | getText: function() { |
|
606 | getText: function() { | |
637 | return this.element.innerHTML; |
|
607 | return this.element.innerHTML; | |
638 | }, |
|
608 | }, | |
639 | loadExternalText: function() { |
|
609 | handleAJAXFailure: function(transport) { | |
640 | Element.addClassName(this.form, this.options.loadingClassName); |
|
610 | this.triggerCallback('onFailure', transport); | |
641 | this.editField.disabled = true; |
|
611 | if (this._oldInnerHTML) { | |
642 | new Ajax.Request( |
|
612 | this.element.innerHTML = this._oldInnerHTML; | |
643 | this.options.loadTextURL, |
|
613 | this._oldInnerHTML = null; | |
644 | Object.extend({ |
|
|||
645 | asynchronous: true, |
|
|||
646 | onComplete: this.onLoadedExternalText.bind(this) |
|
|||
647 | }, this.options.ajaxOptions) |
|
|||
648 | ); |
|
|||
649 | }, |
|
|||
650 | onLoadedExternalText: function(transport) { |
|
|||
651 | Element.removeClassName(this.form, this.options.loadingClassName); |
|
|||
652 | this.editField.disabled = false; |
|
|||
653 | this.editField.value = transport.responseText.stripTags(); |
|
|||
654 | Field.scrollFreeActivate(this.editField); |
|
|||
655 | }, |
|
|||
656 | onclickCancel: function() { |
|
|||
657 | this.onComplete(); |
|
|||
658 | this.leaveEditMode(); |
|
|||
659 | return false; |
|
|||
660 | }, |
|
|||
661 | onFailure: function(transport) { |
|
|||
662 | this.options.onFailure(transport); |
|
|||
663 | if (this.oldInnerHTML) { |
|
|||
664 | this.element.innerHTML = this.oldInnerHTML; |
|
|||
665 | this.oldInnerHTML = null; |
|
|||
666 | } |
|
614 | } | |
667 | return false; |
|
|||
668 | }, |
|
615 | }, | |
669 | onSubmit: function() { |
|
616 | handleFormCancellation: function(e) { | |
670 | // onLoading resets these so we need to save them away for the Ajax call |
|
617 | this.wrapUp(); | |
671 | var form = this.form; |
|
618 | if (e) Event.stop(e); | |
672 | var value = this.editField.value; |
|
619 | }, | |
673 |
|
620 | handleFormSubmission: function(e) { | ||
674 | // do this first, sometimes the ajax call returns before we get a chance to switch on Saving... |
|
621 | var form = this._form; | |
675 | // which means this will actually switch on Saving... *after* we've left edit mode causing Saving... |
|
622 | var value = $F(this._controls.editor); | |
676 | // to be displayed indefinitely |
|
623 | this.prepareSubmission(); | |
677 | this.onLoading(); |
|
624 | var params = this.options.callback(form, value) || ''; | |
678 |
|
625 | if (Object.isString(params)) | ||
679 | if (this.options.evalScripts) { |
|
626 | params = params.toQueryParams(); | |
680 | new Ajax.Request( |
|
627 | params.editorId = this.element.id; | |
681 | this.url, Object.extend({ |
|
628 | if (this.options.htmlResponse) { | |
682 | parameters: this.options.callback(form, value), |
|
629 | var options = Object.extend({ evalScripts: true }, this.options.ajaxOptions); | |
683 | onComplete: this.onComplete.bind(this), |
|
630 | Object.extend(options, { | |
684 | onFailure: this.onFailure.bind(this), |
|
631 | parameters: params, | |
685 | asynchronous:true, |
|
632 | onComplete: this._boundWrapperHandler, | |
686 | evalScripts:true |
|
633 | onFailure: this._boundFailureHandler | |
687 | }, this.options.ajaxOptions)); |
|
634 | }); | |
688 | } else { |
|
635 | new Ajax.Updater({ success: this.element }, this.url, options); | |
689 | new Ajax.Updater( |
|
636 | } else { | |
690 | { success: this.element, |
|
637 | var options = Object.extend({ method: 'get' }, this.options.ajaxOptions); | |
691 | // don't update on failure (this could be an option) |
|
638 | Object.extend(options, { | |
692 | failure: null }, |
|
639 | parameters: params, | |
693 | this.url, Object.extend({ |
|
640 | onComplete: this._boundWrapperHandler, | |
694 | parameters: this.options.callback(form, value), |
|
641 | onFailure: this._boundFailureHandler | |
695 | onComplete: this.onComplete.bind(this), |
|
642 | }); | |
696 | onFailure: this.onFailure.bind(this) |
|
643 | new Ajax.Request(this.url, options); | |
697 | }, this.options.ajaxOptions)); |
|
|||
698 | } |
|
|||
699 | // stop the event to avoid a page refresh in Safari |
|
|||
700 | if (arguments.length > 1) { |
|
|||
701 | Event.stop(arguments[0]); |
|
|||
702 | } |
|
644 | } | |
703 | return false; |
|
645 | if (e) Event.stop(e); | |
|
646 | }, | |||
|
647 | leaveEditMode: function() { | |||
|
648 | this.element.removeClassName(this.options.savingClassName); | |||
|
649 | this.removeForm(); | |||
|
650 | this.leaveHover(); | |||
|
651 | this.element.style.backgroundColor = this._originalBackground; | |||
|
652 | this.element.show(); | |||
|
653 | if (this.options.externalControl) | |||
|
654 | this.options.externalControl.show(); | |||
|
655 | this._saving = false; | |||
|
656 | this._editing = false; | |||
|
657 | this._oldInnerHTML = null; | |||
|
658 | this.triggerCallback('onLeaveEditMode'); | |||
|
659 | }, | |||
|
660 | leaveHover: function(e) { | |||
|
661 | if (this.options.hoverClassName) | |||
|
662 | this.element.removeClassName(this.options.hoverClassName); | |||
|
663 | if (this._saving) return; | |||
|
664 | this.triggerCallback('onLeaveHover'); | |||
704 | }, |
|
665 | }, | |
705 |
|
|
666 | loadExternalText: function() { | |
706 | this.saving = true; |
|
667 | this._form.addClassName(this.options.loadingClassName); | |
|
668 | this._controls.editor.disabled = true; | |||
|
669 | var options = Object.extend({ method: 'get' }, this.options.ajaxOptions); | |||
|
670 | Object.extend(options, { | |||
|
671 | parameters: 'editorId=' + encodeURIComponent(this.element.id), | |||
|
672 | onComplete: Prototype.emptyFunction, | |||
|
673 | onSuccess: function(transport) { | |||
|
674 | this._form.removeClassName(this.options.loadingClassName); | |||
|
675 | var text = transport.responseText; | |||
|
676 | if (this.options.stripLoadedTextTags) | |||
|
677 | text = text.stripTags(); | |||
|
678 | this._controls.editor.value = text; | |||
|
679 | this._controls.editor.disabled = false; | |||
|
680 | this.postProcessEditField(); | |||
|
681 | }.bind(this), | |||
|
682 | onFailure: this._boundFailureHandler | |||
|
683 | }); | |||
|
684 | new Ajax.Request(this.options.loadTextURL, options); | |||
|
685 | }, | |||
|
686 | postProcessEditField: function() { | |||
|
687 | var fpc = this.options.fieldPostCreation; | |||
|
688 | if (fpc) | |||
|
689 | $(this._controls.editor)['focus' == fpc ? 'focus' : 'activate'](); | |||
|
690 | }, | |||
|
691 | prepareOptions: function() { | |||
|
692 | this.options = Object.clone(Ajax.InPlaceEditor.DefaultOptions); | |||
|
693 | Object.extend(this.options, Ajax.InPlaceEditor.DefaultCallbacks); | |||
|
694 | [this._extraDefaultOptions].flatten().compact().each(function(defs) { | |||
|
695 | Object.extend(this.options, defs); | |||
|
696 | }.bind(this)); | |||
|
697 | }, | |||
|
698 | prepareSubmission: function() { | |||
|
699 | this._saving = true; | |||
707 | this.removeForm(); |
|
700 | this.removeForm(); | |
708 | this.leaveHover(); |
|
701 | this.leaveHover(); | |
709 | this.showSaving(); |
|
702 | this.showSaving(); | |
710 | }, |
|
703 | }, | |
|
704 | registerListeners: function() { | |||
|
705 | this._listeners = { }; | |||
|
706 | var listener; | |||
|
707 | $H(Ajax.InPlaceEditor.Listeners).each(function(pair) { | |||
|
708 | listener = this[pair.value].bind(this); | |||
|
709 | this._listeners[pair.key] = listener; | |||
|
710 | if (!this.options.externalControlOnly) | |||
|
711 | this.element.observe(pair.key, listener); | |||
|
712 | if (this.options.externalControl) | |||
|
713 | this.options.externalControl.observe(pair.key, listener); | |||
|
714 | }.bind(this)); | |||
|
715 | }, | |||
|
716 | removeForm: function() { | |||
|
717 | if (!this._form) return; | |||
|
718 | this._form.remove(); | |||
|
719 | this._form = null; | |||
|
720 | this._controls = { }; | |||
|
721 | }, | |||
711 | showSaving: function() { |
|
722 | showSaving: function() { | |
712 | this.oldInnerHTML = this.element.innerHTML; |
|
723 | this._oldInnerHTML = this.element.innerHTML; | |
713 | this.element.innerHTML = this.options.savingText; |
|
724 | this.element.innerHTML = this.options.savingText; | |
714 |
|
|
725 | this.element.addClassName(this.options.savingClassName); | |
715 | this.element.style.backgroundColor = this.originalBackground; |
|
726 | this.element.style.backgroundColor = this._originalBackground; | |
716 |
|
|
727 | this.element.show(); | |
717 | }, |
|
728 | }, | |
718 | removeForm: function() { |
|
729 | triggerCallback: function(cbName, arg) { | |
719 | if(this.form) { |
|
730 | if ('function' == typeof this.options[cbName]) { | |
720 | if (this.form.parentNode) Element.remove(this.form); |
|
731 | this.options[cbName](this, arg); | |
721 | this.form = null; |
|
|||
722 | } |
|
732 | } | |
723 | }, |
|
733 | }, | |
724 |
|
|
734 | unregisterListeners: function() { | |
725 | if (this.saving) return; |
|
735 | $H(this._listeners).each(function(pair) { | |
726 | this.element.style.backgroundColor = this.options.highlightcolor; |
|
736 | if (!this.options.externalControlOnly) | |
727 | if (this.effect) { |
|
737 | this.element.stopObserving(pair.key, pair.value); | |
728 | this.effect.cancel(); |
|
738 | if (this.options.externalControl) | |
729 | } |
|
739 | this.options.externalControl.stopObserving(pair.key, pair.value); | |
730 | Element.addClassName(this.element, this.options.hoverClassName) |
|
740 | }.bind(this)); | |
731 | }, |
|
741 | }, | |
732 | leaveHover: function() { |
|
742 | wrapUp: function(transport) { | |
733 | if (this.options.backgroundColor) { |
|
743 | this.leaveEditMode(); | |
734 | this.element.style.backgroundColor = this.oldBackground; |
|
744 | // Can't use triggerCallback due to backward compatibility: requires | |
735 | } |
|
745 | // binding + direct element | |
736 | Element.removeClassName(this.element, this.options.hoverClassName) |
|
746 | this._boundComplete(transport, this.element); | |
737 | if (this.saving) return; |
|
747 | } | |
738 | this.effect = new Effect.Highlight(this.element, { |
|
748 | }); | |
739 | startcolor: this.options.highlightcolor, |
|
749 | ||
740 | endcolor: this.options.highlightendcolor, |
|
750 | Object.extend(Ajax.InPlaceEditor.prototype, { | |
741 | restorecolor: this.originalBackground |
|
751 | dispose: Ajax.InPlaceEditor.prototype.destroy | |
|
752 | }); | |||
|
753 | ||||
|
754 | Ajax.InPlaceCollectionEditor = Class.create(Ajax.InPlaceEditor, { | |||
|
755 | initialize: function($super, element, url, options) { | |||
|
756 | this._extraDefaultOptions = Ajax.InPlaceCollectionEditor.DefaultOptions; | |||
|
757 | $super(element, url, options); | |||
|
758 | }, | |||
|
759 | ||||
|
760 | createEditField: function() { | |||
|
761 | var list = document.createElement('select'); | |||
|
762 | list.name = this.options.paramName; | |||
|
763 | list.size = 1; | |||
|
764 | this._controls.editor = list; | |||
|
765 | this._collection = this.options.collection || []; | |||
|
766 | if (this.options.loadCollectionURL) | |||
|
767 | this.loadCollection(); | |||
|
768 | else | |||
|
769 | this.checkForExternalText(); | |||
|
770 | this._form.appendChild(this._controls.editor); | |||
|
771 | }, | |||
|
772 | ||||
|
773 | loadCollection: function() { | |||
|
774 | this._form.addClassName(this.options.loadingClassName); | |||
|
775 | this.showLoadingText(this.options.loadingCollectionText); | |||
|
776 | var options = Object.extend({ method: 'get' }, this.options.ajaxOptions); | |||
|
777 | Object.extend(options, { | |||
|
778 | parameters: 'editorId=' + encodeURIComponent(this.element.id), | |||
|
779 | onComplete: Prototype.emptyFunction, | |||
|
780 | onSuccess: function(transport) { | |||
|
781 | var js = transport.responseText.strip(); | |||
|
782 | if (!/^\[.*\]$/.test(js)) // TODO: improve sanity check | |||
|
783 | throw 'Server returned an invalid collection representation.'; | |||
|
784 | this._collection = eval(js); | |||
|
785 | this.checkForExternalText(); | |||
|
786 | }.bind(this), | |||
|
787 | onFailure: this.onFailure | |||
742 | }); |
|
788 | }); | |
|
789 | new Ajax.Request(this.options.loadCollectionURL, options); | |||
743 | }, |
|
790 | }, | |
744 | leaveEditMode: function() { |
|
791 | ||
745 | Element.removeClassName(this.element, this.options.savingClassName); |
|
792 | showLoadingText: function(text) { | |
746 | this.removeForm(); |
|
793 | this._controls.editor.disabled = true; | |
747 | this.leaveHover(); |
|
794 | var tempOption = this._controls.editor.firstChild; | |
748 | this.element.style.backgroundColor = this.originalBackground; |
|
795 | if (!tempOption) { | |
749 | Element.show(this.element); |
|
796 | tempOption = document.createElement('option'); | |
750 | if (this.options.externalControl) { |
|
797 | tempOption.value = ''; | |
751 | Element.show(this.options.externalControl); |
|
798 | this._controls.editor.appendChild(tempOption); | |
|
799 | tempOption.selected = true; | |||
752 | } |
|
800 | } | |
753 | this.editing = false; |
|
801 | tempOption.update((text || '').stripScripts().stripTags()); | |
754 | this.saving = false; |
|
|||
755 | this.oldInnerHTML = null; |
|
|||
756 | this.onLeaveEditMode(); |
|
|||
757 | }, |
|
802 | }, | |
758 | onComplete: function(transport) { |
|
803 | ||
759 | this.leaveEditMode(); |
|
804 | checkForExternalText: function() { | |
760 | this.options.onComplete.bind(this)(transport, this.element); |
|
805 | this._text = this.getText(); | |
|
806 | if (this.options.loadTextURL) | |||
|
807 | this.loadExternalText(); | |||
|
808 | else | |||
|
809 | this.buildOptionList(); | |||
761 | }, |
|
810 | }, | |
762 | onEnterEditMode: function() {}, |
|
811 | ||
763 |
|
|
812 | loadExternalText: function() { | |
764 | dispose: function() { |
|
813 | this.showLoadingText(this.options.loadingText); | |
765 | if (this.oldInnerHTML) { |
|
814 | var options = Object.extend({ method: 'get' }, this.options.ajaxOptions); | |
766 | this.element.innerHTML = this.oldInnerHTML; |
|
815 | Object.extend(options, { | |
767 | } |
|
816 | parameters: 'editorId=' + encodeURIComponent(this.element.id), | |
768 | this.leaveEditMode(); |
|
817 | onComplete: Prototype.emptyFunction, | |
769 | Event.stopObserving(this.element, 'click', this.onclickListener); |
|
818 | onSuccess: function(transport) { | |
770 | Event.stopObserving(this.element, 'mouseover', this.mouseoverListener); |
|
819 | this._text = transport.responseText.strip(); | |
771 | Event.stopObserving(this.element, 'mouseout', this.mouseoutListener); |
|
820 | this.buildOptionList(); | |
772 | if (this.options.externalControl) { |
|
821 | }.bind(this), | |
773 | Event.stopObserving(this.options.externalControl, 'click', this.onclickListener); |
|
822 | onFailure: this.onFailure | |
774 | Event.stopObserving(this.options.externalControl, 'mouseover', this.mouseoverListener); |
|
823 | }); | |
775 | Event.stopObserving(this.options.externalControl, 'mouseout', this.mouseoutListener); |
|
824 | new Ajax.Request(this.options.loadTextURL, options); | |
776 |
|
|
825 | }, | |
|
826 | ||||
|
827 | buildOptionList: function() { | |||
|
828 | this._form.removeClassName(this.options.loadingClassName); | |||
|
829 | this._collection = this._collection.map(function(entry) { | |||
|
830 | return 2 === entry.length ? entry : [entry, entry].flatten(); | |||
|
831 | }); | |||
|
832 | var marker = ('value' in this.options) ? this.options.value : this._text; | |||
|
833 | var textFound = this._collection.any(function(entry) { | |||
|
834 | return entry[0] == marker; | |||
|
835 | }.bind(this)); | |||
|
836 | this._controls.editor.update(''); | |||
|
837 | var option; | |||
|
838 | this._collection.each(function(entry, index) { | |||
|
839 | option = document.createElement('option'); | |||
|
840 | option.value = entry[0]; | |||
|
841 | option.selected = textFound ? entry[0] == marker : 0 == index; | |||
|
842 | option.appendChild(document.createTextNode(entry[1])); | |||
|
843 | this._controls.editor.appendChild(option); | |||
|
844 | }.bind(this)); | |||
|
845 | this._controls.editor.disabled = false; | |||
|
846 | Field.scrollFreeActivate(this._controls.editor); | |||
777 | } |
|
847 | } | |
778 | }; |
|
848 | }); | |
779 |
|
849 | |||
780 | Ajax.InPlaceCollectionEditor = Class.create(); |
|
850 | //**** DEPRECATION LAYER FOR InPlace[Collection]Editor! **** | |
781 | Object.extend(Ajax.InPlaceCollectionEditor.prototype, Ajax.InPlaceEditor.prototype); |
|
851 | //**** This only exists for a while, in order to let **** | |
782 | Object.extend(Ajax.InPlaceCollectionEditor.prototype, { |
|
852 | //**** users adapt to the new API. Read up on the new **** | |
783 | createEditField: function() { |
|
853 | //**** API and convert your code to it ASAP! **** | |
784 | if (!this.cached_selectTag) { |
|
854 | ||
785 | var selectTag = document.createElement("select"); |
|
855 | Ajax.InPlaceEditor.prototype.initialize.dealWithDeprecatedOptions = function(options) { | |
786 | var collection = this.options.collection || []; |
|
856 | if (!options) return; | |
787 | var optionTag; |
|
857 | function fallback(name, expr) { | |
788 | collection.each(function(e,i) { |
|
858 | if (name in options || expr === undefined) return; | |
789 | optionTag = document.createElement("option"); |
|
859 | options[name] = expr; | |
790 | optionTag.value = (e instanceof Array) ? e[0] : e; |
|
860 | }; | |
791 | if((typeof this.options.value == 'undefined') && |
|
861 | fallback('cancelControl', (options.cancelLink ? 'link' : (options.cancelButton ? 'button' : | |
792 | ((e instanceof Array) ? this.element.innerHTML == e[1] : e == optionTag.value)) optionTag.selected = true; |
|
862 | options.cancelLink == options.cancelButton == false ? false : undefined))); | |
793 | if(this.options.value==optionTag.value) optionTag.selected = true; |
|
863 | fallback('okControl', (options.okLink ? 'link' : (options.okButton ? 'button' : | |
794 | optionTag.appendChild(document.createTextNode((e instanceof Array) ? e[1] : e)); |
|
864 | options.okLink == options.okButton == false ? false : undefined))); | |
795 | selectTag.appendChild(optionTag); |
|
865 | fallback('highlightColor', options.highlightcolor); | |
796 | }.bind(this)); |
|
866 | fallback('highlightEndColor', options.highlightendcolor); | |
797 | this.cached_selectTag = selectTag; |
|
867 | }; | |
798 | } |
|
|||
799 |
|
868 | |||
800 | this.editField = this.cached_selectTag; |
|
869 | Object.extend(Ajax.InPlaceEditor, { | |
801 | if(this.options.loadTextURL) this.loadExternalText(); |
|
870 | DefaultOptions: { | |
802 | this.form.appendChild(this.editField); |
|
871 | ajaxOptions: { }, | |
803 | this.options.callback = function(form, value) { |
|
872 | autoRows: 3, // Use when multi-line w/ rows == 1 | |
804 | return "value=" + encodeURIComponent(value); |
|
873 | cancelControl: 'link', // 'link'|'button'|false | |
|
874 | cancelText: 'cancel', | |||
|
875 | clickToEditText: 'Click to edit', | |||
|
876 | externalControl: null, // id|elt | |||
|
877 | externalControlOnly: false, | |||
|
878 | fieldPostCreation: 'activate', // 'activate'|'focus'|false | |||
|
879 | formClassName: 'inplaceeditor-form', | |||
|
880 | formId: null, // id|elt | |||
|
881 | highlightColor: '#ffff99', | |||
|
882 | highlightEndColor: '#ffffff', | |||
|
883 | hoverClassName: '', | |||
|
884 | htmlResponse: true, | |||
|
885 | loadingClassName: 'inplaceeditor-loading', | |||
|
886 | loadingText: 'Loading...', | |||
|
887 | okControl: 'button', // 'link'|'button'|false | |||
|
888 | okText: 'ok', | |||
|
889 | paramName: 'value', | |||
|
890 | rows: 1, // If 1 and multi-line, uses autoRows | |||
|
891 | savingClassName: 'inplaceeditor-saving', | |||
|
892 | savingText: 'Saving...', | |||
|
893 | size: 0, | |||
|
894 | stripLoadedTextTags: false, | |||
|
895 | submitOnBlur: false, | |||
|
896 | textAfterControls: '', | |||
|
897 | textBeforeControls: '', | |||
|
898 | textBetweenControls: '' | |||
|
899 | }, | |||
|
900 | DefaultCallbacks: { | |||
|
901 | callback: function(form) { | |||
|
902 | return Form.serialize(form); | |||
|
903 | }, | |||
|
904 | onComplete: function(transport, element) { | |||
|
905 | // For backward compatibility, this one is bound to the IPE, and passes | |||
|
906 | // the element directly. It was too often customized, so we don't break it. | |||
|
907 | new Effect.Highlight(element, { | |||
|
908 | startcolor: this.options.highlightColor, keepBackgroundImage: true }); | |||
|
909 | }, | |||
|
910 | onEnterEditMode: null, | |||
|
911 | onEnterHover: function(ipe) { | |||
|
912 | ipe.element.style.backgroundColor = ipe.options.highlightColor; | |||
|
913 | if (ipe._effect) | |||
|
914 | ipe._effect.cancel(); | |||
|
915 | }, | |||
|
916 | onFailure: function(transport, ipe) { | |||
|
917 | alert('Error communication with the server: ' + transport.responseText.stripTags()); | |||
|
918 | }, | |||
|
919 | onFormCustomization: null, // Takes the IPE and its generated form, after editor, before controls. | |||
|
920 | onLeaveEditMode: null, | |||
|
921 | onLeaveHover: function(ipe) { | |||
|
922 | ipe._effect = new Effect.Highlight(ipe.element, { | |||
|
923 | startcolor: ipe.options.highlightColor, endcolor: ipe.options.highlightEndColor, | |||
|
924 | restorecolor: ipe._originalBackground, keepBackgroundImage: true | |||
|
925 | }); | |||
805 | } |
|
926 | } | |
|
927 | }, | |||
|
928 | Listeners: { | |||
|
929 | click: 'enterEditMode', | |||
|
930 | keydown: 'checkForEscapeOrReturn', | |||
|
931 | mouseover: 'enterHover', | |||
|
932 | mouseout: 'leaveHover' | |||
806 | } |
|
933 | } | |
807 | }); |
|
934 | }); | |
808 |
|
935 | |||
|
936 | Ajax.InPlaceCollectionEditor.DefaultOptions = { | |||
|
937 | loadingCollectionText: 'Loading options...' | |||
|
938 | }; | |||
|
939 | ||||
809 | // Delayed observer, like Form.Element.Observer, |
|
940 | // Delayed observer, like Form.Element.Observer, | |
810 | // but waits for delay after last key input |
|
941 | // but waits for delay after last key input | |
811 | // Ideal for live-search fields |
|
942 | // Ideal for live-search fields | |
812 |
|
943 | |||
813 |
Form.Element.DelayedObserver = Class.create( |
|
944 | Form.Element.DelayedObserver = Class.create({ | |
814 | Form.Element.DelayedObserver.prototype = { |
|
|||
815 | initialize: function(element, delay, callback) { |
|
945 | initialize: function(element, delay, callback) { | |
816 | this.delay = delay || 0.5; |
|
946 | this.delay = delay || 0.5; | |
817 | this.element = $(element); |
|
947 | this.element = $(element); | |
@@ -830,4 +960,4 Form.Element.DelayedObserver.prototype = { | |||||
830 | this.timer = null; |
|
960 | this.timer = null; | |
831 | this.callback(this.element, $F(this.element)); |
|
961 | this.callback(this.element, $F(this.element)); | |
832 | } |
|
962 | } | |
833 | }; |
|
963 | }); |
@@ -1,10 +1,10 | |||||
1 |
// Copyright (c) 2005 |
|
1 | // Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) | |
2 |
// (c) 2005 |
|
2 | // (c) 2005-2007 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz) | |
3 | // |
|
3 | // | |
4 | // script.aculo.us is freely distributable under the terms of an MIT-style license. |
|
4 | // script.aculo.us is freely distributable under the terms of an MIT-style license. | |
5 | // For details, see the script.aculo.us web site: http://script.aculo.us/ |
|
5 | // For details, see the script.aculo.us web site: http://script.aculo.us/ | |
6 |
|
6 | |||
7 | if(typeof Effect == 'undefined') |
|
7 | if(Object.isUndefined(Effect)) | |
8 | throw("dragdrop.js requires including script.aculo.us' effects.js library"); |
|
8 | throw("dragdrop.js requires including script.aculo.us' effects.js library"); | |
9 |
|
9 | |||
10 | var Droppables = { |
|
10 | var Droppables = { | |
@@ -20,14 +20,13 var Droppables = { | |||||
20 | greedy: true, |
|
20 | greedy: true, | |
21 | hoverclass: null, |
|
21 | hoverclass: null, | |
22 | tree: false |
|
22 | tree: false | |
23 | }, arguments[1] || {}); |
|
23 | }, arguments[1] || { }); | |
24 |
|
24 | |||
25 | // cache containers |
|
25 | // cache containers | |
26 | if(options.containment) { |
|
26 | if(options.containment) { | |
27 | options._containers = []; |
|
27 | options._containers = []; | |
28 | var containment = options.containment; |
|
28 | var containment = options.containment; | |
29 | if((typeof containment == 'object') && |
|
29 | if(Object.isArray(containment)) { | |
30 | (containment.constructor == Array)) { |
|
|||
31 | containment.each( function(c) { options._containers.push($(c)) }); |
|
30 | containment.each( function(c) { options._containers.push($(c)) }); | |
32 | } else { |
|
31 | } else { | |
33 | options._containers.push($(containment)); |
|
32 | options._containers.push($(containment)); | |
@@ -87,21 +86,23 var Droppables = { | |||||
87 |
|
86 | |||
88 | show: function(point, element) { |
|
87 | show: function(point, element) { | |
89 | if(!this.drops.length) return; |
|
88 | if(!this.drops.length) return; | |
90 | var affected = []; |
|
89 | var drop, affected = []; | |
91 |
|
90 | |||
92 | if(this.last_active) this.deactivate(this.last_active); |
|
|||
93 | this.drops.each( function(drop) { |
|
91 | this.drops.each( function(drop) { | |
94 | if(Droppables.isAffected(point, element, drop)) |
|
92 | if(Droppables.isAffected(point, element, drop)) | |
95 | affected.push(drop); |
|
93 | affected.push(drop); | |
96 | }); |
|
94 | }); | |
97 |
|
95 | |||
98 |
if(affected.length>0) |
|
96 | if(affected.length>0) | |
99 | drop = Droppables.findDeepestChild(affected); |
|
97 | drop = Droppables.findDeepestChild(affected); | |
|
98 | ||||
|
99 | if(this.last_active && this.last_active != drop) this.deactivate(this.last_active); | |||
|
100 | if (drop) { | |||
100 | Position.within(drop.element, point[0], point[1]); |
|
101 | Position.within(drop.element, point[0], point[1]); | |
101 | if(drop.onHover) |
|
102 | if(drop.onHover) | |
102 | drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element)); |
|
103 | drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element)); | |
103 |
|
104 | |||
104 | Droppables.activate(drop); |
|
105 | if (drop != this.last_active) Droppables.activate(drop); | |
105 | } |
|
106 | } | |
106 | }, |
|
107 | }, | |
107 |
|
108 | |||
@@ -110,8 +111,10 var Droppables = { | |||||
110 | Position.prepare(); |
|
111 | Position.prepare(); | |
111 |
|
112 | |||
112 | if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active)) |
|
113 | if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active)) | |
113 | if (this.last_active.onDrop) |
|
114 | if (this.last_active.onDrop) { | |
114 | this.last_active.onDrop(element, this.last_active.element, event); |
|
115 | this.last_active.onDrop(element, this.last_active.element, event); | |
|
116 | return true; | |||
|
117 | } | |||
115 | }, |
|
118 | }, | |
116 |
|
119 | |||
117 | reset: function() { |
|
120 | reset: function() { | |
@@ -219,10 +222,7 var Draggables = { | |||||
219 |
|
222 | |||
220 | /*--------------------------------------------------------------------------*/ |
|
223 | /*--------------------------------------------------------------------------*/ | |
221 |
|
224 | |||
222 |
var Draggable = Class.create( |
|
225 | var Draggable = Class.create({ | |
223 | Draggable._dragging = {}; |
|
|||
224 |
|
||||
225 | Draggable.prototype = { |
|
|||
226 | initialize: function(element) { |
|
226 | initialize: function(element) { | |
227 | var defaults = { |
|
227 | var defaults = { | |
228 | handle: false, |
|
228 | handle: false, | |
@@ -233,7 +233,7 Draggable.prototype = { | |||||
233 | }); |
|
233 | }); | |
234 | }, |
|
234 | }, | |
235 | endeffect: function(element) { |
|
235 | endeffect: function(element) { | |
236 |
var toOpacity = |
|
236 | var toOpacity = Object.isNumber(element._opacity) ? element._opacity : 1.0; | |
237 | new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity, |
|
237 | new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity, | |
238 | queue: {scope:'_draggable', position:'end'}, |
|
238 | queue: {scope:'_draggable', position:'end'}, | |
239 | afterFinish: function(){ |
|
239 | afterFinish: function(){ | |
@@ -243,6 +243,7 Draggable.prototype = { | |||||
243 | }, |
|
243 | }, | |
244 | zindex: 1000, |
|
244 | zindex: 1000, | |
245 | revert: false, |
|
245 | revert: false, | |
|
246 | quiet: false, | |||
246 | scroll: false, |
|
247 | scroll: false, | |
247 | scrollSensitivity: 20, |
|
248 | scrollSensitivity: 20, | |
248 | scrollSpeed: 15, |
|
249 | scrollSpeed: 15, | |
@@ -250,7 +251,7 Draggable.prototype = { | |||||
250 | delay: 0 |
|
251 | delay: 0 | |
251 | }; |
|
252 | }; | |
252 |
|
253 | |||
253 |
if(!arguments[1] || |
|
254 | if(!arguments[1] || Object.isUndefined(arguments[1].endeffect)) | |
254 | Object.extend(defaults, { |
|
255 | Object.extend(defaults, { | |
255 | starteffect: function(element) { |
|
256 | starteffect: function(element) { | |
256 | element._opacity = Element.getOpacity(element); |
|
257 | element._opacity = Element.getOpacity(element); | |
@@ -259,11 +260,11 Draggable.prototype = { | |||||
259 | } |
|
260 | } | |
260 | }); |
|
261 | }); | |
261 |
|
262 | |||
262 | var options = Object.extend(defaults, arguments[1] || {}); |
|
263 | var options = Object.extend(defaults, arguments[1] || { }); | |
263 |
|
264 | |||
264 | this.element = $(element); |
|
265 | this.element = $(element); | |
265 |
|
266 | |||
266 |
if(options.handle && ( |
|
267 | if(options.handle && Object.isString(options.handle)) | |
267 | this.handle = this.element.down('.'+options.handle, 0); |
|
268 | this.handle = this.element.down('.'+options.handle, 0); | |
268 |
|
269 | |||
269 | if(!this.handle) this.handle = $(options.handle); |
|
270 | if(!this.handle) this.handle = $(options.handle); | |
@@ -276,7 +277,6 Draggable.prototype = { | |||||
276 |
|
277 | |||
277 | Element.makePositioned(this.element); // fix IE |
|
278 | Element.makePositioned(this.element); // fix IE | |
278 |
|
279 | |||
279 | this.delta = this.currentDelta(); |
|
|||
280 | this.options = options; |
|
280 | this.options = options; | |
281 | this.dragging = false; |
|
281 | this.dragging = false; | |
282 |
|
282 | |||
@@ -298,17 +298,17 Draggable.prototype = { | |||||
298 | }, |
|
298 | }, | |
299 |
|
299 | |||
300 | initDrag: function(event) { |
|
300 | initDrag: function(event) { | |
301 |
if( |
|
301 | if(!Object.isUndefined(Draggable._dragging[this.element]) && | |
302 | Draggable._dragging[this.element]) return; |
|
302 | Draggable._dragging[this.element]) return; | |
303 | if(Event.isLeftClick(event)) { |
|
303 | if(Event.isLeftClick(event)) { | |
304 | // abort on form elements, fixes a Firefox issue |
|
304 | // abort on form elements, fixes a Firefox issue | |
305 | var src = Event.element(event); |
|
305 | var src = Event.element(event); | |
306 | if(src.tagName && ( |
|
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 | var pointer = [Event.pointerX(event), Event.pointerY(event)]; |
|
313 | var pointer = [Event.pointerX(event), Event.pointerY(event)]; | |
314 | var pos = Position.cumulativeOffset(this.element); |
|
314 | var pos = Position.cumulativeOffset(this.element); | |
@@ -321,6 +321,8 Draggable.prototype = { | |||||
321 |
|
321 | |||
322 | startDrag: function(event) { |
|
322 | startDrag: function(event) { | |
323 | this.dragging = true; |
|
323 | this.dragging = true; | |
|
324 | if(!this.delta) | |||
|
325 | this.delta = this.currentDelta(); | |||
324 |
|
326 | |||
325 | if(this.options.zindex) { |
|
327 | if(this.options.zindex) { | |
326 | this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0); |
|
328 | this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0); | |
@@ -329,7 +331,9 Draggable.prototype = { | |||||
329 |
|
331 | |||
330 | if(this.options.ghosting) { |
|
332 | if(this.options.ghosting) { | |
331 | this._clone = this.element.cloneNode(true); |
|
333 | this._clone = this.element.cloneNode(true); | |
332 | Position.absolutize(this.element); |
|
334 | this.element._originallyAbsolute = (this.element.getStyle('position') == 'absolute'); | |
|
335 | if (!this.element._originallyAbsolute) | |||
|
336 | Position.absolutize(this.element); | |||
333 | this.element.parentNode.insertBefore(this._clone, this.element); |
|
337 | this.element.parentNode.insertBefore(this._clone, this.element); | |
334 | } |
|
338 | } | |
335 |
|
339 | |||
@@ -351,8 +355,12 Draggable.prototype = { | |||||
351 |
|
355 | |||
352 | updateDrag: function(event, pointer) { |
|
356 | updateDrag: function(event, pointer) { | |
353 | if(!this.dragging) this.startDrag(event); |
|
357 | if(!this.dragging) this.startDrag(event); | |
354 | Position.prepare(); |
|
358 | ||
355 | Droppables.show(pointer, this.element); |
|
359 | if(!this.options.quiet){ | |
|
360 | Position.prepare(); | |||
|
361 | Droppables.show(pointer, this.element); | |||
|
362 | } | |||
|
363 | ||||
356 | Draggables.notify('onDrag', this, event); |
|
364 | Draggables.notify('onDrag', this, event); | |
357 |
|
365 | |||
358 | this.draw(pointer); |
|
366 | this.draw(pointer); | |
@@ -380,30 +388,44 Draggable.prototype = { | |||||
380 | } |
|
388 | } | |
381 |
|
389 | |||
382 | // fix AppleWebKit rendering |
|
390 | // fix AppleWebKit rendering | |
383 |
if( |
|
391 | if(Prototype.Browser.WebKit) window.scrollBy(0,0); | |
384 |
|
392 | |||
385 | Event.stop(event); |
|
393 | Event.stop(event); | |
386 | }, |
|
394 | }, | |
387 |
|
395 | |||
388 | finishDrag: function(event, success) { |
|
396 | finishDrag: function(event, success) { | |
389 | this.dragging = false; |
|
397 | this.dragging = false; | |
|
398 | ||||
|
399 | if(this.options.quiet){ | |||
|
400 | Position.prepare(); | |||
|
401 | var pointer = [Event.pointerX(event), Event.pointerY(event)]; | |||
|
402 | Droppables.show(pointer, this.element); | |||
|
403 | } | |||
390 |
|
404 | |||
391 | if(this.options.ghosting) { |
|
405 | if(this.options.ghosting) { | |
392 | Position.relativize(this.element); |
|
406 | if (!this.element._originallyAbsolute) | |
|
407 | Position.relativize(this.element); | |||
|
408 | delete this.element._originallyAbsolute; | |||
393 | Element.remove(this._clone); |
|
409 | Element.remove(this._clone); | |
394 | this._clone = null; |
|
410 | this._clone = null; | |
395 | } |
|
411 | } | |
396 |
|
412 | |||
397 | if(success) Droppables.fire(event, this.element); |
|
413 | var dropped = false; | |
|
414 | if(success) { | |||
|
415 | dropped = Droppables.fire(event, this.element); | |||
|
416 | if (!dropped) dropped = false; | |||
|
417 | } | |||
|
418 | if(dropped && this.options.onDropped) this.options.onDropped(this.element); | |||
398 | Draggables.notify('onEnd', this, event); |
|
419 | Draggables.notify('onEnd', this, event); | |
399 |
|
420 | |||
400 | var revert = this.options.revert; |
|
421 | var revert = this.options.revert; | |
401 |
if(revert && |
|
422 | if(revert && Object.isFunction(revert)) revert = revert(this.element); | |
402 |
|
423 | |||
403 | var d = this.currentDelta(); |
|
424 | var d = this.currentDelta(); | |
404 | if(revert && this.options.reverteffect) { |
|
425 | if(revert && this.options.reverteffect) { | |
405 | this.options.reverteffect(this.element, |
|
426 | if (dropped == 0 || revert != 'failure') | |
406 | d[1]-this.delta[1], d[0]-this.delta[0]); |
|
427 | this.options.reverteffect(this.element, | |
|
428 | d[1]-this.delta[1], d[0]-this.delta[0]); | |||
407 | } else { |
|
429 | } else { | |
408 | this.delta = d; |
|
430 | this.delta = d; | |
409 | } |
|
431 | } | |
@@ -451,15 +473,15 Draggable.prototype = { | |||||
451 | }.bind(this)); |
|
473 | }.bind(this)); | |
452 |
|
474 | |||
453 | if(this.options.snap) { |
|
475 | if(this.options.snap) { | |
454 |
if( |
|
476 | if(Object.isFunction(this.options.snap)) { | |
455 | p = this.options.snap(p[0],p[1],this); |
|
477 | p = this.options.snap(p[0],p[1],this); | |
456 | } else { |
|
478 | } else { | |
457 |
if(this.options.snap |
|
479 | if(Object.isArray(this.options.snap)) { | |
458 | p = p.map( function(v, i) { |
|
480 | p = p.map( function(v, i) { | |
459 |
return |
|
481 | return (v/this.options.snap[i]).round()*this.options.snap[i] }.bind(this)) | |
460 | } else { |
|
482 | } else { | |
461 | p = p.map( function(v) { |
|
483 | p = p.map( function(v) { | |
462 |
return |
|
484 | return (v/this.options.snap).round()*this.options.snap }.bind(this)) | |
463 | } |
|
485 | } | |
464 | }} |
|
486 | }} | |
465 |
|
487 | |||
@@ -543,12 +565,13 Draggable.prototype = { | |||||
543 | } |
|
565 | } | |
544 | return { top: T, left: L, width: W, height: H }; |
|
566 | return { top: T, left: L, width: W, height: H }; | |
545 | } |
|
567 | } | |
546 | } |
|
568 | }); | |
|
569 | ||||
|
570 | Draggable._dragging = { }; | |||
547 |
|
571 | |||
548 |
|
|
572 | /*--------------------------------------------------------------------------*/ | |
549 |
|
573 | |||
550 |
var SortableObserver = Class.create( |
|
574 | var SortableObserver = Class.create({ | |
551 | SortableObserver.prototype = { |
|
|||
552 | initialize: function(element, observer) { |
|
575 | initialize: function(element, observer) { | |
553 | this.element = $(element); |
|
576 | this.element = $(element); | |
554 | this.observer = observer; |
|
577 | this.observer = observer; | |
@@ -564,15 +587,15 SortableObserver.prototype = { | |||||
564 | if(this.lastValue != Sortable.serialize(this.element)) |
|
587 | if(this.lastValue != Sortable.serialize(this.element)) | |
565 | this.observer(this.element) |
|
588 | this.observer(this.element) | |
566 | } |
|
589 | } | |
567 | } |
|
590 | }); | |
568 |
|
591 | |||
569 | var Sortable = { |
|
592 | var Sortable = { | |
570 | SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/, |
|
593 | SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/, | |
571 |
|
594 | |||
572 | sortables: {}, |
|
595 | sortables: { }, | |
573 |
|
596 | |||
574 | _findRootElement: function(element) { |
|
597 | _findRootElement: function(element) { | |
575 | while (element.tagName != "BODY") { |
|
598 | while (element.tagName.toUpperCase() != "BODY") { | |
576 | if(element.id && Sortable.sortables[element.id]) return element; |
|
599 | if(element.id && Sortable.sortables[element.id]) return element; | |
577 | element = element.parentNode; |
|
600 | element = element.parentNode; | |
578 | } |
|
601 | } | |
@@ -612,13 +635,20 var Sortable = { | |||||
612 | delay: 0, |
|
635 | delay: 0, | |
613 | hoverclass: null, |
|
636 | hoverclass: null, | |
614 | ghosting: false, |
|
637 | ghosting: false, | |
|
638 | quiet: false, | |||
615 | scroll: false, |
|
639 | scroll: false, | |
616 | scrollSensitivity: 20, |
|
640 | scrollSensitivity: 20, | |
617 | scrollSpeed: 15, |
|
641 | scrollSpeed: 15, | |
618 | format: this.SERIALIZE_RULE, |
|
642 | format: this.SERIALIZE_RULE, | |
|
643 | ||||
|
644 | // these take arrays of elements or ids and can be | |||
|
645 | // used for better initialization performance | |||
|
646 | elements: false, | |||
|
647 | handles: false, | |||
|
648 | ||||
619 | onChange: Prototype.emptyFunction, |
|
649 | onChange: Prototype.emptyFunction, | |
620 | onUpdate: Prototype.emptyFunction |
|
650 | onUpdate: Prototype.emptyFunction | |
621 | }, arguments[1] || {}); |
|
651 | }, arguments[1] || { }); | |
622 |
|
652 | |||
623 | // clear any old sortable with same element |
|
653 | // clear any old sortable with same element | |
624 | this.destroy(element); |
|
654 | this.destroy(element); | |
@@ -626,6 +656,7 var Sortable = { | |||||
626 | // build options for the draggables |
|
656 | // build options for the draggables | |
627 | var options_for_draggable = { |
|
657 | var options_for_draggable = { | |
628 | revert: true, |
|
658 | revert: true, | |
|
659 | quiet: options.quiet, | |||
629 | scroll: options.scroll, |
|
660 | scroll: options.scroll, | |
630 | scrollSpeed: options.scrollSpeed, |
|
661 | scrollSpeed: options.scrollSpeed, | |
631 | scrollSensitivity: options.scrollSensitivity, |
|
662 | scrollSensitivity: options.scrollSensitivity, | |
@@ -679,10 +710,9 var Sortable = { | |||||
679 | options.droppables.push(element); |
|
710 | options.droppables.push(element); | |
680 | } |
|
711 | } | |
681 |
|
712 | |||
682 | (this.findElements(element, options) || []).each( function(e) { |
|
713 | (options.elements || this.findElements(element, options) || []).each( function(e,i) { | |
683 | // handles are per-draggable |
|
714 | var handle = options.handles ? $(options.handles[i]) : | |
684 | var handle = options.handle ? |
|
715 | (options.handle ? $(e).select('.' + options.handle)[0] : e); | |
685 | $(e).down('.'+options.handle,0) : e; |
|
|||
686 | options.draggables.push( |
|
716 | options.draggables.push( | |
687 | new Draggable(e, Object.extend(options_for_draggable, { handle: handle }))); |
|
717 | new Draggable(e, Object.extend(options_for_draggable, { handle: handle }))); | |
688 | Droppables.add(e, options_for_droppable); |
|
718 | Droppables.add(e, options_for_droppable); | |
@@ -842,7 +872,7 var Sortable = { | |||||
842 | only: sortableOptions.only, |
|
872 | only: sortableOptions.only, | |
843 | name: element.id, |
|
873 | name: element.id, | |
844 | format: sortableOptions.format |
|
874 | format: sortableOptions.format | |
845 | }, arguments[1] || {}); |
|
875 | }, arguments[1] || { }); | |
846 |
|
876 | |||
847 | var root = { |
|
877 | var root = { | |
848 | id: null, |
|
878 | id: null, | |
@@ -866,7 +896,7 var Sortable = { | |||||
866 |
|
896 | |||
867 | sequence: function(element) { |
|
897 | sequence: function(element) { | |
868 | element = $(element); |
|
898 | element = $(element); | |
869 | var options = Object.extend(this.options(element), arguments[1] || {}); |
|
899 | var options = Object.extend(this.options(element), arguments[1] || { }); | |
870 |
|
900 | |||
871 | return $(this.findElements(element, options) || []).map( function(item) { |
|
901 | return $(this.findElements(element, options) || []).map( function(item) { | |
872 | return item.id.match(options.format) ? item.id.match(options.format)[1] : ''; |
|
902 | return item.id.match(options.format) ? item.id.match(options.format)[1] : ''; | |
@@ -875,9 +905,9 var Sortable = { | |||||
875 |
|
905 | |||
876 | setSequence: function(element, new_sequence) { |
|
906 | setSequence: function(element, new_sequence) { | |
877 | element = $(element); |
|
907 | element = $(element); | |
878 | var options = Object.extend(this.options(element), arguments[2] || {}); |
|
908 | var options = Object.extend(this.options(element), arguments[2] || { }); | |
879 |
|
909 | |||
880 | var nodeMap = {}; |
|
910 | var nodeMap = { }; | |
881 | this.findElements(element, options).each( function(n) { |
|
911 | this.findElements(element, options).each( function(n) { | |
882 | if (n.id.match(options.format)) |
|
912 | if (n.id.match(options.format)) | |
883 | nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode]; |
|
913 | nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode]; | |
@@ -895,7 +925,7 var Sortable = { | |||||
895 |
|
925 | |||
896 | serialize: function(element) { |
|
926 | serialize: function(element) { | |
897 | element = $(element); |
|
927 | element = $(element); | |
898 | var options = Object.extend(Sortable.options(element), arguments[1] || {}); |
|
928 | var options = Object.extend(Sortable.options(element), arguments[1] || { }); | |
899 | var name = encodeURIComponent( |
|
929 | var name = encodeURIComponent( | |
900 | (arguments[1] && arguments[1].name) ? arguments[1].name : element.id); |
|
930 | (arguments[1] && arguments[1].name) ? arguments[1].name : element.id); | |
901 |
|
931 | |||
@@ -919,7 +949,7 Element.isParent = function(child, element) { | |||||
919 | return Element.isParent(child.parentNode, element); |
|
949 | return Element.isParent(child.parentNode, element); | |
920 | } |
|
950 | } | |
921 |
|
951 | |||
922 |
Element.findChildren = function(element, only, recursive, tagName) { |
|
952 | Element.findChildren = function(element, only, recursive, tagName) { | |
923 | if(!element.hasChildNodes()) return null; |
|
953 | if(!element.hasChildNodes()) return null; | |
924 | tagName = tagName.toUpperCase(); |
|
954 | tagName = tagName.toUpperCase(); | |
925 | if(only) only = [only].flatten(); |
|
955 | if(only) only = [only].flatten(); |
This diff has been collapsed as it changes many lines, (760 lines changed) Show them Hide them | |||||
@@ -1,4 +1,4 | |||||
1 |
// Copyright (c) 2005 |
|
1 | // Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) | |
2 | // Contributors: |
|
2 | // Contributors: | |
3 | // Justin Palmer (http://encytemedia.com/) |
|
3 | // Justin Palmer (http://encytemedia.com/) | |
4 | // Mark Pilgrim (http://diveintomark.org/) |
|
4 | // Mark Pilgrim (http://diveintomark.org/) | |
@@ -11,17 +11,17 | |||||
11 | // returns self (or first argument) if not convertable |
|
11 | // returns self (or first argument) if not convertable | |
12 | String.prototype.parseColor = function() { |
|
12 | String.prototype.parseColor = function() { | |
13 | var color = '#'; |
|
13 | var color = '#'; | |
14 | if(this.slice(0,4) == 'rgb(') { |
|
14 | if (this.slice(0,4) == 'rgb(') { | |
15 | var cols = this.slice(4,this.length-1).split(','); |
|
15 | var cols = this.slice(4,this.length-1).split(','); | |
16 | var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3); |
|
16 | var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3); | |
17 | } else { |
|
17 | } else { | |
18 | if(this.slice(0,1) == '#') { |
|
18 | if (this.slice(0,1) == '#') { | |
19 | if(this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase(); |
|
19 | if (this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase(); | |
20 | if(this.length==7) color = this.toLowerCase(); |
|
20 | if (this.length==7) color = this.toLowerCase(); | |
21 | } |
|
21 | } | |
22 | } |
|
22 | } | |
23 | return(color.length==7 ? color : (arguments[0] || this)); |
|
23 | return (color.length==7 ? color : (arguments[0] || this)); | |
24 | } |
|
24 | }; | |
25 |
|
25 | |||
26 |
|
|
26 | /*--------------------------------------------------------------------------*/ | |
27 |
|
27 | |||
@@ -30,7 +30,7 Element.collectTextNodes = function(element) { | |||||
30 | return (node.nodeType==3 ? node.nodeValue : |
|
30 | return (node.nodeType==3 ? node.nodeValue : | |
31 | (node.hasChildNodes() ? Element.collectTextNodes(node) : '')); |
|
31 | (node.hasChildNodes() ? Element.collectTextNodes(node) : '')); | |
32 | }).flatten().join(''); |
|
32 | }).flatten().join(''); | |
33 | } |
|
33 | }; | |
34 |
|
34 | |||
35 | Element.collectTextNodesIgnoreClass = function(element, className) { |
|
35 | Element.collectTextNodesIgnoreClass = function(element, className) { | |
36 | return $A($(element).childNodes).collect( function(node) { |
|
36 | return $A($(element).childNodes).collect( function(node) { | |
@@ -38,47 +38,18 Element.collectTextNodesIgnoreClass = function(element, className) { | |||||
38 | ((node.hasChildNodes() && !Element.hasClassName(node,className)) ? |
|
38 | ((node.hasChildNodes() && !Element.hasClassName(node,className)) ? | |
39 | Element.collectTextNodesIgnoreClass(node, className) : '')); |
|
39 | Element.collectTextNodesIgnoreClass(node, className) : '')); | |
40 | }).flatten().join(''); |
|
40 | }).flatten().join(''); | |
41 | } |
|
41 | }; | |
42 |
|
42 | |||
43 | Element.setContentZoom = function(element, percent) { |
|
43 | Element.setContentZoom = function(element, percent) { | |
44 | element = $(element); |
|
44 | element = $(element); | |
45 | element.setStyle({fontSize: (percent/100) + 'em'}); |
|
45 | element.setStyle({fontSize: (percent/100) + 'em'}); | |
46 |
if( |
|
46 | if (Prototype.Browser.WebKit) window.scrollBy(0,0); | |
47 | return element; |
|
47 | return element; | |
48 | } |
|
48 | }; | |
49 |
|
||||
50 | Element.getOpacity = function(element){ |
|
|||
51 | element = $(element); |
|
|||
52 | var opacity; |
|
|||
53 | if (opacity = element.getStyle('opacity')) |
|
|||
54 | return parseFloat(opacity); |
|
|||
55 | if (opacity = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/)) |
|
|||
56 | if(opacity[1]) return parseFloat(opacity[1]) / 100; |
|
|||
57 | return 1.0; |
|
|||
58 | } |
|
|||
59 |
|
49 | |||
60 |
Element. |
|
50 | Element.getInlineOpacity = function(element){ | |
61 | element= $(element); |
|
|||
62 | if (value == 1){ |
|
|||
63 | element.setStyle({ opacity: |
|
|||
64 | (/Gecko/.test(navigator.userAgent) && !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ? |
|
|||
65 | 0.999999 : 1.0 }); |
|
|||
66 | if(/MSIE/.test(navigator.userAgent) && !window.opera) |
|
|||
67 | element.setStyle({filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'')}); |
|
|||
68 | } else { |
|
|||
69 | if(value < 0.00001) value = 0; |
|
|||
70 | element.setStyle({opacity: value}); |
|
|||
71 | if(/MSIE/.test(navigator.userAgent) && !window.opera) |
|
|||
72 | element.setStyle( |
|
|||
73 | { filter: element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'') + |
|
|||
74 | 'alpha(opacity='+value*100+')' }); |
|
|||
75 | } |
|
|||
76 | return element; |
|
|||
77 | } |
|
|||
78 |
|
||||
79 | Element.getInlineOpacity = function(element){ |
|
|||
80 | return $(element).style.opacity || ''; |
|
51 | return $(element).style.opacity || ''; | |
81 | } |
|
52 | }; | |
82 |
|
53 | |||
83 | Element.forceRerendering = function(element) { |
|
54 | Element.forceRerendering = function(element) { | |
84 | try { |
|
55 | try { | |
@@ -91,31 +62,63 Element.forceRerendering = function(element) { | |||||
91 |
|
62 | |||
92 | /*--------------------------------------------------------------------------*/ |
|
63 | /*--------------------------------------------------------------------------*/ | |
93 |
|
64 | |||
94 | Array.prototype.call = function() { |
|
|||
95 | var args = arguments; |
|
|||
96 | this.each(function(f){ f.apply(this, args) }); |
|
|||
97 | } |
|
|||
98 |
|
||||
99 | /*--------------------------------------------------------------------------*/ |
|
|||
100 |
|
||||
101 | var Effect = { |
|
65 | var Effect = { | |
102 | _elementDoesNotExistError: { |
|
66 | _elementDoesNotExistError: { | |
103 | name: 'ElementDoesNotExistError', |
|
67 | name: 'ElementDoesNotExistError', | |
104 | message: 'The specified DOM element does not exist, but is required for this effect to operate' |
|
68 | message: 'The specified DOM element does not exist, but is required for this effect to operate' | |
105 | }, |
|
69 | }, | |
|
70 | Transitions: { | |||
|
71 | linear: Prototype.K, | |||
|
72 | sinoidal: function(pos) { | |||
|
73 | return (-Math.cos(pos*Math.PI)/2) + 0.5; | |||
|
74 | }, | |||
|
75 | reverse: function(pos) { | |||
|
76 | return 1-pos; | |||
|
77 | }, | |||
|
78 | flicker: function(pos) { | |||
|
79 | var pos = ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4; | |||
|
80 | return pos > 1 ? 1 : pos; | |||
|
81 | }, | |||
|
82 | wobble: function(pos) { | |||
|
83 | return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5; | |||
|
84 | }, | |||
|
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 | ); | |||
|
92 | }, | |||
|
93 | spring: function(pos) { | |||
|
94 | return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6)); | |||
|
95 | }, | |||
|
96 | none: function(pos) { | |||
|
97 | return 0; | |||
|
98 | }, | |||
|
99 | full: function(pos) { | |||
|
100 | return 1; | |||
|
101 | } | |||
|
102 | }, | |||
|
103 | DefaultOptions: { | |||
|
104 | duration: 1.0, // seconds | |||
|
105 | fps: 100, // 100= assume 66fps max. | |||
|
106 | sync: false, // true for combining | |||
|
107 | from: 0.0, | |||
|
108 | to: 1.0, | |||
|
109 | delay: 0.0, | |||
|
110 | queue: 'parallel' | |||
|
111 | }, | |||
106 | tagifyText: function(element) { |
|
112 | tagifyText: function(element) { | |
107 | if(typeof Builder == 'undefined') |
|
|||
108 | throw("Effect.tagifyText requires including script.aculo.us' builder.js library"); |
|
|||
109 |
|
||||
110 | var tagifyStyle = 'position:relative'; |
|
113 | var tagifyStyle = 'position:relative'; | |
111 | if(/MSIE/.test(navigator.userAgent) && !window.opera) tagifyStyle += ';zoom:1'; |
|
114 | if (Prototype.Browser.IE) tagifyStyle += ';zoom:1'; | |
112 |
|
115 | |||
113 | element = $(element); |
|
116 | element = $(element); | |
114 | $A(element.childNodes).each( function(child) { |
|
117 | $A(element.childNodes).each( function(child) { | |
115 | if(child.nodeType==3) { |
|
118 | if (child.nodeType==3) { | |
116 | child.nodeValue.toArray().each( function(character) { |
|
119 | child.nodeValue.toArray().each( function(character) { | |
117 | element.insertBefore( |
|
120 | element.insertBefore( | |
118 |
|
|
121 | new Element('span', {style: tagifyStyle}).update( | |
119 | character == ' ' ? String.fromCharCode(160) : character), |
|
122 | character == ' ' ? String.fromCharCode(160) : character), | |
120 | child); |
|
123 | child); | |
121 | }); |
|
124 | }); | |
@@ -125,8 +128,8 var Effect = { | |||||
125 | }, |
|
128 | }, | |
126 | multiple: function(element, effect) { |
|
129 | multiple: function(element, effect) { | |
127 | var elements; |
|
130 | var elements; | |
128 | if(((typeof element == 'object') || |
|
131 | if (((typeof element == 'object') || | |
129 | (typeof element == 'function')) && |
|
132 | Object.isFunction(element)) && | |
130 | (element.length)) |
|
133 | (element.length)) | |
131 | elements = element; |
|
134 | elements = element; | |
132 | else |
|
135 | else | |
@@ -135,7 +138,7 var Effect = { | |||||
135 | var options = Object.extend({ |
|
138 | var options = Object.extend({ | |
136 | speed: 0.1, |
|
139 | speed: 0.1, | |
137 | delay: 0.0 |
|
140 | delay: 0.0 | |
138 | }, arguments[2] || {}); |
|
141 | }, arguments[2] || { }); | |
139 | var masterDelay = options.delay; |
|
142 | var masterDelay = options.delay; | |
140 |
|
143 | |||
141 | $A(elements).each( function(element, index) { |
|
144 | $A(elements).each( function(element, index) { | |
@@ -152,53 +155,20 var Effect = { | |||||
152 | effect = (effect || 'appear').toLowerCase(); |
|
155 | effect = (effect || 'appear').toLowerCase(); | |
153 | var options = Object.extend({ |
|
156 | var options = Object.extend({ | |
154 | queue: { position:'end', scope:(element.id || 'global'), limit: 1 } |
|
157 | queue: { position:'end', scope:(element.id || 'global'), limit: 1 } | |
155 | }, arguments[2] || {}); |
|
158 | }, arguments[2] || { }); | |
156 | Effect[element.visible() ? |
|
159 | Effect[element.visible() ? | |
157 | Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options); |
|
160 | Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options); | |
158 | } |
|
161 | } | |
159 | }; |
|
162 | }; | |
160 |
|
163 | |||
161 | var Effect2 = Effect; // deprecated |
|
164 | Effect.DefaultOptions.transition = Effect.Transitions.sinoidal; | |
162 |
|
||||
163 | /* ------------- transitions ------------- */ |
|
|||
164 |
|
||||
165 | Effect.Transitions = { |
|
|||
166 | linear: Prototype.K, |
|
|||
167 | sinoidal: function(pos) { |
|
|||
168 | return (-Math.cos(pos*Math.PI)/2) + 0.5; |
|
|||
169 | }, |
|
|||
170 | reverse: function(pos) { |
|
|||
171 | return 1-pos; |
|
|||
172 | }, |
|
|||
173 | flicker: function(pos) { |
|
|||
174 | return ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4; |
|
|||
175 | }, |
|
|||
176 | wobble: function(pos) { |
|
|||
177 | return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5; |
|
|||
178 | }, |
|
|||
179 | pulse: function(pos, pulses) { |
|
|||
180 | pulses = pulses || 5; |
|
|||
181 | return ( |
|
|||
182 | Math.round((pos % (1/pulses)) * pulses) == 0 ? |
|
|||
183 | ((pos * pulses * 2) - Math.floor(pos * pulses * 2)) : |
|
|||
184 | 1 - ((pos * pulses * 2) - Math.floor(pos * pulses * 2)) |
|
|||
185 | ); |
|
|||
186 | }, |
|
|||
187 | none: function(pos) { |
|
|||
188 | return 0; |
|
|||
189 | }, |
|
|||
190 | full: function(pos) { |
|
|||
191 | return 1; |
|
|||
192 | } |
|
|||
193 | }; |
|
|||
194 |
|
165 | |||
195 | /* ------------- core effects ------------- */ |
|
166 | /* ------------- core effects ------------- */ | |
196 |
|
167 | |||
197 |
Effect.ScopedQueue = Class.create( |
|
168 | Effect.ScopedQueue = Class.create(Enumerable, { | |
198 | Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), { |
|
|||
199 | initialize: function() { |
|
169 | initialize: function() { | |
200 | this.effects = []; |
|
170 | this.effects = []; | |
201 | this.interval = null; |
|
171 | this.interval = null; | |
202 | }, |
|
172 | }, | |
203 | _each: function(iterator) { |
|
173 | _each: function(iterator) { | |
204 | this.effects._each(iterator); |
|
174 | this.effects._each(iterator); | |
@@ -206,7 +176,7 Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), { | |||||
206 | add: function(effect) { |
|
176 | add: function(effect) { | |
207 | var timestamp = new Date().getTime(); |
|
177 | var timestamp = new Date().getTime(); | |
208 |
|
178 | |||
209 |
var position = ( |
|
179 | var position = Object.isString(effect.options.queue) ? | |
210 | effect.options.queue : effect.options.queue.position; |
|
180 | effect.options.queue : effect.options.queue.position; | |
211 |
|
181 | |||
212 | switch(position) { |
|
182 | switch(position) { | |
@@ -229,115 +199,111 Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), { | |||||
229 | effect.startOn += timestamp; |
|
199 | effect.startOn += timestamp; | |
230 | effect.finishOn += timestamp; |
|
200 | effect.finishOn += timestamp; | |
231 |
|
201 | |||
232 | if(!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit)) |
|
202 | if (!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit)) | |
233 | this.effects.push(effect); |
|
203 | this.effects.push(effect); | |
234 |
|
204 | |||
235 |
if(!this.interval) |
|
205 | if (!this.interval) | |
236 |
this.interval = setInterval(this.loop.bind(this), |
|
206 | this.interval = setInterval(this.loop.bind(this), 15); | |
237 | }, |
|
207 | }, | |
238 | remove: function(effect) { |
|
208 | remove: function(effect) { | |
239 | this.effects = this.effects.reject(function(e) { return e==effect }); |
|
209 | this.effects = this.effects.reject(function(e) { return e==effect }); | |
240 | if(this.effects.length == 0) { |
|
210 | if (this.effects.length == 0) { | |
241 | clearInterval(this.interval); |
|
211 | clearInterval(this.interval); | |
242 | this.interval = null; |
|
212 | this.interval = null; | |
243 | } |
|
213 | } | |
244 | }, |
|
214 | }, | |
245 | loop: function() { |
|
215 | loop: function() { | |
246 | var timePos = new Date().getTime(); |
|
216 | var timePos = new Date().getTime(); | |
247 | this.effects.invoke('loop', timePos); |
|
217 | for(var i=0, len=this.effects.length;i<len;i++) | |
|
218 | this.effects[i] && this.effects[i].loop(timePos); | |||
248 | } |
|
219 | } | |
249 | }); |
|
220 | }); | |
250 |
|
221 | |||
251 | Effect.Queues = { |
|
222 | Effect.Queues = { | |
252 | instances: $H(), |
|
223 | instances: $H(), | |
253 | get: function(queueName) { |
|
224 | get: function(queueName) { | |
254 |
if( |
|
225 | if (!Object.isString(queueName)) return queueName; | |
255 |
|
226 | |||
256 |
|
|
227 | return this.instances.get(queueName) || | |
257 |
this.instances |
|
228 | this.instances.set(queueName, new Effect.ScopedQueue()); | |
258 |
|
||||
259 | return this.instances[queueName]; |
|
|||
260 | } |
|
229 | } | |
261 | } |
|
230 | }; | |
262 | Effect.Queue = Effect.Queues.get('global'); |
|
231 | Effect.Queue = Effect.Queues.get('global'); | |
263 |
|
232 | |||
264 | Effect.DefaultOptions = { |
|
233 | Effect.Base = Class.create({ | |
265 | transition: Effect.Transitions.sinoidal, |
|
|||
266 | duration: 1.0, // seconds |
|
|||
267 | fps: 25.0, // max. 25fps due to Effect.Queue implementation |
|
|||
268 | sync: false, // true for combining |
|
|||
269 | from: 0.0, |
|
|||
270 | to: 1.0, |
|
|||
271 | delay: 0.0, |
|
|||
272 | queue: 'parallel' |
|
|||
273 | } |
|
|||
274 |
|
||||
275 | Effect.Base = function() {}; |
|
|||
276 | Effect.Base.prototype = { |
|
|||
277 | position: null, |
|
234 | position: null, | |
278 | start: function(options) { |
|
235 | start: function(options) { | |
279 | this.options = Object.extend(Object.extend({},Effect.DefaultOptions), options || {}); |
|
236 | function codeForEvent(options,eventName){ | |
|
237 | return ( | |||
|
238 | (options[eventName+'Internal'] ? 'this.options.'+eventName+'Internal(this);' : '') + | |||
|
239 | (options[eventName] ? 'this.options.'+eventName+'(this);' : '') | |||
|
240 | ); | |||
|
241 | } | |||
|
242 | if (options && options.transition === false) options.transition = Effect.Transitions.linear; | |||
|
243 | this.options = Object.extend(Object.extend({ },Effect.DefaultOptions), options || { }); | |||
280 | this.currentFrame = 0; |
|
244 | this.currentFrame = 0; | |
281 | this.state = 'idle'; |
|
245 | this.state = 'idle'; | |
282 | this.startOn = this.options.delay*1000; |
|
246 | this.startOn = this.options.delay*1000; | |
283 |
this.finishOn = this.startOn |
|
247 | this.finishOn = this.startOn+(this.options.duration*1000); | |
|
248 | this.fromToDelta = this.options.to-this.options.from; | |||
|
249 | this.totalTime = this.finishOn-this.startOn; | |||
|
250 | this.totalFrames = this.options.fps*this.options.duration; | |||
|
251 | ||||
|
252 | eval('this.render = function(pos){ '+ | |||
|
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 | '}}'); | |||
|
264 | ||||
284 | this.event('beforeStart'); |
|
265 | this.event('beforeStart'); | |
285 | if(!this.options.sync) |
|
266 | if (!this.options.sync) | |
286 |
Effect.Queues.get( |
|
267 | Effect.Queues.get(Object.isString(this.options.queue) ? | |
287 | 'global' : this.options.queue.scope).add(this); |
|
268 | 'global' : this.options.queue.scope).add(this); | |
288 | }, |
|
269 | }, | |
289 | loop: function(timePos) { |
|
270 | loop: function(timePos) { | |
290 | if(timePos >= this.startOn) { |
|
271 | if (timePos >= this.startOn) { | |
291 | if(timePos >= this.finishOn) { |
|
272 | if (timePos >= this.finishOn) { | |
292 | this.render(1.0); |
|
273 | this.render(1.0); | |
293 | this.cancel(); |
|
274 | this.cancel(); | |
294 | this.event('beforeFinish'); |
|
275 | this.event('beforeFinish'); | |
295 | if(this.finish) this.finish(); |
|
276 | if (this.finish) this.finish(); | |
296 | this.event('afterFinish'); |
|
277 | this.event('afterFinish'); | |
297 | return; |
|
278 | return; | |
298 | } |
|
279 | } | |
299 |
var pos = (timePos - this.startOn) / |
|
280 | var pos = (timePos - this.startOn) / this.totalTime, | |
300 | var frame = Math.round(pos * this.options.fps * this.options.duration); |
|
281 | frame = (pos * this.totalFrames).round(); | |
301 | if(frame > this.currentFrame) { |
|
282 | if (frame > this.currentFrame) { | |
302 | this.render(pos); |
|
283 | this.render(pos); | |
303 | this.currentFrame = frame; |
|
284 | this.currentFrame = frame; | |
304 | } |
|
285 | } | |
305 | } |
|
286 | } | |
306 | }, |
|
287 | }, | |
307 | render: function(pos) { |
|
|||
308 | if(this.state == 'idle') { |
|
|||
309 | this.state = 'running'; |
|
|||
310 | this.event('beforeSetup'); |
|
|||
311 | if(this.setup) this.setup(); |
|
|||
312 | this.event('afterSetup'); |
|
|||
313 | } |
|
|||
314 | if(this.state == 'running') { |
|
|||
315 | if(this.options.transition) pos = this.options.transition(pos); |
|
|||
316 | pos *= (this.options.to-this.options.from); |
|
|||
317 | pos += this.options.from; |
|
|||
318 | this.position = pos; |
|
|||
319 | this.event('beforeUpdate'); |
|
|||
320 | if(this.update) this.update(pos); |
|
|||
321 | this.event('afterUpdate'); |
|
|||
322 | } |
|
|||
323 | }, |
|
|||
324 | cancel: function() { |
|
288 | cancel: function() { | |
325 | if(!this.options.sync) |
|
289 | if (!this.options.sync) | |
326 |
Effect.Queues.get( |
|
290 | Effect.Queues.get(Object.isString(this.options.queue) ? | |
327 | 'global' : this.options.queue.scope).remove(this); |
|
291 | 'global' : this.options.queue.scope).remove(this); | |
328 | this.state = 'finished'; |
|
292 | this.state = 'finished'; | |
329 | }, |
|
293 | }, | |
330 | event: function(eventName) { |
|
294 | event: function(eventName) { | |
331 | if(this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this); |
|
295 | if (this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this); | |
332 | if(this.options[eventName]) this.options[eventName](this); |
|
296 | if (this.options[eventName]) this.options[eventName](this); | |
333 | }, |
|
297 | }, | |
334 | inspect: function() { |
|
298 | inspect: function() { | |
335 | return '#<Effect:' + $H(this).inspect() + ',options:' + $H(this.options).inspect() + '>'; |
|
299 | var data = $H(); | |
|
300 | for(property in this) | |||
|
301 | if (!Object.isFunction(this[property])) data.set(property, this[property]); | |||
|
302 | return '#<Effect:' + data.inspect() + ',options:' + $H(this.options).inspect() + '>'; | |||
336 | } |
|
303 | } | |
337 | } |
|
304 | }); | |
338 |
|
305 | |||
339 |
Effect.Parallel = Class.create( |
|
306 | Effect.Parallel = Class.create(Effect.Base, { | |
340 | Object.extend(Object.extend(Effect.Parallel.prototype, Effect.Base.prototype), { |
|
|||
341 | initialize: function(effects) { |
|
307 | initialize: function(effects) { | |
342 | this.effects = effects || []; |
|
308 | this.effects = effects || []; | |
343 | this.start(arguments[1]); |
|
309 | this.start(arguments[1]); | |
@@ -350,35 +316,45 Object.extend(Object.extend(Effect.Parallel.prototype, Effect.Base.prototype), { | |||||
350 | effect.render(1.0); |
|
316 | effect.render(1.0); | |
351 | effect.cancel(); |
|
317 | effect.cancel(); | |
352 | effect.event('beforeFinish'); |
|
318 | effect.event('beforeFinish'); | |
353 | if(effect.finish) effect.finish(position); |
|
319 | if (effect.finish) effect.finish(position); | |
354 | effect.event('afterFinish'); |
|
320 | effect.event('afterFinish'); | |
355 | }); |
|
321 | }); | |
356 | } |
|
322 | } | |
357 | }); |
|
323 | }); | |
358 |
|
324 | |||
359 |
Effect. |
|
325 | Effect.Tween = Class.create(Effect.Base, { | |
360 | Object.extend(Object.extend(Effect.Event.prototype, Effect.Base.prototype), { |
|
326 | initialize: function(object, from, to) { | |
|
327 | object = Object.isString(object) ? $(object) : object; | |||
|
328 | var args = $A(arguments), method = args.last(), | |||
|
329 | options = args.length == 5 ? args[3] : null; | |||
|
330 | this.method = Object.isFunction(method) ? method.bind(object) : | |||
|
331 | Object.isFunction(object[method]) ? object[method].bind(object) : | |||
|
332 | function(value) { object[method] = value }; | |||
|
333 | this.start(Object.extend({ from: from, to: to }, options || { })); | |||
|
334 | }, | |||
|
335 | update: function(position) { | |||
|
336 | this.method(position); | |||
|
337 | } | |||
|
338 | }); | |||
|
339 | ||||
|
340 | Effect.Event = Class.create(Effect.Base, { | |||
361 | initialize: function() { |
|
341 | initialize: function() { | |
362 | var options = Object.extend({ |
|
342 | this.start(Object.extend({ duration: 0 }, arguments[0] || { })); | |
363 | duration: 0 |
|
|||
364 | }, arguments[0] || {}); |
|
|||
365 | this.start(options); |
|
|||
366 | }, |
|
343 | }, | |
367 | update: Prototype.emptyFunction |
|
344 | update: Prototype.emptyFunction | |
368 | }); |
|
345 | }); | |
369 |
|
346 | |||
370 |
Effect.Opacity = Class.create( |
|
347 | Effect.Opacity = Class.create(Effect.Base, { | |
371 | Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), { |
|
|||
372 | initialize: function(element) { |
|
348 | initialize: function(element) { | |
373 | this.element = $(element); |
|
349 | this.element = $(element); | |
374 | if(!this.element) throw(Effect._elementDoesNotExistError); |
|
350 | if (!this.element) throw(Effect._elementDoesNotExistError); | |
375 | // make this work on IE on elements without 'layout' |
|
351 | // make this work on IE on elements without 'layout' | |
376 |
if( |
|
352 | if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout)) | |
377 | this.element.setStyle({zoom: 1}); |
|
353 | this.element.setStyle({zoom: 1}); | |
378 | var options = Object.extend({ |
|
354 | var options = Object.extend({ | |
379 | from: this.element.getOpacity() || 0.0, |
|
355 | from: this.element.getOpacity() || 0.0, | |
380 | to: 1.0 |
|
356 | to: 1.0 | |
381 | }, arguments[1] || {}); |
|
357 | }, arguments[1] || { }); | |
382 | this.start(options); |
|
358 | this.start(options); | |
383 | }, |
|
359 | }, | |
384 | update: function(position) { |
|
360 | update: function(position) { | |
@@ -386,36 +362,30 Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), { | |||||
386 | } |
|
362 | } | |
387 | }); |
|
363 | }); | |
388 |
|
364 | |||
389 |
Effect.Move = Class.create( |
|
365 | Effect.Move = Class.create(Effect.Base, { | |
390 | Object.extend(Object.extend(Effect.Move.prototype, Effect.Base.prototype), { |
|
|||
391 | initialize: function(element) { |
|
366 | initialize: function(element) { | |
392 | this.element = $(element); |
|
367 | this.element = $(element); | |
393 | if(!this.element) throw(Effect._elementDoesNotExistError); |
|
368 | if (!this.element) throw(Effect._elementDoesNotExistError); | |
394 | var options = Object.extend({ |
|
369 | var options = Object.extend({ | |
395 | x: 0, |
|
370 | x: 0, | |
396 | y: 0, |
|
371 | y: 0, | |
397 | mode: 'relative' |
|
372 | mode: 'relative' | |
398 | }, arguments[1] || {}); |
|
373 | }, arguments[1] || { }); | |
399 | this.start(options); |
|
374 | this.start(options); | |
400 | }, |
|
375 | }, | |
401 | setup: function() { |
|
376 | setup: function() { | |
402 | // Bug in Opera: Opera returns the "real" position of a static element or |
|
|||
403 | // relative element that does not have top/left explicitly set. |
|
|||
404 | // ==> Always set top and left for position relative elements in your stylesheets |
|
|||
405 | // (to 0 if you do not need them) |
|
|||
406 |
|
|
377 | this.element.makePositioned(); | |
407 | this.originalLeft = parseFloat(this.element.getStyle('left') || '0'); |
|
378 | this.originalLeft = parseFloat(this.element.getStyle('left') || '0'); | |
408 | this.originalTop = parseFloat(this.element.getStyle('top') || '0'); |
|
379 | this.originalTop = parseFloat(this.element.getStyle('top') || '0'); | |
409 | if(this.options.mode == 'absolute') { |
|
380 | if (this.options.mode == 'absolute') { | |
410 | // absolute movement, so we need to calc deltaX and deltaY |
|
|||
411 |
|
|
381 | this.options.x = this.options.x - this.originalLeft; | |
412 | this.options.y = this.options.y - this.originalTop; |
|
382 | this.options.y = this.options.y - this.originalTop; | |
413 | } |
|
383 | } | |
414 | }, |
|
384 | }, | |
415 | update: function(position) { |
|
385 | update: function(position) { | |
416 | this.element.setStyle({ |
|
386 | this.element.setStyle({ | |
417 |
left: |
|
387 | left: (this.options.x * position + this.originalLeft).round() + 'px', | |
418 |
top: |
|
388 | top: (this.options.y * position + this.originalTop).round() + 'px' | |
419 | }); |
|
389 | }); | |
420 | } |
|
390 | } | |
421 | }); |
|
391 | }); | |
@@ -423,30 +393,29 Object.extend(Object.extend(Effect.Move.prototype, Effect.Base.prototype), { | |||||
423 | // for backwards compatibility |
|
393 | // for backwards compatibility | |
424 | Effect.MoveBy = function(element, toTop, toLeft) { |
|
394 | Effect.MoveBy = function(element, toTop, toLeft) { | |
425 | return new Effect.Move(element, |
|
395 | return new Effect.Move(element, | |
426 | Object.extend({ x: toLeft, y: toTop }, arguments[3] || {})); |
|
396 | Object.extend({ x: toLeft, y: toTop }, arguments[3] || { })); | |
427 | }; |
|
397 | }; | |
428 |
|
398 | |||
429 |
Effect.Scale = Class.create( |
|
399 | Effect.Scale = Class.create(Effect.Base, { | |
430 | Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), { |
|
|||
431 | initialize: function(element, percent) { |
|
400 | initialize: function(element, percent) { | |
432 | this.element = $(element); |
|
401 | this.element = $(element); | |
433 | if(!this.element) throw(Effect._elementDoesNotExistError); |
|
402 | if (!this.element) throw(Effect._elementDoesNotExistError); | |
434 | var options = Object.extend({ |
|
403 | var options = Object.extend({ | |
435 | scaleX: true, |
|
404 | scaleX: true, | |
436 | scaleY: true, |
|
405 | scaleY: true, | |
437 | scaleContent: true, |
|
406 | scaleContent: true, | |
438 | scaleFromCenter: false, |
|
407 | scaleFromCenter: false, | |
439 | scaleMode: 'box', // 'box' or 'contents' or {} with provided values |
|
408 | scaleMode: 'box', // 'box' or 'contents' or { } with provided values | |
440 | scaleFrom: 100.0, |
|
409 | scaleFrom: 100.0, | |
441 | scaleTo: percent |
|
410 | scaleTo: percent | |
442 | }, arguments[2] || {}); |
|
411 | }, arguments[2] || { }); | |
443 | this.start(options); |
|
412 | this.start(options); | |
444 | }, |
|
413 | }, | |
445 | setup: function() { |
|
414 | setup: function() { | |
446 | this.restoreAfterFinish = this.options.restoreAfterFinish || false; |
|
415 | this.restoreAfterFinish = this.options.restoreAfterFinish || false; | |
447 | this.elementPositioning = this.element.getStyle('position'); |
|
416 | this.elementPositioning = this.element.getStyle('position'); | |
448 |
|
417 | |||
449 | this.originalStyle = {}; |
|
418 | this.originalStyle = { }; | |
450 | ['top','left','width','height','fontSize'].each( function(k) { |
|
419 | ['top','left','width','height','fontSize'].each( function(k) { | |
451 | this.originalStyle[k] = this.element.style[k]; |
|
420 | this.originalStyle[k] = this.element.style[k]; | |
452 | }.bind(this)); |
|
421 | }.bind(this)); | |
@@ -456,7 +425,7 Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), { | |||||
456 |
|
425 | |||
457 | var fontSize = this.element.getStyle('font-size') || '100%'; |
|
426 | var fontSize = this.element.getStyle('font-size') || '100%'; | |
458 | ['em','px','%','pt'].each( function(fontSizeType) { |
|
427 | ['em','px','%','pt'].each( function(fontSizeType) { | |
459 | if(fontSize.indexOf(fontSizeType)>0) { |
|
428 | if (fontSize.indexOf(fontSizeType)>0) { | |
460 | this.fontSize = parseFloat(fontSize); |
|
429 | this.fontSize = parseFloat(fontSize); | |
461 | this.fontSizeType = fontSizeType; |
|
430 | this.fontSizeType = fontSizeType; | |
462 | } |
|
431 | } | |
@@ -465,60 +434,61 Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), { | |||||
465 | this.factor = (this.options.scaleTo - this.options.scaleFrom)/100; |
|
434 | this.factor = (this.options.scaleTo - this.options.scaleFrom)/100; | |
466 |
|
435 | |||
467 | this.dims = null; |
|
436 | this.dims = null; | |
468 | if(this.options.scaleMode=='box') |
|
437 | if (this.options.scaleMode=='box') | |
469 | this.dims = [this.element.offsetHeight, this.element.offsetWidth]; |
|
438 | this.dims = [this.element.offsetHeight, this.element.offsetWidth]; | |
470 | if(/^content/.test(this.options.scaleMode)) |
|
439 | if (/^content/.test(this.options.scaleMode)) | |
471 | this.dims = [this.element.scrollHeight, this.element.scrollWidth]; |
|
440 | this.dims = [this.element.scrollHeight, this.element.scrollWidth]; | |
472 | if(!this.dims) |
|
441 | if (!this.dims) | |
473 | this.dims = [this.options.scaleMode.originalHeight, |
|
442 | this.dims = [this.options.scaleMode.originalHeight, | |
474 | this.options.scaleMode.originalWidth]; |
|
443 | this.options.scaleMode.originalWidth]; | |
475 | }, |
|
444 | }, | |
476 | update: function(position) { |
|
445 | update: function(position) { | |
477 | var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position); |
|
446 | var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position); | |
478 | if(this.options.scaleContent && this.fontSize) |
|
447 | if (this.options.scaleContent && this.fontSize) | |
479 | this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType }); |
|
448 | this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType }); | |
480 | this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale); |
|
449 | this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale); | |
481 | }, |
|
450 | }, | |
482 | finish: function(position) { |
|
451 | finish: function(position) { | |
483 | if(this.restoreAfterFinish) this.element.setStyle(this.originalStyle); |
|
452 | if (this.restoreAfterFinish) this.element.setStyle(this.originalStyle); | |
484 | }, |
|
453 | }, | |
485 | setDimensions: function(height, width) { |
|
454 | setDimensions: function(height, width) { | |
486 | var d = {}; |
|
455 | var d = { }; | |
487 |
if(this.options.scaleX) d.width = |
|
456 | if (this.options.scaleX) d.width = width.round() + 'px'; | |
488 |
if(this.options.scaleY) d.height = |
|
457 | if (this.options.scaleY) d.height = height.round() + 'px'; | |
489 | if(this.options.scaleFromCenter) { |
|
458 | if (this.options.scaleFromCenter) { | |
490 | var topd = (height - this.dims[0])/2; |
|
459 | var topd = (height - this.dims[0])/2; | |
491 | var leftd = (width - this.dims[1])/2; |
|
460 | var leftd = (width - this.dims[1])/2; | |
492 | if(this.elementPositioning == 'absolute') { |
|
461 | if (this.elementPositioning == 'absolute') { | |
493 | if(this.options.scaleY) d.top = this.originalTop-topd + 'px'; |
|
462 | if (this.options.scaleY) d.top = this.originalTop-topd + 'px'; | |
494 | if(this.options.scaleX) d.left = this.originalLeft-leftd + 'px'; |
|
463 | if (this.options.scaleX) d.left = this.originalLeft-leftd + 'px'; | |
495 | } else { |
|
464 | } else { | |
496 | if(this.options.scaleY) d.top = -topd + 'px'; |
|
465 | if (this.options.scaleY) d.top = -topd + 'px'; | |
497 | if(this.options.scaleX) d.left = -leftd + 'px'; |
|
466 | if (this.options.scaleX) d.left = -leftd + 'px'; | |
498 | } |
|
467 | } | |
499 | } |
|
468 | } | |
500 | this.element.setStyle(d); |
|
469 | this.element.setStyle(d); | |
501 | } |
|
470 | } | |
502 | }); |
|
471 | }); | |
503 |
|
472 | |||
504 |
Effect.Highlight = Class.create( |
|
473 | Effect.Highlight = Class.create(Effect.Base, { | |
505 | Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype), { |
|
|||
506 | initialize: function(element) { |
|
474 | initialize: function(element) { | |
507 | this.element = $(element); |
|
475 | this.element = $(element); | |
508 | if(!this.element) throw(Effect._elementDoesNotExistError); |
|
476 | if (!this.element) throw(Effect._elementDoesNotExistError); | |
509 | var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || {}); |
|
477 | var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || { }); | |
510 | this.start(options); |
|
478 | this.start(options); | |
511 | }, |
|
479 | }, | |
512 | setup: function() { |
|
480 | setup: function() { | |
513 | // Prevent executing on elements not in the layout flow |
|
481 | // Prevent executing on elements not in the layout flow | |
514 | if(this.element.getStyle('display')=='none') { this.cancel(); return; } |
|
482 | if (this.element.getStyle('display')=='none') { this.cancel(); return; } | |
515 | // Disable background image during the effect |
|
483 | // Disable background image during the effect | |
516 | this.oldStyle = { |
|
484 | this.oldStyle = { }; | |
517 | backgroundImage: this.element.getStyle('background-image') }; |
|
485 | if (!this.options.keepBackgroundImage) { | |
518 | this.element.setStyle({backgroundImage: 'none'}); |
|
486 | this.oldStyle.backgroundImage = this.element.getStyle('background-image'); | |
519 | if(!this.options.endcolor) |
|
487 | this.element.setStyle({backgroundImage: 'none'}); | |
|
488 | } | |||
|
489 | if (!this.options.endcolor) | |||
520 | this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff'); |
|
490 | this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff'); | |
521 | if(!this.options.restorecolor) |
|
491 | if (!this.options.restorecolor) | |
522 | this.options.restorecolor = this.element.getStyle('background-color'); |
|
492 | this.options.restorecolor = this.element.getStyle('background-color'); | |
523 | // init color calculations |
|
493 | // init color calculations | |
524 | this._base = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this)); |
|
494 | this._base = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this)); | |
@@ -526,7 +496,7 Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype), | |||||
526 | }, |
|
496 | }, | |
527 | update: function(position) { |
|
497 | update: function(position) { | |
528 | this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){ |
|
498 | this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){ | |
529 |
return m+( |
|
499 | return m+((this._base[i]+(this._delta[i]*position)).round().toColorPart()); }.bind(this)) }); | |
530 | }, |
|
500 | }, | |
531 | finish: function() { |
|
501 | finish: function() { | |
532 | this.element.setStyle(Object.extend(this.oldStyle, { |
|
502 | this.element.setStyle(Object.extend(this.oldStyle, { | |
@@ -535,30 +505,21 Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype), | |||||
535 | } |
|
505 | } | |
536 | }); |
|
506 | }); | |
537 |
|
507 | |||
538 |
Effect.ScrollTo = |
|
508 | Effect.ScrollTo = function(element) { | |
539 | Object.extend(Object.extend(Effect.ScrollTo.prototype, Effect.Base.prototype), { |
|
509 | var options = arguments[1] || { }, | |
540 | initialize: function(element) { |
|
510 | scrollOffsets = document.viewport.getScrollOffsets(), | |
541 | this.element = $(element); |
|
511 | elementOffsets = $(element).cumulativeOffset(), | |
542 | this.start(arguments[1] || {}); |
|
512 | max = (window.height || document.body.scrollHeight) - document.viewport.getHeight(); | |
543 | }, |
|
513 | ||
544 | setup: function() { |
|
514 | if (options.offset) elementOffsets[1] += options.offset; | |
545 | Position.prepare(); |
|
515 | ||
546 | var offsets = Position.cumulativeOffset(this.element); |
|
516 | return new Effect.Tween(null, | |
547 | if(this.options.offset) offsets[1] += this.options.offset; |
|
517 | scrollOffsets.top, | |
548 | var max = window.innerHeight ? |
|
518 | elementOffsets[1] > max ? max : elementOffsets[1], | |
549 | window.height - window.innerHeight : |
|
519 | options, | |
550 | document.body.scrollHeight - |
|
520 | function(p){ scrollTo(scrollOffsets.left, p.round()) } | |
551 | (document.documentElement.clientHeight ? |
|
521 | ); | |
552 | document.documentElement.clientHeight : document.body.clientHeight); |
|
522 | }; | |
553 | this.scrollStart = Position.deltaY; |
|
|||
554 | this.delta = (offsets[1] > max ? max : offsets[1]) - this.scrollStart; |
|
|||
555 | }, |
|
|||
556 | update: function(position) { |
|
|||
557 | Position.prepare(); |
|
|||
558 | window.scrollTo(Position.deltaX, |
|
|||
559 | this.scrollStart + (position*this.delta)); |
|
|||
560 | } |
|
|||
561 | }); |
|
|||
562 |
|
523 | |||
563 | /* ------------- combination effects ------------- */ |
|
524 | /* ------------- combination effects ------------- */ | |
564 |
|
525 | |||
@@ -566,14 +527,15 Effect.Fade = function(element) { | |||||
566 | element = $(element); |
|
527 | element = $(element); | |
567 | var oldOpacity = element.getInlineOpacity(); |
|
528 | var oldOpacity = element.getInlineOpacity(); | |
568 | var options = Object.extend({ |
|
529 | var options = Object.extend({ | |
569 | from: element.getOpacity() || 1.0, |
|
530 | from: element.getOpacity() || 1.0, | |
570 | to: 0.0, |
|
531 | to: 0.0, | |
571 | afterFinishInternal: function(effect) { |
|
532 | afterFinishInternal: function(effect) { | |
572 | if(effect.options.to!=0) return; |
|
533 | if (effect.options.to!=0) return; | |
573 | effect.element.hide().setStyle({opacity: oldOpacity}); |
|
534 | effect.element.hide().setStyle({opacity: oldOpacity}); | |
574 | }}, arguments[1] || {}); |
|
535 | } | |
|
536 | }, arguments[1] || { }); | |||
575 | return new Effect.Opacity(element,options); |
|
537 | return new Effect.Opacity(element,options); | |
576 | } |
|
538 | }; | |
577 |
|
539 | |||
578 | Effect.Appear = function(element) { |
|
540 | Effect.Appear = function(element) { | |
579 | element = $(element); |
|
541 | element = $(element); | |
@@ -586,9 +548,9 Effect.Appear = function(element) { | |||||
586 | }, |
|
548 | }, | |
587 | beforeSetup: function(effect) { |
|
549 | beforeSetup: function(effect) { | |
588 | effect.element.setOpacity(effect.options.from).show(); |
|
550 | effect.element.setOpacity(effect.options.from).show(); | |
589 | }}, arguments[1] || {}); |
|
551 | }}, arguments[1] || { }); | |
590 | return new Effect.Opacity(element,options); |
|
552 | return new Effect.Opacity(element,options); | |
591 | } |
|
553 | }; | |
592 |
|
554 | |||
593 | Effect.Puff = function(element) { |
|
555 | Effect.Puff = function(element) { | |
594 | element = $(element); |
|
556 | element = $(element); | |
@@ -610,9 +572,9 Effect.Puff = function(element) { | |||||
610 | }, |
|
572 | }, | |
611 | afterFinishInternal: function(effect) { |
|
573 | afterFinishInternal: function(effect) { | |
612 | effect.effects[0].element.hide().setStyle(oldStyle); } |
|
574 | effect.effects[0].element.hide().setStyle(oldStyle); } | |
613 | }, arguments[1] || {}) |
|
575 | }, arguments[1] || { }) | |
614 | ); |
|
576 | ); | |
615 | } |
|
577 | }; | |
616 |
|
578 | |||
617 | Effect.BlindUp = function(element) { |
|
579 | Effect.BlindUp = function(element) { | |
618 | element = $(element); |
|
580 | element = $(element); | |
@@ -624,9 +586,9 Effect.BlindUp = function(element) { | |||||
624 | afterFinishInternal: function(effect) { |
|
586 | afterFinishInternal: function(effect) { | |
625 | effect.element.hide().undoClipping(); |
|
587 | effect.element.hide().undoClipping(); | |
626 | } |
|
588 | } | |
627 | }, arguments[1] || {}) |
|
589 | }, arguments[1] || { }) | |
628 | ); |
|
590 | ); | |
629 | } |
|
591 | }; | |
630 |
|
592 | |||
631 | Effect.BlindDown = function(element) { |
|
593 | Effect.BlindDown = function(element) { | |
632 | element = $(element); |
|
594 | element = $(element); | |
@@ -643,8 +605,8 Effect.BlindDown = function(element) { | |||||
643 | afterFinishInternal: function(effect) { |
|
605 | afterFinishInternal: function(effect) { | |
644 | effect.element.undoClipping(); |
|
606 | effect.element.undoClipping(); | |
645 | } |
|
607 | } | |
646 | }, arguments[1] || {})); |
|
608 | }, arguments[1] || { })); | |
647 | } |
|
609 | }; | |
648 |
|
610 | |||
649 | Effect.SwitchOff = function(element) { |
|
611 | Effect.SwitchOff = function(element) { | |
650 | element = $(element); |
|
612 | element = $(element); | |
@@ -665,8 +627,8 Effect.SwitchOff = function(element) { | |||||
665 | } |
|
627 | } | |
666 | }) |
|
628 | }) | |
667 | } |
|
629 | } | |
668 | }, arguments[1] || {})); |
|
630 | }, arguments[1] || { })); | |
669 | } |
|
631 | }; | |
670 |
|
632 | |||
671 | Effect.DropOut = function(element) { |
|
633 | Effect.DropOut = function(element) { | |
672 | element = $(element); |
|
634 | element = $(element); | |
@@ -685,29 +647,35 Effect.DropOut = function(element) { | |||||
685 | afterFinishInternal: function(effect) { |
|
647 | afterFinishInternal: function(effect) { | |
686 | effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle); |
|
648 | effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle); | |
687 | } |
|
649 | } | |
688 | }, arguments[1] || {})); |
|
650 | }, arguments[1] || { })); | |
689 | } |
|
651 | }; | |
690 |
|
652 | |||
691 | Effect.Shake = function(element) { |
|
653 | Effect.Shake = function(element) { | |
692 | element = $(element); |
|
654 | element = $(element); | |
|
655 | var options = Object.extend({ | |||
|
656 | distance: 20, | |||
|
657 | duration: 0.5 | |||
|
658 | }, arguments[1] || {}); | |||
|
659 | var distance = parseFloat(options.distance); | |||
|
660 | var split = parseFloat(options.duration) / 10.0; | |||
693 | var oldStyle = { |
|
661 | var oldStyle = { | |
694 | top: element.getStyle('top'), |
|
662 | top: element.getStyle('top'), | |
695 | left: element.getStyle('left') }; |
|
663 | left: element.getStyle('left') }; | |
696 |
return new Effect.Move(element, |
|
664 | return new Effect.Move(element, | |
697 |
{ x: |
|
665 | { x: distance, y: 0, duration: split, afterFinishInternal: function(effect) { | |
698 | new Effect.Move(effect.element, |
|
666 | new Effect.Move(effect.element, | |
699 |
{ x: - |
|
667 | { x: -distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) { | |
700 | new Effect.Move(effect.element, |
|
668 | new Effect.Move(effect.element, | |
701 |
{ x: |
|
669 | { x: distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) { | |
702 | new Effect.Move(effect.element, |
|
670 | new Effect.Move(effect.element, | |
703 |
{ x: - |
|
671 | { x: -distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) { | |
704 | new Effect.Move(effect.element, |
|
672 | new Effect.Move(effect.element, | |
705 |
{ x: |
|
673 | { x: distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) { | |
706 | new Effect.Move(effect.element, |
|
674 | new Effect.Move(effect.element, | |
707 |
{ x: - |
|
675 | { x: -distance, y: 0, duration: split, afterFinishInternal: function(effect) { | |
708 | effect.element.undoPositioned().setStyle(oldStyle); |
|
676 | effect.element.undoPositioned().setStyle(oldStyle); | |
709 | }}) }}) }}) }}) }}) }}); |
|
677 | }}) }}) }}) }}) }}) }}); | |
710 | } |
|
678 | }; | |
711 |
|
679 | |||
712 | Effect.SlideDown = function(element) { |
|
680 | Effect.SlideDown = function(element) { | |
713 | element = $(element).cleanWhitespace(); |
|
681 | element = $(element).cleanWhitespace(); | |
@@ -723,7 +691,7 Effect.SlideDown = function(element) { | |||||
723 | afterSetup: function(effect) { |
|
691 | afterSetup: function(effect) { | |
724 | effect.element.makePositioned(); |
|
692 | effect.element.makePositioned(); | |
725 | effect.element.down().makePositioned(); |
|
693 | effect.element.down().makePositioned(); | |
726 | if(window.opera) effect.element.setStyle({top: ''}); |
|
694 | if (window.opera) effect.element.setStyle({top: ''}); | |
727 | effect.element.makeClipping().setStyle({height: '0px'}).show(); |
|
695 | effect.element.makeClipping().setStyle({height: '0px'}).show(); | |
728 | }, |
|
696 | }, | |
729 | afterUpdateInternal: function(effect) { |
|
697 | afterUpdateInternal: function(effect) { | |
@@ -733,23 +701,25 Effect.SlideDown = function(element) { | |||||
733 | afterFinishInternal: function(effect) { |
|
701 | afterFinishInternal: function(effect) { | |
734 | effect.element.undoClipping().undoPositioned(); |
|
702 | effect.element.undoClipping().undoPositioned(); | |
735 | effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); } |
|
703 | effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); } | |
736 | }, arguments[1] || {}) |
|
704 | }, arguments[1] || { }) | |
737 | ); |
|
705 | ); | |
738 | } |
|
706 | }; | |
739 |
|
707 | |||
740 | Effect.SlideUp = function(element) { |
|
708 | Effect.SlideUp = function(element) { | |
741 | element = $(element).cleanWhitespace(); |
|
709 | element = $(element).cleanWhitespace(); | |
742 | var oldInnerBottom = element.down().getStyle('bottom'); |
|
710 | var oldInnerBottom = element.down().getStyle('bottom'); | |
|
711 | var elementDimensions = element.getDimensions(); | |||
743 | return new Effect.Scale(element, window.opera ? 0 : 1, |
|
712 | return new Effect.Scale(element, window.opera ? 0 : 1, | |
744 | Object.extend({ scaleContent: false, |
|
713 | Object.extend({ scaleContent: false, | |
745 | scaleX: false, |
|
714 | scaleX: false, | |
746 | scaleMode: 'box', |
|
715 | scaleMode: 'box', | |
747 | scaleFrom: 100, |
|
716 | scaleFrom: 100, | |
|
717 | scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width}, | |||
748 | restoreAfterFinish: true, |
|
718 | restoreAfterFinish: true, | |
749 |
|
|
719 | afterSetup: function(effect) { | |
750 | effect.element.makePositioned(); |
|
720 | effect.element.makePositioned(); | |
751 | effect.element.down().makePositioned(); |
|
721 | effect.element.down().makePositioned(); | |
752 | if(window.opera) effect.element.setStyle({top: ''}); |
|
722 | if (window.opera) effect.element.setStyle({top: ''}); | |
753 | effect.element.makeClipping().show(); |
|
723 | effect.element.makeClipping().show(); | |
754 | }, |
|
724 | }, | |
755 | afterUpdateInternal: function(effect) { |
|
725 | afterUpdateInternal: function(effect) { | |
@@ -757,12 +727,12 Effect.SlideUp = function(element) { | |||||
757 | (effect.dims[0] - effect.element.clientHeight) + 'px' }); |
|
727 | (effect.dims[0] - effect.element.clientHeight) + 'px' }); | |
758 | }, |
|
728 | }, | |
759 | afterFinishInternal: function(effect) { |
|
729 | afterFinishInternal: function(effect) { | |
760 |
effect.element.hide().undoClipping().undoPositioned() |
|
730 | effect.element.hide().undoClipping().undoPositioned(); | |
761 | effect.element.down().undoPositioned(); |
|
731 | effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); | |
762 | } |
|
732 | } | |
763 | }, arguments[1] || {}) |
|
733 | }, arguments[1] || { }) | |
764 | ); |
|
734 | ); | |
765 | } |
|
735 | }; | |
766 |
|
736 | |||
767 |
|
|
737 | // Bug in opera makes the TD containing this element expand for a instance after finish | |
768 | Effect.Squish = function(element) { |
|
738 | Effect.Squish = function(element) { | |
@@ -775,7 +745,7 Effect.Squish = function(element) { | |||||
775 | effect.element.hide().undoClipping(); |
|
745 | effect.element.hide().undoClipping(); | |
776 | } |
|
746 | } | |
777 | }); |
|
747 | }); | |
778 | } |
|
748 | }; | |
779 |
|
749 | |||
780 | Effect.Grow = function(element) { |
|
750 | Effect.Grow = function(element) { | |
781 | element = $(element); |
|
751 | element = $(element); | |
@@ -784,7 +754,7 Effect.Grow = function(element) { | |||||
784 | moveTransition: Effect.Transitions.sinoidal, |
|
754 | moveTransition: Effect.Transitions.sinoidal, | |
785 | scaleTransition: Effect.Transitions.sinoidal, |
|
755 | scaleTransition: Effect.Transitions.sinoidal, | |
786 | opacityTransition: Effect.Transitions.full |
|
756 | opacityTransition: Effect.Transitions.full | |
787 | }, arguments[1] || {}); |
|
757 | }, arguments[1] || { }); | |
788 | var oldStyle = { |
|
758 | var oldStyle = { | |
789 | top: element.style.top, |
|
759 | top: element.style.top, | |
790 | left: element.style.left, |
|
760 | left: element.style.left, | |
@@ -849,7 +819,7 Effect.Grow = function(element) { | |||||
849 | ) |
|
819 | ) | |
850 | } |
|
820 | } | |
851 | }); |
|
821 | }); | |
852 | } |
|
822 | }; | |
853 |
|
823 | |||
854 | Effect.Shrink = function(element) { |
|
824 | Effect.Shrink = function(element) { | |
855 | element = $(element); |
|
825 | element = $(element); | |
@@ -858,7 +828,7 Effect.Shrink = function(element) { | |||||
858 | moveTransition: Effect.Transitions.sinoidal, |
|
828 | moveTransition: Effect.Transitions.sinoidal, | |
859 | scaleTransition: Effect.Transitions.sinoidal, |
|
829 | scaleTransition: Effect.Transitions.sinoidal, | |
860 | opacityTransition: Effect.Transitions.none |
|
830 | opacityTransition: Effect.Transitions.none | |
861 | }, arguments[1] || {}); |
|
831 | }, arguments[1] || { }); | |
862 | var oldStyle = { |
|
832 | var oldStyle = { | |
863 | top: element.style.top, |
|
833 | top: element.style.top, | |
864 | left: element.style.left, |
|
834 | left: element.style.left, | |
@@ -903,11 +873,11 Effect.Shrink = function(element) { | |||||
903 | effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); } |
|
873 | effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); } | |
904 | }, options) |
|
874 | }, options) | |
905 | ); |
|
875 | ); | |
906 | } |
|
876 | }; | |
907 |
|
877 | |||
908 | Effect.Pulsate = function(element) { |
|
878 | Effect.Pulsate = function(element) { | |
909 | element = $(element); |
|
879 | element = $(element); | |
910 | var options = arguments[1] || {}; |
|
880 | var options = arguments[1] || { }; | |
911 | var oldOpacity = element.getInlineOpacity(); |
|
881 | var oldOpacity = element.getInlineOpacity(); | |
912 | var transition = options.transition || Effect.Transitions.sinoidal; |
|
882 | var transition = options.transition || Effect.Transitions.sinoidal; | |
913 | var reverser = function(pos){ return transition(1-Effect.Transitions.pulse(pos, options.pulses)) }; |
|
883 | var reverser = function(pos){ return transition(1-Effect.Transitions.pulse(pos, options.pulses)) }; | |
@@ -916,7 +886,7 Effect.Pulsate = function(element) { | |||||
916 | Object.extend(Object.extend({ duration: 2.0, from: 0, |
|
886 | Object.extend(Object.extend({ duration: 2.0, from: 0, | |
917 | afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); } |
|
887 | afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); } | |
918 | }, options), {transition: reverser})); |
|
888 | }, options), {transition: reverser})); | |
919 | } |
|
889 | }; | |
920 |
|
890 | |||
921 | Effect.Fold = function(element) { |
|
891 | Effect.Fold = function(element) { | |
922 | element = $(element); |
|
892 | element = $(element); | |
@@ -936,37 +906,71 Effect.Fold = function(element) { | |||||
936 | afterFinishInternal: function(effect) { |
|
906 | afterFinishInternal: function(effect) { | |
937 | effect.element.hide().undoClipping().setStyle(oldStyle); |
|
907 | effect.element.hide().undoClipping().setStyle(oldStyle); | |
938 | } }); |
|
908 | } }); | |
939 | }}, arguments[1] || {})); |
|
909 | }}, arguments[1] || { })); | |
940 | }; |
|
910 | }; | |
941 |
|
911 | |||
942 |
Effect.Morph = Class.create( |
|
912 | Effect.Morph = Class.create(Effect.Base, { | |
943 | Object.extend(Object.extend(Effect.Morph.prototype, Effect.Base.prototype), { |
|
|||
944 | initialize: function(element) { |
|
913 | initialize: function(element) { | |
945 | this.element = $(element); |
|
914 | this.element = $(element); | |
946 | if(!this.element) throw(Effect._elementDoesNotExistError); |
|
915 | if (!this.element) throw(Effect._elementDoesNotExistError); | |
947 | var options = Object.extend({ |
|
916 | var options = Object.extend({ | |
948 |
style: |
|
917 | style: { } | |
949 | }, arguments[1] || {}); |
|
918 | }, arguments[1] || { }); | |
|
919 | ||||
|
920 | if (!Object.isString(options.style)) this.style = $H(options.style); | |||
|
921 | else { | |||
|
922 | if (options.style.include(':')) | |||
|
923 | this.style = options.style.parseStyle(); | |||
|
924 | else { | |||
|
925 | this.element.addClassName(options.style); | |||
|
926 | this.style = $H(this.element.getStyles()); | |||
|
927 | this.element.removeClassName(options.style); | |||
|
928 | var css = this.element.getStyles(); | |||
|
929 | this.style = this.style.reject(function(style) { | |||
|
930 | return style.value == css[style.key]; | |||
|
931 | }); | |||
|
932 | options.afterFinishInternal = function(effect) { | |||
|
933 | effect.element.addClassName(effect.options.style); | |||
|
934 | effect.transforms.each(function(transform) { | |||
|
935 | effect.element.style[transform.style] = ''; | |||
|
936 | }); | |||
|
937 | } | |||
|
938 | } | |||
|
939 | } | |||
950 | this.start(options); |
|
940 | this.start(options); | |
951 | }, |
|
941 | }, | |
|
942 | ||||
952 | setup: function(){ |
|
943 | setup: function(){ | |
953 | function parseColor(color){ |
|
944 | function parseColor(color){ | |
954 | if(!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff'; |
|
945 | if (!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff'; | |
955 | color = color.parseColor(); |
|
946 | color = color.parseColor(); | |
956 | return $R(0,2).map(function(i){ |
|
947 | return $R(0,2).map(function(i){ | |
957 | return parseInt( color.slice(i*2+1,i*2+3), 16 ) |
|
948 | return parseInt( color.slice(i*2+1,i*2+3), 16 ) | |
958 | }); |
|
949 | }); | |
959 | } |
|
950 | } | |
960 |
this.transforms = this. |
|
951 | this.transforms = this.style.map(function(pair){ | |
961 | var originalValue = this.element.getStyle(property[0]); |
|
952 | var property = pair[0], value = pair[1], unit = null; | |
962 | return $H({ |
|
953 | ||
963 | style: property[0], |
|
954 | if (value.parseColor('#zzzzzz') != '#zzzzzz') { | |
964 | originalValue: property[1].unit=='color' ? |
|
955 | value = value.parseColor(); | |
965 | parseColor(originalValue) : parseFloat(originalValue || 0), |
|
956 | unit = 'color'; | |
966 | targetValue: property[1].unit=='color' ? |
|
957 | } else if (property == 'opacity') { | |
967 | parseColor(property[1].value) : property[1].value, |
|
958 | value = parseFloat(value); | |
968 | unit: property[1].unit |
|
959 | if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout)) | |
969 | }); |
|
960 | this.element.setStyle({zoom: 1}); | |
|
961 | } else if (Element.CSS_LENGTH.test(value)) { | |||
|
962 | var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/); | |||
|
963 | value = parseFloat(components[1]); | |||
|
964 | unit = (components.length == 3) ? components[2] : null; | |||
|
965 | } | |||
|
966 | ||||
|
967 | var originalValue = this.element.getStyle(property); | |||
|
968 | return { | |||
|
969 | style: property.camelize(), | |||
|
970 | originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0), | |||
|
971 | targetValue: unit=='color' ? parseColor(value) : value, | |||
|
972 | unit: unit | |||
|
973 | }; | |||
970 | }.bind(this)).reject(function(transform){ |
|
974 | }.bind(this)).reject(function(transform){ | |
971 | return ( |
|
975 | return ( | |
972 | (transform.originalValue == transform.targetValue) || |
|
976 | (transform.originalValue == transform.targetValue) || | |
@@ -978,32 +982,35 Object.extend(Object.extend(Effect.Morph.prototype, Effect.Base.prototype), { | |||||
978 | }); |
|
982 | }); | |
979 | }, |
|
983 | }, | |
980 | update: function(position) { |
|
984 | update: function(position) { | |
981 | var style = $H(), value = null; |
|
985 | var style = { }, transform, i = this.transforms.length; | |
982 | this.transforms.each(function(transform){ |
|
986 | while(i--) | |
983 | value = transform.unit=='color' ? |
|
987 | style[(transform = this.transforms[i]).style] = | |
984 | $R(0,2).inject('#',function(m,v,i){ |
|
988 | transform.unit=='color' ? '#'+ | |
985 |
|
|
989 | (Math.round(transform.originalValue[0]+ | |
986 |
(transform.targetValue[ |
|
990 | (transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart() + | |
987 |
|
|
991 | (Math.round(transform.originalValue[1]+ | |
988 |
|
|
992 | (transform.targetValue[1]-transform.originalValue[1])*position)).toColorPart() + | |
989 | style[transform.style] = value; |
|
993 | (Math.round(transform.originalValue[2]+ | |
990 | }); |
|
994 | (transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() : | |
991 | this.element.setStyle(style); |
|
995 | (transform.originalValue + | |
|
996 | (transform.targetValue - transform.originalValue) * position).toFixed(3) + | |||
|
997 | (transform.unit === null ? '' : transform.unit); | |||
|
998 | this.element.setStyle(style, true); | |||
992 | } |
|
999 | } | |
993 | }); |
|
1000 | }); | |
994 |
|
1001 | |||
995 |
Effect.Transform = Class.create( |
|
1002 | Effect.Transform = Class.create({ | |
996 | Object.extend(Effect.Transform.prototype, { |
|
|||
997 | initialize: function(tracks){ |
|
1003 | initialize: function(tracks){ | |
998 | this.tracks = []; |
|
1004 | this.tracks = []; | |
999 | this.options = arguments[1] || {}; |
|
1005 | this.options = arguments[1] || { }; | |
1000 | this.addTracks(tracks); |
|
1006 | this.addTracks(tracks); | |
1001 | }, |
|
1007 | }, | |
1002 | addTracks: function(tracks){ |
|
1008 | addTracks: function(tracks){ | |
1003 | tracks.each(function(track){ |
|
1009 | tracks.each(function(track){ | |
1004 | var data = $H(track).values().first(); |
|
1010 | track = $H(track); | |
|
1011 | var data = track.values().first(); | |||
1005 | this.tracks.push($H({ |
|
1012 | this.tracks.push($H({ | |
1006 |
ids: |
|
1013 | ids: track.keys().first(), | |
1007 | effect: Effect.Morph, |
|
1014 | effect: Effect.Morph, | |
1008 | options: { style: data } |
|
1015 | options: { style: data } | |
1009 | })); |
|
1016 | })); | |
@@ -1013,76 +1020,101 Object.extend(Effect.Transform.prototype, { | |||||
1013 | play: function(){ |
|
1020 | play: function(){ | |
1014 | return new Effect.Parallel( |
|
1021 | return new Effect.Parallel( | |
1015 | this.tracks.map(function(track){ |
|
1022 | this.tracks.map(function(track){ | |
1016 | var elements = [$(track.ids) || $$(track.ids)].flatten(); |
|
1023 | var ids = track.get('ids'), effect = track.get('effect'), options = track.get('options'); | |
1017 | return elements.map(function(e){ return new track.effect(e, Object.extend({ sync:true }, track.options)) }); |
|
1024 | var elements = [$(ids) || $$(ids)].flatten(); | |
|
1025 | return elements.map(function(e){ return new effect(e, Object.extend({ sync:true }, options)) }); | |||
1018 | }).flatten(), |
|
1026 | }).flatten(), | |
1019 | this.options |
|
1027 | this.options | |
1020 | ); |
|
1028 | ); | |
1021 | } |
|
1029 | } | |
1022 | }); |
|
1030 | }); | |
1023 |
|
1031 | |||
1024 | Element.CSS_PROPERTIES = ['azimuth', 'backgroundAttachment', 'backgroundColor', 'backgroundImage', |
|
1032 | Element.CSS_PROPERTIES = $w( | |
1025 |
'backgroundPosition' |
|
1033 | 'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' + | |
1026 |
'borderBottomWidth' |
|
1034 | 'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' + | |
1027 |
'borderRightColor' |
|
1035 | 'borderRightColor borderRightStyle borderRightWidth borderSpacing ' + | |
1028 |
'borderTopStyle' |
|
1036 | 'borderTopColor borderTopStyle borderTopWidth bottom clip color ' + | |
1029 | 'counterIncrement', 'counterReset', 'cssFloat', 'cueAfter', 'cueBefore', 'cursor', 'direction', |
|
1037 | 'fontSize fontWeight height left letterSpacing lineHeight ' + | |
1030 | 'display', 'elevation', 'emptyCells', 'fontFamily', 'fontSize', 'fontSizeAdjust', 'fontStretch', |
|
1038 | 'marginBottom marginLeft marginRight marginTop markerOffset maxHeight '+ | |
1031 | 'fontStyle', 'fontVariant', 'fontWeight', 'height', 'left', 'letterSpacing', 'lineHeight', |
|
1039 | 'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' + | |
1032 | 'listStyleImage', 'listStylePosition', 'listStyleType', 'marginBottom', 'marginLeft', 'marginRight', |
|
1040 | 'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' + | |
1033 | 'marginTop', 'markerOffset', 'marks', 'maxHeight', 'maxWidth', 'minHeight', 'minWidth', 'opacity', |
|
1041 | 'right textIndent top width wordSpacing zIndex'); | |
1034 | 'orphans', 'outlineColor', 'outlineOffset', 'outlineStyle', 'outlineWidth', 'overflowX', 'overflowY', |
|
|||
1035 | 'paddingBottom', 'paddingLeft', 'paddingRight', 'paddingTop', 'page', 'pageBreakAfter', 'pageBreakBefore', |
|
|||
1036 | 'pageBreakInside', 'pauseAfter', 'pauseBefore', 'pitch', 'pitchRange', 'position', 'quotes', |
|
|||
1037 | 'richness', 'right', 'size', 'speakHeader', 'speakNumeral', 'speakPunctuation', 'speechRate', 'stress', |
|
|||
1038 | 'tableLayout', 'textAlign', 'textDecoration', 'textIndent', 'textShadow', 'textTransform', 'top', |
|
|||
1039 | 'unicodeBidi', 'verticalAlign', 'visibility', 'voiceFamily', 'volume', 'whiteSpace', 'widows', |
|
|||
1040 | 'width', 'wordSpacing', 'zIndex']; |
|
|||
1041 |
|
1042 | |||
1042 | Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/; |
|
1043 | Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/; | |
1043 |
|
1044 | |||
|
1045 | String.__parseStyleElement = document.createElement('div'); | |||
1044 | String.prototype.parseStyle = function(){ |
|
1046 | String.prototype.parseStyle = function(){ | |
1045 | var element = Element.extend(document.createElement('div')); |
|
1047 | var style, styleRules = $H(); | |
1046 | element.innerHTML = '<div style="' + this + '"></div>'; |
|
1048 | if (Prototype.Browser.WebKit) | |
1047 | var style = element.down().style, styleRules = $H(); |
|
1049 | style = new Element('div',{style:this}).style; | |
|
1050 | else { | |||
|
1051 | String.__parseStyleElement.innerHTML = '<div style="' + this + '"></div>'; | |||
|
1052 | style = String.__parseStyleElement.childNodes[0].style; | |||
|
1053 | } | |||
1048 |
|
1054 | |||
1049 | Element.CSS_PROPERTIES.each(function(property){ |
|
1055 | Element.CSS_PROPERTIES.each(function(property){ | |
1050 |
if(style[property]) styleRules |
|
1056 | if (style[property]) styleRules.set(property, style[property]); | |
1051 | }); |
|
1057 | }); | |
1052 |
|
1058 | |||
1053 | var result = $H(); |
|
1059 | if (Prototype.Browser.IE && this.include('opacity')) | |
1054 |
|
1060 | styleRules.set('opacity', this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1]); | ||
1055 | styleRules.each(function(pair){ |
|
1061 | ||
1056 | var property = pair[0], value = pair[1], unit = null; |
|
1062 | return styleRules; | |
1057 |
|
||||
1058 | if(value.parseColor('#zzzzzz') != '#zzzzzz') { |
|
|||
1059 | value = value.parseColor(); |
|
|||
1060 | unit = 'color'; |
|
|||
1061 | } else if(Element.CSS_LENGTH.test(value)) |
|
|||
1062 | var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/), |
|
|||
1063 | value = parseFloat(components[1]), unit = (components.length == 3) ? components[2] : null; |
|
|||
1064 |
|
||||
1065 | result[property.underscore().dasherize()] = $H({ value:value, unit:unit }); |
|
|||
1066 | }.bind(this)); |
|
|||
1067 |
|
||||
1068 | return result; |
|
|||
1069 | }; |
|
1063 | }; | |
1070 |
|
1064 | |||
1071 | Element.morph = function(element, style) { |
|
1065 | if (document.defaultView && document.defaultView.getComputedStyle) { | |
1072 | new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || {})); |
|
1066 | Element.getStyles = function(element) { | |
1073 | return element; |
|
1067 | var css = document.defaultView.getComputedStyle($(element), null); | |
|
1068 | return Element.CSS_PROPERTIES.inject({ }, function(styles, property) { | |||
|
1069 | styles[property] = css[property]; | |||
|
1070 | return styles; | |||
|
1071 | }); | |||
|
1072 | }; | |||
|
1073 | } else { | |||
|
1074 | Element.getStyles = function(element) { | |||
|
1075 | element = $(element); | |||
|
1076 | var css = element.currentStyle, styles; | |||
|
1077 | styles = Element.CSS_PROPERTIES.inject({ }, function(hash, property) { | |||
|
1078 | hash.set(property, css[property]); | |||
|
1079 | return hash; | |||
|
1080 | }); | |||
|
1081 | if (!styles.opacity) styles.set('opacity', element.getOpacity()); | |||
|
1082 | return styles; | |||
|
1083 | }; | |||
1074 | }; |
|
1084 | }; | |
1075 |
|
1085 | |||
1076 | ['setOpacity','getOpacity','getInlineOpacity','forceRerendering','setContentZoom', |
|
1086 | Effect.Methods = { | |
1077 | 'collectTextNodes','collectTextNodesIgnoreClass','morph'].each( |
|
1087 | morph: function(element, style) { | |
1078 | function(f) { Element.Methods[f] = Element[f]; } |
|
1088 | element = $(element); | |
|
1089 | new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || { })); | |||
|
1090 | return element; | |||
|
1091 | }, | |||
|
1092 | visualEffect: function(element, effect, options) { | |||
|
1093 | element = $(element) | |||
|
1094 | var s = effect.dasherize().camelize(), klass = s.charAt(0).toUpperCase() + s.substring(1); | |||
|
1095 | new Effect[klass](element, options); | |||
|
1096 | return element; | |||
|
1097 | }, | |||
|
1098 | highlight: function(element, options) { | |||
|
1099 | element = $(element); | |||
|
1100 | new Effect.Highlight(element, options); | |||
|
1101 | return element; | |||
|
1102 | } | |||
|
1103 | }; | |||
|
1104 | ||||
|
1105 | $w('fade appear grow shrink fold blindUp blindDown slideUp slideDown '+ | |||
|
1106 | 'pulsate shake puff squish switchOff dropOut').each( | |||
|
1107 | function(effect) { | |||
|
1108 | Effect.Methods[effect] = function(element, options){ | |||
|
1109 | element = $(element); | |||
|
1110 | Effect[effect.charAt(0).toUpperCase() + effect.substring(1)](element, options); | |||
|
1111 | return element; | |||
|
1112 | } | |||
|
1113 | } | |||
1079 | ); |
|
1114 | ); | |
1080 |
|
1115 | |||
1081 | Element.Methods.visualEffect = function(element, effect, options) { |
|
1116 | $w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each( | |
1082 | s = effect.gsub(/_/, '-').camelize(); |
|
1117 | function(f) { Effect.Methods[f] = Element[f]; } | |
1083 | effect_class = s.charAt(0).toUpperCase() + s.substring(1); |
|
1118 | ); | |
1084 | new Effect[effect_class](element, options); |
|
|||
1085 | return $(element); |
|
|||
1086 | }; |
|
|||
1087 |
|
1119 | |||
1088 | Element.addMethods(); No newline at end of file |
|
1120 | Element.addMethods(Effect.Methods); |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
General Comments 0
You need to be logged in to leave comments.
Login now