diff options
Diffstat (limited to 'xstatic/pkg/angular_irdragndrop/data/irdragndrop.js')
-rw-r--r-- | xstatic/pkg/angular_irdragndrop/data/irdragndrop.js | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/xstatic/pkg/angular_irdragndrop/data/irdragndrop.js b/xstatic/pkg/angular_irdragndrop/data/irdragndrop.js new file mode 100644 index 0000000..2b7c383 --- /dev/null +++ b/xstatic/pkg/angular_irdragndrop/data/irdragndrop.js @@ -0,0 +1,184 @@ +(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);
\ No newline at end of file |