UNPKG

dockview-core

Version:

Zero dependency layout manager supporting tabs, groups, grids and splitviews for vanilla TypeScript

196 lines (195 loc) 8.86 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.PointerDragSource = void 0; var events_1 = require("../../events"); var lifecycle_1 = require("../../lifecycle"); var pointerDragController_1 = require("./pointerDragController"); var DEFAULT_THRESHOLD = 5; var DEFAULT_TOUCH_INITIATION_DELAY = 250; var DEFAULT_PRESS_TOLERANCE = 8; /** * Pointer-event drag source. Waits for movement past `threshold` (and * touch-only `touchInitiationDelay`) before promoting to a drag so taps * pass through unaffected. */ var PointerDragSource = /** @class */ (function (_super) { __extends(PointerDragSource, _super); function PointerDragSource(element, options) { var _a; var _this = _super.call(this) || this; _this.element = element; _this.options = options; _this._disabled = false; _this._armed = false; _this._startX = 0; _this._startY = 0; _this._touchOnly = (_a = options.touchOnly) !== null && _a !== void 0 ? _a : true; _this.addDisposables((0, events_1.addDisposableListener)(_this.element, 'pointerdown', function (e) { _this._onPointerDown(e); })); return _this; } PointerDragSource.prototype.setDisabled = function (value) { this._disabled = value; if (value) { this._cancelPending(); } }; /** * `false` lets the pointer source also handle mouse pointers; used when * `dndStrategy: 'pointer'` to drive every input type through this path. */ PointerDragSource.prototype.setTouchOnly = function (value) { if (this._touchOnly === value) { return; } this._touchOnly = value; // A pending mouse-tracked drag should be abandoned if we re-enable // the touch-only filter mid-flight. if (value) { this._cancelPending(); } }; PointerDragSource.prototype._shouldHandle = function (event) { var _a, _b; if (this._disabled) { return false; } // Pointer-type filter runs before isCancelled — consumer state read // by isCancelled may not be populated for events we'll never handle. if (this._touchOnly && event.pointerType !== 'touch' && event.pointerType !== 'pen') { return false; } if ((_b = (_a = this.options).isCancelled) === null || _b === void 0 ? void 0 : _b.call(_a, event)) { return false; } return true; }; PointerDragSource.prototype._onPointerDown = function (event) { var _this = this; var _a, _b, _c, _d, _e; if (!this._shouldHandle(event)) { return; } // Defensive: a fresh pointerdown supersedes any in-flight tracking. this._cancelPending(); this._pendingPointerId = event.pointerId; this._startX = event.clientX; this._startY = event.clientY; this._startEvent = event; var isTouch = event.pointerType === 'touch' || event.pointerType === 'pen'; // Touch waits a short window so a still finger can press-and-hold // before drifting; once the timer fires, any motion past `threshold` // begins the drag. var initiationDelayOpt = this.options.touchInitiationDelay; var initiationDelay = (_a = (typeof initiationDelayOpt === 'function' ? initiationDelayOpt() : initiationDelayOpt)) !== null && _a !== void 0 ? _a : DEFAULT_TOUCH_INITIATION_DELAY; this._armed = !isTouch || initiationDelay <= 0; if (isTouch && initiationDelay > 0 && isFinite(initiationDelay)) { this._armTimer = setTimeout(function () { _this._armTimer = undefined; _this._armed = true; }, initiationDelay); } var threshold = (_b = this.options.threshold) !== null && _b !== void 0 ? _b : DEFAULT_THRESHOLD; var pressToleranceOpt = this.options.pressTolerance; var pressTolerance = (_c = (typeof pressToleranceOpt === 'function' ? pressToleranceOpt() : pressToleranceOpt)) !== null && _c !== void 0 ? _c : DEFAULT_PRESS_TOLERANCE; // Source's owning window — popout drags fire on their own window. var targetWindow = (_e = (_d = this.element.ownerDocument) === null || _d === void 0 ? void 0 : _d.defaultView) !== null && _e !== void 0 ? _e : window; this._pendingMoveListener = (0, events_1.addDisposableListener)(targetWindow, 'pointermove', function (moveEvent) { if (moveEvent.pointerId !== _this._pendingPointerId) { return; } var dx = moveEvent.clientX - _this._startX; var dy = moveEvent.clientY - _this._startY; var distance = Math.hypot(dx, dy); if (_this._armed) { if (distance >= threshold) { _this._beginDrag(moveEvent); } return; } // Pre-arm phase: a flick past `pressTolerance` in any // direction is treated as drag intent. The element opts out // of native scroll via `touch-action: none`; container-level // scrolling lives on the surrounding strip's empty space. if (distance > pressTolerance) { _this._beginDrag(moveEvent); } }); this._pendingUpListener = (0, events_1.addDisposableListener)(targetWindow, 'pointerup', function (upEvent) { if (upEvent.pointerId !== _this._pendingPointerId) { return; } _this._cancelPending(); }); this._pendingCancelListener = (0, events_1.addDisposableListener)(targetWindow, 'pointercancel', function (cancelEvent) { if (cancelEvent.pointerId !== _this._pendingPointerId) { return; } _this._cancelPending(); }); }; /** For sibling gesture detectors (e.g. LongPressDetector) to dismiss a pending drag. */ PointerDragSource.prototype.cancelPending = function () { this._cancelPending(); }; PointerDragSource.prototype._cancelPending = function () { var _a, _b, _c; this._pendingPointerId = undefined; if (this._armTimer !== undefined) { clearTimeout(this._armTimer); this._armTimer = undefined; } this._armed = false; (_a = this._pendingMoveListener) === null || _a === void 0 ? void 0 : _a.dispose(); (_b = this._pendingUpListener) === null || _b === void 0 ? void 0 : _b.dispose(); (_c = this._pendingCancelListener) === null || _c === void 0 ? void 0 : _c.dispose(); this._pendingMoveListener = undefined; this._pendingUpListener = undefined; this._pendingCancelListener = undefined; this._startEvent = undefined; }; PointerDragSource.prototype._beginDrag = function (triggerEvent) { var _this = this; var _a, _b, _c, _d, _e; var startEvent = (_a = this._startEvent) !== null && _a !== void 0 ? _a : triggerEvent; this._cancelPending(); (_c = (_b = this.options).onDragStart) === null || _c === void 0 ? void 0 : _c.call(_b, startEvent); var ghost = (_e = (_d = this.options).createGhost) === null || _e === void 0 ? void 0 : _e.call(_d, startEvent); pointerDragController_1.PointerDragController.getInstance().beginDrag({ pointerEvent: triggerEvent, source: this.element, getData: function () { return _this.options.getData(startEvent); }, ghost: ghost, onDragMove: this.options.onDragMove, onDragEnd: this.options.onDragEnd, }); }; PointerDragSource.prototype.dispose = function () { this._cancelPending(); _super.prototype.dispose.call(this); }; return PointerDragSource; }(lifecycle_1.CompositeDisposable)); exports.PointerDragSource = PointerDragSource;