@foblex/flow 1.2.8 → 1.3.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.
@@ -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
 
@@ -496,6 +496,14 @@ function getFlowUid() {
496
496
  return FLOW.UID;
497
497
  }
498
498
 
499
+ var EFMarkerType;
500
+ (function (EFMarkerType) {
501
+ EFMarkerType["START"] = "f-connection-marker-start";
502
+ EFMarkerType["END"] = "f-connection-marker-end";
503
+ EFMarkerType["SELECTED_START"] = "selected_start";
504
+ EFMarkerType["SELECTED_END"] = "selected_end";
505
+ })(EFMarkerType || (EFMarkerType = {}));
506
+
499
507
  class FConnectionPathComponent {
500
508
  get linkToGradient() {
501
509
  return F_CONNECTION_IDENTIFIERS.linkToGradient(this.base.outputId + this.base.inputId);
@@ -517,15 +525,18 @@ class FConnectionPathComponent {
517
525
  this.hostElement.setAttribute("d", `${path}`);
518
526
  }
519
527
  select() {
520
- this.hostElement.setAttribute('marker-start', `url(#${sanitizeElementId(getFlowUid() + '-f-connection-marker-start-selected')})`);
521
- this.hostElement.setAttribute('marker-end', `url(#${sanitizeElementId(getFlowUid() + '-f-connection-marker-end-selected')})`);
528
+ this.hostElement.setAttribute('marker-start', `url(#${this.getMarkerId(EFMarkerType.SELECTED_START)})`);
529
+ this.hostElement.setAttribute('marker-end', `url(#${this.getMarkerId(EFMarkerType.SELECTED_END)})`);
522
530
  }
523
531
  deselect() {
524
- this.hostElement.setAttribute('marker-start', `url(#${sanitizeElementId(getFlowUid() + '-f-connection-marker-start-' + this.base.id)})`);
525
- this.hostElement.setAttribute('marker-end', `url(#${sanitizeElementId(getFlowUid() + '-f-connection-marker-end-' + this.base.id)})`);
532
+ this.hostElement.setAttribute('marker-start', `url(#${this.getMarkerId(EFMarkerType.START)})`);
533
+ this.hostElement.setAttribute('marker-end', `url(#${this.getMarkerId(EFMarkerType.END)})`);
534
+ }
535
+ getMarkerId(type) {
536
+ return sanitizeElementId(`${getFlowUid()}-${type}-${this.base.id}`);
526
537
  }
527
538
  isSelected() {
528
- return this.hostElement.getAttribute('marker-start') === `url(#${sanitizeElementId(getFlowUid() + '-f-connection-marker-start-selected')})`;
539
+ return this.hostElement.getAttribute('marker-start') === `url(#${this.getMarkerId(EFMarkerType.SELECTED_START)})`;
529
540
  }
530
541
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.9", ngImport: i0, type: FConnectionPathComponent, deps: [{ token: i0.ElementRef }, { token: F_CONNECTION }], target: i0.ɵɵFactoryTarget.Component }); }
531
542
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.9", type: FConnectionPathComponent, selector: "path[f-connection-path]", host: { properties: { "attr.id": "attrConnectionId", "attr.stroke": "linkToGradient" }, classAttribute: "f-component f-connection-path" }, providers: [{ provide: CONNECTION_PATH, useExisting: FConnectionPathComponent }], ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
@@ -900,14 +911,6 @@ function castToConnectionType(type) {
900
911
  return result;
901
912
  }
902
913
 
903
- var EFMarkerType;
904
- (function (EFMarkerType) {
905
- EFMarkerType["START"] = "f-connection-marker-start";
906
- EFMarkerType["END"] = "f-connection-marker-end";
907
- EFMarkerType["SELECTED_START"] = "selected_start";
908
- EFMarkerType["SELECTED_END"] = "selected_end";
909
- })(EFMarkerType || (EFMarkerType = {}));
910
-
911
914
  const F_MARKER = new InjectionToken('F_MARKER');
912
915
  class FMarkerBase {
913
916
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.9", ngImport: i0, type: FMarkerBase, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
@@ -2680,6 +2683,9 @@ class SingleSelectOnPointerDown {
2680
2683
  this.getConnectionHandler = getConnectionHandler;
2681
2684
  }
2682
2685
  handle(event) {
2686
+ if (!this.fComponentsStore.fFlow?.hostElement.contains(event.targetElement)) {
2687
+ return;
2688
+ }
2683
2689
  const node = this.fComponentsStore.findNode(event.targetElement);
2684
2690
  const connection = this.getConnectionHandler.handle(event.targetElement);
2685
2691
  this.deselectAll(node, event);
@@ -2886,6 +2892,152 @@ const SELECTION_AREA_PROVIDERS = [
2886
2892
  SelectionAreaOnPointerUp,
2887
2893
  ];
2888
2894
 
2895
+ const MOUSE_EVENT_IGNORE_TIME = 800;
2896
+ class IDragAndDropBase {
2897
+ isSyntheticEvent(event) {
2898
+ const isSyntheticEvent = !!this.lastTouchEventTime &&
2899
+ (this.lastTouchEventTime + MOUSE_EVENT_IGNORE_TIME > Date.now());
2900
+ return isSyntheticEvent;
2901
+ }
2902
+ constructor(ngZone) {
2903
+ this.ngZone = ngZone;
2904
+ this.mouseListeners = EventExtensions.emptyListener();
2905
+ this.touchListeners = EventExtensions.emptyListener();
2906
+ this.startListeners = EventExtensions.emptyListener();
2907
+ this.lastTouchEventTime = 0;
2908
+ this.isDragStarted = false;
2909
+ this.dragStartThreshold = 5;
2910
+ this.dragStartDelay = 0;
2911
+ this.dragStartTime = 0;
2912
+ this.dragStartPosition = PointExtensions.initialize();
2913
+ this.moveHandler = this.checkDragSequenceToStart;
2914
+ this.onMouseDown = (event) => {
2915
+ const isSyntheticEvent = this.isSyntheticEvent(event);
2916
+ const isFakeEvent = isFakeMousedownFromScreenReader(event);
2917
+ const mouseEvent = new IMouseEvent(event);
2918
+ if (isSyntheticEvent || isFakeEvent || this.disabled) {
2919
+ return;
2920
+ }
2921
+ let result = this.onPointerDown(mouseEvent);
2922
+ if (result) {
2923
+ this.dragStartTime = Date.now();
2924
+ this.dragStartPosition = mouseEvent.getPosition();
2925
+ this.ngZone.runOutsideAngular(() => {
2926
+ this.element.addEventListener('mousemove', this.onMouseMove);
2927
+ this.element.addEventListener('mouseup', this.onMouseUp);
2928
+ });
2929
+ this.mouseListeners = () => {
2930
+ this.element.removeEventListener('mousemove', this.onMouseMove);
2931
+ this.element.removeEventListener('mouseup', this.onMouseUp);
2932
+ };
2933
+ }
2934
+ };
2935
+ this.onTouchDown = (event) => {
2936
+ const isFakeEvent = isFakeTouchstartFromScreenReader(event);
2937
+ const touchEvent = new ITouchDownEvent(event);
2938
+ if (isFakeEvent || this.disabled) {
2939
+ return;
2940
+ }
2941
+ let result = this.onPointerDown(new ITouchDownEvent(event));
2942
+ if (result) {
2943
+ this.dragStartTime = Date.now();
2944
+ this.dragStartPosition = touchEvent.getPosition();
2945
+ this.ngZone.runOutsideAngular(() => {
2946
+ this.element.addEventListener('touchmove', this.onTouchMove);
2947
+ this.element.addEventListener('touchend', this.onTouchUp);
2948
+ });
2949
+ this.touchListeners = () => {
2950
+ this.element.removeEventListener('touchmove', this.onTouchMove);
2951
+ this.element.removeEventListener('touchend', this.onTouchUp);
2952
+ };
2953
+ }
2954
+ };
2955
+ this.onMouseMove = (event) => {
2956
+ this.moveHandler(new IMouseEvent(event));
2957
+ };
2958
+ this.onTouchMove = (event) => {
2959
+ this.moveHandler(new ITouchMoveEvent(event));
2960
+ };
2961
+ this.onMouseUp = (event) => {
2962
+ if (this.isDragStarted) {
2963
+ this.onPointerUp(new IMouseEvent(event));
2964
+ }
2965
+ this.endDragSequence();
2966
+ };
2967
+ this.onTouchUp = (event) => {
2968
+ if (this.isDragStarted) {
2969
+ this.onPointerUp(new ITouchUpEvent(event));
2970
+ }
2971
+ this.endDragSequence();
2972
+ };
2973
+ }
2974
+ checkDragSequenceToStart(event) {
2975
+ const pointerPosition = event.getPosition();
2976
+ if (!this.isDragStarted) {
2977
+ const distanceX = Math.abs(pointerPosition.x - this.dragStartPosition.x);
2978
+ const distanceY = Math.abs(pointerPosition.y - this.dragStartPosition.y);
2979
+ const isOverThreshold = distanceX + distanceY >= this.dragStartThreshold;
2980
+ if (isOverThreshold) {
2981
+ const isDelayElapsed = Date.now() >= this.dragStartTime + this.dragStartDelay;
2982
+ if (!isDelayElapsed) {
2983
+ this.endDragSequence();
2984
+ return;
2985
+ }
2986
+ event.preventDefault();
2987
+ this.prepareDragSequence(event);
2988
+ this.isDragStarted = true;
2989
+ this.moveHandler = this.onPointerMove;
2990
+ if (isTouchEvent(event.originalEvent)) {
2991
+ this.lastTouchEventTime = Date.now();
2992
+ }
2993
+ }
2994
+ }
2995
+ }
2996
+ endDragSequence() {
2997
+ this.isDragStarted = false;
2998
+ this.moveHandler = this.checkDragSequenceToStart;
2999
+ this.mouseListeners();
3000
+ this.mouseListeners = EventExtensions.emptyListener();
3001
+ this.touchListeners();
3002
+ this.touchListeners = EventExtensions.emptyListener();
3003
+ }
3004
+ subscribe(elementToSubscribe) {
3005
+ if (this.element) {
3006
+ this.unsubscribe();
3007
+ }
3008
+ this.element = elementToSubscribe;
3009
+ this.ngZone.runOutsideAngular(() => {
3010
+ this.element.addEventListener('mousedown', this.onMouseDown, EventExtensions.activeListener());
3011
+ this.element.addEventListener('touchstart', this.onTouchDown, EventExtensions.passiveListener());
3012
+ });
3013
+ this.startListeners = () => {
3014
+ this.element.removeEventListener('mousedown', this.onMouseDown, EventExtensions.activeListener());
3015
+ this.element.removeEventListener('touchstart', this.onTouchDown, EventExtensions.passiveListener());
3016
+ };
3017
+ }
3018
+ unsubscribe() {
3019
+ this.startListeners();
3020
+ this.startListeners = EventExtensions.emptyListener();
3021
+ this.touchListeners();
3022
+ this.touchListeners = EventExtensions.emptyListener();
3023
+ this.mouseListeners();
3024
+ this.mouseListeners = EventExtensions.emptyListener();
3025
+ }
3026
+ }
3027
+ function isTouchEvent(event) {
3028
+ return event.type[0] === 't';
3029
+ }
3030
+ function isFakeMousedownFromScreenReader(event) {
3031
+ return event.buttons === 0 || (event.offsetX === 0 && event.offsetY === 0);
3032
+ }
3033
+ function isFakeTouchstartFromScreenReader(event) {
3034
+ const touch = (event.touches && event.touches[0]) || (event.changedTouches && event.changedTouches[0]);
3035
+ return (!!touch &&
3036
+ touch.identifier === -1 &&
3037
+ (touch.radiusX == null || touch.radiusX === 1) &&
3038
+ (touch.radiusY == null || touch.radiusY === 1));
3039
+ }
3040
+
2889
3041
  const F_DRAGGABLE = new InjectionToken('F_DRAGGABLE');
2890
3042
  class FDraggableBase extends IDragAndDropBase {
2891
3043
  constructor(ngZone) {