ngx-kit 9.0.0 → 9.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/drag-resize/README.md +6 -5
- package/fesm2022/ngx-kit-drag-resize.mjs +413 -161
- package/fesm2022/ngx-kit-drag-resize.mjs.map +1 -1
- package/fesm2022/ngx-kit-lazy-i18n.mjs +141 -53
- package/fesm2022/ngx-kit-lazy-i18n.mjs.map +1 -1
- package/lazy-i18n/README.md +86 -20
- package/package.json +1 -1
- package/types/ngx-kit-drag-resize.d.ts +13 -4
- package/types/ngx-kit-lazy-i18n.d.ts +83 -15
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { signal, EventEmitter, Injectable, InjectionToken, inject, ApplicationRef, Directive, model, input, output, Renderer2, effect, ContentChild, Input, HostListener, Output, ElementRef } from '@angular/core';
|
|
3
|
-
import { DOCUMENT } from '@angular/common';
|
|
4
3
|
|
|
5
4
|
/**
|
|
6
5
|
* Boundary clamping utilities.
|
|
@@ -70,15 +69,67 @@ function clampResizeWithinBoundary(boundaryRect, startRect, width, height, left,
|
|
|
70
69
|
return { width: clampedWidth, height: clampedHeight, left: clampedLeft, top: clampedTop };
|
|
71
70
|
}
|
|
72
71
|
/** Current page zoom level (1 = 100%). Falls back to devicePixelRatio pre visualViewport. */
|
|
73
|
-
function getPageZoom() {
|
|
74
|
-
|
|
72
|
+
function getPageZoom(element) {
|
|
73
|
+
const win = element?.ownerDocument.defaultView ?? (typeof window !== 'undefined' ? window : null);
|
|
74
|
+
return win?.visualViewport?.scale ?? win?.devicePixelRatio ?? 1;
|
|
75
75
|
}
|
|
76
76
|
/** Adjusts a raw pointer-derived value for the current page zoom level. */
|
|
77
|
-
function adjustForZoom(value) {
|
|
78
|
-
const zoom = getPageZoom();
|
|
77
|
+
function adjustForZoom(value, element) {
|
|
78
|
+
const zoom = getPageZoom(element);
|
|
79
79
|
return zoom ? value / zoom : value;
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
+
/** Base (LTR) physical direction for every logical direction. */
|
|
83
|
+
const LTR_BASE = {
|
|
84
|
+
start: 'w',
|
|
85
|
+
end: 'e',
|
|
86
|
+
'n-start': 'nw',
|
|
87
|
+
'n-end': 'ne',
|
|
88
|
+
's-start': 'sw',
|
|
89
|
+
's-end': 'se',
|
|
90
|
+
};
|
|
91
|
+
/** Mirrors the horizontal component of a physical direction. 'n' / 's' pass through unchanged. */
|
|
92
|
+
const MIRROR = {
|
|
93
|
+
n: 'n',
|
|
94
|
+
s: 's',
|
|
95
|
+
e: 'w',
|
|
96
|
+
w: 'e',
|
|
97
|
+
ne: 'nw',
|
|
98
|
+
nw: 'ne',
|
|
99
|
+
se: 'sw',
|
|
100
|
+
sw: 'se',
|
|
101
|
+
};
|
|
102
|
+
function isLogicalDirection(dir) {
|
|
103
|
+
return Object.prototype.hasOwnProperty.call(LTR_BASE, dir);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* True when `element` sits inside a right-to-left context.
|
|
107
|
+
*
|
|
108
|
+
* Reads the *computed* `direction` style instead of `element.dir`, because
|
|
109
|
+
* `direction` is inherited and is almost never set on the resizable element
|
|
110
|
+
* itself - it's usually set on `<html>`, `<body>`, or some ancestor wrapper.
|
|
111
|
+
*/
|
|
112
|
+
function isRtl(element) {
|
|
113
|
+
const win = element.ownerDocument.defaultView;
|
|
114
|
+
return win ? win.getComputedStyle(element).direction === 'rtl' : false;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Resolves a logical direction ('start' | 'end' | 'n-start' | 'n-end' | 's-start' | 's-end')
|
|
118
|
+
* to a physical, viewport-space direction ('n' | 'e' | 's' | 'w' | 'ne' | 'nw' | 'se' | 'sw')
|
|
119
|
+
* based on `rtl`.
|
|
120
|
+
*
|
|
121
|
+
* Physical directions pass through untouched, so it's always safe to call this
|
|
122
|
+
* even when `dir` might already be physical (e.g. resolving a direction that was
|
|
123
|
+
* already resolved once before).
|
|
124
|
+
*/
|
|
125
|
+
function resolveLogicalDirection(dir, rtl) {
|
|
126
|
+
if (!isLogicalDirection(dir)) {
|
|
127
|
+
return dir;
|
|
128
|
+
}
|
|
129
|
+
const base = LTR_BASE[dir];
|
|
130
|
+
return rtl ? MIRROR[base] : base;
|
|
131
|
+
}
|
|
132
|
+
|
|
82
133
|
/** Above any app chrome (modals, sticky headers) but below the browser's own UI. */
|
|
83
134
|
const PREVIEW_Z_INDEX = '2147483000';
|
|
84
135
|
class DragPreviewRef {
|
|
@@ -135,9 +186,10 @@ class DragPreviewRef {
|
|
|
135
186
|
willChange: 'transform',
|
|
136
187
|
zIndex: PREVIEW_Z_INDEX,
|
|
137
188
|
});
|
|
189
|
+
const win = doc.defaultView;
|
|
138
190
|
if (isRtl(doc.body)) {
|
|
139
191
|
Object.assign(this.element.style, {
|
|
140
|
-
right: `${
|
|
192
|
+
right: `${(win?.innerWidth ?? rect.right) - rect.right}px`,
|
|
141
193
|
left: 'auto',
|
|
142
194
|
});
|
|
143
195
|
}
|
|
@@ -147,7 +199,7 @@ class DragPreviewRef {
|
|
|
147
199
|
right: 'auto',
|
|
148
200
|
});
|
|
149
201
|
}
|
|
150
|
-
doc.body.appendChild(this.element);
|
|
202
|
+
(doc.body ?? doc.documentElement).appendChild(this.element);
|
|
151
203
|
return this.element;
|
|
152
204
|
}
|
|
153
205
|
detach() {
|
|
@@ -161,6 +213,139 @@ class DragPreviewRef {
|
|
|
161
213
|
}
|
|
162
214
|
}
|
|
163
215
|
|
|
216
|
+
function viewportDeltaToLocal(element, delta, includeElementTransform = true) {
|
|
217
|
+
const matrix = getLocalToViewportMatrix(element, includeElementTransform);
|
|
218
|
+
const determinant = matrix.a * matrix.d - matrix.b * matrix.c;
|
|
219
|
+
if (!Number.isFinite(determinant) || Math.abs(determinant) < 1e-8) {
|
|
220
|
+
// A zero-scale ancestor has no invertible coordinate space. Avoid NaN/Infinity.
|
|
221
|
+
return { x: 0, y: 0 };
|
|
222
|
+
}
|
|
223
|
+
const inverseA = matrix.d / determinant;
|
|
224
|
+
const inverseB = -matrix.b / determinant;
|
|
225
|
+
const inverseC = -matrix.c / determinant;
|
|
226
|
+
const inverseD = matrix.a / determinant;
|
|
227
|
+
return {
|
|
228
|
+
x: inverseA * delta.x + inverseC * delta.y,
|
|
229
|
+
y: inverseB * delta.x + inverseD * delta.y,
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
function localDeltaToViewport(element, delta) {
|
|
233
|
+
const matrix = getLocalToViewportMatrix(element);
|
|
234
|
+
return {
|
|
235
|
+
x: matrix.a * delta.x + matrix.c * delta.y,
|
|
236
|
+
y: matrix.b * delta.x + matrix.d * delta.y,
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
/** Returns the composed 2D linear transform from element-local to viewport space. */
|
|
240
|
+
function getLocalToViewportMatrix(element, includeElementTransform = true) {
|
|
241
|
+
const win = element.ownerDocument.defaultView;
|
|
242
|
+
if (!win || typeof win.DOMMatrix !== 'function') {
|
|
243
|
+
return { a: 1, b: 0, c: 0, d: 1 };
|
|
244
|
+
}
|
|
245
|
+
let result = { a: 1, b: 0, c: 0, d: 1 };
|
|
246
|
+
let current = includeElementTransform ? element : element.parentElement;
|
|
247
|
+
while (current) {
|
|
248
|
+
const style = win.getComputedStyle(current);
|
|
249
|
+
const transform = style.transform;
|
|
250
|
+
if (transform && transform !== 'none') {
|
|
251
|
+
try {
|
|
252
|
+
const matrix = new win.DOMMatrix(transform);
|
|
253
|
+
result = multiplyLinear({ a: matrix.a, b: matrix.b, c: matrix.c, d: matrix.d }, result);
|
|
254
|
+
}
|
|
255
|
+
catch {
|
|
256
|
+
// Ignore unsupported/malformed transforms and continue with remaining ancestors.
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
// CSS `zoom` is not represented consistently in computed `transform` across browsers.
|
|
260
|
+
const zoom = Number.parseFloat(style.getPropertyValue('zoom'));
|
|
261
|
+
if (Number.isFinite(zoom) && zoom > 0 && zoom !== 1) {
|
|
262
|
+
result = multiplyLinear({ a: zoom, b: 0, c: 0, d: zoom }, result);
|
|
263
|
+
}
|
|
264
|
+
current = current.parentElement;
|
|
265
|
+
}
|
|
266
|
+
return result;
|
|
267
|
+
}
|
|
268
|
+
function multiplyLinear(left, right) {
|
|
269
|
+
return {
|
|
270
|
+
a: left.a * right.a + left.c * right.b,
|
|
271
|
+
b: left.b * right.a + left.d * right.b,
|
|
272
|
+
c: left.a * right.c + left.c * right.d,
|
|
273
|
+
d: left.b * right.c + left.d * right.d,
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Converts a client-space point from one same-origin Document viewport to another.
|
|
278
|
+
* The conversion walks both frameElement chains through their common top-level document.
|
|
279
|
+
* Cross-origin frame boundaries cannot be inspected and return null.
|
|
280
|
+
*/
|
|
281
|
+
function convertPointBetweenDocuments(point, fromDocument, toDocument) {
|
|
282
|
+
if (fromDocument === toDocument)
|
|
283
|
+
return { ...point };
|
|
284
|
+
const toTop = (doc, value) => {
|
|
285
|
+
let current = doc;
|
|
286
|
+
let result = { ...value };
|
|
287
|
+
const visited = new Set();
|
|
288
|
+
while (current.defaultView?.frameElement) {
|
|
289
|
+
if (visited.has(current))
|
|
290
|
+
return null;
|
|
291
|
+
visited.add(current);
|
|
292
|
+
let frame;
|
|
293
|
+
try {
|
|
294
|
+
frame = current.defaultView.frameElement;
|
|
295
|
+
}
|
|
296
|
+
catch {
|
|
297
|
+
return null;
|
|
298
|
+
}
|
|
299
|
+
const iframe = frame;
|
|
300
|
+
const rect = iframe.getBoundingClientRect();
|
|
301
|
+
const scaleX = iframe.offsetWidth ? rect.width / iframe.offsetWidth : 1;
|
|
302
|
+
const scaleY = iframe.offsetHeight ? rect.height / iframe.offsetHeight : 1;
|
|
303
|
+
result = {
|
|
304
|
+
x: rect.left + iframe.clientLeft * scaleX + result.x * scaleX,
|
|
305
|
+
y: rect.top + iframe.clientTop * scaleY + result.y * scaleY,
|
|
306
|
+
};
|
|
307
|
+
current = iframe.ownerDocument;
|
|
308
|
+
}
|
|
309
|
+
return { document: current, point: result };
|
|
310
|
+
};
|
|
311
|
+
const from = toTop(fromDocument, point);
|
|
312
|
+
if (!from)
|
|
313
|
+
return null;
|
|
314
|
+
const targetFrames = [];
|
|
315
|
+
let current = toDocument;
|
|
316
|
+
const visited = new Set();
|
|
317
|
+
while (current && current !== from.document) {
|
|
318
|
+
if (visited.has(current))
|
|
319
|
+
return null;
|
|
320
|
+
visited.add(current);
|
|
321
|
+
let frame;
|
|
322
|
+
try {
|
|
323
|
+
frame = current.defaultView?.frameElement ?? null;
|
|
324
|
+
}
|
|
325
|
+
catch {
|
|
326
|
+
return null;
|
|
327
|
+
}
|
|
328
|
+
if (!frame)
|
|
329
|
+
return null;
|
|
330
|
+
targetFrames.push(frame);
|
|
331
|
+
current = frame.ownerDocument;
|
|
332
|
+
}
|
|
333
|
+
if (current !== from.document)
|
|
334
|
+
return null;
|
|
335
|
+
let result = from.point;
|
|
336
|
+
for (let i = targetFrames.length - 1; i >= 0; i--) {
|
|
337
|
+
const iframe = targetFrames[i];
|
|
338
|
+
const rect = iframe.getBoundingClientRect();
|
|
339
|
+
const scaleX = iframe.offsetWidth ? rect.width / iframe.offsetWidth : 1;
|
|
340
|
+
const scaleY = iframe.offsetHeight ? rect.height / iframe.offsetHeight : 1;
|
|
341
|
+
result = {
|
|
342
|
+
x: (result.x - rect.left) / scaleX - iframe.clientLeft,
|
|
343
|
+
y: (result.y - rect.top) / scaleY - iframe.clientTop,
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
return result;
|
|
347
|
+
}
|
|
348
|
+
|
|
164
349
|
let zIndexCounter = 1000;
|
|
165
350
|
class DragRef {
|
|
166
351
|
data;
|
|
@@ -197,6 +382,8 @@ class DragRef {
|
|
|
197
382
|
sourceDisplay = '';
|
|
198
383
|
sourcePointerEvents = '';
|
|
199
384
|
sourceTransition = '';
|
|
385
|
+
sourceWillChange = '';
|
|
386
|
+
sourceTransform = '';
|
|
200
387
|
/** True while a drop-list drag (body preview + placeholder) is in progress. Free drag: always false. */
|
|
201
388
|
listDrag = false;
|
|
202
389
|
cachedLists = [];
|
|
@@ -212,7 +399,9 @@ class DragRef {
|
|
|
212
399
|
scrollListener;
|
|
213
400
|
resizeListener;
|
|
214
401
|
init() {
|
|
215
|
-
this.previousTransform =
|
|
402
|
+
this.previousTransform =
|
|
403
|
+
this.el.ownerDocument.defaultView?.getComputedStyle(this.el).transform ?? '';
|
|
404
|
+
this.sourceTransform = this.el.style.transform;
|
|
216
405
|
}
|
|
217
406
|
withDropList(list) {
|
|
218
407
|
if (this.dropList === list)
|
|
@@ -242,13 +431,16 @@ class DragRef {
|
|
|
242
431
|
const list = this.dropList && this.dropList.el === this.el.parentElement ? this.dropList : null;
|
|
243
432
|
this.originDropList = list;
|
|
244
433
|
this.originIndex = list?.getItemIndex(this) ?? -1;
|
|
245
|
-
|
|
434
|
+
const win = this.el.ownerDocument.defaultView;
|
|
435
|
+
this.previousTransform = win?.getComputedStyle(this.el).transform ?? '';
|
|
436
|
+
this.sourceTransform = this.el.style.transform;
|
|
246
437
|
this.isDragging.set(true);
|
|
247
438
|
this.previousZIndex = this.el.style.zIndex;
|
|
248
439
|
this.sourceVisibility = this.el.style.visibility;
|
|
249
440
|
this.sourceDisplay = this.el.style.display;
|
|
250
441
|
this.sourcePointerEvents = this.el.style.pointerEvents;
|
|
251
442
|
this.sourceTransition = this.el.style.transition;
|
|
443
|
+
this.sourceWillChange = this.el.style.willChange;
|
|
252
444
|
this.el.classList.add('ngx-draggable--dragging');
|
|
253
445
|
this.el.style.willChange = 'transform';
|
|
254
446
|
this.el.style.transition = 'none';
|
|
@@ -334,7 +526,8 @@ class DragRef {
|
|
|
334
526
|
this.el.style.visibility = this.sourceVisibility;
|
|
335
527
|
this.el.style.display = this.sourceDisplay;
|
|
336
528
|
this.el.style.pointerEvents = this.sourcePointerEvents;
|
|
337
|
-
this.el.style.willChange =
|
|
529
|
+
this.el.style.willChange = this.sourceWillChange;
|
|
530
|
+
this.el.style.transition = this.sourceTransition;
|
|
338
531
|
this.el.style.zIndex = this.previousZIndex;
|
|
339
532
|
}
|
|
340
533
|
cancelDrag() {
|
|
@@ -350,7 +543,7 @@ class DragRef {
|
|
|
350
543
|
return;
|
|
351
544
|
}
|
|
352
545
|
// ---- free drag: unchanged ----
|
|
353
|
-
this.el.style.transform = this.
|
|
546
|
+
this.el.style.transform = this.sourceTransform;
|
|
354
547
|
this.el.style.visibility = this.sourceVisibility;
|
|
355
548
|
this.el.style.pointerEvents = this.sourcePointerEvents;
|
|
356
549
|
this.scrollCompensation = { x: 0, y: 0 };
|
|
@@ -358,10 +551,24 @@ class DragRef {
|
|
|
358
551
|
}
|
|
359
552
|
/** Abort without emitting anything (the directive was destroyed mid-drag). Idempotent. */
|
|
360
553
|
dispose() {
|
|
361
|
-
if (!this.
|
|
554
|
+
if (!this.isDragging())
|
|
362
555
|
return;
|
|
363
556
|
this.isDragging.set(false);
|
|
364
|
-
this.
|
|
557
|
+
this.position.set({ x: 0, y: 0 });
|
|
558
|
+
if (this.listDrag) {
|
|
559
|
+
this.finishListDrag(false);
|
|
560
|
+
return;
|
|
561
|
+
}
|
|
562
|
+
this.el.style.transform = this.sourceTransform;
|
|
563
|
+
this.el.style.visibility = this.sourceVisibility;
|
|
564
|
+
this.el.style.display = this.sourceDisplay;
|
|
565
|
+
this.el.style.pointerEvents = this.sourcePointerEvents;
|
|
566
|
+
this.el.style.transition = this.sourceTransition;
|
|
567
|
+
this.el.style.willChange = this.sourceWillChange;
|
|
568
|
+
this.el.style.zIndex = this.previousZIndex;
|
|
569
|
+
this.el.classList.remove('ngx-draggable--dragging');
|
|
570
|
+
this.scrollCompensation = { x: 0, y: 0 };
|
|
571
|
+
this.position.set({ x: 0, y: 0 });
|
|
365
572
|
}
|
|
366
573
|
/** True while a drop-list drag is running. */
|
|
367
574
|
get isListDrag() {
|
|
@@ -410,14 +617,17 @@ class DragRef {
|
|
|
410
617
|
: '';
|
|
411
618
|
const tx = this.moveDx + this.scrollCompensation.x;
|
|
412
619
|
const ty = this.moveDy + this.scrollCompensation.y;
|
|
413
|
-
this.el
|
|
620
|
+
const local = viewportDeltaToLocal(this.el, { x: tx, y: ty });
|
|
621
|
+
this.el.style.transform = `${base}translate3d(${local.x}px, ${local.y}px, 0)`;
|
|
414
622
|
}
|
|
415
623
|
// -------------------------------------------------------------------------------------
|
|
416
624
|
// drop-list drag
|
|
417
625
|
// -------------------------------------------------------------------------------------
|
|
418
626
|
beginListDrag(origin, pointer) {
|
|
419
627
|
const doc = this.el.ownerDocument;
|
|
420
|
-
const win = doc.defaultView
|
|
628
|
+
const win = doc.defaultView;
|
|
629
|
+
if (!win)
|
|
630
|
+
return;
|
|
421
631
|
this.dropListsSnapshot = null; // force refreshDropCandidates() to do a full pass below
|
|
422
632
|
this.refreshDropCandidates(origin);
|
|
423
633
|
this.lastEffective = { ...pointer };
|
|
@@ -484,9 +694,11 @@ class DragRef {
|
|
|
484
694
|
if (!origin)
|
|
485
695
|
return;
|
|
486
696
|
this.refreshDropCandidates(origin);
|
|
487
|
-
const
|
|
697
|
+
const resolved = this.resolveDropList(pointer);
|
|
698
|
+
const next = resolved?.list ?? null;
|
|
699
|
+
const targetPointer = resolved?.pointer ?? pointer;
|
|
488
700
|
if (next === this.activeDropList) {
|
|
489
|
-
next?.sortItem(this,
|
|
701
|
+
next?.sortItem(this, targetPointer);
|
|
490
702
|
return;
|
|
491
703
|
}
|
|
492
704
|
const prev = this.activeDropList;
|
|
@@ -501,7 +713,7 @@ class DragRef {
|
|
|
501
713
|
origin.exit(this); // truly outside the origin's territory now: reset it (idempotent)
|
|
502
714
|
}
|
|
503
715
|
this.activeDropList = next;
|
|
504
|
-
next?.enter(this,
|
|
716
|
+
next?.enter(this, targetPointer.x, targetPointer.y); // coordinates belong to the target document
|
|
505
717
|
}
|
|
506
718
|
/**
|
|
507
719
|
* Innermost connected list under the pointer, from the precomputed candidates: deeper always
|
|
@@ -513,15 +725,22 @@ class DragRef {
|
|
|
513
725
|
let best = null;
|
|
514
726
|
let bestDepth = -1;
|
|
515
727
|
for (const { list, depth } of this.dropCandidates) {
|
|
516
|
-
|
|
728
|
+
const targetDocument = list.el?.ownerDocument;
|
|
729
|
+
if (!targetDocument)
|
|
730
|
+
continue;
|
|
731
|
+
// Pointer coordinates originate in the draggable's document. A same-origin iframe has
|
|
732
|
+
// its own viewport coordinate space, so convert before testing its DropList geometry.
|
|
733
|
+
const targetPoint = convertPointBetweenDocuments(pointer, this.el.ownerDocument, targetDocument);
|
|
734
|
+
if (!targetPoint || !list._containsPoint(targetPoint.x, targetPoint.y))
|
|
517
735
|
continue;
|
|
518
736
|
if (!best || depth > bestDepth) {
|
|
519
|
-
best = list;
|
|
737
|
+
best = { list, pointer: targetPoint };
|
|
520
738
|
bestDepth = depth;
|
|
521
739
|
}
|
|
522
|
-
else if (depth === bestDepth && best !== this.activeDropList) {
|
|
523
|
-
if (list === this.activeDropList || list._area() < best._area())
|
|
524
|
-
best = list;
|
|
740
|
+
else if (depth === bestDepth && best.list !== this.activeDropList) {
|
|
741
|
+
if (list === this.activeDropList || list._area() < best.list._area()) {
|
|
742
|
+
best = { list, pointer: targetPoint };
|
|
743
|
+
}
|
|
525
744
|
}
|
|
526
745
|
}
|
|
527
746
|
return best;
|
|
@@ -536,7 +755,7 @@ class DragRef {
|
|
|
536
755
|
if (this.scrollListener)
|
|
537
756
|
doc.removeEventListener('scroll', this.scrollListener, { capture: true });
|
|
538
757
|
if (this.resizeListener)
|
|
539
|
-
|
|
758
|
+
doc.defaultView?.removeEventListener('resize', this.resizeListener);
|
|
540
759
|
this.scrollListener = this.resizeListener = undefined;
|
|
541
760
|
const target = commit ? this.activeDropList : null;
|
|
542
761
|
const event = target?._finish(this, true) ?? null;
|
|
@@ -556,7 +775,7 @@ class DragRef {
|
|
|
556
775
|
this.el.style.display = this.sourceDisplay;
|
|
557
776
|
this.el.style.pointerEvents = this.sourcePointerEvents;
|
|
558
777
|
this.el.style.transition = this.sourceTransition;
|
|
559
|
-
this.el.style.willChange =
|
|
778
|
+
this.el.style.willChange = this.sourceWillChange;
|
|
560
779
|
this.el.style.zIndex = this.previousZIndex;
|
|
561
780
|
if (event && target)
|
|
562
781
|
target.onDrop.emit(event);
|
|
@@ -564,6 +783,7 @@ class DragRef {
|
|
|
564
783
|
updatePreview() {
|
|
565
784
|
if (!this.preview || !this.preview.element)
|
|
566
785
|
return;
|
|
786
|
+
// Preview is fixed in the source document's viewport coordinate space.
|
|
567
787
|
this.preview.element.style.transform = `translate3d(${this.moveDx}px, ${this.moveDy}px, 0)`;
|
|
568
788
|
}
|
|
569
789
|
}
|
|
@@ -586,7 +806,7 @@ class ElementHelper {
|
|
|
586
806
|
return false;
|
|
587
807
|
}
|
|
588
808
|
static findParentBySelector(elm, selector) {
|
|
589
|
-
var all =
|
|
809
|
+
var all = elm.ownerDocument.querySelectorAll(selector);
|
|
590
810
|
var cur = elm.parentNode;
|
|
591
811
|
while (cur && !ElementHelper.collectionHas(all, cur)) {
|
|
592
812
|
//keep going up until you find a match
|
|
@@ -615,15 +835,17 @@ function getFirstLevelDraggables(container) {
|
|
|
615
835
|
return firstLevel;
|
|
616
836
|
}
|
|
617
837
|
function isElementNode(node) {
|
|
618
|
-
return node?.nodeType === Node.ELEMENT_NODE;
|
|
838
|
+
return node?.nodeType === Node.ELEMENT_NODE; // 1
|
|
619
839
|
}
|
|
620
840
|
function isDocumentNode(node) {
|
|
621
|
-
return node?.nodeType === Node.DOCUMENT_NODE;
|
|
841
|
+
return node?.nodeType === Node.DOCUMENT_NODE; // 9
|
|
622
842
|
}
|
|
623
843
|
function isShadowRootNode(node) {
|
|
624
844
|
return node?.nodeType === Node.DOCUMENT_FRAGMENT_NODE && 'host' in node;
|
|
625
845
|
}
|
|
626
846
|
function getOwnerWindow(node) {
|
|
847
|
+
if (isDocumentNode(node))
|
|
848
|
+
return node.defaultView;
|
|
627
849
|
return node?.ownerDocument?.defaultView ?? null;
|
|
628
850
|
}
|
|
629
851
|
function isWindow(value) {
|
|
@@ -950,7 +1172,7 @@ class ScrollFrame {
|
|
|
950
1172
|
* @param start first element to inspect (walks up through its ancestors)
|
|
951
1173
|
* @param includeStart whether `start` itself counts (true for a list whose own scroll moves its items)
|
|
952
1174
|
*/
|
|
953
|
-
constructor(start, includeStart = true, win =
|
|
1175
|
+
constructor(start, includeStart = true, win = start?.ownerDocument.defaultView ?? null) {
|
|
954
1176
|
this.win = win;
|
|
955
1177
|
let node = includeStart ? start : (start?.parentElement ?? null);
|
|
956
1178
|
const root = start?.ownerDocument.documentElement;
|
|
@@ -960,7 +1182,8 @@ class ScrollFrame {
|
|
|
960
1182
|
this.targets.push(node);
|
|
961
1183
|
node = node.parentElement;
|
|
962
1184
|
}
|
|
963
|
-
|
|
1185
|
+
if (win)
|
|
1186
|
+
this.targets.push(win);
|
|
964
1187
|
this.origin = this.read();
|
|
965
1188
|
}
|
|
966
1189
|
/** Call when any scroll event fires. */
|
|
@@ -980,23 +1203,26 @@ class ScrollFrame {
|
|
|
980
1203
|
let x = 0;
|
|
981
1204
|
let y = 0;
|
|
982
1205
|
for (const t of this.targets) {
|
|
983
|
-
if (t === this.win) {
|
|
1206
|
+
if (this.win && t === this.win) {
|
|
984
1207
|
x += this.win.scrollX;
|
|
985
1208
|
y += this.win.scrollY;
|
|
986
1209
|
}
|
|
987
1210
|
else {
|
|
988
|
-
|
|
989
|
-
|
|
1211
|
+
const el = t;
|
|
1212
|
+
// Element scroll offsets are local CSS pixels; geometry snapshots are viewport pixels.
|
|
1213
|
+
const delta = localDeltaToViewport(el, { x: el.scrollLeft, y: el.scrollTop });
|
|
1214
|
+
x += delta.x;
|
|
1215
|
+
y += delta.y;
|
|
990
1216
|
}
|
|
991
1217
|
}
|
|
992
1218
|
return { x, y };
|
|
993
1219
|
}
|
|
994
1220
|
}
|
|
995
1221
|
function scrolls(el) {
|
|
996
|
-
const s = getComputedStyle
|
|
1222
|
+
const s = el.ownerDocument.defaultView?.getComputedStyle(el);
|
|
997
1223
|
// `hidden` containers still scroll programmatically; `clip` never does.
|
|
998
1224
|
const scrollish = (v) => v === 'auto' || v === 'scroll' || v === 'overlay' || v === 'hidden';
|
|
999
|
-
return scrollish(s.overflowX) || scrollish(s.overflowY);
|
|
1225
|
+
return !!s && (scrollish(s.overflowX) || scrollish(s.overflowY));
|
|
1000
1226
|
}
|
|
1001
1227
|
|
|
1002
1228
|
/**
|
|
@@ -1007,7 +1233,7 @@ function scrolls(el) {
|
|
|
1007
1233
|
*/
|
|
1008
1234
|
function makeSpacer(container) {
|
|
1009
1235
|
for (const n of Array.from(container.childNodes)) {
|
|
1010
|
-
if (n.nodeType ===
|
|
1236
|
+
if (n.nodeType === 3 && n.nodeValue && /^\s+$/.test(n.nodeValue)) {
|
|
1011
1237
|
return container.ownerDocument.createTextNode(n.nodeValue);
|
|
1012
1238
|
}
|
|
1013
1239
|
}
|
|
@@ -1215,6 +1441,7 @@ class SortSession {
|
|
|
1215
1441
|
const horizontal = this.model.axis === 'x';
|
|
1216
1442
|
this.entries.forEach((e, i) => {
|
|
1217
1443
|
const o = offsets[i];
|
|
1444
|
+
// `o` is derived from DOMRect measurements (viewport CSS pixels).
|
|
1218
1445
|
this.setOffset(e, horizontal ? { x: o, y: 0 } : { x: 0, y: o });
|
|
1219
1446
|
});
|
|
1220
1447
|
}
|
|
@@ -1228,7 +1455,8 @@ class SortSession {
|
|
|
1228
1455
|
}
|
|
1229
1456
|
else {
|
|
1230
1457
|
this.applied.set(e.el, off);
|
|
1231
|
-
|
|
1458
|
+
const local = viewportDeltaToLocal(e.el, off, false);
|
|
1459
|
+
e.el.style.transform = `translate3d(${local.x}px, ${local.y}px, 0)${e.base}`;
|
|
1232
1460
|
}
|
|
1233
1461
|
this.onOffsetChange?.(e.el, off);
|
|
1234
1462
|
}
|
|
@@ -1253,7 +1481,8 @@ class SortSession {
|
|
|
1253
1481
|
const dx = first[i].left - last[i].left;
|
|
1254
1482
|
const dy = first[i].top - last[i].top;
|
|
1255
1483
|
if (this.animationMs > 0 && (Math.abs(dx) > 0.5 || Math.abs(dy) > 0.5)) {
|
|
1256
|
-
e.el
|
|
1484
|
+
const local = viewportDeltaToLocal(e.el, { x: dx, y: dy }, false);
|
|
1485
|
+
e.el.style.transform = `translate3d(${local.x}px, ${local.y}px, 0)${e.base}`;
|
|
1257
1486
|
moved.push(e);
|
|
1258
1487
|
}
|
|
1259
1488
|
});
|
|
@@ -1298,63 +1527,10 @@ class SortSession {
|
|
|
1298
1527
|
}
|
|
1299
1528
|
}
|
|
1300
1529
|
function initialTransform(el) {
|
|
1301
|
-
const t = getComputedStyle
|
|
1530
|
+
const t = el.ownerDocument.defaultView?.getComputedStyle(el).transform;
|
|
1302
1531
|
return t && t !== 'none' ? ` ${t}` : '';
|
|
1303
1532
|
}
|
|
1304
1533
|
|
|
1305
|
-
/** Base (LTR) physical direction for every logical direction. */
|
|
1306
|
-
const LTR_BASE = {
|
|
1307
|
-
start: 'w',
|
|
1308
|
-
end: 'e',
|
|
1309
|
-
'n-start': 'nw',
|
|
1310
|
-
'n-end': 'ne',
|
|
1311
|
-
's-start': 'sw',
|
|
1312
|
-
's-end': 'se',
|
|
1313
|
-
};
|
|
1314
|
-
/** Mirrors the horizontal component of a physical direction. 'n' / 's' pass through unchanged. */
|
|
1315
|
-
const MIRROR = {
|
|
1316
|
-
n: 'n',
|
|
1317
|
-
s: 's',
|
|
1318
|
-
e: 'w',
|
|
1319
|
-
w: 'e',
|
|
1320
|
-
ne: 'nw',
|
|
1321
|
-
nw: 'ne',
|
|
1322
|
-
se: 'sw',
|
|
1323
|
-
sw: 'se',
|
|
1324
|
-
};
|
|
1325
|
-
function isLogicalDirection(dir) {
|
|
1326
|
-
return Object.prototype.hasOwnProperty.call(LTR_BASE, dir);
|
|
1327
|
-
}
|
|
1328
|
-
/**
|
|
1329
|
-
* True when `element` sits inside a right-to-left context.
|
|
1330
|
-
*
|
|
1331
|
-
* Reads the *computed* `direction` style instead of `element.dir`, because
|
|
1332
|
-
* `direction` is inherited and is almost never set on the resizable element
|
|
1333
|
-
* itself - it's usually set on `<html>`, `<body>`, or some ancestor wrapper.
|
|
1334
|
-
*/
|
|
1335
|
-
function isRtl(element) {
|
|
1336
|
-
if (typeof window === 'undefined') {
|
|
1337
|
-
return false;
|
|
1338
|
-
}
|
|
1339
|
-
return window.getComputedStyle(element).direction === 'rtl';
|
|
1340
|
-
}
|
|
1341
|
-
/**
|
|
1342
|
-
* Resolves a logical direction ('start' | 'end' | 'n-start' | 'n-end' | 's-start' | 's-end')
|
|
1343
|
-
* to a physical, viewport-space direction ('n' | 'e' | 's' | 'w' | 'ne' | 'nw' | 'se' | 'sw')
|
|
1344
|
-
* based on `rtl`.
|
|
1345
|
-
*
|
|
1346
|
-
* Physical directions pass through untouched, so it's always safe to call this
|
|
1347
|
-
* even when `dir` might already be physical (e.g. resolving a direction that was
|
|
1348
|
-
* already resolved once before).
|
|
1349
|
-
*/
|
|
1350
|
-
function resolveLogicalDirection(dir, rtl) {
|
|
1351
|
-
if (!isLogicalDirection(dir)) {
|
|
1352
|
-
return dir;
|
|
1353
|
-
}
|
|
1354
|
-
const base = LTR_BASE[dir];
|
|
1355
|
-
return rtl ? MIRROR[base] : base;
|
|
1356
|
-
}
|
|
1357
|
-
|
|
1358
1534
|
/**
|
|
1359
1535
|
* A drop list.
|
|
1360
1536
|
*
|
|
@@ -1853,13 +2029,14 @@ class DropListRef {
|
|
|
1853
2029
|
}
|
|
1854
2030
|
/** Orientation to assume while a list has fewer than two items to measure. */
|
|
1855
2031
|
function fallbackAxis(container) {
|
|
1856
|
-
const
|
|
1857
|
-
|
|
2032
|
+
const win = container.ownerDocument.defaultView;
|
|
2033
|
+
const s = win?.getComputedStyle(container);
|
|
2034
|
+
if (s?.display.includes('flex'))
|
|
1858
2035
|
return s.flexDirection.startsWith('column') ? 'y' : 'x';
|
|
1859
|
-
if (s
|
|
2036
|
+
if (s?.display.includes('grid'))
|
|
1860
2037
|
return 'y';
|
|
1861
2038
|
const child = container.firstElementChild;
|
|
1862
|
-
if (child && getComputedStyle(child).display.startsWith('inline'))
|
|
2039
|
+
if (child && win?.getComputedStyle(child).display.startsWith('inline'))
|
|
1863
2040
|
return 'x';
|
|
1864
2041
|
return 'y';
|
|
1865
2042
|
}
|
|
@@ -1871,7 +2048,9 @@ function measureHit(el) {
|
|
|
1871
2048
|
const clips = [];
|
|
1872
2049
|
const root = el.ownerDocument.documentElement;
|
|
1873
2050
|
for (let node = el.parentElement; node && node !== root; node = node.parentElement) {
|
|
1874
|
-
const s = getComputedStyle(node);
|
|
2051
|
+
const s = node.ownerDocument.defaultView?.getComputedStyle(node);
|
|
2052
|
+
if (!s)
|
|
2053
|
+
continue;
|
|
1875
2054
|
const cx = s.overflowX !== 'visible';
|
|
1876
2055
|
const cy = s.overflowY !== 'visible';
|
|
1877
2056
|
if (!cx && !cy)
|
|
@@ -1957,6 +2136,8 @@ class DragDropService {
|
|
|
1957
2136
|
continue;
|
|
1958
2137
|
}
|
|
1959
2138
|
if (isDocumentNode(node)) {
|
|
2139
|
+
// Same-origin iframe: continue the logical DOM ancestry through its frame element.
|
|
2140
|
+
// This lets a DropList inside an iframe inherit an outer NgxDropListGroup.
|
|
1960
2141
|
const frame = node.defaultView?.frameElement;
|
|
1961
2142
|
if (frame) {
|
|
1962
2143
|
node = frame;
|
|
@@ -1985,15 +2166,13 @@ class DragDropService {
|
|
|
1985
2166
|
node = node.host;
|
|
1986
2167
|
continue;
|
|
1987
2168
|
}
|
|
1988
|
-
// iframe
|
|
1989
|
-
// 9 === DOCUMENT_NODE
|
|
2169
|
+
// Cross a same-origin iframe boundary so groups can connect lists in both documents.
|
|
1990
2170
|
if (node.nodeType === 9) {
|
|
1991
2171
|
const frame = node.defaultView?.frameElement;
|
|
1992
2172
|
if (frame) {
|
|
1993
2173
|
node = frame;
|
|
1994
2174
|
continue;
|
|
1995
2175
|
}
|
|
1996
|
-
// root document
|
|
1997
2176
|
break;
|
|
1998
2177
|
}
|
|
1999
2178
|
node = node.parentNode;
|
|
@@ -2030,12 +2209,16 @@ class DragDropService {
|
|
|
2030
2209
|
if (!source)
|
|
2031
2210
|
return null;
|
|
2032
2211
|
let best = null;
|
|
2212
|
+
const sourceDocument = dragEl?.ownerDocument ?? source.el?.ownerDocument;
|
|
2213
|
+
if (!sourceDocument)
|
|
2214
|
+
return null;
|
|
2033
2215
|
for (const list of this.dropLists()) {
|
|
2034
2216
|
if (!list.el || !source.isConnectedTo(list))
|
|
2035
2217
|
continue;
|
|
2036
2218
|
if (dragEl && dragEl !== list.el && dragEl.contains(list.el))
|
|
2037
2219
|
continue;
|
|
2038
|
-
|
|
2220
|
+
const targetPoint = convertPointBetweenDocuments(point, sourceDocument, list.el.ownerDocument);
|
|
2221
|
+
if (!targetPoint || !list._containsPoint(targetPoint.x, targetPoint.y))
|
|
2039
2222
|
continue;
|
|
2040
2223
|
if (!best)
|
|
2041
2224
|
best = list;
|
|
@@ -2065,7 +2248,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
2065
2248
|
*/
|
|
2066
2249
|
class AutoScroller {
|
|
2067
2250
|
raf = 0;
|
|
2068
|
-
container
|
|
2251
|
+
container;
|
|
2252
|
+
win;
|
|
2069
2253
|
speed = { x: 0, y: 0 };
|
|
2070
2254
|
onTick;
|
|
2071
2255
|
edge;
|
|
@@ -2076,6 +2260,7 @@ class AutoScroller {
|
|
|
2076
2260
|
}
|
|
2077
2261
|
/** onTick اجرا میشود بعد از هر گام اسکرول، تا با آخرین موقعیت pointer، sort/placeholder بهروز شود. */
|
|
2078
2262
|
start(fromEl, onTick) {
|
|
2263
|
+
this.win = fromEl.ownerDocument.defaultView ?? undefined;
|
|
2079
2264
|
this.container = findScrollableAncestor(fromEl);
|
|
2080
2265
|
this.onTick = onTick;
|
|
2081
2266
|
}
|
|
@@ -2090,15 +2275,16 @@ class AutoScroller {
|
|
|
2090
2275
|
y: edgeSpeed(clientY, rect.top, rect.bottom, this.edge, this.maxSpeed),
|
|
2091
2276
|
};
|
|
2092
2277
|
if ((this.speed.x || this.speed.y) && !this.raf) {
|
|
2093
|
-
this.raf = requestAnimationFrame(this.tick);
|
|
2278
|
+
this.raf = this.win?.requestAnimationFrame(this.tick) ?? 0;
|
|
2094
2279
|
}
|
|
2095
2280
|
}
|
|
2096
2281
|
stop() {
|
|
2097
2282
|
if (this.raf)
|
|
2098
|
-
cancelAnimationFrame(this.raf);
|
|
2283
|
+
this.win?.cancelAnimationFrame(this.raf);
|
|
2099
2284
|
this.raf = 0;
|
|
2100
2285
|
this.speed = { x: 0, y: 0 };
|
|
2101
2286
|
this.onTick = undefined;
|
|
2287
|
+
this.win = undefined;
|
|
2102
2288
|
}
|
|
2103
2289
|
tick = () => {
|
|
2104
2290
|
if (!this.speed.x && !this.speed.y) {
|
|
@@ -2110,13 +2296,15 @@ class AutoScroller {
|
|
|
2110
2296
|
container.scrollBy(this.speed.x, this.speed.y);
|
|
2111
2297
|
}
|
|
2112
2298
|
else {
|
|
2113
|
-
|
|
2114
|
-
container
|
|
2299
|
+
// Edge speed is measured in viewport pixels; scrollLeft/Top are local to the scroller.
|
|
2300
|
+
const local = viewportDeltaToLocal(container, this.speed);
|
|
2301
|
+
container.scrollLeft += local.x;
|
|
2302
|
+
container.scrollTop += local.y;
|
|
2115
2303
|
}
|
|
2116
2304
|
// Pointer ثابت مانده ولی محتوا اسکرول شده؛
|
|
2117
2305
|
// بنابراین موقعیت placeholder/sort را دوباره محاسبه کن.
|
|
2118
2306
|
this.onTick?.();
|
|
2119
|
-
this.raf = requestAnimationFrame(this.tick);
|
|
2307
|
+
this.raf = this.win?.requestAnimationFrame(this.tick) ?? 0;
|
|
2120
2308
|
};
|
|
2121
2309
|
}
|
|
2122
2310
|
function edgeSpeed(pos, min, max, edge, maxSpeed) {
|
|
@@ -2128,25 +2316,28 @@ function edgeSpeed(pos, min, max, edge, maxSpeed) {
|
|
|
2128
2316
|
}
|
|
2129
2317
|
function getScrollRect(container) {
|
|
2130
2318
|
if (isWindow(container)) {
|
|
2131
|
-
return { left: 0, top: 0, right:
|
|
2319
|
+
return { left: 0, top: 0, right: container.innerWidth, bottom: container.innerHeight };
|
|
2132
2320
|
}
|
|
2133
2321
|
return container.getBoundingClientRect();
|
|
2134
2322
|
}
|
|
2135
2323
|
function findScrollableAncestor(el) {
|
|
2136
2324
|
let node = el;
|
|
2137
2325
|
while (node) {
|
|
2138
|
-
const
|
|
2326
|
+
const win = node.ownerDocument.defaultView;
|
|
2327
|
+
if (!win)
|
|
2328
|
+
break;
|
|
2329
|
+
const style = win.getComputedStyle(node);
|
|
2139
2330
|
const scrollable = /(auto|scroll|overlay)/.test(style.overflowY + style.overflowX);
|
|
2140
2331
|
if (scrollable && node.scrollHeight > node.clientHeight) {
|
|
2141
2332
|
return node;
|
|
2142
2333
|
}
|
|
2143
2334
|
node = node.parentElement;
|
|
2144
2335
|
}
|
|
2145
|
-
return el.ownerDocument.defaultView ??
|
|
2336
|
+
return el.ownerDocument.defaultView ?? el;
|
|
2146
2337
|
}
|
|
2147
2338
|
function getScrollPosition(container) {
|
|
2148
2339
|
if (isWindow(container)) {
|
|
2149
|
-
return { left:
|
|
2340
|
+
return { left: container.scrollX, top: container.scrollY };
|
|
2150
2341
|
}
|
|
2151
2342
|
return { left: container.scrollLeft, top: container.scrollTop };
|
|
2152
2343
|
}
|
|
@@ -2222,7 +2413,6 @@ class NgxDraggable {
|
|
|
2222
2413
|
_ref = new DragRef();
|
|
2223
2414
|
dragging = signal(false, /* @ts-ignore */
|
|
2224
2415
|
...(ngDevMode ? [{ debugName: "dragging" }] : /* istanbul ignore next */ []));
|
|
2225
|
-
doc = inject(DOCUMENT);
|
|
2226
2416
|
service = inject(DragDropService);
|
|
2227
2417
|
scroller = new AutoScroller();
|
|
2228
2418
|
down = false;
|
|
@@ -2236,7 +2426,7 @@ class NgxDraggable {
|
|
|
2236
2426
|
removeEscape;
|
|
2237
2427
|
removeCancel;
|
|
2238
2428
|
removeLostCapture;
|
|
2239
|
-
scrollTarget
|
|
2429
|
+
scrollTarget;
|
|
2240
2430
|
lastScroll = { left: 0, top: 0 };
|
|
2241
2431
|
lastWindowScroll = { left: 0, top: 0 };
|
|
2242
2432
|
removeContainerScroll;
|
|
@@ -2251,6 +2441,8 @@ class NgxDraggable {
|
|
|
2251
2441
|
});
|
|
2252
2442
|
}
|
|
2253
2443
|
ngOnInit() {
|
|
2444
|
+
this.scrollTarget =
|
|
2445
|
+
this.host.nativeElement.ownerDocument.defaultView ?? this.host.nativeElement;
|
|
2254
2446
|
this._ref.el = this.dragRootElement()
|
|
2255
2447
|
? (this.host.nativeElement.closest(this.dragRootElement()) ?? this.host.nativeElement)
|
|
2256
2448
|
: this.host.nativeElement;
|
|
@@ -2310,12 +2502,13 @@ class NgxDraggable {
|
|
|
2310
2502
|
this._ref.pointerDown(this.start);
|
|
2311
2503
|
this.removeMove = this.renderer.listen(this._ref.el, 'pointermove', (ev) => this.pointerMove(ev));
|
|
2312
2504
|
this.removeUp = this.renderer.listen(this._ref.el, 'pointerup', (ev) => this.pointerUp(ev));
|
|
2313
|
-
|
|
2505
|
+
const doc = this._ref.el.ownerDocument;
|
|
2506
|
+
this.removeEscape = this.renderer.listen(doc, 'keydown', (ev) => {
|
|
2314
2507
|
if (ev.key === 'Escape' && this.dragging())
|
|
2315
2508
|
this.cancel();
|
|
2316
2509
|
});
|
|
2317
|
-
this.removeCancel = this.renderer.listen(
|
|
2318
|
-
this.removeLostCapture = this.renderer.listen(
|
|
2510
|
+
this.removeCancel = this.renderer.listen(doc, 'pointercancel', (ev) => this.pointerCancel(ev));
|
|
2511
|
+
this.removeLostCapture = this.renderer.listen(doc, 'lostpointercapture', (ev) => this.pointerCancel(ev));
|
|
2319
2512
|
}
|
|
2320
2513
|
applyDragUpdate(p) {
|
|
2321
2514
|
const before = this._ref.activeDropList;
|
|
@@ -2326,32 +2519,39 @@ class NgxDraggable {
|
|
|
2326
2519
|
const after = this._ref.activeDropList;
|
|
2327
2520
|
// Follow the hovered list; outside every list, scroll the page.
|
|
2328
2521
|
if (after !== before)
|
|
2329
|
-
this.scroller.retarget(after?.el ?? this.
|
|
2522
|
+
this.scroller.retarget(after?.el ?? this._ref.el.ownerDocument.body);
|
|
2330
2523
|
}
|
|
2331
2524
|
this.dragMove.emit(p);
|
|
2332
2525
|
}
|
|
2333
2526
|
/** فراخوانی میشود دقیقاً وقتی drag واقعاً شروع میشود (چه با موس، چه با کیبورد). */
|
|
2334
2527
|
startScrollTracking() {
|
|
2528
|
+
const win = this._ref.el.ownerDocument.defaultView;
|
|
2335
2529
|
this.scrollTarget = findScrollableAncestor(this._ref.el);
|
|
2336
2530
|
this.lastScroll = getScrollPosition(this.scrollTarget);
|
|
2337
|
-
this.lastWindowScroll = { left:
|
|
2338
|
-
if (this.scrollTarget !==
|
|
2531
|
+
this.lastWindowScroll = { left: win?.scrollX ?? 0, top: win?.scrollY ?? 0 };
|
|
2532
|
+
if (win && this.scrollTarget !== win) {
|
|
2339
2533
|
this.removeContainerScroll = this.renderer.listen(this.scrollTarget, 'scroll', () => this.handleContainerScroll());
|
|
2340
2534
|
}
|
|
2341
2535
|
// همیشه window رو هم جدا گوش میدیم؛ چون ممکنه container محلی نداشته باشیم
|
|
2342
2536
|
// ولی خودِ صفحه اسکرول بشه.
|
|
2343
|
-
|
|
2537
|
+
if (win) {
|
|
2538
|
+
this.removeWindowScroll = this.renderer.listen(win, 'scroll', () => this.handleWindowScroll());
|
|
2539
|
+
}
|
|
2344
2540
|
}
|
|
2345
2541
|
handleContainerScroll() {
|
|
2346
2542
|
const pos = getScrollPosition(this.scrollTarget);
|
|
2347
2543
|
const dx = pos.left - this.lastScroll.left;
|
|
2348
2544
|
const dy = pos.top - this.lastScroll.top;
|
|
2349
2545
|
this.lastScroll = pos;
|
|
2350
|
-
this.
|
|
2546
|
+
const viewportDelta = localDeltaToViewport(this.scrollTarget, { x: dx, y: dy });
|
|
2547
|
+
this._ref.notifyScroll(viewportDelta.x, viewportDelta.y);
|
|
2351
2548
|
}
|
|
2352
2549
|
handleWindowScroll() {
|
|
2353
|
-
const
|
|
2354
|
-
|
|
2550
|
+
const win = this._ref.el.ownerDocument.defaultView;
|
|
2551
|
+
if (!win)
|
|
2552
|
+
return;
|
|
2553
|
+
const left = win.scrollX;
|
|
2554
|
+
const top = win.scrollY;
|
|
2355
2555
|
const dx = left - this.lastWindowScroll.left;
|
|
2356
2556
|
const dy = top - this.lastWindowScroll.top;
|
|
2357
2557
|
this.lastWindowScroll = { left, top };
|
|
@@ -2392,14 +2592,14 @@ class NgxDraggable {
|
|
|
2392
2592
|
}
|
|
2393
2593
|
if (this.dragging()) {
|
|
2394
2594
|
// Also when released OUTSIDE every list: endDrag() rolls the drag back and cleans up.
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
this._ref.dragMove(p);
|
|
2401
|
-
this._ref.endDrag();
|
|
2595
|
+
// The release position is authoritative for list sorting (a fast flick may end with
|
|
2596
|
+
// a pointerup that has no preceding pointermove at that position).
|
|
2597
|
+
const p = { x: e.clientX, y: e.clientY };
|
|
2598
|
+
if (this._ref.isListDrag && (p.x !== this.lastPointer.x || p.y !== this.lastPointer.y)) {
|
|
2599
|
+
this._ref.dragMove(p);
|
|
2402
2600
|
}
|
|
2601
|
+
// endDrag must run for free drags too, otherwise their lifecycle never completes.
|
|
2602
|
+
this._ref.endDrag();
|
|
2403
2603
|
this.service.end(this._ref);
|
|
2404
2604
|
}
|
|
2405
2605
|
this.finish();
|
|
@@ -2409,7 +2609,7 @@ class NgxDraggable {
|
|
|
2409
2609
|
pointerCancel(e) {
|
|
2410
2610
|
if (!this.down || e.pointerId !== this.pointerId)
|
|
2411
2611
|
return;
|
|
2412
|
-
if (this.dragging()
|
|
2612
|
+
if (this.dragging()) {
|
|
2413
2613
|
this.cancel();
|
|
2414
2614
|
return;
|
|
2415
2615
|
}
|
|
@@ -2421,6 +2621,9 @@ class NgxDraggable {
|
|
|
2421
2621
|
this.finish();
|
|
2422
2622
|
}
|
|
2423
2623
|
finish() {
|
|
2624
|
+
if (this.pointerId >= 0 && this._ref.el.hasPointerCapture?.(this.pointerId)) {
|
|
2625
|
+
this._ref.el.releasePointerCapture(this.pointerId);
|
|
2626
|
+
}
|
|
2424
2627
|
this.dragging.set(false);
|
|
2425
2628
|
this.down = false;
|
|
2426
2629
|
this.scroller.stop();
|
|
@@ -2473,26 +2676,24 @@ class NgxDraggable {
|
|
|
2473
2676
|
this._ref.endDrag();
|
|
2474
2677
|
this.service.end(this._ref);
|
|
2475
2678
|
this.dragEnd.emit(this._ref.pointer);
|
|
2476
|
-
this.
|
|
2477
|
-
this.stopScrollTracking();
|
|
2679
|
+
this.finish();
|
|
2478
2680
|
}
|
|
2479
2681
|
else if (e.key === 'Escape' && this.dragging()) {
|
|
2480
2682
|
e.preventDefault();
|
|
2481
2683
|
this._ref.cancelDrag();
|
|
2482
2684
|
this.service.end(this._ref);
|
|
2483
|
-
this.
|
|
2685
|
+
this.finish();
|
|
2484
2686
|
}
|
|
2485
2687
|
}
|
|
2486
2688
|
isOnHandle(target) {
|
|
2487
2689
|
if (!this.dragHandle())
|
|
2488
2690
|
return true;
|
|
2489
2691
|
// TODO notsafe instanseof: node.nodeType === Node.ELEMENT_NODE
|
|
2490
|
-
return target
|
|
2692
|
+
return isElementTarget(target) && !!target.closest(this.dragHandle());
|
|
2491
2693
|
}
|
|
2492
2694
|
isInteractive(target) {
|
|
2493
2695
|
// TODO notsafe instanseof: node.nodeType === Node.ELEMENT_NODE
|
|
2494
|
-
return (target
|
|
2495
|
-
!!target.closest('button,a,input,textarea,select,[data-no-drag]'));
|
|
2696
|
+
return (isElementTarget(target) && !!target.closest('button,a,input,textarea,select,[data-no-drag]'));
|
|
2496
2697
|
}
|
|
2497
2698
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: NgxDraggable, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
2498
2699
|
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.4", type: NgxDraggable, isStandalone: true, selector: "[NgxDraggable],[ngxDraggable]", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, boundary: { classPropertyName: "boundary", publicName: "boundary", isSignal: true, isRequired: false, transformFunction: null }, dragRootElement: { classPropertyName: "dragRootElement", publicName: "dragRootElement", isSignal: true, isRequired: false, transformFunction: null }, dragHandle: { classPropertyName: "dragHandle", publicName: "dragHandle", isSignal: true, isRequired: false, transformFunction: null }, lockAxis: { classPropertyName: "lockAxis", publicName: "lockAxis", isSignal: true, isRequired: false, transformFunction: null }, dragThreshold: { classPropertyName: "dragThreshold", publicName: "dragThreshold", isSignal: true, isRequired: false, transformFunction: null }, keyboardStep: { classPropertyName: "keyboardStep", publicName: "keyboardStep", isSignal: true, isRequired: false, transformFunction: null }, autoScroll: { classPropertyName: "autoScroll", publicName: "autoScroll", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { disabled: "disabledChange", dragRootElement: "dragRootElementChange", dragHandle: "dragHandleChange", dragStart: "dragStart", dragMove: "dragMove", dragEnd: "dragEnd" }, host: { properties: { "style.touch-action": "\"none\"", "attr.tabindex": "disabled() ? null : 0", "attr.aria-grabbed": "dragging()", "class.disable-drag": "disabled()" }, classAttribute: "ngx-draggable" }, providers: [{ provide: NGX_DRAGGABLE, useExisting: NgxDraggable }], queries: [{ propertyName: "customPreview", first: true, predicate: NgxDragPreview, descendants: true }], ngImport: i0 });
|
|
@@ -2517,6 +2718,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
2517
2718
|
type: ContentChild,
|
|
2518
2719
|
args: [NgxDragPreview]
|
|
2519
2720
|
}], dragStart: [{ type: i0.Output, args: ["dragStart"] }], dragMove: [{ type: i0.Output, args: ["dragMove"] }], dragEnd: [{ type: i0.Output, args: ["dragEnd"] }] } });
|
|
2721
|
+
function isElementTarget(target) {
|
|
2722
|
+
return (!!target &&
|
|
2723
|
+
typeof target === 'object' &&
|
|
2724
|
+
'nodeType' in target &&
|
|
2725
|
+
target.nodeType === 1 &&
|
|
2726
|
+
'closest' in target);
|
|
2727
|
+
}
|
|
2520
2728
|
|
|
2521
2729
|
const ALL_DIRECTIONS = ['n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw'];
|
|
2522
2730
|
const KEYBOARD_STEP = 8;
|
|
@@ -2558,9 +2766,19 @@ class NgxResizable {
|
|
|
2558
2766
|
beforeHeight = '';
|
|
2559
2767
|
beforeTransform = '';
|
|
2560
2768
|
pointerId = -1;
|
|
2769
|
+
startWidth = 0;
|
|
2770
|
+
startHeight = 0;
|
|
2771
|
+
removeDocumentListeners = [];
|
|
2772
|
+
renderer = inject(Renderer2);
|
|
2561
2773
|
constructor(el) {
|
|
2562
2774
|
this.el = el;
|
|
2563
2775
|
}
|
|
2776
|
+
ngOnDestroy() {
|
|
2777
|
+
if (this.resizing()) {
|
|
2778
|
+
this.restoreBeforeResize();
|
|
2779
|
+
this.finish();
|
|
2780
|
+
}
|
|
2781
|
+
}
|
|
2564
2782
|
onPointerDown(e) {
|
|
2565
2783
|
if (this.disabled() || e.button !== 0) {
|
|
2566
2784
|
return;
|
|
@@ -2585,6 +2803,10 @@ class NgxResizable {
|
|
|
2585
2803
|
y: e.clientY,
|
|
2586
2804
|
};
|
|
2587
2805
|
this.beforeTransition = element.style.transition;
|
|
2806
|
+
this.beforeWidth = element.style.width;
|
|
2807
|
+
this.beforeHeight = element.style.height;
|
|
2808
|
+
this.startWidth = element.offsetWidth;
|
|
2809
|
+
this.startHeight = element.offsetHeight;
|
|
2588
2810
|
/**
|
|
2589
2811
|
* Keep DragRef's transform as the immutable base.
|
|
2590
2812
|
*
|
|
@@ -2595,6 +2817,14 @@ class NgxResizable {
|
|
|
2595
2817
|
this.resizing.set(true);
|
|
2596
2818
|
element.style.transition = 'none';
|
|
2597
2819
|
element.setPointerCapture?.(e.pointerId);
|
|
2820
|
+
const doc = element.ownerDocument;
|
|
2821
|
+
this.removeDocumentListeners = [
|
|
2822
|
+
this.renderer.listen(doc, 'pointermove', (event) => this.onPointerMove(event)),
|
|
2823
|
+
this.renderer.listen(doc, 'pointerup', (event) => this.onPointerUp(event)),
|
|
2824
|
+
this.renderer.listen(doc, 'pointercancel', (event) => this.onPointerCancel(event)),
|
|
2825
|
+
this.renderer.listen(doc, 'lostpointercapture', (event) => this.onPointerCancel(event)),
|
|
2826
|
+
this.renderer.listen(doc, 'keydown', (event) => this.onDocumentKeyDown(event)),
|
|
2827
|
+
];
|
|
2598
2828
|
const out = this.calculate(e);
|
|
2599
2829
|
this.apply(out);
|
|
2600
2830
|
this.resizeStart.emit(out);
|
|
@@ -2624,11 +2854,20 @@ class NgxResizable {
|
|
|
2624
2854
|
return;
|
|
2625
2855
|
}
|
|
2626
2856
|
e.preventDefault();
|
|
2857
|
+
this.restoreBeforeResize();
|
|
2858
|
+
this.finish();
|
|
2859
|
+
}
|
|
2860
|
+
onPointerCancel(e) {
|
|
2861
|
+
if (!this.resizing() || e.pointerId !== this.pointerId)
|
|
2862
|
+
return;
|
|
2863
|
+
this.restoreBeforeResize();
|
|
2864
|
+
this.finish();
|
|
2865
|
+
}
|
|
2866
|
+
restoreBeforeResize() {
|
|
2627
2867
|
const element = this.el.nativeElement;
|
|
2628
2868
|
element.style.width = this.beforeWidth;
|
|
2629
2869
|
element.style.height = this.beforeHeight;
|
|
2630
2870
|
element.style.transform = this.beforeTransform;
|
|
2631
|
-
this.finish();
|
|
2632
2871
|
}
|
|
2633
2872
|
onHandleKeyDown(e) {
|
|
2634
2873
|
if (this.disabled()) {
|
|
@@ -2655,8 +2894,8 @@ class NgxResizable {
|
|
|
2655
2894
|
}
|
|
2656
2895
|
e.preventDefault();
|
|
2657
2896
|
const rect = this.el.nativeElement.getBoundingClientRect();
|
|
2658
|
-
const width = this.clampGrid(Math.max(this.minWidth(), Math.min(this.maxWidth(),
|
|
2659
|
-
const height = this.clampGrid(Math.max(this.minHeight(), Math.min(this.maxHeight(),
|
|
2897
|
+
const width = this.clampGrid(Math.max(this.minWidth(), Math.min(this.maxWidth(), this.el.nativeElement.offsetWidth + dw)), 'x');
|
|
2898
|
+
const height = this.clampGrid(Math.max(this.minHeight(), Math.min(this.maxHeight(), this.el.nativeElement.offsetHeight + dh)), 'y');
|
|
2660
2899
|
this.el.nativeElement.style.width = `${width}px`;
|
|
2661
2900
|
this.el.nativeElement.style.height = `${height}px`;
|
|
2662
2901
|
const out = {
|
|
@@ -2672,10 +2911,14 @@ class NgxResizable {
|
|
|
2672
2911
|
this.resizeEnd.emit(out);
|
|
2673
2912
|
}
|
|
2674
2913
|
calculate(e) {
|
|
2675
|
-
const
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2914
|
+
const localDelta = viewportDeltaToLocal(this.el.nativeElement, {
|
|
2915
|
+
x: e.clientX - this.pointer.x,
|
|
2916
|
+
y: e.clientY - this.pointer.y,
|
|
2917
|
+
});
|
|
2918
|
+
const dx = localDelta.x;
|
|
2919
|
+
const dy = localDelta.y;
|
|
2920
|
+
let width = this.startWidth;
|
|
2921
|
+
let height = this.startHeight;
|
|
2679
2922
|
/**
|
|
2680
2923
|
* East
|
|
2681
2924
|
*/
|
|
@@ -2708,13 +2951,16 @@ class NgxResizable {
|
|
|
2708
2951
|
* This is useful for boundary calculations and
|
|
2709
2952
|
* emitted resize events.
|
|
2710
2953
|
*/
|
|
2954
|
+
const matrix = getLocalToViewportMatrix(this.el.nativeElement);
|
|
2955
|
+
const scaleX = Math.hypot(matrix.a, matrix.b) || 1;
|
|
2956
|
+
const scaleY = Math.hypot(matrix.c, matrix.d) || 1;
|
|
2711
2957
|
let left = this.start.left;
|
|
2712
2958
|
let top = this.start.top;
|
|
2713
2959
|
if (this.direction.includes('w')) {
|
|
2714
|
-
left = this.start.right - width;
|
|
2960
|
+
left = this.start.right - width * scaleX;
|
|
2715
2961
|
}
|
|
2716
2962
|
if (this.direction.includes('n')) {
|
|
2717
|
-
top = this.start.bottom - height;
|
|
2963
|
+
top = this.start.bottom - height * scaleY;
|
|
2718
2964
|
}
|
|
2719
2965
|
let moveLeft = left - this.start.left;
|
|
2720
2966
|
let moveTop = top - this.start.top;
|
|
@@ -2722,9 +2968,9 @@ class NgxResizable {
|
|
|
2722
2968
|
* Boundary constraint.
|
|
2723
2969
|
*/
|
|
2724
2970
|
if (this.boundary) {
|
|
2725
|
-
const clamped = clampResizeWithinBoundary(this.boundary()?.getBoundingClientRect(), this.start, width, height, moveLeft, moveTop);
|
|
2726
|
-
width = clamped.width;
|
|
2727
|
-
height = clamped.height;
|
|
2971
|
+
const clamped = clampResizeWithinBoundary(this.boundary()?.getBoundingClientRect(), this.start, width * scaleX, height * scaleY, moveLeft, moveTop);
|
|
2972
|
+
width = clamped.width / scaleX;
|
|
2973
|
+
height = clamped.height / scaleY;
|
|
2728
2974
|
moveLeft = clamped.left;
|
|
2729
2975
|
moveTop = clamped.top;
|
|
2730
2976
|
left = this.start.left + moveLeft;
|
|
@@ -2787,8 +3033,9 @@ class NgxResizable {
|
|
|
2787
3033
|
* correction required by Resize.
|
|
2788
3034
|
*/
|
|
2789
3035
|
const baseTransform = this.beforeTransform && this.beforeTransform !== 'none' ? `${this.beforeTransform} ` : '';
|
|
3036
|
+
const localCorrection = viewportDeltaToLocal(element, { x: correctionX, y: correctionY });
|
|
2790
3037
|
element.style.transform =
|
|
2791
|
-
`${baseTransform}translate3d(` + `${
|
|
3038
|
+
`${baseTransform}translate3d(` + `${localCorrection.x}px, ` + `${localCorrection.y}px, 0)`;
|
|
2792
3039
|
}
|
|
2793
3040
|
clampGrid(value, axis) {
|
|
2794
3041
|
const grid = typeof this.grid() === 'number' ? this.grid : this.grid()?.[axis];
|
|
@@ -2800,7 +3047,14 @@ class NgxResizable {
|
|
|
2800
3047
|
finish() {
|
|
2801
3048
|
this.resizing.set(false);
|
|
2802
3049
|
this.el.nativeElement.style.transition = this.beforeTransition;
|
|
3050
|
+
const pointerId = this.pointerId;
|
|
2803
3051
|
this.pointerId = -1;
|
|
3052
|
+
for (const remove of this.removeDocumentListeners)
|
|
3053
|
+
remove();
|
|
3054
|
+
this.removeDocumentListeners = [];
|
|
3055
|
+
if (pointerId >= 0 && this.el.nativeElement.hasPointerCapture?.(pointerId)) {
|
|
3056
|
+
this.el.nativeElement.releasePointerCapture(pointerId);
|
|
3057
|
+
}
|
|
2804
3058
|
this.beforeTransform = '';
|
|
2805
3059
|
}
|
|
2806
3060
|
resolvedDirections() {
|
|
@@ -2823,7 +3077,7 @@ class NgxResizable {
|
|
|
2823
3077
|
* Explicit resize handle has priority.
|
|
2824
3078
|
*/
|
|
2825
3079
|
// TODO notsafe instanceof:node.nodeType === Node.ELEMENT_NODE
|
|
2826
|
-
const handle = e.target
|
|
3080
|
+
const handle = isHTMLElementTarget(e.target)
|
|
2827
3081
|
? e.target.closest('[data-ngx-resize-handle]')
|
|
2828
3082
|
: null;
|
|
2829
3083
|
if (handle && element.contains(handle)) {
|
|
@@ -2866,7 +3120,7 @@ class NgxResizable {
|
|
|
2866
3120
|
return this.resolvedDirections().includes(direction) ? direction : null;
|
|
2867
3121
|
}
|
|
2868
3122
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: NgxResizable, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
2869
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.4", type: NgxResizable, isStandalone: true, selector: "[NgxResizable],[ngxResizable]", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, minWidth: { classPropertyName: "minWidth", publicName: "minWidth", isSignal: true, isRequired: false, transformFunction: null }, minHeight: { classPropertyName: "minHeight", publicName: "minHeight", isSignal: true, isRequired: false, transformFunction: null }, maxWidth: { classPropertyName: "maxWidth", publicName: "maxWidth", isSignal: true, isRequired: false, transformFunction: null }, maxHeight: { classPropertyName: "maxHeight", publicName: "maxHeight", isSignal: true, isRequired: false, transformFunction: null }, directions: { classPropertyName: "directions", publicName: "directions", isSignal: true, isRequired: false, transformFunction: null }, grid: { classPropertyName: "grid", publicName: "grid", isSignal: true, isRequired: false, transformFunction: null }, boundary: { classPropertyName: "boundary", publicName: "boundary", isSignal: true, isRequired: false, transformFunction: null }, keyboardStep: { classPropertyName: "keyboardStep", publicName: "keyboardStep", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { disabled: "disabledChange", minWidth: "minWidthChange", minHeight: "minHeightChange", maxWidth: "maxWidthChange", maxHeight: "maxHeightChange", resizeStart: "resizeStart", resizeMove: "resizeMove", resizeEnd: "resizeEnd" }, host: { listeners: { "pointerdown": "onPointerDown($event)", "
|
|
3123
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.4", type: NgxResizable, isStandalone: true, selector: "[NgxResizable],[ngxResizable]", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, minWidth: { classPropertyName: "minWidth", publicName: "minWidth", isSignal: true, isRequired: false, transformFunction: null }, minHeight: { classPropertyName: "minHeight", publicName: "minHeight", isSignal: true, isRequired: false, transformFunction: null }, maxWidth: { classPropertyName: "maxWidth", publicName: "maxWidth", isSignal: true, isRequired: false, transformFunction: null }, maxHeight: { classPropertyName: "maxHeight", publicName: "maxHeight", isSignal: true, isRequired: false, transformFunction: null }, directions: { classPropertyName: "directions", publicName: "directions", isSignal: true, isRequired: false, transformFunction: null }, grid: { classPropertyName: "grid", publicName: "grid", isSignal: true, isRequired: false, transformFunction: null }, boundary: { classPropertyName: "boundary", publicName: "boundary", isSignal: true, isRequired: false, transformFunction: null }, keyboardStep: { classPropertyName: "keyboardStep", publicName: "keyboardStep", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { disabled: "disabledChange", minWidth: "minWidthChange", minHeight: "minHeightChange", maxWidth: "maxWidthChange", maxHeight: "maxHeightChange", resizeStart: "resizeStart", resizeMove: "resizeMove", resizeEnd: "resizeEnd" }, host: { listeners: { "pointerdown": "onPointerDown($event)", "keydown": "onHandleKeyDown($event)" }, properties: { "style.touch-action": "\"none\"" }, classAttribute: "ngx-resizable" }, ngImport: i0 });
|
|
2870
3124
|
}
|
|
2871
3125
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: NgxResizable, decorators: [{
|
|
2872
3126
|
type: Directive,
|
|
@@ -2880,19 +3134,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
2880
3134
|
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }, { type: i0.Output, args: ["disabledChange"] }], minWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "minWidth", required: false }] }, { type: i0.Output, args: ["minWidthChange"] }], minHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "minHeight", required: false }] }, { type: i0.Output, args: ["minHeightChange"] }], maxWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxWidth", required: false }] }, { type: i0.Output, args: ["maxWidthChange"] }], maxHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxHeight", required: false }] }, { type: i0.Output, args: ["maxHeightChange"] }], directions: [{ type: i0.Input, args: [{ isSignal: true, alias: "directions", required: false }] }], grid: [{ type: i0.Input, args: [{ isSignal: true, alias: "grid", required: false }] }], boundary: [{ type: i0.Input, args: [{ isSignal: true, alias: "boundary", required: false }] }], keyboardStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "keyboardStep", required: false }] }], resizeStart: [{ type: i0.Output, args: ["resizeStart"] }], resizeMove: [{ type: i0.Output, args: ["resizeMove"] }], resizeEnd: [{ type: i0.Output, args: ["resizeEnd"] }], onPointerDown: [{
|
|
2881
3135
|
type: HostListener,
|
|
2882
3136
|
args: ['pointerdown', ['$event']]
|
|
2883
|
-
}], onPointerMove: [{
|
|
2884
|
-
type: HostListener,
|
|
2885
|
-
args: ['document:pointermove', ['$event']]
|
|
2886
|
-
}], onPointerUp: [{
|
|
2887
|
-
type: HostListener,
|
|
2888
|
-
args: ['document:pointerup', ['$event']]
|
|
2889
|
-
}], onDocumentKeyDown: [{
|
|
2890
|
-
type: HostListener,
|
|
2891
|
-
args: ['document:keydown', ['$event']]
|
|
2892
3137
|
}], onHandleKeyDown: [{
|
|
2893
3138
|
type: HostListener,
|
|
2894
3139
|
args: ['keydown', ['$event']]
|
|
2895
3140
|
}] } });
|
|
3141
|
+
function isHTMLElementTarget(target) {
|
|
3142
|
+
return (!!target &&
|
|
3143
|
+
typeof target === 'object' &&
|
|
3144
|
+
'nodeType' in target &&
|
|
3145
|
+
target.nodeType === 1 &&
|
|
3146
|
+
'closest' in target);
|
|
3147
|
+
}
|
|
2896
3148
|
|
|
2897
3149
|
const NGX_PLACEHOLDER = new InjectionToken('ngx-place-holder');
|
|
2898
3150
|
/**
|