@duoduo-oba/ng-devui
Version:
DevUI components based on Angular
1,272 lines • 134 kB
JavaScript
/**
* @fileoverview added by tsickle
* Generated from: directives/droppable.directive.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import * as tslib_1 from "tslib";
import { distinctUntilChanged, filter } from 'rxjs/operators';
import { Directive, ElementRef, HostListener, Input, Output, EventEmitter, Renderer2, NgZone } from '@angular/core';
import { DropEvent } from '../shared/drop-event.model';
import { DragDropService } from '../services/drag-drop.service';
import { Utils } from '../shared/utils';
import { Subscription, fromEvent, Subject } from 'rxjs';
var DroppableDirective = /** @class */ (function () {
function DroppableDirective(el, renderer, dragDropService, ngZone) {
var _this = this;
this.el = el;
this.renderer = renderer;
this.dragDropService = dragDropService;
this.ngZone = ngZone;
/**
* Event fired when Drag dragged element enters a valid drop target.
*/
this.dragEnterEvent = new EventEmitter();
/**
* Event fired when an element is being dragged over a valid drop target
*/
this.dragOverEvent = new EventEmitter();
/**
* Event fired when a dragged element leaves a valid drop target.
*/
this.dragLeaveEvent = new EventEmitter();
/**
* Event fired when an element is dropped on a valid drop target.
*/
this.dropEvent = new EventEmitter(); // 注意使用了虚拟滚动后,DropEvent中的dragFromIndex无效
/**
* Defines compatible drag drop pairs. Values must match both in draggable and droppable.dropScope.
*/
this.dropScope = 'default';
this.placeholderTag = 'div';
this.placeholderStyle = { backgroundColor: ['#6A98E3', "var(--brand-4, '#859bff')"], opacity: '.4' };
/**
* 设置placeholder的提示性文字,仅支持文本(安全起见)
*/
this.placeholderText = '';
/**
* 用于允许拖动到元素上,方便树形结构的拖动可以成为元素的子节点
*/
this.allowDropOnItem = false;
/**
* 是否启用越过立即交换位置的算法, 不能与allowDropOnItem一起用,allowDropOnItem为true时,此规则无效
*
*/
this.switchWhileCrossEdge = false;
/**
* sortable的情况下,拖动到可以drop但不在sortContainer里的时候默认drop的位置
*
*/
this.defaultDropPosition = 'closest';
// 用于修复dragleave多次触发
this.dragCount = 0;
this.dropIndex = undefined;
/* 协同拖拽需要 */
this.placeholderInsertionEvent = new Subject();
this.placeholderRenderEvent = new Subject();
this.dropSortCountSelectorFilterFn = (/**
* @param {?} value
* @return {?}
*/
function (value) {
return Utils.matches(value, _this.dropSortCountSelector)
|| value.contains(_this.placeholder)
|| value === _this.dragDropService.dragOriginPlaceholder;
});
this.setPlaceholder = (/**
* @return {?}
*/
function () {
_this.ngZone.runOutsideAngular((/**
* @return {?}
*/
function () {
_this.placeholder.style.width = _this.dragDropService.dragOffset.width + 'px';
_this.placeholder.style.height = _this.dragDropService.dragOffset.height + 'px'; // ie下clientHeight为0
Utils.addElStyles(_this.placeholder, _this.placeholderStyle);
_this.placeholderRenderEvent.next({ width: _this.dragDropService.dragOffset.width, height: _this.dragDropService.dragOffset.height });
}));
});
}
/**
* @return {?}
*/
DroppableDirective.prototype.ngOnInit = /**
* @return {?}
*/
function () {
var _this = this;
this.placeholder = document.createElement(this.placeholderTag);
this.placeholder.className = 'drag-placeholder';
this.placeholder.innerText = this.placeholderText;
this.dragStartSubscription = this.dragDropService.dragStartEvent.subscribe((/**
* @return {?}
*/
function () { return _this.setPlaceholder(); }));
if (this.dragDropService.draggedEl) {
this.setPlaceholder(); // 虚拟滚动生成元素过程中
}
this.dropEndSubscription = this.dragDropService.dropEvent.subscribe((/**
* @return {?}
*/
function () {
if (_this.dragDropService.draggedEl) {
if (!_this.dragDropService.dragFollow) {
_this.renderer.setStyle(_this.dragDropService.draggedEl, 'display', '');
_this.dragDropService.dragElShowHideEvent.next(true);
}
}
_this.removePlaceholder();
_this.overElement = undefined;
_this.allowDropCache = undefined;
_this.dragElIndex = undefined;
_this.dropIndex = undefined;
}));
this.dragEndSubscription = this.dragDropService.dragEndEvent.subscribe((/**
* @return {?}
*/
function () {
if (_this.dragDropService.draggedEl) {
if (!_this.dragDropService.dragFollow) {
_this.renderer.setStyle(_this.dragDropService.draggedEl, 'display', '');
_this.dragDropService.dragElShowHideEvent.next(true);
}
}
_this.removePlaceholder();
_this.dragCount = 0;
_this.overElement = undefined;
_this.allowDropCache = undefined;
_this.dragElIndex = undefined;
_this.dropIndex = undefined;
}));
this.ngZone.runOutsideAngular((/**
* @return {?}
*/
function () {
_this.dragPartEventSub = new Subscription();
_this.dragPartEventSub.add(fromEvent(_this.el.nativeElement, 'dragover')
.pipe(filter((/**
* @param {?} event
* @return {?}
*/
function (event) { return _this.allowDrop(event); })), distinctUntilChanged((/**
* @param {?} prev
* @param {?} current
* @return {?}
*/
function (prev, current) {
/** @type {?} */
var bool = (prev.clientX === current.clientX && prev.clientY === current.clientY && prev.target === current.target);
if (bool) {
current.preventDefault();
current.stopPropagation();
}
return bool;
})))
.subscribe((/**
* @param {?} event
* @return {?}
*/
function (event) { return _this.dragOver(event); })));
_this.dragPartEventSub.add(fromEvent(_this.el.nativeElement, 'dragenter').subscribe((/**
* @param {?} event
* @return {?}
*/
function (event) { return _this.dragEnter(event); })));
_this.dragPartEventSub.add(fromEvent(_this.el.nativeElement, 'dragleave').subscribe((/**
* @param {?} event
* @return {?}
*/
function (event) { return _this.dragLeave(event); })));
}));
};
/**
* @return {?}
*/
DroppableDirective.prototype.ngAfterViewInit = /**
* @return {?}
*/
function () {
if (this.el.nativeElement.hasAttribute('d-sortable')) {
this.sortContainer = this.el.nativeElement;
}
else {
this.sortContainer = this.el.nativeElement.querySelector('[d-sortable]');
}
this.sortDirection = this.sortContainer ? this.sortContainer.getAttribute('dsortable') || 'v' : 'v';
this.sortDirectionZMode = this.sortContainer ? (this.sortContainer.getAttribute('d-sortable-zmode') === 'true' || false) : false;
};
/**
* @return {?}
*/
DroppableDirective.prototype.ngOnDestroy = /**
* @return {?}
*/
function () {
this.dragStartSubscription.unsubscribe();
this.dragEndSubscription.unsubscribe();
this.dropEndSubscription.unsubscribe();
if (this.dragPartEventSub) {
this.dragPartEventSub.unsubscribe();
}
};
/**
* @param {?} e
* @return {?}
*/
DroppableDirective.prototype.dragEnter = /**
* @param {?} e
* @return {?}
*/
function (e) {
this.dragCount++;
e.preventDefault(); // ie11 dragenter需要preventDefault否则dragover无效
this.dragEnterEvent.emit(e);
};
/**
* @param {?} e
* @return {?}
*/
DroppableDirective.prototype.dragOver = /**
* @param {?} e
* @return {?}
*/
function (e) {
var _this = this;
if (this.allowDrop(e)) {
if (this.dragDropService.dropTargets.indexOf(this.el) === -1) {
this.dragDropService.dropTargets.forEach((/**
* @param {?} el
* @return {?}
*/
function (el) {
/** @type {?} */
var placeHolderEl = el.nativeElement.querySelector('.drag-placeholder');
if (placeHolderEl) {
placeHolderEl.parentElement.removeChild(placeHolderEl);
}
Utils.removeClass(el, _this.dragOverClass);
_this.removeDragoverItemClass(el.nativeElement);
}));
this.dragDropService.dropTargets = [this.el];
this.overElement = undefined; // 否则会遇到上一次position= 这一次的然后不刷新和插入。
}
Utils.addClass(this.el, this.dragOverClass);
/** @type {?} */
var hitPlaceholder = this.dragDropService.dragOriginPlaceholder && this.dragDropService.dragOriginPlaceholder.contains(e.target);
if (this.sortContainer && ((hitPlaceholder && this.overElement === undefined)
|| !(e.target.contains(this.placeholder) || hitPlaceholder)
|| (this.switchWhileCrossEdge && !this.placeholder.contains(e.target) && !hitPlaceholder) // 越边交换回折的情况需要重新计算
|| (!this.sortContainer.contains(e.target) && this.defaultDropPosition === 'closest') // 就近模式需要重新计算
)) {
/** @type {?} */
var overElement = this.findSortableEl(e);
if (!(this.overElement && overElement) || this.overElement.index !== overElement.index
|| (this.allowDropOnItem && this.overElement.position !== overElement.position
&& (this.overElement.position === 'inside' || overElement.position === 'inside'))) {
// overElement的参数有刷新的时候才进行插入等操作
this.overElement = overElement;
this.insertPlaceholder(overElement);
this.removeDragoverItemClass(this.sortContainer, overElement);
if (overElement.position === 'inside' && this.dragOverItemClass) {
Utils.addClass(overElement.el, this.dragOverItemClass);
}
}
else {
this.overElement = overElement;
}
}
else {
if (this.sortContainer && this.overElement && this.overElement.el) {
if (!this.overElement.el.contains(e.target)) {
this.overElement.realEl = e.target;
}
else {
this.overElement.realEl = undefined;
}
}
}
if (this.dragDropService.draggedEl) {
if (!this.dragDropService.dragFollow) {
this.renderer.setStyle(this.dragDropService.draggedEl, 'display', 'none');
this.dragDropService.dragElShowHideEvent.next(false);
if (this.dragDropService.dragOriginPlaceholder) {
this.renderer.setStyle(this.dragDropService.dragOriginPlaceholder, 'display', 'block');
}
}
}
e.preventDefault();
e.stopPropagation();
this.dragOverEvent.emit(e);
}
};
/**
* @param {?} e
* @return {?}
*/
DroppableDirective.prototype.dragLeave = /**
* @param {?} e
* @return {?}
*/
function (e) {
// 用于修复包含子元素时,多次触发dragleave
this.dragCount--;
if (0 === this.dragCount) {
if (this.dragDropService.dropTargets.indexOf(this.el) !== -1) {
this.dragDropService.dropTargets = [];
}
Utils.removeClass(this.el, this.dragOverClass);
this.removePlaceholder();
this.removeDragoverItemClass(this.el.nativeElement);
this.overElement = undefined;
this.dragElIndex = undefined;
this.dropIndex = undefined;
}
e.preventDefault();
this.dragLeaveEvent.emit(e);
};
/**
* @param {?} e
* @return {?}
*/
DroppableDirective.prototype.drop = /**
* @param {?} e
* @return {?}
*/
function (e) {
var _this = this;
if (!this.allowDrop(e)) {
return;
}
this.dragCount = 0;
Utils.removeClass(this.el, this.dragOverClass);
this.removeDragoverItemClass(this.sortContainer);
this.removePlaceholder();
e.preventDefault();
e.stopPropagation();
this.dragDropService.dropOnOrigin = this.isDragPlaceholderPosition(this.dropIndex);
/** @type {?} */
var draggedElIdentity = this.dragDropService.draggedElIdentity;
this.dragDropService.draggedElIdentity = undefined; // 需要提前清除,避免新生成的节点复用了id 刷新了dragOriginPlaceholder
// 需要提前清除,避免新生成的节点复用了id 刷新了dragOriginPlaceholder
/** @type {?} */
var batchDraggble = [];
if (this.dragDropService.batchDragData && this.dragDropService.batchDragData.length > 1) {
batchDraggble = this.dragDropService.batchDragData.map((/**
* @param {?} dragData
* @return {?}
*/
function (dragData) { return dragData.draggable; }))
.filter((/**
* @param {?} draggable
* @return {?}
*/
function (draggable) { return draggable && draggable.el.nativeElement !== _this.dragDropService.draggedEl; }));
}
this.dropEvent.emit(new DropEvent(e, this.dragDropService.dragData, this.dragDropService.dropEvent, this.dropSortVirtualScrollOption ? this.getRealIndex(this.dropIndex, this.dropFlag) : this.dropIndex, this.sortContainer ? this.checkSelfFromIndex(this.dragDropService.draggedEl) : -1, this.dragDropService.dropOnItem, this.dragDropService.dropOnOrigin, (this.dragDropService.batchDragging)
? this.dragDropService.getBatchDragData(draggedElIdentity)
: undefined));
// 如果drop之后drag元素被删除,则不会发生dragend事件,需要代替dragend清理
if (this.dragDropService.dragFollow) {
this.dragDropService.disableDraggedCloneNodeFollowMouse();
}
else {
this.renderer.setStyle(this.dragDropService.draggedEl, 'display', '');
this.dragDropService.dragElShowHideEvent.next(false);
}
if (batchDraggble.length > 0 && this.dragDropService.batchDragging) {
batchDraggble.forEach((/**
* @param {?} draggable
* @return {?}
*/
function (draggable) {
if (!draggable.originPlaceholder || draggable.originPlaceholder.show === false) {
draggable.el.nativeElement.style.display = '';
}
else if (draggable.originPlaceholder.removeDelay > 0 && !_this.dragDropService.dropOnOrigin) {
draggable.delayRemoveOriginPlaceholder(false);
}
else {
draggable.el.nativeElement.style.display = '';
draggable.removeOriginPlaceholder(false);
}
}));
}
this.dragDropService.dropEvent.next(e);
this.dragDropService.dragData = undefined;
this.dragDropService.scope = undefined;
this.dragDropService.draggedEl = undefined;
this.dragDropService.dragFollow = undefined;
this.dragDropService.dragFollowOptions = undefined;
this.dragDropService.dragOffset = undefined;
this.dragDropService.dropOnOrigin = undefined;
this.dragDropService.batchDragging = false;
this.dragDropService.batchDragStyle = undefined;
this.dragDropService.dragPreviewDirective = undefined;
};
/**
* @param {?} e
* @return {?}
*/
DroppableDirective.prototype.allowDrop = /**
* @param {?} e
* @return {?}
*/
function (e) {
var _this = this;
if (!e) {
return false;
}
if (this.allowDropCache !== undefined) {
return this.allowDropCache;
}
/** @type {?} */
var allowed = false;
if (typeof this.dropScope === 'string') {
if (typeof this.dragDropService.scope === 'string') {
allowed = this.dragDropService.scope === this.dropScope;
}
if (this.dragDropService.scope instanceof Array) {
allowed = this.dragDropService.scope.indexOf(this.dropScope) > -1;
}
}
if (this.dropScope instanceof Array) {
if (typeof this.dragDropService.scope === 'string') {
allowed = this.dropScope.indexOf(this.dragDropService.scope) > -1;
}
if (this.dragDropService.scope instanceof Array) {
allowed = this.dropScope.filter((/**
* @param {?} item
* @return {?}
*/
function (item) {
return _this.dragDropService.scope.indexOf(item) !== -1;
})).length > 0;
}
}
this.allowDropCache = allowed;
return allowed;
};
// 查询需要插入placeholder的位置
// 查询需要插入placeholder的位置
/**
* @private
* @param {?} event
* @return {?}
*/
DroppableDirective.prototype.findSortableEl =
// 查询需要插入placeholder的位置
/**
* @private
* @param {?} event
* @return {?}
*/
function (event) {
var _this = this;
/** @type {?} */
var moveElement = event.target;
/** @type {?} */
var overElement = null;
if (!this.sortContainer) {
return overElement;
}
overElement = { index: 0, el: null, position: 'before' };
this.dropIndex = 0;
this.dropFlag = undefined;
/** @type {?} */
var childEls = Utils.slice(this.sortContainer.children);
// 删除虚拟滚动等的额外元素不需要计算的元素
if (this.dropSortCountSelector) {
childEls = childEls.filter(this.dropSortCountSelectorFilterFn);
}
// 如果没有主动删除则删除多余的originplaceholder
if (childEls.some((/**
* @param {?} el
* @return {?}
*/
function (el) {
return el !== _this.dragDropService.dragOriginPlaceholder
&& el.classList.contains('drag-origin-placeholder');
}))) {
childEls = childEls.filter((/**
* @param {?} el
* @return {?}
*/
function (el) {
return !(el.classList.contains('drag-origin-placeholder')
&& el !== _this.dragDropService.dragOriginPlaceholder);
}));
}
// 要先删除clonenode否则placeholderindex是错的
if (this.dragDropService.dragFollow && this.dragDropService.dragCloneNode) {
/** @type {?} */
var cloneNodeIndex = childEls.findIndex((/**
* @param {?} value
* @return {?}
*/
function (value) { return value === _this.dragDropService.dragCloneNode; }));
if (-1 !== cloneNodeIndex) {
childEls.splice(cloneNodeIndex, 1);
}
}
// 计算index数组需要删除源占位符
if (this.dragDropService.dragOriginPlaceholder) {
/** @type {?} */
var dragOriginPlaceholderIndex = childEls.findIndex((/**
* @param {?} value
* @return {?}
*/
function (value) { return value === _this.dragDropService.dragOriginPlaceholder; }));
if (-1 !== dragOriginPlaceholderIndex) {
this.dragElIndex = dragOriginPlaceholderIndex - 1;
childEls.splice(dragOriginPlaceholderIndex, 1);
}
else {
this.dragElIndex = -1;
}
}
else {
this.dragElIndex = -1;
}
// 查询是否已经插入了placeholder
/** @type {?} */
var placeholderIndex = childEls.findIndex((/**
* @param {?} value
* @return {?}
*/
function (value) { return value.contains(_this.placeholder); }));
// 删除placeholder
if (-1 !== placeholderIndex) {
childEls.splice(placeholderIndex, 1);
}
// 如果还有placeholder在前面 dragElIndex得再减一
if (-1 !== placeholderIndex && -1 !== this.dragElIndex && placeholderIndex < this.dragElIndex) {
this.dragElIndex--;
}
/** @type {?} */
var positionIndex = -1 !== placeholderIndex ? placeholderIndex : this.dragElIndex;
/** @type {?} */
var currentIndex = childEls.findIndex((/**
* @param {?} value
* @return {?}
*/
function (value) { return (value.contains(moveElement)
|| value.nextElementSibling === moveElement
&& value.nextElementSibling.classList.contains('drag-origin-placeholder')); }));
if (this.switchWhileCrossEdge && !this.allowDropOnItem && childEls.length
&& -1 !== positionIndex
&& currentIndex > -1) { // 越过元素边界立即交换位置算法
// 越过元素边界立即交换位置算法
/** @type {?} */
var lastIndex = positionIndex;
// 解决抖动
/** @type {?} */
var realEl = this.overElement && (this.overElement.realEl || this.overElement.el);
if (-1 !== currentIndex && realEl === childEls[currentIndex]) {
this.dropIndex = this.overElement.index;
return this.overElement;
}
overElement = {
index: lastIndex > currentIndex ? currentIndex : (currentIndex + 1),
el: childEls[currentIndex],
position: lastIndex > currentIndex ? 'before' : 'after'
};
this.dragDropService.dropOnItem = false;
this.dropIndex = overElement.index;
return overElement;
}
if (moveElement === this.sortContainer
|| moveElement.classList.contains('drag-origin-placeholder')
|| moveElement === (this.dragDropService && this.dragDropService.dragOriginPlaceholder)
|| (!this.sortContainer.contains(moveElement) && this.defaultDropPosition === 'closest')) {
if (!childEls.length) {
this.dropIndex = 0;
this.dragDropService.dropOnItem = false;
return overElement;
}
// 落入A元素和B元素的间隙里
/** @type {?} */
var findInGap = false;
for (var i = 0; i < childEls.length; i++) {
/** @type {?} */
var targetElement = childEls[i];
// 处理非越边的落到side-origin-placeholder
if (childEls[i].nextSibling === moveElement
&& moveElement.classList.contains('drag-origin-placeholder')) {
/** @type {?} */
var position = this.calcPosition(event, moveElement);
this.dragDropService.dropOnItem = position === 'inside';
overElement = { index: position === 'after' ? (i + 1) : i, el: childEls[i], position: position };
this.dropIndex = overElement.index;
return overElement;
}
/** @type {?} */
var positionOutside = this.calcPositionOutside(event, targetElement);
if (positionOutside === 'before') {
this.dragDropService.dropOnItem = false;
overElement = { index: i, el: childEls[i], position: positionOutside, realEl: moveElement };
this.dropIndex = overElement.index;
findInGap = true;
break;
}
else {
// for 'notsure'
}
}
if (!findInGap) {
this.dragDropService.dropOnItem = false;
overElement = { index: childEls.length, el: childEls[childEls.length - 1], position: 'after', realEl: moveElement };
this.dropIndex = childEls.length;
}
return overElement;
}
if (!this.sortContainer.contains(moveElement)) {
if (this.defaultDropPosition === 'before') {
overElement = { index: 0, el: childEls.length ? childEls[0] : null, position: 'before', realEl: moveElement };
this.dropFlag = 'beforeAll';
}
else {
overElement = {
index: childEls.length,
el: childEls.length ? childEls[childEls.length - 1] : null,
position: 'after',
realEl: moveElement
};
this.dropFlag = 'afterAll';
}
this.dropIndex = overElement.index;
return overElement;
}
/** @type {?} */
var find = false;
for (var i = 0; i < childEls.length; i++) {
if (childEls[i].contains(moveElement)) {
/** @type {?} */
var targetElement = childEls[i];
/** @type {?} */
var position = this.calcPosition(event, targetElement);
this.dragDropService.dropOnItem = position === 'inside';
overElement = { index: position === 'after' ? (i + 1) : i, el: childEls[i], position: position };
this.dropIndex = overElement.index;
find = true;
break;
}
}
if (!find) {
if (childEls.length) {
overElement = { index: childEls.length, el: childEls[childEls.length - 1], position: 'after' };
}
this.dropIndex = childEls.length;
this.dragDropService.dropOnItem = false;
}
return overElement;
};
/**
* @private
* @param {?} event
* @param {?} targetElement
* @return {?}
*/
DroppableDirective.prototype.calcPosition = /**
* @private
* @param {?} event
* @param {?} targetElement
* @return {?}
*/
function (event, targetElement) {
/** @type {?} */
var rect = targetElement.getBoundingClientRect();
/** @type {?} */
var relY = event.clientY - (rect.y || rect.top);
/** @type {?} */
var relX = event.clientX - (rect.x || rect.left);
// 处理允许drop到元素自己
if (this.allowDropOnItem) {
/** @type {?} */
var dropOnItemEdge = {
// 有内嵌列表的时候需要修正元素的高度活宽度
height: (this.nestingTargetRect && this.nestingTargetRect.height || rect.height),
width: (this.nestingTargetRect && this.nestingTargetRect.width || rect.width)
};
/** @type {?} */
var threeQuartersOfHeight = dropOnItemEdge.height * 3 / 4;
/** @type {?} */
var threeQuartersOfWidth = dropOnItemEdge.width * 3 / 4;
/** @type {?} */
var AQuarterOfHeight = dropOnItemEdge.height * 1 / 4;
/** @type {?} */
var AQuarterOfWidth = dropOnItemEdge.width * 1 / 4;
if (this.sortDirectionZMode) {
/** @type {?} */
var slashPosition = (relY / dropOnItemEdge.height + relX / dropOnItemEdge.width);
if (slashPosition > 0.3 && slashPosition <= 0.7) {
return 'inside';
}
else if (slashPosition > 0.7) {
/** @type {?} */
var slashPositionNesting = ((relY - rect.height + dropOnItemEdge.height) / dropOnItemEdge.height
+ (relX - rect.width + dropOnItemEdge.width) / dropOnItemEdge.width);
if (slashPositionNesting <= 0.7) {
return 'inside';
}
}
}
if ((this.sortDirection === 'v' && relY > AQuarterOfHeight && relY <= threeQuartersOfHeight) ||
(this.sortDirection !== 'v' && relX > AQuarterOfWidth && relX <= threeQuartersOfWidth)) {
// 高度的中间1/4 - 3/4 属于drop到元素自己
return 'inside';
}
else if ((this.sortDirection === 'v' && relY > threeQuartersOfHeight
&& relY <= (rect.height - AQuarterOfHeight)) ||
(this.sortDirection !== 'v' && relX > threeQuartersOfWidth
&& relX <= (rect.width - AQuarterOfWidth))) {
// 内嵌列表后中间区域都属于inside
return 'inside';
}
}
if (this.sortDirectionZMode) {
if ((relY / rect.height + relX / rect.width) < 1) {
return 'before';
}
return 'after';
}
// 其他情况保持原来的属于上半部分或者下半部分
if ((this.sortDirection === 'v' && relY > (rect.height / 2)) ||
(this.sortDirection !== 'v' && relX > (rect.width / 2))) {
return 'after';
}
return 'before';
};
/**
* @private
* @param {?} event
* @param {?} targetElement
* @return {?}
*/
DroppableDirective.prototype.calcPositionOutside = /**
* @private
* @param {?} event
* @param {?} targetElement
* @return {?}
*/
function (event, targetElement) {
/** @type {?} */
var rect = this.getBoundingRectAndRealPosition(targetElement);
// targetElement.getBoundingClientRect();
/** @type {?} */
var relY = event.clientY - (rect.y || rect.top);
/** @type {?} */
var relX = event.clientX - (rect.x || rect.left);
if (this.sortDirectionZMode) {
if ((this.sortDirection === 'v' && (relY < 0 || (relY < rect.height && relX < 0)))
|| (this.sortDirection !== 'v' && (relX < 0 || (relX < rect.width && relY < 0)))) {
return 'before';
}
return 'notsure';
}
if ((this.sortDirection === 'v' && relY < (rect.height / 2)) ||
(this.sortDirection !== 'v' && relX < (rect.width / 2))) {
return 'before';
}
return 'notsure';
};
// 插入placeholder
// 插入placeholder
/**
* @private
* @param {?} overElement
* @return {?}
*/
DroppableDirective.prototype.insertPlaceholder =
// 插入placeholder
/**
* @private
* @param {?} overElement
* @return {?}
*/
function (overElement) {
var _this = this;
/** @type {?} */
var tempScrollTop = this.sortContainer.scrollTop;
/** @type {?} */
var tempScrollLeft = this.sortContainer.scrollLeft;
/** @type {?} */
var hitPlaceholder = false;
/** @type {?} */
var cmd;
/** @type {?} */
var getIndex = (/**
* @param {?} arr
* @param {?} el
* @param {?} defaultValue
* @return {?}
*/
function (arr, el, defaultValue) {
/** @type {?} */
var index = arr.indexOf(el);
return index > -1 ? index : defaultValue;
});
if (null !== overElement) {
/** @type {?} */
var sortContainerChildren = Utils.slice(this.sortContainer.children).filter((/**
* @param {?} el
* @return {?}
*/
function (el) { return el !== _this.dragDropService.dragCloneNode; }));
if (null === overElement.el) {
cmd = {
command: 'append'
};
this.sortContainer.appendChild(this.placeholder);
}
else {
if (overElement.position === 'inside') {
cmd = {
command: 'remove'
};
this.removePlaceholder();
}
else if (this.dragDropService.dragOriginPlaceholder && this.isDragPlaceholderPosition(overElement.index)) {
cmd = {
command: 'remove'
};
this.removePlaceholder();
hitPlaceholder = true;
}
else if (overElement.position === 'after') {
if (overElement.el.nextSibling && overElement.el.nextSibling.classList
&& overElement.el.nextSibling.classList.contains('drag-origin-placeholder')) {
// 针对多源占位符场景
cmd = {
command: 'insertBefore',
index: getIndex(sortContainerChildren, overElement.el.nextSibling.nextSibling, sortContainerChildren.length)
};
this.sortContainer.insertBefore(this.placeholder, overElement.el.nextSibling.nextSibling);
}
else {
cmd = {
command: 'insertBefore',
index: getIndex(sortContainerChildren, overElement.el.nextSibling, sortContainerChildren.length)
};
this.sortContainer.insertBefore(this.placeholder, overElement.el.nextSibling);
}
}
else {
cmd = {
command: 'insertBefore',
index: getIndex(sortContainerChildren, overElement.el, sortContainerChildren.length)
};
this.sortContainer.insertBefore(this.placeholder, overElement.el);
}
}
}
this.placeholderInsertionEvent.next(cmd);
this.sortContainer.scrollTop = tempScrollTop;
this.sortContainer.scrollLeft = tempScrollLeft;
if (this.dragDropService.dragOriginPlaceholder) {
if (hitPlaceholder) {
this.hitDragOriginPlaceholder();
}
else {
this.hitDragOriginPlaceholder(false);
}
}
};
/**
* @private
* @param {?} index
* @return {?}
*/
DroppableDirective.prototype.isDragPlaceholderPosition = /**
* @private
* @param {?} index
* @return {?}
*/
function (index) {
if (this.dragElIndex > -1 && (index === this.dragElIndex || index === this.dragElIndex + 1)) {
return true;
}
else {
return false;
}
};
/**
* @private
* @param {?=} bool
* @return {?}
*/
DroppableDirective.prototype.hitDragOriginPlaceholder = /**
* @private
* @param {?=} bool
* @return {?}
*/
function (bool) {
if (bool === void 0) { bool = true; }
/** @type {?} */
var placeholder = this.dragDropService.dragOriginPlaceholder;
if (bool) {
placeholder.classList.add('hit-origin-placeholder');
}
else {
placeholder.classList.remove('hit-origin-placeholder');
}
};
/**
* @private
* @return {?}
*/
DroppableDirective.prototype.removePlaceholder = /**
* @private
* @return {?}
*/
function () {
if (this.sortContainer && this.sortContainer.contains(this.placeholder)) {
this.sortContainer.removeChild(this.placeholder);
this.placeholderInsertionEvent.next({
command: 'remove'
});
}
};
/**
* @private
* @param {?} container
* @param {?=} overElement
* @return {?}
*/
DroppableDirective.prototype.removeDragoverItemClass = /**
* @private
* @param {?} container
* @param {?=} overElement
* @return {?}
*/
function (container, overElement) {
var e_1, _a;
if (this.dragOverItemClass) {
/** @type {?} */
var dragOverItemClassGroup = container.querySelectorAll('.' + this.dragOverItemClass);
if (dragOverItemClassGroup && dragOverItemClassGroup.length > 0) {
try {
for (var dragOverItemClassGroup_1 = tslib_1.__values(dragOverItemClassGroup), dragOverItemClassGroup_1_1 = dragOverItemClassGroup_1.next(); !dragOverItemClassGroup_1_1.done; dragOverItemClassGroup_1_1 = dragOverItemClassGroup_1.next()) {
var element = dragOverItemClassGroup_1_1.value;
if (overElement) {
if (element !== overElement.el || overElement.position !== 'inside') {
Utils.removeClass(element, this.dragOverItemClass);
}
}
else {
Utils.removeClass(element, this.dragOverItemClass);
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (dragOverItemClassGroup_1_1 && !dragOverItemClassGroup_1_1.done && (_a = dragOverItemClassGroup_1.return)) _a.call(dragOverItemClassGroup_1);
}
finally { if (e_1) throw e_1.error; }
}
}
}
};
/**
* @private
* @param {?} el
* @return {?}
*/
DroppableDirective.prototype.checkSelfFromIndex = /**
* @private
* @param {?} el
* @return {?}
*/
function (el) {
/** @type {?} */
var fromIndex = -1;
if (!this.sortContainer.contains(el)) {
return fromIndex;
}
/** @type {?} */
var childs = Utils.slice(this.sortContainer.children);
if (this.dropSortCountSelector) {
childs = childs.filter(this.dropSortCountSelectorFilterFn);
}
for (var i = 0; i < childs.length; i++) {
if (childs[i].contains(this.dragDropService.draggedEl)) {
fromIndex = i;
break;
}
}
return this.getRealIndex(fromIndex);
};
/**
* @private
* @param {?} index
* @param {?=} flag
* @return {?}
*/
DroppableDirective.prototype.getRealIndex = /**
* @private
* @param {?} index
* @param {?=} flag
* @return {?}
*/
function (index, flag) {
/** @type {?} */
var realIndex;
/** @type {?} */
var startIndex = this.dropSortVirtualScrollOption && this.dropSortVirtualScrollOption.startIndex || 0;
/** @type {?} */
var totalLength = this.dropSortVirtualScrollOption && this.dropSortVirtualScrollOption.totalLength;
if (flag === 'beforeAll') {
realIndex = 0;
}
else if (flag === 'afterAll') {
realIndex = totalLength || index;
}
else {
realIndex = startIndex + index;
}
return realIndex;
};
/**
* @param {?} targetElement
* @return {?}
*/
DroppableDirective.prototype.getBoundingRectAndRealPosition = /**
* @param {?} targetElement
* @return {?}
*/
function (targetElement) {
// 用于修复部分display none的元素获取到的top和left是0, 取它下一个元素的左上角为坐标
/** @type {?} */
var rect = targetElement.getBoundingClientRect();
var bottom = rect.bottom, right = rect.right, width = rect.width, height = rect.height;
if (rect.width === 0 && rect.height === 0 &&
(targetElement.style.display === 'none' || getComputedStyle(targetElement).display === 'none')) {
if (targetElement.nextElementSibling) {
var _a = targetElement.nextElementSibling.getBoundingClientRect(), realTop = _a.top, realLeft = _a.left;
rect = { x: realLeft, y: realTop, top: realTop, left: realLeft, bottom: bottom, right: right, width: width, height: height };
}
}
return rect;
};
/**
* @return {?}
*/
DroppableDirective.prototype.getSortContainer = /**
* @return {?}
*/
function () {
return this.sortContainer;
};
DroppableDirective.decorators = [
{ type: Directive, args: [{
selector: '[dDroppable]'
},] }
];
/** @nocollapse */
DroppableDirective.ctorParameters = function () { return [
{ type: ElementRef },
{ type: Renderer2 },
{ type: DragDropService },
{ type: NgZone }
]; };
DroppableDirective.propDecorators = {
dragEnterEvent: [{ type: Output }],
dragOverEvent: [{ type: Output }],
dragLeaveEvent: [{ type: Output }],
dropEvent: [{ type: Output }],
dragOverClass: [{ type: Input }],
dropScope: [{ type: Input }],
placeholderTag: [{ type: Input }],
placeholderStyle: [{ type: Input }],
placeholderText: [{ type: Input }],
allowDropOnItem: [{ type: Input }],
dragOverItemClass: [{ type: Input }],
nestingTargetRect: [{ type: Input }],
switchWhileCrossEdge: [{ type: Input }],
defaultDropPosition: [{ type: Input }],
dropSortCountSelector: [{ type: Input }],
dropSortVirtualScrollOption: [{ type: Input }],
drop: [{ type: HostListener, args: ['drop', ['$event'],] }]
};
return DroppableDirective;
}());
export { DroppableDirective };
if (false) {
/**
* Event fired when Drag dragged element enters a valid drop target.
* @type {?}
*/
DroppableDirective.prototype.dragEnterEvent;
/**
* Event fired when an element is being dragged over a valid drop target
* @type {?}
*/
DroppableDirective.prototype.dragOverEvent;
/**
* Event fired when a dragged element leaves a valid drop target.
* @type {?}
*/
DroppableDirective.prototype.dragLeaveEvent;
/**
* Event fired when an element is dropped on a valid drop target.
* @type {?}
*/
DroppableDirective.prototype.dropEvent;
/**
* CSS class applied on the draggable that is applied when the item is being dragged.
* @type {?}
*/
DroppableDirective.prototype.dragOverClass;
/**
* Defines compatible drag drop pairs. Values must match both in draggable and droppable.dropScope.
* @type {?}
*/
DroppableDirective.prototype.dropScope;
/** @type {?} */
DroppableDirective.prototype.placeholderTag;
/** @type {?} */
DroppableDirective.prototype.placeholderStyle;
/**
* 设置placeholder的提示性文字,仅支持文本(安全起见)
* @type {?}
*/
DroppableDirective.prototype.placeholderText;
/**
* 用于允许拖动到元素上,方便树形结构的拖动可以成为元素的子节点
* @type {?}
*/
DroppableDirective.prototype.allowDropOnItem;
/**
* allowDropOnItem为true时,才有效,用于允许拖动到元素上后,被命中的元素增加样式
* @type {?}
*/
DroppableDirective.prototype.dragOverItemClass;
/**
* 用于修正有内嵌列表后,父项高度被撑大,此处height,width为父项自己的高度(用于纵向拖动),宽度(用于横向拖动)
*
* @type {?}
*/
DroppableDirective.prototype.nestingTargetRect;
/**
* 是否启用越过立即交换位置的算法, 不能与allowDropOnItem一起用,allowDropOnItem为true时,此规则无效
*
* @type {?}
*/
DroppableDirective.prototype.switchWhileCrossEdge;
/**
* sortable的情况下,拖动到可以drop但不在sortContainer里的时候默认drop的位置
*
* @type {?}
*/
DroppableDirective.prototype.defaultDropPosition;
/**
* sortable的情况下,列表如果使用了virtual scroll等部分加载技术时候返回正确的dropIndex
*
* @type {?}
*/
DroppableDirective.prototype.dropSortCountSelector;
/** @type {?} */
DroppableDirective.prototype.dropSortVirtualScrollOption;
/**
* @type {?}
* @private
*/
DroppableDirective.prototype.dropFlag;
/**
* @type {?}
* @private
*/
DroppableDirective.prototype.sortContainer;
/**
* @type {?}
* @private
*/
DroppableDirective.prototype.sortDirection;
/**
* @type {?}
* @private
*/
DroppableDirective.prototype.sortDirectionZMode;
/**
* @type {?}
* @private
*/
DroppableDirective.prototype.placeholder;
/**
* @type {?}
* @private
*/
DroppableDirective.prototype.dragCount;
/**
* @type {?}
* @private
*/
DroppableDirective.prototype.dropIndex;
/**
* @type {?}
* @private
*/
DroppableDirective.prototype.dragStartSubscription;
/**
* @type {?}
* @private
*/
DroppableDirective.prototype.dragEndSubscription;
/**
* @type {?}
* @private
*/
DroppableDirective.prototype.dropEndSubscription;
/**
* @type {?}
* @private
*/
DroppableDirective.prototype.overElement;
/**
* @type {?}
* @private
*/
DroppableDirective.prototype.dragPartEventSub;
/**
* @type {?}
* @private
*/
DroppableDirective.prototype.allowDropCache;
/**
* @type {?}
* @private
*/
DroppableDirective.prototype.dragElIndex;
/** @type {?} */
DroppableDirective.prototype.placeholderInsertionEvent;
/** @type {?} */
DroppableDirective.prototype.placeholderRenderEvent;
/**
* @type {?}
* @private
*/
DroppableDirective.prototype.dropSortCountSelectorFilterFn;
/** @type {?} */
DroppableDirective.prototype.setPlaceholder;
/**
* @type {?}
* @protected
*/
DroppableDirective.prototype.el;
/**
* @type {?}
* @private
*/
DroppableDirective.prototype.renderer;
/**
* @type {?}
* @private
*/
DroppableDirective.prototype.dragDropService;
/**
* @type {?}
* @private
*/
DroppableDirective.prototype.ngZone;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJvcHBhYmxlLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25nLWRldnVpL2RyYWdkcm9wLyIsInNvdXJjZXMiOlsiZGlyZWN0aXZlcy9kcm9wcGFibGUuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM5RCxPQUFPLEVBQ0wsU0FBUyxFQUNULFVBQVUsRUFDVixZQUFZLEVBQ1osS0FBSyxFQUNMLE1BQU0sRUFDTixZQUFZLEVBQ1osU0FBUyxFQUlULE1BQU0sRUFDUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDdkQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQ2hFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN4QyxPQUFPLEVBQUUsWUFBWSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFLeEQ7SUF3R0ksNEJBQXNCLEVBQWMsRUFBVSxRQUFtQixFQUFVLGVBQWdDLEVBQVUsTUFBYztRQUFuSSxpQkFFQztRQUZxQixPQUFFLEdBQUYsRUFBRSxDQUFZO1FBQVUsYUFBUSxHQUFSLFFBQVEsQ0FBVztRQUFVLG9CQUFlLEdBQWYsZUFBZSxDQUFpQjtRQUFVLFdBQU0sR0FBTixNQUFNLENBQVE7Ozs7UUFoR3pILG1CQUFjLEdBQXNCLElBQUksWUFBWSxFQUFFLENBQUM7Ozs7UUFLdkQsa0JBQWEsR0FBc0IsSUFBSSxZQUFZLEVBQUUsQ0FBQzs7OztRQUt0RCxtQkFBYyxHQUFzQixJQUFJLFlBQVksRUFBRSxDQUFDOzs7O1FBS3ZELGNBQVMsR0FBNEIsSUFBSSxZQUFZLEVBQUUsQ0FBQyxDQUFDLHdDQUF3Qzs7OztRQVVsRyxjQUFTLEdBQTJCLFNBQVMsQ0FBQztRQUU5QyxtQkFBYyxHQUFHLEtBQUssQ0FBQztRQUV2QixxQkFBZ0IsR0FBUSxFQUFDLGVBQWUsRUFBRSxDQUFDLFNBQVMsRUFBRSwyQkFBMkIsQ0FBQyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUMsQ0FBQzs7OztRQUtuRyxvQkFBZSxHQUFHLEVBQUUsQ0FBQzs7OztRQUtyQixvQkFBZSxHQUFHLEtBQUssQ0FBQzs7Ozs7UUFleEIseUJBQW9CLEdBQUcsS0FBSyxDQUFDOzs7OztRQUs3Qix3QkFBbUIsR0FBbUMsU0FBUyxDQUFDOztRQW1CakUsY0FBUyxHQUFHLENBQUMsQ0FBQztRQUVkLGNBQVMsR0FBRyxTQUFTLENBQUM7O1FBYTlCLDhCQUF5QixHQUFHLElBQUksT0FBTyxFQUFpQyxDQUFDO1FBQ3pFLDJCQUFzQixHQUFHLElBQUksT0FBTyxFQUFPLENBQUM7UUFvUXRDLGtDQUE2Qjs7OztRQUFHLFVBQUMsS0FBSztZQUM1QyxPQUFPLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEtBQUksQ0FBQyxxQkFBcUIsQ0FBQzttQkFDbEQsS0F