@foblex/flow 1.2.9 → 1.3.1

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.
@@ -9,4 +9,5 @@ export * from './e-draggable-type';
9
9
  export * from './f-draggable.directive';
10
10
  export * from './f-draggable-base';
11
11
  export * from './f-draggable-data-context';
12
+ export * from './i-drag-and-drop-base';
12
13
  export * from './i-draggable-item';
@@ -1,6 +1,6 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { InjectionToken, Component, ChangeDetectionStrategy, Input, Directive, Injectable, ContentChild, Inject, ViewChild, ContentChildren, EventEmitter, Output, Optional, SkipSelf, HostBinding, NgModule } from '@angular/core';
3
- import { TransformModelExtensions, DomElementExtensions, RectExtensions, sanitizeElementId, PointExtensions, Point, GuidExtensions, VectorExtensions, SizeExtensions, MouseEventExtensions, IDragAndDropBase, BooleanExtensions, EventExtensions } from '@foblex/core';
3
+ import { TransformModelExtensions, DomElementExtensions, RectExtensions, sanitizeElementId, PointExtensions, Point, GuidExtensions, VectorExtensions, SizeExtensions, MouseEventExtensions, EventExtensions, IMouseEvent, ITouchDownEvent, ITouchMoveEvent, ITouchUpEvent, BooleanExtensions } from '@foblex/core';
4
4
  import { Subject, Subscription, Observable, startWith, debounceTime } from 'rxjs';
5
5
  import { DOCUMENT, CommonModule } from '@angular/common';
6
6
 
