ag-grid
Version:
Advanced Data Grid / Data Table supporting Javascript / React / AngularJS / Web Components
288 lines (287 loc) • 13.8 kB
JavaScript
/**
* ag-grid - Advanced Data Grid / Data Table supporting Javascript / React / AngularJS / Web Components
* @version v18.1.2
* @link http://www.ag-grid.com/
* @license MIT
*/
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
var context_1 = require("../context/context");
var logger_1 = require("../logger");
var utils_1 = require("../utils");
var eventService_1 = require("../eventService");
var events_1 = require("../events");
var gridOptionsWrapper_1 = require("../gridOptionsWrapper");
var columnApi_1 = require("../columnController/columnApi");
var gridApi_1 = require("../gridApi");
/** Adds drag listening onto an element. In ag-Grid this is used twice, first is resizing columns,
* second is moving the columns and column groups around (ie the 'drag' part of Drag and Drop. */
var DragService = (function () {
function DragService() {
this.onMouseUpListener = this.onMouseUp.bind(this);
this.onMouseMoveListener = this.onMouseMove.bind(this);
this.onTouchEndListener = this.onTouchUp.bind(this);
this.onTouchMoveListener = this.onTouchMove.bind(this);
this.dragEndFunctions = [];
this.dragSources = [];
}
DragService.prototype.init = function () {
this.logger = this.loggerFactory.create('DragService');
};
DragService.prototype.destroy = function () {
this.dragSources.forEach(this.removeListener.bind(this));
this.dragSources.length = 0;
};
DragService.prototype.removeListener = function (dragSourceAndListener) {
var element = dragSourceAndListener.dragSource.eElement;
var mouseDownListener = dragSourceAndListener.mouseDownListener;
element.removeEventListener('mousedown', mouseDownListener);
// remove touch listener only if it exists
if (dragSourceAndListener.touchEnabled) {
var touchStartListener = dragSourceAndListener.touchStartListener;
element.removeEventListener('touchstart', touchStartListener, { passive: true });
}
};
DragService.prototype.removeDragSource = function (params) {
var dragSourceAndListener = utils_1.Utils.find(this.dragSources, function (item) { return item.dragSource === params; });
if (!dragSourceAndListener) {
return;
}
this.removeListener(dragSourceAndListener);
utils_1.Utils.removeFromArray(this.dragSources, dragSourceAndListener);
};
DragService.prototype.setNoSelectToBody = function (noSelect) {
var usrDocument = this.gridOptionsWrapper.getDocument();
var eBody = usrDocument.querySelector('body');
if (utils_1.Utils.exists(eBody)) {
utils_1.Utils.addOrRemoveCssClass(eBody, 'ag-body-no-select', noSelect);
}
};
DragService.prototype.addDragSource = function (params, includeTouch) {
if (includeTouch === void 0) { includeTouch = false; }
var mouseListener = this.onMouseDown.bind(this, params);
params.eElement.addEventListener('mousedown', mouseListener);
var touchListener = null;
var suppressTouch = this.gridOptionsWrapper.isSuppressTouch();
var reallyIncludeTouch = includeTouch && !suppressTouch;
if (reallyIncludeTouch) {
touchListener = this.onTouchStart.bind(this, params);
params.eElement.addEventListener('touchstart', touchListener, { passive: false });
}
this.dragSources.push({
dragSource: params,
mouseDownListener: mouseListener,
touchStartListener: touchListener,
touchEnabled: includeTouch
});
};
// gets called whenever mouse down on any drag source
DragService.prototype.onTouchStart = function (params, touchEvent) {
var _this = this;
this.currentDragParams = params;
this.dragging = false;
var touch = touchEvent.touches[0];
this.touchLastTime = touch;
this.touchStart = touch;
touchEvent.preventDefault();
// we temporally add these listeners, for the duration of the drag, they
// are removed in touch end handling.
params.eElement.addEventListener('touchmove', this.onTouchMoveListener, { passive: true });
params.eElement.addEventListener('touchend', this.onTouchEndListener, { passive: true });
params.eElement.addEventListener('touchcancel', this.onTouchEndListener, { passive: true });
this.dragEndFunctions.push(function () {
params.eElement.removeEventListener('touchmove', _this.onTouchMoveListener, { passive: true });
params.eElement.removeEventListener('touchend', _this.onTouchEndListener, { passive: true });
params.eElement.removeEventListener('touchcancel', _this.onTouchEndListener, { passive: true });
});
// see if we want to start dragging straight away
if (params.dragStartPixels === 0) {
this.onCommonMove(touch, this.touchStart);
}
};
// gets called whenever mouse down on any drag source
DragService.prototype.onMouseDown = function (params, mouseEvent) {
var _this = this;
// we ignore when shift key is pressed. this is for the range selection, as when
// user shift-clicks a cell, this should not be interpreted as the start of a drag.
// if (mouseEvent.shiftKey) { return; }
if (params.skipMouseEvent) {
if (params.skipMouseEvent(mouseEvent)) {
return;
}
}
// if there are two elements with parent / child relationship, and both are draggable,
// when we drag the child, we should NOT drag the parent. an example of this is row moving
// and range selection - row moving should get preference when use drags the rowDrag component.
if (mouseEvent._alreadyProcessedByDragService) {
return;
}
mouseEvent._alreadyProcessedByDragService = true;
// only interested in left button clicks
if (mouseEvent.button !== 0) {
return;
}
this.currentDragParams = params;
this.dragging = false;
this.mouseEventLastTime = mouseEvent;
this.mouseStartEvent = mouseEvent;
var usrDocument = this.gridOptionsWrapper.getDocument();
// we temporally add these listeners, for the duration of the drag, they
// are removed in mouseup handling.
usrDocument.addEventListener('mousemove', this.onMouseMoveListener);
usrDocument.addEventListener('mouseup', this.onMouseUpListener);
this.dragEndFunctions.push(function () {
usrDocument.removeEventListener('mousemove', _this.onMouseMoveListener);
usrDocument.removeEventListener('mouseup', _this.onMouseUpListener);
});
// see if we want to start dragging straight away
if (params.dragStartPixels === 0) {
this.onMouseMove(mouseEvent);
}
};
// returns true if the event is close to the original event by X pixels either vertically or horizontally.
// we only start dragging after X pixels so this allows us to know if we should start dragging yet.
DragService.prototype.isEventNearStartEvent = function (currentEvent, startEvent) {
// by default, we wait 4 pixels before starting the drag
var requiredPixelDiff = utils_1.Utils.exists(this.currentDragParams.dragStartPixels) ? this.currentDragParams.dragStartPixels : 4;
return utils_1.Utils.areEventsNear(currentEvent, startEvent, requiredPixelDiff);
};
DragService.prototype.getFirstActiveTouch = function (touchList) {
for (var i = 0; i < touchList.length; i++) {
var matches = touchList[i].identifier === this.touchStart.identifier;
if (matches) {
return touchList[i];
}
}
return null;
};
DragService.prototype.onCommonMove = function (currentEvent, startEvent) {
if (!this.dragging) {
// if mouse hasn't travelled from the start position enough, do nothing
var toEarlyToDrag = !this.dragging && this.isEventNearStartEvent(currentEvent, startEvent);
if (toEarlyToDrag) {
return;
}
else {
// alert(`started`);
this.dragging = true;
var event_1 = {
type: events_1.Events.EVENT_DRAG_STARTED,
api: this.gridApi,
columnApi: this.columnApi
};
this.eventService.dispatchEvent(event_1);
this.currentDragParams.onDragStart(startEvent);
this.setNoSelectToBody(true);
}
}
this.currentDragParams.onDragging(currentEvent);
};
DragService.prototype.onTouchMove = function (touchEvent) {
var touch = this.getFirstActiveTouch(touchEvent.touches);
if (!touch) {
return;
}
// this.___statusBar.setInfoText(Math.random() + ' onTouchMove preventDefault stopPropagation');
// if we don't preview default, then the browser will try and do it's own touch stuff,
// like do 'back button' (chrome does this) or scroll the page (eg drag column could be confused
// with scroll page in the app)
// touchEvent.preventDefault();
this.onCommonMove(touch, this.touchStart);
};
// only gets called after a mouse down - as this is only added after mouseDown
// and is removed when mouseUp happens
DragService.prototype.onMouseMove = function (mouseEvent) {
this.onCommonMove(mouseEvent, this.mouseStartEvent);
};
DragService.prototype.onTouchUp = function (touchEvent) {
var touch = this.getFirstActiveTouch(touchEvent.changedTouches);
// i haven't worked this out yet, but there is no matching touch
// when we get the touch up event. to get around this, we swap in
// the last touch. this is a hack to 'get it working' while we
// figure out what's going on, why we are not getting a touch in
// current event.
if (!touch) {
touch = this.touchLastTime;
}
// if mouse was left up before we started to move, then this is a tap.
// we check this before onUpCommon as onUpCommon resets the dragging
// let tap = !this.dragging;
// let tapTarget = this.currentDragParams.eElement;
this.onUpCommon(touch);
// if tap, tell user
// console.log(`${Math.random()} tap = ${tap}`);
// if (tap) {
// tapTarget.click();
// }
};
DragService.prototype.onMouseUp = function (mouseEvent) {
this.onUpCommon(mouseEvent);
};
DragService.prototype.onUpCommon = function (eventOrTouch) {
if (this.dragging) {
this.dragging = false;
this.currentDragParams.onDragStop(eventOrTouch);
var event_2 = {
type: events_1.Events.EVENT_DRAG_STOPPED,
api: this.gridApi,
columnApi: this.columnApi
};
this.eventService.dispatchEvent(event_2);
}
this.setNoSelectToBody(false);
this.mouseStartEvent = null;
this.mouseEventLastTime = null;
this.touchStart = null;
this.touchLastTime = null;
this.currentDragParams = null;
this.dragEndFunctions.forEach(function (func) { return func(); });
this.dragEndFunctions.length = 0;
};
__decorate([
context_1.Autowired('loggerFactory'),
__metadata("design:type", logger_1.LoggerFactory)
], DragService.prototype, "loggerFactory", void 0);
__decorate([
context_1.Autowired('eventService'),
__metadata("design:type", eventService_1.EventService)
], DragService.prototype, "eventService", void 0);
__decorate([
context_1.Autowired('gridOptionsWrapper'),
__metadata("design:type", gridOptionsWrapper_1.GridOptionsWrapper)
], DragService.prototype, "gridOptionsWrapper", void 0);
__decorate([
context_1.Autowired('columnApi'),
__metadata("design:type", columnApi_1.ColumnApi)
], DragService.prototype, "columnApi", void 0);
__decorate([
context_1.Autowired('gridApi'),
__metadata("design:type", gridApi_1.GridApi)
], DragService.prototype, "gridApi", void 0);
__decorate([
context_1.PostConstruct,
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", void 0)
], DragService.prototype, "init", null);
__decorate([
context_1.PreDestroy,
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", void 0)
], DragService.prototype, "destroy", null);
DragService = __decorate([
context_1.Bean('dragService')
], DragService);
return DragService;
}());
exports.DragService = DragService;