
The release .2 on PyPi already includes changes acted uppon in Horizon. This patch commits those changes to stackforge. It also adds a .gitreview file. Change-Id: Ibc25f66dba97c2121b5d7fe485175d7cd76b6267
184 lines
6.6 KiB
JavaScript
184 lines
6.6 KiB
JavaScript
(function (ng) {
|
|
'use strict';
|
|
|
|
function isJqueryEventDataTransfer(){
|
|
return window.jQuery && (-1 == window.jQuery.event.props.indexOf('dataTransfer'));
|
|
}
|
|
|
|
if (isJqueryEventDataTransfer()) {
|
|
window.jQuery.event.props.push('dataTransfer');
|
|
}
|
|
|
|
var module = ng.module('lrDragNDrop', []);
|
|
|
|
module.service('lrDragStore', ['$document', function (document) {
|
|
|
|
var store = {};
|
|
|
|
this.hold = function hold(key, item, collectionFrom, safe) {
|
|
store[key] = {
|
|
item: item,
|
|
collection: collectionFrom,
|
|
safe: safe === true
|
|
}
|
|
};
|
|
|
|
this.get = function (namespace) {
|
|
var
|
|
modelItem = store[namespace], itemIndex;
|
|
|
|
if (modelItem) {
|
|
itemIndex = modelItem.collection.indexOf(modelItem.item);
|
|
return modelItem.safe === true ? modelItem.item : modelItem.collection.splice(itemIndex, 1)[0];
|
|
} else {
|
|
return null;
|
|
}
|
|
};
|
|
|
|
this.clean = function clean() {
|
|
store = {};
|
|
};
|
|
|
|
this.isHolding = function (namespace) {
|
|
return store[namespace] !== undefined;
|
|
};
|
|
|
|
document.bind('dragend', this.clean);
|
|
}]);
|
|
|
|
module.service('lrDragHelper', function () {
|
|
var th = this;
|
|
|
|
th.parseRepeater = function(scope, attr) {
|
|
var
|
|
repeatExpression = attr.ngRepeat,
|
|
match;
|
|
|
|
if (!repeatExpression) {
|
|
throw Error('this directive must be used with ngRepeat directive');
|
|
}
|
|
match = repeatExpression.match(/^(.*\sin).(\S*)/);
|
|
if (!match) {
|
|
throw Error("Expected ngRepeat in form of '_item_ in _collection_' but got '" +
|
|
repeatExpression + "'.");
|
|
}
|
|
|
|
return scope.$eval(match[2]);
|
|
};
|
|
|
|
th.lrDragSrcDirective = function(store, safe) {
|
|
return function compileFunc(el, iattr) {
|
|
iattr.$set('draggable', true);
|
|
return function linkFunc(scope, element, attr) {
|
|
var
|
|
collection,
|
|
key = (safe === true ? attr.lrDragSrcSafe : attr.lrDragSrc ) || 'temp';
|
|
|
|
if(attr.lrDragData) {
|
|
scope.$watch(attr.lrDragData, function (newValue) {
|
|
collection = newValue;
|
|
});
|
|
} else {
|
|
collection = th.parseRepeater(scope, attr);
|
|
}
|
|
|
|
element.bind('dragstart', function (evt) {
|
|
store.hold(key, collection[scope.$index], collection, safe);
|
|
if(angular.isDefined(evt.dataTransfer)) {
|
|
evt.dataTransfer.setData('text/html', null); //FF/jQuery fix
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
module.directive('lrDragSrc', ['lrDragStore', 'lrDragHelper', function (store, dragHelper) {
|
|
return{
|
|
compile: dragHelper.lrDragSrcDirective(store)
|
|
};
|
|
}]);
|
|
|
|
module.directive('lrDragSrcSafe', ['lrDragStore', 'lrDragHelper', function (store, dragHelper) {
|
|
return{
|
|
compile: dragHelper.lrDragSrcDirective(store, true)
|
|
};
|
|
}]);
|
|
|
|
module.directive('lrDropTarget', ['lrDragStore', 'lrDragHelper', '$parse', function (store, dragHelper, $parse) {
|
|
return {
|
|
link: function (scope, element, attr) {
|
|
|
|
var
|
|
collection,
|
|
key = attr.lrDropTarget || 'temp',
|
|
classCache = null;
|
|
|
|
function isAfter(x, y) {
|
|
//check if below or over the diagonal of the box element
|
|
return (element[0].offsetHeight - x * element[0].offsetHeight / element[0].offsetWidth) < y;
|
|
}
|
|
|
|
function resetStyle() {
|
|
if (classCache !== null) {
|
|
element.removeClass(classCache);
|
|
classCache = null;
|
|
}
|
|
}
|
|
|
|
if(attr.lrDragData) {
|
|
scope.$watch(attr.lrDragData, function (newValue) {
|
|
collection = newValue;
|
|
});
|
|
} else {
|
|
collection = dragHelper.parseRepeater(scope, attr);
|
|
}
|
|
|
|
element.bind('drop', function (evt) {
|
|
var
|
|
collectionCopy = ng.copy(collection),
|
|
item = store.get(key),
|
|
dropIndex, i, l;
|
|
if (item !== null) {
|
|
dropIndex = scope.$index;
|
|
dropIndex = isAfter(evt.offsetX, evt.offsetY) ? dropIndex + 1 : dropIndex;
|
|
//srcCollection=targetCollection => we may need to apply a correction
|
|
if (collectionCopy.length > collection.length) {
|
|
for (i = 0, l = Math.min(dropIndex, collection.length - 1); i <= l; i++) {
|
|
if (!ng.equals(collectionCopy[i], collection[i])) {
|
|
dropIndex = dropIndex - 1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
scope.$apply(function () {
|
|
collection.splice(dropIndex, 0, item);
|
|
var fn = $parse(attr.lrDropSuccess) || ng.noop;
|
|
fn(scope, {e: evt, item: item, collection: collection});
|
|
});
|
|
evt.preventDefault();
|
|
resetStyle();
|
|
store.clean();
|
|
}
|
|
});
|
|
|
|
element.bind('dragleave', resetStyle);
|
|
|
|
element.bind('dragover', function (evt) {
|
|
var className;
|
|
if (store.isHolding(key)) {
|
|
className = isAfter(evt.offsetX, evt.offsetY) ? 'lr-drop-target-after' : 'lr-drop-target-before';
|
|
if (classCache !== className && classCache !== null) {
|
|
element.removeClass(classCache);
|
|
}
|
|
if (classCache !== className) {
|
|
element.addClass(className);
|
|
}
|
|
classCache = className;
|
|
}
|
|
evt.preventDefault();
|
|
});
|
|
}
|
|
};
|
|
}]);
|
|
})(angular); |