@@ -1410,6 +1410,7 @@ class CanvasDragHandler {
1410
1410
  class FDraggableDataContext {
1411
1411
  constructor() {
1412
1412
  this.selectedItems = [];
1413
+ this.isSelectedChanged = false;
1413
1414
  this.onPointerDownScale = 1;
1414
1415
  this.onPointerDownPosition = new Point(0, 0);
1415
1416
  this.draggableItems = [];
@@ -1418,6 +1419,7 @@ class FDraggableDataContext {
1418
1419
  this.draggableItems = [];
1419
1420
  this.onPointerDownScale = 1;
1420
1421
  this.onPointerDownPosition = new Point(0, 0);
1422
+ this.isSelectedChanged = false;
1421
1423
  }
1422
1424
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.9", ngImport: i0, type: FDraggableDataContext, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1423
1425
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.9", ngImport: i0, type: FDraggableDataContext }); }
@@ -2606,6 +2608,7 @@ class NodePrepareDragSequence {
2606
2608
  if (!this.fDraggableDataContext.selectedItems.includes(node)) {
2607
2609
  this.fDraggableDataContext.selectedItems.push(node);
2608
2610
  node.select();
2611
+ this.fDraggableDataContext.isSelectedChanged = true;
2609
2612
  }
2610
2613
  this.updateNodeLayerHandler.handle(node);
2611
2614
  const itemsToDrag = this.calculateDraggableConnectionsAndNodes();
@@ -2683,13 +2686,23 @@ class SingleSelectOnPointerDown {
2683
2686
  this.getConnectionHandler = getConnectionHandler;
2684
2687
  }
2685
2688
  handle(event) {
2689
+ if (!this.fComponentsStore.fFlow?.hostElement.contains(event.targetElement)) {
2690
+ return;
2691
+ }
2686
2692
  const node = this.fComponentsStore.findNode(event.targetElement);
2687
2693
  const connection = this.getConnectionHandler.handle(event.targetElement);
2688
2694
  this.deselectAll(node, event);
2695
+ let element;
2696
+ if (this.fDraggableDataContext.selectedItems.length) {
2697
+ element = this.fDraggableDataContext.selectedItems[0];
2698
+ }
2689
2699
  this.resetSelectionIfNotMultiselect(event);
2690
2700
  if (node) {
2691
2701
  if (!this.fDraggableDataContext.selectedItems.includes(node)) {
2692
2702
  this.fDraggableDataContext.selectedItems.push(node);
2703
+ if (element?.hostElement.id !== node.hostElement.id) {
2704
+ this.fDraggableDataContext.isSelectedChanged = true;
2705
+ }
2693
2706
  }
2694
2707
  else {
2695
2708
  this.fDraggableDataContext.selectedItems.splice(this.fDraggableDataContext.selectedItems.indexOf(node), 1);
@@ -2698,6 +2711,9 @@ class SingleSelectOnPointerDown {
2698
2711
  else if (connection) {
2699
2712
  if (!this.fDraggableDataContext.selectedItems.includes(connection)) {
2700
2713
  this.fDraggableDataContext.selectedItems.push(connection);
2714
+ if (element?.hostElement.id !== connection.hostElement.id) {
2715
+ this.fDraggableDataContext.isSelectedChanged = true;
2716
+ }
2701
2717
  }
2702
2718
  else {
2703
2719
  this.fDraggableDataContext.selectedItems.splice(this.fDraggableDataContext.selectedItems.indexOf(connection), 1);
@@ -2835,6 +2851,9 @@ class SelectionAreaDragHandle {
2835
2851
  complete() {
2836
2852
  this.fDraggableDataContext.fSelectionArea?.hide();
2837
2853
  this.fDraggableDataContext.selectedItems.push(...this.selectedByMove);
2854
+ if (this.selectedByMove.length > 0) {
2855
+ this.fDraggableDataContext.isSelectedChanged = true;
2856
+ }
2838
2857
  }
2839
2858
  }
2840
2859
 
@@ -2889,6 +2908,152 @@ const SELECTION_AREA_PROVIDERS = [
2889
2908
  SelectionAreaOnPointerUp,
2890
2909
  ];
2891
2910
 
2911
+ const MOUSE_EVENT_IGNORE_TIME = 800;
2912
+ class IDragAndDropBase {
2913
+ isSyntheticEvent(event) {
2914
+ const isSyntheticEvent = !!this.lastTouchEventTime &&
2915
+ (this.lastTouchEventTime + MOUSE_EVENT_IGNORE_TIME > Date.now());
2916
+ return isSyntheticEvent;
2917
+ }
2918
+ constructor(ngZone) {
2919
+ this.ngZone = ngZone;
2920
+ this.mouseListeners = EventExtensions.emptyListener();
2921
+ this.touchListeners = EventExtensions.emptyListener();
2922
+ this.startListeners = EventExtensions.emptyListener();
2923
+ this.lastTouchEventTime = 0;
2924
+ this.isDragStarted = false;
2925
+ this.dragStartThreshold = 5;
2926
+ this.dragStartDelay = 0;
2927
+ this.dragStartTime = 0;
2928
+ this.dragStartPosition = PointExtensions.initialize();
2929
+ this.moveHandler = this.checkDragSequenceToStart;
2930
+ this.onMouseDown = (event) => {
2931
+ const isSyntheticEvent = this.isSyntheticEvent(event);
2932
+ const isFakeEvent = isFakeMousedownFromScreenReader(event);
2933
+ const mouseEvent = new IMouseEvent(event);
2934
+ if (isSyntheticEvent || isFakeEvent || this.disabled) {
2935
+ return;
2936
+ }
2937
+ let result = this.onPointerDown(mouseEvent);
2938
+ if (result) {
2939
+ this.dragStartTime = Date.now();
2940
+ this.dragStartPosition = mouseEvent.getPosition();
2941
+ this.ngZone.runOutsideAngular(() => {
2942
+ this.element.addEventListener('mousemove', this.onMouseMove);
2943
+ this.element.addEventListener('mouseup', this.onMouseUp);
2944
+ });
2945
+ this.mouseListeners = () => {
2946
+ this.element.removeEventListener('mousemove', this.onMouseMove);
2947
+ this.element.removeEventListener('mouseup', this.onMouseUp);
2948
+ };
2949
+ }
2950
+ };
2951
+ this.onTouchDown = (event) => {
2952
+ const isFakeEvent = isFakeTouchstartFromScreenReader(event);
2953
+ const touchEvent = new ITouchDownEvent(event);
2954
+ if (isFakeEvent || this.disabled) {
2955
+ return;
2956
+ }
2957
+ let result = this.onPointerDown(new ITouchDownEvent(event));
2958
+ if (result) {
2959
+ this.dragStartTime = Date.now();
2960
+ this.dragStartPosition = touchEvent.getPosition();
2961
+ this.ngZone.runOutsideAngular(() => {
2962
+ this.element.addEventListener('touchmove', this.onTouchMove);
2963
+ this.element.addEventListener('touchend', this.onTouchUp);
2964
+ });
2965
+ this.touchListeners = () => {
2966
+ this.element.removeEventListener('touchmove', this.onTouchMove);
2967
+ this.element.removeEventListener('touchend', this.onTouchUp);
2968
+ };
2969
+ }
2970
+ };
2971
+ this.onMouseMove = (event) => {
2972
+ this.moveHandler(new IMouseEvent(event));
2973
+ };
2974
+ this.onTouchMove = (event) => {
2975
+ this.moveHandler(new ITouchMoveEvent(event));
2976
+ };
2977
+ this.onMouseUp = (event) => {
2978
+ if (this.isDragStarted) {
2979
+ this.onPointerUp(new IMouseEvent(event));
2980
+ }
2981
+ this.endDragSequence();
2982
+ };
2983
+ this.onTouchUp = (event) => {
2984
+ if (this.isDragStarted) {
2985
+ this.onPointerUp(new ITouchUpEvent(event));
2986
+ }
2987
+ this.endDragSequence();
2988
+ };
2989
+ }
2990
+ checkDragSequenceToStart(event) {
2991
+ const pointerPosition = event.getPosition();
2992
+ if (!this.isDragStarted) {
2993
+ const distanceX = Math.abs(pointerPosition.x - this.dragStartPosition.x);
2994
+ const distanceY = Math.abs(pointerPosition.y - this.dragStartPosition.y);
2995
+ const isOverThreshold = distanceX + distanceY >= this.dragStartThreshold;
2996
+ if (isOverThreshold) {
2997
+ const isDelayElapsed = Date.now() >= this.dragStartTime + this.dragStartDelay;
2998
+ if (!isDelayElapsed) {
2999
+ this.endDragSequence();
3000
+ return;
3001
+ }
3002
+ event.preventDefault();
3003
+ this.prepareDragSequence(event);
3004
+ this.isDragStarted = true;
3005
+ this.moveHandler = this.onPointerMove;
3006
+ if (isTouchEvent(event.originalEvent)) {
3007
+ this.lastTouchEventTime = Date.now();
3008
+ }
3009
+ }
3010
+ }
3011
+ }
3012
+ endDragSequence() {
3013
+ this.isDragStarted = false;
3014
+ this.moveHandler = this.checkDragSequenceToStart;
3015
+ this.mouseListeners();
3016
+ this.mouseListeners = EventExtensions.emptyListener();
3017
+ this.touchListeners();
3018
+ this.touchListeners = EventExtensions.emptyListener();
3019
+ }
3020
+ subscribe(elementToSubscribe) {
3021
+ if (this.element) {
3022
+ this.unsubscribe();
3023
+ }
3024
+ this.element = elementToSubscribe;
3025
+ this.ngZone.runOutsideAngular(() => {
3026
+ this.element.addEventListener('mousedown', this.onMouseDown, EventExtensions.activeListener());
3027
+ this.element.addEventListener('touchstart', this.onTouchDown, EventExtensions.passiveListener());
3028
+ });
3029
+ this.startListeners = () => {
3030
+ this.element.removeEventListener('mousedown', this.onMouseDown, EventExtensions.activeListener());
3031
+ this.element.removeEventListener('touchstart', this.onTouchDown, EventExtensions.passiveListener());
3032
+ };
3033
+ }
3034
+ unsubscribe() {
3035
+ this.startListeners();
3036
+ this.startListeners = EventExtensions.emptyListener();
3037
+ this.touchListeners();
3038
+ this.touchListeners = EventExtensions.emptyListener();
3039
+ this.mouseListeners();
3040
+ this.mouseListeners = EventExtensions.emptyListener();
3041
+ }
3042
+ }
3043
+ function isTouchEvent(event) {
3044
+ return event.type[0] === 't';
3045
+ }
3046
+ function isFakeMousedownFromScreenReader(event) {
3047
+ return event.buttons === 0 || (event.offsetX === 0 && event.offsetY === 0);
3048
+ }
3049
+ function isFakeTouchstartFromScreenReader(event) {
3050
+ const touch = (event.touches && event.touches[0]) || (event.changedTouches && event.changedTouches[0]);
3051
+ return (!!touch &&
3052
+ touch.identifier === -1 &&
3053
+ (touch.radiusX == null || touch.radiusX === 1) &&
3054
+ (touch.radiusY == null || touch.radiusY === 1));
3055
+ }
3056
+
2892
3057
  const F_DRAGGABLE = new InjectionToken('F_DRAGGABLE');
2893
3058
  class FDraggableBase extends IDragAndDropBase {
2894
3059
  constructor(ngZone) {
@@ -2967,6 +3132,9 @@ class FDraggableDirective extends FDraggableBase {
2967
3132
  this.fDraggableDataContext.reset();
2968
3133
  }
2969
3134
  emitSelectionChangeEvent() {
3135
+ if (!this.fDraggableDataContext.isSelectedChanged) {
3136
+ return;
3137
+ }
2970
3138
  let selectedNodes = [];
2971
3139
  let selectedConnections = [];
2972
3140
  this.fDraggableDataContext.selectedItems.forEach((x) => {
@@ -3031,6 +3199,7 @@ class SelectAllHandler {
3031
3199
  x.select();
3032
3200
  this.fDraggableDataContext.selectedItems.push(x);
3033
3201
  });
3202
+ this.fDraggableDataContext.isSelectedChanged = true;
3034
3203
  }
3035
3204
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.9", ngImport: i0, type: SelectAllHandler, deps: [{ token: FComponentsStore }, { token: FDraggableDataContext }], target: i0.ɵɵFactoryTarget.Injectable }); }
3036
3205
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.9", ngImport: i0, type: SelectAllHandler }); }