Skip to content

Commit 56c53d8

Browse files
authored
0.24.5. (#166)
1 parent 4864d91 commit 56c53d8

26 files changed

+120
-117
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# 0.24.5
2+
3+
Fixed another bug with event handling when the designer is placed in a shadow DOM.
4+
15
# 0.24.4
26

37
Fixed event handling when the designer is placed in a shadow DOM.

README.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,10 @@ Add the below code to your head section in HTML document.
103103
```html
104104
<head>
105105
...
106-
<link href="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.24.4/css/designer.css" rel="stylesheet">
107-
<link href="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.24.4/css/designer-light.css" rel="stylesheet">
108-
<link href="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.24.4/css/designer-dark.css" rel="stylesheet">
109-
<script src="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.24.4/dist/index.umd.js"></script>
106+
<link href="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.24.5/css/designer.css" rel="stylesheet">
107+
<link href="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.24.5/css/designer-light.css" rel="stylesheet">
108+
<link href="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.24.5/css/designer-dark.css" rel="stylesheet">
109+
<script src="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.24.5/dist/index.umd.js"></script>
110110
```
111111

112112
Call the designer by:

angular/designer/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "sequential-workflow-designer-angular",
33
"description": "Angular wrapper for Sequential Workflow Designer component.",
4-
"version": "0.24.4",
4+
"version": "0.24.5",
55
"author": {
66
"name": "NoCode JS",
77
"url": "https://nocode-js.com/"
@@ -15,7 +15,7 @@
1515
"peerDependencies": {
1616
"@angular/common": "12 - 18",
1717
"@angular/core": "12 - 18",
18-
"sequential-workflow-designer": "^0.24.4"
18+
"sequential-workflow-designer": "^0.24.5"
1919
},
2020
"dependencies": {
2121
"tslib": "^2.3.0"

demos/angular-app/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@
2626
"@angular/platform-browser-dynamic": "^17.3.9",
2727
"@angular/router": "^17.3.9",
2828
"rxjs": "~7.8.0",
29-
"sequential-workflow-designer": "^0.24.4",
30-
"sequential-workflow-designer-angular": "^0.24.4",
29+
"sequential-workflow-designer": "^0.24.5",
30+
"sequential-workflow-designer-angular": "^0.24.5",
3131
"tslib": "^2.3.0",
3232
"zone.js": "~0.14.6"
3333
},

demos/react-app/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
"dependencies": {
77
"react": "^18.2.0",
88
"react-dom": "^18.2.0",
9-
"sequential-workflow-designer": "^0.24.4",
10-
"sequential-workflow-designer-react": "^0.24.4"
9+
"sequential-workflow-designer": "^0.24.5",
10+
"sequential-workflow-designer-react": "^0.24.5"
1111
},
1212
"devDependencies": {
1313
"@types/jest": "^29.2.5",

demos/svelte-app/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
"eslint": "eslint ./src --ext .ts"
1717
},
1818
"dependencies": {
19-
"sequential-workflow-designer": "^0.24.4",
20-
"sequential-workflow-designer-svelte": "^0.24.4"
19+
"sequential-workflow-designer": "^0.24.5",
20+
"sequential-workflow-designer-svelte": "^0.24.5"
2121
},
2222
"devDependencies": {
2323
"@sveltejs/adapter-static": "^2.0.3",

designer/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "sequential-workflow-designer",
33
"description": "Customizable no-code component for building flow-based programming applications.",
4-
"version": "0.24.4",
4+
"version": "0.24.5",
55
"type": "module",
66
"main": "./lib/esm/index.js",
77
"types": "./lib/index.d.ts",

designer/src/api/designer-api.ts

+2-4
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@ export class DesignerApi {
2121
);
2222

2323
return new DesignerApi(
24-
context.documentOrShadowRoot,
25-
context.documentBody,
24+
context.configuration.shadowRoot,
2625
ControlBarApi.create(context.state, context.historyController, context.stateModifier, viewport),
2726
new ToolboxApi(context.state, context, context.behaviorController, toolboxDataProvider, context.configuration.uidGenerator),
2827
new EditorApi(context.state, context.definitionWalker, context.stateModifier),
@@ -35,8 +34,7 @@ export class DesignerApi {
3534
}
3635

3736
private constructor(
38-
public readonly documentOrShadowRoot: Document | ShadowRoot,
39-
public readonly documentBody: Node,
37+
public readonly shadowRoot: ShadowRoot | undefined,
4038
public readonly controlBar: ControlBarApi,
4139
public readonly toolbox: ToolboxApi,
4240
public readonly editor: EditorApi,

designer/src/behaviors/behavior-controller.ts

+46-20
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,14 @@ export class BehaviorController {
1515
lastPosition?: Vector;
1616
};
1717

18-
public constructor(private readonly documentOrShadowRoot: DocumentOrShadowRoot) {}
18+
public static create(shadowRoot: ShadowRoot | undefined) {
19+
return new BehaviorController(shadowRoot ?? document, shadowRoot);
20+
}
21+
22+
private constructor(
23+
private readonly dom: Document | ShadowRoot,
24+
private readonly shadowRoot: ShadowRoot | undefined
25+
) {}
1926

2027
public start(startPosition: Vector, behavior: Behavior) {
2128
if (this.state) {
@@ -29,42 +36,62 @@ export class BehaviorController {
2936
};
3037
behavior.onStart(this.state.startPosition);
3138

32-
window.addEventListener('mousemove', this.onMouseMove, false);
33-
window.addEventListener('touchmove', this.onTouchMove, nonPassiveOptions);
34-
window.addEventListener('mouseup', this.onMouseUp, false);
35-
window.addEventListener('touchend', this.onTouchEnd, nonPassiveOptions);
36-
window.addEventListener('touchstart', this.onTouchStart, nonPassiveOptions);
39+
if (this.shadowRoot) {
40+
this.bind(this.shadowRoot);
41+
}
42+
this.bind(window);
43+
}
44+
45+
private bind(target: EventTarget) {
46+
target.addEventListener('mousemove', this.onMouseMove, false);
47+
target.addEventListener('touchmove', this.onTouchMove, nonPassiveOptions);
48+
target.addEventListener('mouseup', this.onMouseUp, false);
49+
target.addEventListener('touchend', this.onTouchEnd, nonPassiveOptions);
50+
target.addEventListener('touchstart', this.onTouchStart, nonPassiveOptions);
51+
}
52+
53+
private unbind(target: EventTarget) {
54+
target.removeEventListener('mousemove', this.onMouseMove, false);
55+
target.removeEventListener('touchmove', this.onTouchMove, nonPassiveOptions);
56+
target.removeEventListener('mouseup', this.onMouseUp, false);
57+
target.removeEventListener('touchend', this.onTouchEnd, nonPassiveOptions);
58+
target.removeEventListener('touchstart', this.onTouchStart, nonPassiveOptions);
3759
}
3860

39-
private readonly onMouseMove = (e: MouseEvent) => {
61+
private readonly onMouseMove = (e: Event) => {
4062
e.preventDefault();
41-
this.move(readMousePosition(e));
63+
e.stopPropagation();
64+
this.move(readMousePosition(e as MouseEvent));
4265
};
4366

44-
private readonly onTouchMove = (e: TouchEvent) => {
67+
private readonly onTouchMove = (e: Event) => {
4568
e.preventDefault();
46-
this.move(readTouchPosition(e));
69+
e.stopPropagation();
70+
this.move(readTouchPosition(e as TouchEvent));
4771
};
4872

49-
private readonly onMouseUp = (e: MouseEvent) => {
73+
private readonly onMouseUp = (e: Event) => {
5074
e.preventDefault();
75+
e.stopPropagation();
5176
this.stop(false, e.target as Element | null);
5277
};
5378

54-
private readonly onTouchEnd = (e: TouchEvent) => {
79+
private readonly onTouchEnd = (e: Event) => {
5580
e.preventDefault();
81+
e.stopPropagation();
5682
if (!this.state) {
5783
throw new Error(notInitializedError);
5884
}
5985

6086
const position = this.state.lastPosition ?? this.state.startPosition;
61-
const element = this.documentOrShadowRoot.elementFromPoint(position.x, position.y);
87+
const element = this.dom.elementFromPoint(position.x, position.y);
6288
this.stop(false, element);
6389
};
6490

65-
private readonly onTouchStart = (e: TouchEvent) => {
91+
private readonly onTouchStart = (e: Event) => {
6692
e.preventDefault();
67-
if (e.touches.length !== 1) {
93+
e.stopPropagation();
94+
if ((e as TouchEvent).touches.length !== 1) {
6895
this.stop(true, null);
6996
}
7097
};
@@ -92,11 +119,10 @@ export class BehaviorController {
92119
throw new Error(notInitializedError);
93120
}
94121

95-
window.removeEventListener('mousemove', this.onMouseMove, false);
96-
window.removeEventListener('touchmove', this.onTouchMove, nonPassiveOptions);
97-
window.removeEventListener('mouseup', this.onMouseUp, false);
98-
window.removeEventListener('touchend', this.onTouchEnd, nonPassiveOptions);
99-
window.removeEventListener('touchstart', this.onTouchStart, nonPassiveOptions);
122+
if (this.shadowRoot) {
123+
this.unbind(this.shadowRoot);
124+
}
125+
this.unbind(window);
100126

101127
this.state.behavior.onEnd(interrupt, element);
102128
this.state = undefined;

designer/src/behaviors/drag-step-behavior-view.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,21 @@ import { DraggedComponent } from '../designer-extension';
66

77
export class DragStepView {
88
public static create(step: Step, theme: string, componentContext: ComponentContext): DragStepView {
9+
const body = componentContext.shadowRoot ?? document.body;
910
const layer = Dom.element('div', {
1011
class: `sqd-drag sqd-theme-${theme}`
1112
});
12-
componentContext.documentBody.appendChild(layer);
13+
body.appendChild(layer);
1314

1415
const component = componentContext.services.draggedComponent.create(layer, step, componentContext);
1516

16-
return new DragStepView(component, layer, componentContext.documentBody);
17+
return new DragStepView(component, layer, body);
1718
}
1819

1920
private constructor(
2021
public readonly component: DraggedComponent,
2122
private readonly layer: HTMLElement,
22-
private readonly documentBody: Node
23+
private readonly body: Node
2324
) {}
2425

2526
public setPosition(position: Vector) {
@@ -29,6 +30,6 @@ export class DragStepView {
2930

3031
public remove() {
3132
this.component.destroy();
32-
this.documentBody.removeChild(this.layer);
33+
this.body.removeChild(this.layer);
3334
}
3435
}

designer/src/component-context.ts

+2-6
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ import { StepExtensionResolver } from './workspace/step-extension-resolver';
1010

1111
export class ComponentContext {
1212
public static create(
13-
documentOrShadowRoot: Document | ShadowRoot,
14-
documentBody: Node,
1513
configuration: DesignerConfiguration,
1614
state: DesignerState,
1715
stepExtensionResolver: StepExtensionResolver,
@@ -25,8 +23,7 @@ export class ComponentContext {
2523
const iconProvider = new IconProvider(configuration.steps);
2624
const stepComponentFactory = new StepComponentFactory(stepExtensionResolver);
2725
return new ComponentContext(
28-
documentOrShadowRoot,
29-
documentBody,
26+
configuration.shadowRoot,
3027
validator,
3128
iconProvider,
3229
placeholderController,
@@ -39,8 +36,7 @@ export class ComponentContext {
3936
}
4037

4138
private constructor(
42-
public readonly documentOrShadowRoot: Document | ShadowRoot,
43-
public readonly documentBody: Node,
39+
public readonly shadowRoot: ShadowRoot | undefined,
4440
public readonly validator: DefinitionValidator,
4541
public readonly iconProvider: IconProvider,
4642
public readonly placeholderController: PlaceholderController,
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,19 @@
11
import { isElementAttached } from './is-element-attached';
22

33
describe('isElementAttached', () => {
4-
const documentBody = document.body;
5-
64
it('returns true if attached', () => {
75
const element = document.createElement('h2');
86

97
document.body.appendChild(element);
108

11-
expect(isElementAttached(element, documentBody)).toBe(true);
9+
expect(isElementAttached(document, element)).toBe(true);
1210

1311
document.body.removeChild(element);
1412
});
1513

1614
it('returns false if not attached', () => {
1715
const element = document.createElement('h2');
1816

19-
expect(isElementAttached(element, documentBody)).toBe(false);
17+
expect(isElementAttached(document, element)).toBe(false);
2018
});
2119
});
+2-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
export function isElementAttached(element: HTMLElement, documentBody: Node): boolean {
2-
return !(documentBody.compareDocumentPosition(element) & Node.DOCUMENT_POSITION_DISCONNECTED);
1+
export function isElementAttached(dom: Document | ShadowRoot, element: HTMLElement): boolean {
2+
return !(dom.compareDocumentPosition(element) & Node.DOCUMENT_POSITION_DISCONNECTED);
33
}

designer/src/designer-configuration.ts

+2-7
Original file line numberDiff line numberDiff line change
@@ -89,14 +89,9 @@ export interface DesignerConfiguration<TDefinition extends Definition = Definiti
8989
i18n?: I18n;
9090

9191
/**
92-
* @description The document or shadow root where the designer is rendered. By default, the designer will use the `document`.
92+
* @description Pass the shadow root of the shadow root to the designer if the designer is placed inside the shadow DOM.
9393
*/
94-
documentOrShadowRoot?: Document | ShadowRoot;
95-
96-
/**
97-
* @description The body of the document. By default, the designer will use the `document.body`.
98-
*/
99-
documentBody?: Node;
94+
shadowRoot?: ShadowRoot;
10095
}
10196

10297
export type UidGenerator = () => string;

designer/src/designer-context.ts

+4-12
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,15 @@ import { PlaceholderController } from './designer-extension';
1616

1717
export class DesignerContext {
1818
public static create(
19-
documentOrShadowRoot: Document | ShadowRoot,
20-
documentBody: Node,
21-
parent: HTMLElement,
19+
placeholder: HTMLElement,
2220
startDefinition: Definition,
2321
configuration: DesignerConfiguration,
2422
services: Services
2523
): DesignerContext {
2624
const definition = ObjectCloner.deepClone(startDefinition);
2725

28-
const layoutController = new LayoutController(parent);
29-
const isReadonly = !!configuration.isReadonly;
26+
const layoutController = new LayoutController(placeholder);
27+
const isReadonly = Boolean(configuration.isReadonly);
3028

3129
const isToolboxCollapsed = configuration.toolbox ? configuration.toolbox.isCollapsed ?? layoutController.isMobile() : false;
3230
const isEditorCollapsed = configuration.editors ? configuration.editors.isCollapsed ?? layoutController.isMobile() : false;
@@ -35,7 +33,7 @@ export class DesignerContext {
3533
const state = new DesignerState(definition, isReadonly, isToolboxCollapsed, isEditorCollapsed);
3634
const workspaceController = new WorkspaceControllerWrapper();
3735
const placeholderController = services.placeholderController.create();
38-
const behaviorController = new BehaviorController(documentOrShadowRoot);
36+
const behaviorController = BehaviorController.create(configuration.shadowRoot);
3937
const stepExtensionResolver = StepExtensionResolver.create(services);
4038
const definitionWalker = configuration.definitionWalker ?? new DefinitionWalker();
4139
const i18n: I18n = configuration.i18n ?? ((_, defaultValue) => defaultValue);
@@ -49,8 +47,6 @@ export class DesignerContext {
4947

5048
const preferenceStorage = configuration.preferenceStorage ?? new MemoryPreferenceStorage();
5149
const componentContext = ComponentContext.create(
52-
documentOrShadowRoot,
53-
documentBody,
5450
configuration,
5551
state,
5652
stepExtensionResolver,
@@ -62,8 +58,6 @@ export class DesignerContext {
6258
);
6359

6460
return new DesignerContext(
65-
documentOrShadowRoot,
66-
documentBody,
6761
theme,
6862
state,
6963
configuration,
@@ -82,8 +76,6 @@ export class DesignerContext {
8276
}
8377

8478
public constructor(
85-
public readonly documentOrShadowRoot: Document | ShadowRoot,
86-
public readonly documentBody: Node,
8779
public readonly theme: string,
8880
public readonly state: DesignerState,
8981
public readonly configuration: DesignerConfiguration,

designer/src/designer.ts

+2-4
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,12 @@ export class Designer<TDefinition extends Definition = Definition> {
3636
const config = configuration as DesignerConfiguration;
3737
validateConfiguration(config);
3838

39-
const documentOrShadowRoot = configuration.documentOrShadowRoot ?? document;
40-
const documentBody = configuration.documentBody ?? document.body;
41-
if (!isElementAttached(placeholder, documentBody)) {
39+
if (!isElementAttached(config.shadowRoot ?? document, placeholder)) {
4240
throw new Error('Placeholder is not attached to the DOM');
4341
}
4442

4543
const services = ServicesResolver.resolve(configuration.extensions, config);
46-
const designerContext = DesignerContext.create(documentOrShadowRoot, documentBody, placeholder, startDefinition, config, services);
44+
const designerContext = DesignerContext.create(placeholder, startDefinition, config, services);
4745
const designerApi = DesignerApi.create(designerContext);
4846

4947
const view = DesignerView.create(placeholder, designerContext, designerApi);

0 commit comments

Comments
 (0)