Files
sentcms/public/static/common/js/droppable.js
2020-03-21 11:17:53 +08:00

398 lines
12 KiB
JavaScript

/* ========================================================================
* ZUI: jquery.extensions.js
* http://zui.sexy
* ========================================================================
* Copyright (c) 2014 cnezsoft.com; Licensed MIT
* ======================================================================== */
(function($, window){
'use strict';
/* Check jquery */
if (typeof($) === 'undefined') throw new Error('ZUI requires jQuery');
// ZUI shared object
if (!$.zui) $.zui = function(obj)
{
if ($.isPlainObject(obj))
{
$.extend($.zui, obj);
}
};
var lastUuidAmend = 0;
$.zui(
{
uuid: function()
{
return (new Date()).getTime() * 1000 + (lastUuidAmend++) % 1000;
},
callEvent: function(func, event, proxy)
{
if ($.isFunction(func))
{
if (typeof proxy != 'undefined')
{
func = $.proxy(func, proxy);
}
var result = func(event);
if (event) event.result = result;
return !(result !== undefined && (!result));
}
return 1;
},
clientLang: function()
{
var lang;
var config = window.config;
if (typeof(config) != 'undefined' && config.clientLang)
{
lang = config.clientLang;
}
else
{
var hl = $('html').attr('lang');
lang = hl ? hl : (navigator.userLanguage || navigator.userLanguage || 'zh_cn');
}
return lang.replace('-', '_').toLowerCase();
}
});
$.fn.callEvent = function(name, event, model)
{
var $this = $(this);
var dotIndex = name.indexOf('.zui.');
var shortName = name;
if (dotIndex < 0 && model && model.name)
{
name += '.' + model.name;
}
else
{
shortName = name.substring(0, dotIndex);
}
var e = $.Event(name, event);
if ((typeof model === 'undefined') && dotIndex > 0)
{
model = $this.data(name.substring(dotIndex + 1));
}
if (model && model.options)
{
var func = model.options[shortName];
if ($.isFunction(func))
{
$.zui.callEvent(model.options[shortName], e, model);
}
}
return e;
};
}(jQuery, window));
/* ========================================================================
* ZUI: droppable.js
* http://zui.sexy
* ========================================================================
* Copyright (c) 2014 cnezsoft.com; Licensed MIT
* ======================================================================== */
(function($, document, Math)
{
'use strict';
var Droppable = function(element, options)
{
this.$ = $(element);
this.options = this.getOptions(options);
this.init();
};
Droppable.DEFAULTS = {
container: 'body',
// flex: false,
// nested: false,
deviation: 5,
sensorOffsetX: 0,
sensorOffsetY: 0
};
Droppable.prototype.getOptions = function(options)
{
options = $.extend(
{}, Droppable.DEFAULTS, this.$.data(), options);
return options;
};
Droppable.prototype.callEvent = function(name, params)
{
return $.zui.callEvent(this.options[name], params, this);
};
Droppable.prototype.init = function()
{
this.handleMouseEvents();
};
Droppable.prototype.handleMouseEvents = function()
{
var $e = this.$,
self = this,
setting = this.options,
BEFORE = 'before';
this.$triggerTarget = (setting.trigger ? ($.isFunction(setting.trigger) ? setting.trigger($e) : $e.find(setting.trigger)).first() : $e);
this.$triggerTarget.on('mousedown', function(event)
{
if (setting.hasOwnProperty(BEFORE) && $.isFunction(setting[BEFORE]))
{
var isSure = setting[BEFORE](
{
event: event,
element: $e
});
if (isSure !== undefined && (!isSure)) return;
}
var $targets = $.isFunction(setting.target) ? setting.target($e) : $(setting.target),
target = null,
shadow = null,
$container = $(setting.container).first(),
isIn = false,
isSelf = true,
oldCssPosition,
startOffset = $e.offset(),
startMouseOffset = {
left: event.pageX,
top: event.pageY
};
var containerOffset = $container.offset();
var clickOffset = {
left: startMouseOffset.left - startOffset.left,
top: startMouseOffset.top - startOffset.top
};
var lastMouseOffset = {
left: startMouseOffset.left,
top: startMouseOffset.top
};
$e.addClass('drag-from');
$(document).bind('mousemove', mouseMove).bind('mouseup', mouseUp);
event.preventDefault();
function mouseMove(event)
{
var mouseOffset = {
left: event.pageX,
top: event.pageY
};
// ignore small move
if (Math.abs(mouseOffset.left - startMouseOffset.left) < setting.deviation && Math.abs(mouseOffset.top - startMouseOffset.top) < setting.deviation) return;
if (shadow === null) // create shadow
{
var cssPosition = $container.css('position');
if (cssPosition != 'absolute' && cssPosition != 'relative' && cssPosition != 'fixed')
{
oldCssPosition = cssPosition;
$container.css('position', 'relative');
}
shadow = $e.clone().removeClass('drag-from').addClass('drag-shadow').css(
{
position: 'absolute',
width: $e.outerWidth(),
transition: 'none'
}).appendTo($container);
$e.addClass('dragging');
self.callEvent('start',
{
event: event,
element: $e
});
}
var offset = {
left: mouseOffset.left - clickOffset.left,
top: mouseOffset.top - clickOffset.top
};
var position = {
left: offset.left - containerOffset.left,
top: offset.top - containerOffset.top
};
shadow.css(position);
lastMouseOffset.left = mouseOffset.left;
lastMouseOffset.top = mouseOffset.top;
var isNew = false;
isIn = false;
if (!setting.flex)
{
$targets.removeClass('drop-to');
}
var newTarget = null;
$targets.each(function()
{
var t = $(this);
var tPos = t.offset();
var tW = t.outerWidth(),
tH = t.outerHeight(),
tX = tPos.left + setting.sensorOffsetX,
tY = tPos.top + setting.sensorOffsetY;
if (mouseOffset.left > tX && mouseOffset.top > tY && mouseOffset.left < (tX + tW) && mouseOffset.top < (tY + tH))
{
if (newTarget) newTarget.removeClass('drop-to');
newTarget = t;
if (!setting.nested) return false;
}
});
if (newTarget)
{
isIn = true;
var id = newTarget.data('id');
if ($e.data('id') != id) isSelf = false;
if (target === null || (target.data('id') !== id && (!isSelf))) isNew = true;
target = newTarget;
if (setting.flex)
{
$targets.removeClass('drop-to');
}
target.addClass('drop-to');
}
if (!setting.flex)
{
$e.toggleClass('drop-in', isIn);
shadow.toggleClass('drop-in', isIn);
}
else if (target !== null && target.length)
{
isIn = true;
}
self.callEvent('drag',
{
event: event,
isIn: isIn,
target: target,
element: $e,
isNew: isNew,
selfTarget: isSelf,
clickOffset: clickOffset,
offset: offset,
position:
{
left: offset.left - containerOffset.left,
top: offset.top - containerOffset.top
},
mouseOffset: mouseOffset
});
event.preventDefault();
}
function mouseUp(event)
{
if (oldCssPosition)
{
$container.css('position', oldCssPosition);
}
if (shadow === null)
{
$e.removeClass('drag-from');
$(document).unbind('mousemove', mouseMove).unbind('mouseup', mouseUp);
self.callEvent('always', {event: event, cancel: true});
return;
}
if (!isIn) target = null;
var isSure = true,
mouseOffset = {
left: event.pageX,
top: event.pageY
};
var offset = {
left: mouseOffset.left - clickOffset.left,
top: mouseOffset.top - clickOffset.top
};
var moveOffset = {
left: mouseOffset.left - lastMouseOffset.left,
top: mouseOffset.top - lastMouseOffset.top
};
lastMouseOffset.left = mouseOffset.left;
lastMouseOffset.top = mouseOffset.top;
var eventOptions = {
event: event,
isIn: isIn,
target: target,
element: $e,
isNew: (!isSelf) && target !== null,
selfTarget: isSelf,
offset: offset,
mouseOffset: mouseOffset,
position:
{
left: offset.left - containerOffset.left,
top: offset.top - containerOffset.top
},
lastMouseOffset: lastMouseOffset,
moveOffset: moveOffset
};
isSure = self.callEvent('beforeDrop', eventOptions);
if (isSure && isIn)
{
self.callEvent('drop', eventOptions);
}
$(document).unbind('mousemove', mouseMove).unbind('mouseup', mouseUp);
$targets.removeClass('drop-to');
$e.removeClass('dragging').removeClass('drag-from');
shadow.remove();
self.callEvent('finish', eventOptions);
self.callEvent('always', eventOptions);
event.preventDefault();
}
});
};
Droppable.prototype.reset = function()
{
this.$triggerTarget.off('mousedown');
this.handleMouseEvents();
};
$.fn.droppable = function(option)
{
return this.each(function()
{
var $this = $(this);
var data = $this.data('zui.droppable');
var options = typeof option == 'object' && option;
if (!data) $this.data('zui.droppable', (data = new Droppable(this, options)));
if (typeof option == 'string') data[option]();
});
};
$.fn.droppable.Constructor = Droppable;
}(jQuery, document, Math));