Notifications
This commit is contained in:
@@ -3,10 +3,10 @@
|
||||
MooTools: the javascript framework
|
||||
|
||||
web build:
|
||||
- http://mootools.net/core/bd6349d3fbc489736e5aefb01157c8a8
|
||||
- http://mootools.net/core/c1215700e7dedaa9d48503126daf2111
|
||||
|
||||
packager build:
|
||||
- packager build Core/Class Core/Class.Extras Core/Element Core/Element.Style Core/Element.Dimensions Core/Fx.Tween Core/Fx.Transitions Core/Request.JSON Core/DOMReady
|
||||
- packager build Core/Class Core/Class.Extras Core/Element Core/Element.Style Core/Element.Dimensions Core/Fx.Tween Core/Fx.Morph Core/Fx.Transitions Core/Request.JSON Core/DOMReady
|
||||
|
||||
/*
|
||||
---
|
||||
@@ -4085,6 +4085,85 @@ Element.implement({
|
||||
});
|
||||
|
||||
|
||||
/*
|
||||
---
|
||||
|
||||
name: Fx.Morph
|
||||
|
||||
description: Formerly Fx.Styles, effect to transition any number of CSS properties for an element using an object of rules, or CSS based selector rules.
|
||||
|
||||
license: MIT-style license.
|
||||
|
||||
requires: Fx.CSS
|
||||
|
||||
provides: Fx.Morph
|
||||
|
||||
...
|
||||
*/
|
||||
|
||||
Fx.Morph = new Class({
|
||||
|
||||
Extends: Fx.CSS,
|
||||
|
||||
initialize: function(element, options){
|
||||
this.element = this.subject = document.id(element);
|
||||
this.parent(options);
|
||||
},
|
||||
|
||||
set: function(now){
|
||||
if (typeof now == 'string') now = this.search(now);
|
||||
for (var p in now) this.render(this.element, p, now[p], this.options.unit);
|
||||
return this;
|
||||
},
|
||||
|
||||
compute: function(from, to, delta){
|
||||
var now = {};
|
||||
for (var p in from) now[p] = this.parent(from[p], to[p], delta);
|
||||
return now;
|
||||
},
|
||||
|
||||
start: function(properties){
|
||||
if (!this.check(properties)) return this;
|
||||
if (typeof properties == 'string') properties = this.search(properties);
|
||||
var from = {}, to = {};
|
||||
for (var p in properties){
|
||||
var parsed = this.prepare(this.element, p, properties[p]);
|
||||
from[p] = parsed.from;
|
||||
to[p] = parsed.to;
|
||||
}
|
||||
return this.parent(from, to);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Element.Properties.morph = {
|
||||
|
||||
set: function(options){
|
||||
this.get('morph').cancel().setOptions(options);
|
||||
return this;
|
||||
},
|
||||
|
||||
get: function(){
|
||||
var morph = this.retrieve('morph');
|
||||
if (!morph){
|
||||
morph = new Fx.Morph(this, {link: 'cancel'});
|
||||
this.store('morph', morph);
|
||||
}
|
||||
return morph;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Element.implement({
|
||||
|
||||
morph: function(props){
|
||||
this.get('morph').start(props);
|
||||
return this;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
/*
|
||||
---
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// MooTools: the javascript framework.
|
||||
// Load this file's selection again by visiting: http://mootools.net/more/a6033a03c64d978cd0033a1d420e16e0
|
||||
// Or build this file again with packager using: packager build More/Element.Forms More/Element.Delegation More/Element.Shortcuts More/Request.JSONP More/Spinner
|
||||
// Load this file's selection again by visiting: http://mootools.net/more/2b832e45b9bf2f9e5fdbdafc9b16febf
|
||||
// Or build this file again with packager using: packager build More/Element.Forms More/Element.Delegation More/Element.Shortcuts More/Fx.Slide More/Sortables More/Request.JSONP More/Spinner
|
||||
/*
|
||||
---
|
||||
|
||||
@@ -767,6 +767,849 @@ Document.implement({
|
||||
});
|
||||
|
||||
|
||||
/*
|
||||
---
|
||||
|
||||
script: Fx.Slide.js
|
||||
|
||||
name: Fx.Slide
|
||||
|
||||
description: Effect to slide an element in and out of view.
|
||||
|
||||
license: MIT-style license
|
||||
|
||||
authors:
|
||||
- Valerio Proietti
|
||||
|
||||
requires:
|
||||
- Core/Fx
|
||||
- Core/Element.Style
|
||||
- /MooTools.More
|
||||
|
||||
provides: [Fx.Slide]
|
||||
|
||||
...
|
||||
*/
|
||||
|
||||
Fx.Slide = new Class({
|
||||
|
||||
Extends: Fx,
|
||||
|
||||
options: {
|
||||
mode: 'vertical',
|
||||
wrapper: false,
|
||||
hideOverflow: true,
|
||||
resetHeight: false
|
||||
},
|
||||
|
||||
initialize: function(element, options){
|
||||
element = this.element = this.subject = document.id(element);
|
||||
this.parent(options);
|
||||
options = this.options;
|
||||
|
||||
var wrapper = element.retrieve('wrapper'),
|
||||
styles = element.getStyles('margin', 'position', 'overflow');
|
||||
|
||||
if (options.hideOverflow) styles = Object.append(styles, {overflow: 'hidden'});
|
||||
if (options.wrapper) wrapper = document.id(options.wrapper).setStyles(styles);
|
||||
|
||||
if (!wrapper) wrapper = new Element('div', {
|
||||
styles: styles
|
||||
}).wraps(element);
|
||||
|
||||
element.store('wrapper', wrapper).setStyle('margin', 0);
|
||||
if (element.getStyle('overflow') == 'visible') element.setStyle('overflow', 'hidden');
|
||||
|
||||
this.now = [];
|
||||
this.open = true;
|
||||
this.wrapper = wrapper;
|
||||
|
||||
this.addEvent('complete', function(){
|
||||
this.open = (wrapper['offset' + this.layout.capitalize()] != 0);
|
||||
if (this.open && options.resetHeight) wrapper.setStyle('height', '');
|
||||
}, true);
|
||||
},
|
||||
|
||||
vertical: function(){
|
||||
this.margin = 'margin-top';
|
||||
this.layout = 'height';
|
||||
this.offset = this.element.offsetHeight;
|
||||
},
|
||||
|
||||
horizontal: function(){
|
||||
this.margin = 'margin-left';
|
||||
this.layout = 'width';
|
||||
this.offset = this.element.offsetWidth;
|
||||
},
|
||||
|
||||
set: function(now){
|
||||
this.element.setStyle(this.margin, now[0]);
|
||||
this.wrapper.setStyle(this.layout, now[1]);
|
||||
return this;
|
||||
},
|
||||
|
||||
compute: function(from, to, delta){
|
||||
return [0, 1].map(function(i){
|
||||
return Fx.compute(from[i], to[i], delta);
|
||||
});
|
||||
},
|
||||
|
||||
start: function(how, mode){
|
||||
if (!this.check(how, mode)) return this;
|
||||
this[mode || this.options.mode]();
|
||||
|
||||
var margin = this.element.getStyle(this.margin).toInt(),
|
||||
layout = this.wrapper.getStyle(this.layout).toInt(),
|
||||
caseIn = [[margin, layout], [0, this.offset]],
|
||||
caseOut = [[margin, layout], [-this.offset, 0]],
|
||||
start;
|
||||
|
||||
switch (how){
|
||||
case 'in': start = caseIn; break;
|
||||
case 'out': start = caseOut; break;
|
||||
case 'toggle': start = (layout == 0) ? caseIn : caseOut;
|
||||
}
|
||||
return this.parent(start[0], start[1]);
|
||||
},
|
||||
|
||||
slideIn: function(mode){
|
||||
return this.start('in', mode);
|
||||
},
|
||||
|
||||
slideOut: function(mode){
|
||||
return this.start('out', mode);
|
||||
},
|
||||
|
||||
hide: function(mode){
|
||||
this[mode || this.options.mode]();
|
||||
this.open = false;
|
||||
return this.set([-this.offset, 0]);
|
||||
},
|
||||
|
||||
show: function(mode){
|
||||
this[mode || this.options.mode]();
|
||||
this.open = true;
|
||||
return this.set([0, this.offset]);
|
||||
},
|
||||
|
||||
toggle: function(mode){
|
||||
return this.start('toggle', mode);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Element.Properties.slide = {
|
||||
|
||||
set: function(options){
|
||||
this.get('slide').cancel().setOptions(options);
|
||||
return this;
|
||||
},
|
||||
|
||||
get: function(){
|
||||
var slide = this.retrieve('slide');
|
||||
if (!slide){
|
||||
slide = new Fx.Slide(this, {link: 'cancel'});
|
||||
this.store('slide', slide);
|
||||
}
|
||||
return slide;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Element.implement({
|
||||
|
||||
slide: function(how, mode){
|
||||
how = how || 'toggle';
|
||||
var slide = this.get('slide'), toggle;
|
||||
switch (how){
|
||||
case 'hide': slide.hide(mode); break;
|
||||
case 'show': slide.show(mode); break;
|
||||
case 'toggle':
|
||||
var flag = this.retrieve('slide:flag', slide.open);
|
||||
slide[flag ? 'slideOut' : 'slideIn'](mode);
|
||||
this.store('slide:flag', !flag);
|
||||
toggle = true;
|
||||
break;
|
||||
default: slide.start(how, mode);
|
||||
}
|
||||
if (!toggle) this.eliminate('slide:flag');
|
||||
return this;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
/*
|
||||
---
|
||||
|
||||
script: Drag.js
|
||||
|
||||
name: Drag
|
||||
|
||||
description: The base Drag Class. Can be used to drag and resize Elements using mouse events.
|
||||
|
||||
license: MIT-style license
|
||||
|
||||
authors:
|
||||
- Valerio Proietti
|
||||
- Tom Occhinno
|
||||
- Jan Kassens
|
||||
|
||||
requires:
|
||||
- Core/Events
|
||||
- Core/Options
|
||||
- Core/Element.Event
|
||||
- Core/Element.Style
|
||||
- Core/Element.Dimensions
|
||||
- /MooTools.More
|
||||
|
||||
provides: [Drag]
|
||||
...
|
||||
|
||||
*/
|
||||
|
||||
var Drag = new Class({
|
||||
|
||||
Implements: [Events, Options],
|
||||
|
||||
options: {/*
|
||||
onBeforeStart: function(thisElement){},
|
||||
onStart: function(thisElement, event){},
|
||||
onSnap: function(thisElement){},
|
||||
onDrag: function(thisElement, event){},
|
||||
onCancel: function(thisElement){},
|
||||
onComplete: function(thisElement, event){},*/
|
||||
snap: 6,
|
||||
unit: 'px',
|
||||
grid: false,
|
||||
style: true,
|
||||
limit: false,
|
||||
handle: false,
|
||||
invert: false,
|
||||
preventDefault: false,
|
||||
stopPropagation: false,
|
||||
modifiers: {x: 'left', y: 'top'}
|
||||
},
|
||||
|
||||
initialize: function(){
|
||||
var params = Array.link(arguments, {
|
||||
'options': Type.isObject,
|
||||
'element': function(obj){
|
||||
return obj != null;
|
||||
}
|
||||
});
|
||||
|
||||
this.element = document.id(params.element);
|
||||
this.document = this.element.getDocument();
|
||||
this.setOptions(params.options || {});
|
||||
var htype = typeOf(this.options.handle);
|
||||
this.handles = ((htype == 'array' || htype == 'collection') ? $$(this.options.handle) : document.id(this.options.handle)) || this.element;
|
||||
this.mouse = {'now': {}, 'pos': {}};
|
||||
this.value = {'start': {}, 'now': {}};
|
||||
|
||||
this.selection = (Browser.ie) ? 'selectstart' : 'mousedown';
|
||||
|
||||
|
||||
if (Browser.ie && !Drag.ondragstartFixed){
|
||||
document.ondragstart = Function.from(false);
|
||||
Drag.ondragstartFixed = true;
|
||||
}
|
||||
|
||||
this.bound = {
|
||||
start: this.start.bind(this),
|
||||
check: this.check.bind(this),
|
||||
drag: this.drag.bind(this),
|
||||
stop: this.stop.bind(this),
|
||||
cancel: this.cancel.bind(this),
|
||||
eventStop: Function.from(false)
|
||||
};
|
||||
this.attach();
|
||||
},
|
||||
|
||||
attach: function(){
|
||||
this.handles.addEvent('mousedown', this.bound.start);
|
||||
return this;
|
||||
},
|
||||
|
||||
detach: function(){
|
||||
this.handles.removeEvent('mousedown', this.bound.start);
|
||||
return this;
|
||||
},
|
||||
|
||||
start: function(event){
|
||||
var options = this.options;
|
||||
|
||||
if (event.rightClick) return;
|
||||
|
||||
if (options.preventDefault) event.preventDefault();
|
||||
if (options.stopPropagation) event.stopPropagation();
|
||||
this.mouse.start = event.page;
|
||||
|
||||
this.fireEvent('beforeStart', this.element);
|
||||
|
||||
var limit = options.limit;
|
||||
this.limit = {x: [], y: []};
|
||||
|
||||
var styles = this.element.getStyles('left', 'right', 'top', 'bottom');
|
||||
this._invert = {
|
||||
x: options.modifiers.x == 'left' && styles.left == 'auto' && !isNaN(styles.right.toInt()) && (options.modifiers.x = 'right'),
|
||||
y: options.modifiers.y == 'top' && styles.top == 'auto' && !isNaN(styles.bottom.toInt()) && (options.modifiers.y = 'bottom')
|
||||
};
|
||||
|
||||
var z, coordinates;
|
||||
for (z in options.modifiers){
|
||||
if (!options.modifiers[z]) continue;
|
||||
|
||||
var style = this.element.getStyle(options.modifiers[z]);
|
||||
|
||||
// Some browsers (IE and Opera) don't always return pixels.
|
||||
if (style && !style.match(/px$/)){
|
||||
if (!coordinates) coordinates = this.element.getCoordinates(this.element.getOffsetParent());
|
||||
style = coordinates[options.modifiers[z]];
|
||||
}
|
||||
|
||||
if (options.style) this.value.now[z] = (style || 0).toInt();
|
||||
else this.value.now[z] = this.element[options.modifiers[z]];
|
||||
|
||||
if (options.invert) this.value.now[z] *= -1;
|
||||
if (this._invert[z]) this.value.now[z] *= -1;
|
||||
|
||||
this.mouse.pos[z] = event.page[z] - this.value.now[z];
|
||||
|
||||
if (limit && limit[z]){
|
||||
var i = 2;
|
||||
while (i--){
|
||||
var limitZI = limit[z][i];
|
||||
if (limitZI || limitZI === 0) this.limit[z][i] = (typeof limitZI == 'function') ? limitZI() : limitZI;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (typeOf(this.options.grid) == 'number') this.options.grid = {
|
||||
x: this.options.grid,
|
||||
y: this.options.grid
|
||||
};
|
||||
|
||||
var events = {
|
||||
mousemove: this.bound.check,
|
||||
mouseup: this.bound.cancel
|
||||
};
|
||||
events[this.selection] = this.bound.eventStop;
|
||||
this.document.addEvents(events);
|
||||
},
|
||||
|
||||
check: function(event){
|
||||
if (this.options.preventDefault) event.preventDefault();
|
||||
var distance = Math.round(Math.sqrt(Math.pow(event.page.x - this.mouse.start.x, 2) + Math.pow(event.page.y - this.mouse.start.y, 2)));
|
||||
if (distance > this.options.snap){
|
||||
this.cancel();
|
||||
this.document.addEvents({
|
||||
mousemove: this.bound.drag,
|
||||
mouseup: this.bound.stop
|
||||
});
|
||||
this.fireEvent('start', [this.element, event]).fireEvent('snap', this.element);
|
||||
}
|
||||
},
|
||||
|
||||
drag: function(event){
|
||||
var options = this.options;
|
||||
|
||||
if (options.preventDefault) event.preventDefault();
|
||||
this.mouse.now = event.page;
|
||||
|
||||
for (var z in options.modifiers){
|
||||
if (!options.modifiers[z]) continue;
|
||||
this.value.now[z] = this.mouse.now[z] - this.mouse.pos[z];
|
||||
|
||||
if (options.invert) this.value.now[z] *= -1;
|
||||
if (this._invert[z]) this.value.now[z] *= -1;
|
||||
|
||||
if (options.limit && this.limit[z]){
|
||||
if ((this.limit[z][1] || this.limit[z][1] === 0) && (this.value.now[z] > this.limit[z][1])){
|
||||
this.value.now[z] = this.limit[z][1];
|
||||
} else if ((this.limit[z][0] || this.limit[z][0] === 0) && (this.value.now[z] < this.limit[z][0])){
|
||||
this.value.now[z] = this.limit[z][0];
|
||||
}
|
||||
}
|
||||
|
||||
if (options.grid[z]) this.value.now[z] -= ((this.value.now[z] - (this.limit[z][0]||0)) % options.grid[z]);
|
||||
|
||||
if (options.style) this.element.setStyle(options.modifiers[z], this.value.now[z] + options.unit);
|
||||
else this.element[options.modifiers[z]] = this.value.now[z];
|
||||
}
|
||||
|
||||
this.fireEvent('drag', [this.element, event]);
|
||||
},
|
||||
|
||||
cancel: function(event){
|
||||
this.document.removeEvents({
|
||||
mousemove: this.bound.check,
|
||||
mouseup: this.bound.cancel
|
||||
});
|
||||
if (event){
|
||||
this.document.removeEvent(this.selection, this.bound.eventStop);
|
||||
this.fireEvent('cancel', this.element);
|
||||
}
|
||||
},
|
||||
|
||||
stop: function(event){
|
||||
var events = {
|
||||
mousemove: this.bound.drag,
|
||||
mouseup: this.bound.stop
|
||||
};
|
||||
events[this.selection] = this.bound.eventStop;
|
||||
this.document.removeEvents(events);
|
||||
if (event) this.fireEvent('complete', [this.element, event]);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Element.implement({
|
||||
|
||||
makeResizable: function(options){
|
||||
var drag = new Drag(this, Object.merge({
|
||||
modifiers: {
|
||||
x: 'width',
|
||||
y: 'height'
|
||||
}
|
||||
}, options));
|
||||
|
||||
this.store('resizer', drag);
|
||||
return drag.addEvent('drag', function(){
|
||||
this.fireEvent('resize', drag);
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
/*
|
||||
---
|
||||
|
||||
script: Drag.Move.js
|
||||
|
||||
name: Drag.Move
|
||||
|
||||
description: A Drag extension that provides support for the constraining of draggables to containers and droppables.
|
||||
|
||||
license: MIT-style license
|
||||
|
||||
authors:
|
||||
- Valerio Proietti
|
||||
- Tom Occhinno
|
||||
- Jan Kassens
|
||||
- Aaron Newton
|
||||
- Scott Kyle
|
||||
|
||||
requires:
|
||||
- Core/Element.Dimensions
|
||||
- /Drag
|
||||
|
||||
provides: [Drag.Move]
|
||||
|
||||
...
|
||||
*/
|
||||
|
||||
Drag.Move = new Class({
|
||||
|
||||
Extends: Drag,
|
||||
|
||||
options: {/*
|
||||
onEnter: function(thisElement, overed){},
|
||||
onLeave: function(thisElement, overed){},
|
||||
onDrop: function(thisElement, overed, event){},*/
|
||||
droppables: [],
|
||||
container: false,
|
||||
precalculate: false,
|
||||
includeMargins: true,
|
||||
checkDroppables: true
|
||||
},
|
||||
|
||||
initialize: function(element, options){
|
||||
this.parent(element, options);
|
||||
element = this.element;
|
||||
|
||||
this.droppables = $$(this.options.droppables);
|
||||
this.container = document.id(this.options.container);
|
||||
|
||||
if (this.container && typeOf(this.container) != 'element')
|
||||
this.container = document.id(this.container.getDocument().body);
|
||||
|
||||
if (this.options.style){
|
||||
if (this.options.modifiers.x == "left" && this.options.modifiers.y == "top"){
|
||||
var parentStyles,
|
||||
parent = element.getOffsetParent();
|
||||
var styles = element.getStyles('left', 'top');
|
||||
if (parent && (styles.left == 'auto' || styles.top == 'auto')){
|
||||
element.setPosition(element.getPosition(parent));
|
||||
}
|
||||
}
|
||||
|
||||
if (element.getStyle('position') == 'static') element.setStyle('position', 'absolute');
|
||||
}
|
||||
|
||||
this.addEvent('start', this.checkDroppables, true);
|
||||
this.overed = null;
|
||||
},
|
||||
|
||||
start: function(event){
|
||||
if (this.container) this.options.limit = this.calculateLimit();
|
||||
|
||||
if (this.options.precalculate){
|
||||
this.positions = this.droppables.map(function(el){
|
||||
return el.getCoordinates();
|
||||
});
|
||||
}
|
||||
|
||||
this.parent(event);
|
||||
},
|
||||
|
||||
calculateLimit: function(){
|
||||
var element = this.element,
|
||||
container = this.container,
|
||||
|
||||
offsetParent = document.id(element.getOffsetParent()) || document.body,
|
||||
containerCoordinates = container.getCoordinates(offsetParent),
|
||||
elementMargin = {},
|
||||
elementBorder = {},
|
||||
containerMargin = {},
|
||||
containerBorder = {},
|
||||
offsetParentPadding = {};
|
||||
|
||||
['top', 'right', 'bottom', 'left'].each(function(pad){
|
||||
elementMargin[pad] = element.getStyle('margin-' + pad).toInt();
|
||||
elementBorder[pad] = element.getStyle('border-' + pad).toInt();
|
||||
containerMargin[pad] = container.getStyle('margin-' + pad).toInt();
|
||||
containerBorder[pad] = container.getStyle('border-' + pad).toInt();
|
||||
offsetParentPadding[pad] = offsetParent.getStyle('padding-' + pad).toInt();
|
||||
}, this);
|
||||
|
||||
var width = element.offsetWidth + elementMargin.left + elementMargin.right,
|
||||
height = element.offsetHeight + elementMargin.top + elementMargin.bottom,
|
||||
left = 0,
|
||||
top = 0,
|
||||
right = containerCoordinates.right - containerBorder.right - width,
|
||||
bottom = containerCoordinates.bottom - containerBorder.bottom - height;
|
||||
|
||||
if (this.options.includeMargins){
|
||||
left += elementMargin.left;
|
||||
top += elementMargin.top;
|
||||
} else {
|
||||
right += elementMargin.right;
|
||||
bottom += elementMargin.bottom;
|
||||
}
|
||||
|
||||
if (element.getStyle('position') == 'relative'){
|
||||
var coords = element.getCoordinates(offsetParent);
|
||||
coords.left -= element.getStyle('left').toInt();
|
||||
coords.top -= element.getStyle('top').toInt();
|
||||
|
||||
left -= coords.left;
|
||||
top -= coords.top;
|
||||
if (container.getStyle('position') != 'relative'){
|
||||
left += containerBorder.left;
|
||||
top += containerBorder.top;
|
||||
}
|
||||
right += elementMargin.left - coords.left;
|
||||
bottom += elementMargin.top - coords.top;
|
||||
|
||||
if (container != offsetParent){
|
||||
left += containerMargin.left + offsetParentPadding.left;
|
||||
top += ((Browser.ie6 || Browser.ie7) ? 0 : containerMargin.top) + offsetParentPadding.top;
|
||||
}
|
||||
} else {
|
||||
left -= elementMargin.left;
|
||||
top -= elementMargin.top;
|
||||
if (container != offsetParent){
|
||||
left += containerCoordinates.left + containerBorder.left;
|
||||
top += containerCoordinates.top + containerBorder.top;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
x: [left, right],
|
||||
y: [top, bottom]
|
||||
};
|
||||
},
|
||||
|
||||
getDroppableCoordinates: function(element){
|
||||
var position = element.getCoordinates();
|
||||
if (element.getStyle('position') == 'fixed'){
|
||||
var scroll = window.getScroll();
|
||||
position.left += scroll.x;
|
||||
position.right += scroll.x;
|
||||
position.top += scroll.y;
|
||||
position.bottom += scroll.y;
|
||||
}
|
||||
return position;
|
||||
},
|
||||
|
||||
checkDroppables: function(){
|
||||
var overed = this.droppables.filter(function(el, i){
|
||||
el = this.positions ? this.positions[i] : this.getDroppableCoordinates(el);
|
||||
var now = this.mouse.now;
|
||||
return (now.x > el.left && now.x < el.right && now.y < el.bottom && now.y > el.top);
|
||||
}, this).getLast();
|
||||
|
||||
if (this.overed != overed){
|
||||
if (this.overed) this.fireEvent('leave', [this.element, this.overed]);
|
||||
if (overed) this.fireEvent('enter', [this.element, overed]);
|
||||
this.overed = overed;
|
||||
}
|
||||
},
|
||||
|
||||
drag: function(event){
|
||||
this.parent(event);
|
||||
if (this.options.checkDroppables && this.droppables.length) this.checkDroppables();
|
||||
},
|
||||
|
||||
stop: function(event){
|
||||
this.checkDroppables();
|
||||
this.fireEvent('drop', [this.element, this.overed, event]);
|
||||
this.overed = null;
|
||||
return this.parent(event);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Element.implement({
|
||||
|
||||
makeDraggable: function(options){
|
||||
var drag = new Drag.Move(this, options);
|
||||
this.store('dragger', drag);
|
||||
return drag;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
/*
|
||||
---
|
||||
|
||||
script: Sortables.js
|
||||
|
||||
name: Sortables
|
||||
|
||||
description: Class for creating a drag and drop sorting interface for lists of items.
|
||||
|
||||
license: MIT-style license
|
||||
|
||||
authors:
|
||||
- Tom Occhino
|
||||
|
||||
requires:
|
||||
- Core/Fx.Morph
|
||||
- /Drag.Move
|
||||
|
||||
provides: [Sortables]
|
||||
|
||||
...
|
||||
*/
|
||||
|
||||
var Sortables = new Class({
|
||||
|
||||
Implements: [Events, Options],
|
||||
|
||||
options: {/*
|
||||
onSort: function(element, clone){},
|
||||
onStart: function(element, clone){},
|
||||
onComplete: function(element){},*/
|
||||
opacity: 1,
|
||||
clone: false,
|
||||
revert: false,
|
||||
handle: false,
|
||||
dragOptions: {}
|
||||
},
|
||||
|
||||
initialize: function(lists, options){
|
||||
this.setOptions(options);
|
||||
|
||||
this.elements = [];
|
||||
this.lists = [];
|
||||
this.idle = true;
|
||||
|
||||
this.addLists($$(document.id(lists) || lists));
|
||||
|
||||
if (!this.options.clone) this.options.revert = false;
|
||||
if (this.options.revert) this.effect = new Fx.Morph(null, Object.merge({
|
||||
duration: 250,
|
||||
link: 'cancel'
|
||||
}, this.options.revert));
|
||||
},
|
||||
|
||||
attach: function(){
|
||||
this.addLists(this.lists);
|
||||
return this;
|
||||
},
|
||||
|
||||
detach: function(){
|
||||
this.lists = this.removeLists(this.lists);
|
||||
return this;
|
||||
},
|
||||
|
||||
addItems: function(){
|
||||
Array.flatten(arguments).each(function(element){
|
||||
this.elements.push(element);
|
||||
var start = element.retrieve('sortables:start', function(event){
|
||||
this.start.call(this, event, element);
|
||||
}.bind(this));
|
||||
(this.options.handle ? element.getElement(this.options.handle) || element : element).addEvent('mousedown', start);
|
||||
}, this);
|
||||
return this;
|
||||
},
|
||||
|
||||
addLists: function(){
|
||||
Array.flatten(arguments).each(function(list){
|
||||
this.lists.include(list);
|
||||
this.addItems(list.getChildren());
|
||||
}, this);
|
||||
return this;
|
||||
},
|
||||
|
||||
removeItems: function(){
|
||||
return $$(Array.flatten(arguments).map(function(element){
|
||||
this.elements.erase(element);
|
||||
var start = element.retrieve('sortables:start');
|
||||
(this.options.handle ? element.getElement(this.options.handle) || element : element).removeEvent('mousedown', start);
|
||||
|
||||
return element;
|
||||
}, this));
|
||||
},
|
||||
|
||||
removeLists: function(){
|
||||
return $$(Array.flatten(arguments).map(function(list){
|
||||
this.lists.erase(list);
|
||||
this.removeItems(list.getChildren());
|
||||
|
||||
return list;
|
||||
}, this));
|
||||
},
|
||||
|
||||
getClone: function(event, element){
|
||||
if (!this.options.clone) return new Element(element.tagName).inject(document.body);
|
||||
if (typeOf(this.options.clone) == 'function') return this.options.clone.call(this, event, element, this.list);
|
||||
var clone = element.clone(true).setStyles({
|
||||
margin: 0,
|
||||
position: 'absolute',
|
||||
visibility: 'hidden',
|
||||
width: element.getStyle('width')
|
||||
}).addEvent('mousedown', function(event){
|
||||
element.fireEvent('mousedown', event);
|
||||
});
|
||||
//prevent the duplicated radio inputs from unchecking the real one
|
||||
if (clone.get('html').test('radio')){
|
||||
clone.getElements('input[type=radio]').each(function(input, i){
|
||||
input.set('name', 'clone_' + i);
|
||||
if (input.get('checked')) element.getElements('input[type=radio]')[i].set('checked', true);
|
||||
});
|
||||
}
|
||||
|
||||
return clone.inject(this.list).setPosition(element.getPosition(element.getOffsetParent()));
|
||||
},
|
||||
|
||||
getDroppables: function(){
|
||||
var droppables = this.list.getChildren().erase(this.clone).erase(this.element);
|
||||
if (!this.options.constrain) droppables.append(this.lists).erase(this.list);
|
||||
return droppables;
|
||||
},
|
||||
|
||||
insert: function(dragging, element){
|
||||
var where = 'inside';
|
||||
if (this.lists.contains(element)){
|
||||
this.list = element;
|
||||
this.drag.droppables = this.getDroppables();
|
||||
} else {
|
||||
where = this.element.getAllPrevious().contains(element) ? 'before' : 'after';
|
||||
}
|
||||
this.element.inject(element, where);
|
||||
this.fireEvent('sort', [this.element, this.clone]);
|
||||
},
|
||||
|
||||
start: function(event, element){
|
||||
if (
|
||||
!this.idle ||
|
||||
event.rightClick ||
|
||||
['button', 'input', 'a'].contains(event.target.get('tag'))
|
||||
) return;
|
||||
|
||||
this.idle = false;
|
||||
this.element = element;
|
||||
this.opacity = element.get('opacity');
|
||||
this.list = element.getParent();
|
||||
this.clone = this.getClone(event, element);
|
||||
|
||||
this.drag = new Drag.Move(this.clone, Object.merge({
|
||||
|
||||
droppables: this.getDroppables()
|
||||
}, this.options.dragOptions)).addEvents({
|
||||
onSnap: function(){
|
||||
event.stop();
|
||||
this.clone.setStyle('visibility', 'visible');
|
||||
this.element.set('opacity', this.options.opacity || 0);
|
||||
this.fireEvent('start', [this.element, this.clone]);
|
||||
}.bind(this),
|
||||
onEnter: this.insert.bind(this),
|
||||
onCancel: this.end.bind(this),
|
||||
onComplete: this.end.bind(this)
|
||||
});
|
||||
|
||||
this.clone.inject(this.element, 'before');
|
||||
this.drag.start(event);
|
||||
},
|
||||
|
||||
end: function(){
|
||||
this.drag.detach();
|
||||
this.element.set('opacity', this.opacity);
|
||||
if (this.effect){
|
||||
var dim = this.element.getStyles('width', 'height'),
|
||||
clone = this.clone,
|
||||
pos = clone.computePosition(this.element.getPosition(this.clone.getOffsetParent()));
|
||||
|
||||
var destroy = function(){
|
||||
this.removeEvent('cancel', destroy);
|
||||
clone.destroy();
|
||||
};
|
||||
|
||||
this.effect.element = clone;
|
||||
this.effect.start({
|
||||
top: pos.top,
|
||||
left: pos.left,
|
||||
width: dim.width,
|
||||
height: dim.height,
|
||||
opacity: 0.25
|
||||
}).addEvent('cancel', destroy).chain(destroy);
|
||||
} else {
|
||||
this.clone.destroy();
|
||||
}
|
||||
this.reset();
|
||||
},
|
||||
|
||||
reset: function(){
|
||||
this.idle = true;
|
||||
this.fireEvent('complete', this.element);
|
||||
},
|
||||
|
||||
serialize: function(){
|
||||
var params = Array.link(arguments, {
|
||||
modifier: Type.isFunction,
|
||||
index: function(obj){
|
||||
return obj != null;
|
||||
}
|
||||
});
|
||||
var serial = this.lists.map(function(list){
|
||||
return list.getChildren().map(params.modifier || function(element){
|
||||
return element.get('id');
|
||||
}, this);
|
||||
}, this);
|
||||
|
||||
var index = params.index;
|
||||
if (this.lists.length == 1) index = 0;
|
||||
return (index || index === 0) && index >= 0 && index < this.lists.length ? serial[index] : serial;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
/*
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user