Skip to content

Commit 9e51faf

Browse files
committed
better mobile experience.
1 parent 409411a commit 9e51faf

16 files changed

+123
-85
lines changed

examples/assets/lib.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
/* global location, document */
22

3-
function isLocalhost() {
4-
return location.hostname.toLowerCase() === 'localhost';
3+
function isTestEnv() {
4+
return location.hostname.toLowerCase() === 'localhost' ||
5+
location.hostname.startsWith('192.168.');
56
}
67

78
function embedScript(url) {
@@ -12,7 +13,7 @@ function embedStylesheet(url) {
1213
document.write(`<link href="${url}" rel="stylesheet">`);
1314
}
1415

15-
const baseUrl = isLocalhost()
16+
const baseUrl = isTestEnv()
1617
? '..'
1718
: '//cdn.jsdelivr.net/npm/[email protected]';
1819

src/behaviors/behavior-controller.ts

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ import { readMousePosition, readTouchPosition } from '../core/event-readers';
44

55
export class BehaviorController {
66
private readonly onMouseMoveHandler = (e: MouseEvent) => this.onMouseMove(e);
7-
private readonly onTouchMoveHandler = (e: TouchEvent) => this.onTouchMove(e);
87
private readonly onMouseUpHandler = (e: MouseEvent) => this.onMouseUp(e);
8+
private readonly onTouchMoveHandler = (e: TouchEvent) => this.onTouchMove(e);
99
private readonly onTouchEndHandler = (e: TouchEvent) => this.onTouchEnd(e);
10+
private readonly onTouchStartHandler = (e: TouchEvent) => this.onTouchStart(e);
1011

1112
private state?: {
1213
startPosition: Vector;
@@ -15,7 +16,7 @@ export class BehaviorController {
1516

1617
public start(startPosition: Vector, behavior: Behavior) {
1718
if (this.state) {
18-
this.stop();
19+
this.stop(true);
1920
return;
2021
}
2122

@@ -25,10 +26,11 @@ export class BehaviorController {
2526
};
2627
behavior.onStart(this.state.startPosition);
2728

28-
window.addEventListener('mousemove', this.onMouseMoveHandler);
29-
window.addEventListener('touchmove', this.onTouchMoveHandler);
30-
window.addEventListener('mouseup', this.onMouseUpHandler);
31-
window.addEventListener('touchend', this.onTouchEndHandler);
29+
window.addEventListener('mousemove', this.onMouseMoveHandler, false);
30+
window.addEventListener('touchmove', this.onTouchMoveHandler, false);
31+
window.addEventListener('mouseup', this.onMouseUpHandler, false);
32+
window.addEventListener('touchend', this.onTouchEndHandler, false);
33+
window.addEventListener('touchstart', this.onTouchStartHandler, false);
3234
}
3335

3436
private onMouseMove(e: MouseEvent) {
@@ -43,12 +45,19 @@ export class BehaviorController {
4345

4446
private onMouseUp(e: MouseEvent) {
4547
e.preventDefault();
46-
this.stop();
48+
this.stop(false);
4749
}
4850

4951
private onTouchEnd(e: TouchEvent) {
5052
e.preventDefault();
51-
this.stop();
53+
this.stop(false);
54+
}
55+
56+
private onTouchStart(e: TouchEvent) {
57+
e.preventDefault();
58+
if (e.touches.length !== 1) {
59+
this.stop(true);
60+
}
5261
}
5362

5463
private move(position: Vector) {
@@ -60,25 +69,26 @@ export class BehaviorController {
6069

6170
const newBehavior = this.state.behavior.onMove(delta);
6271
if (newBehavior) {
63-
this.state.behavior.onEnd();
72+
this.state.behavior.onEnd(true);
6473

6574
this.state.behavior = newBehavior;
6675
this.state.startPosition = position;
6776
this.state.behavior.onStart(this.state.startPosition);
6877
}
6978
}
7079

71-
private stop() {
80+
private stop(interrupt: boolean) {
7281
if (!this.state) {
7382
throw new Error('State is empty');
7483
}
7584

76-
window.removeEventListener('mousemove', this.onMouseMoveHandler);
77-
window.removeEventListener('touchmove', this.onTouchMoveHandler);
78-
window.removeEventListener('mouseup', this.onMouseUpHandler);
79-
window.removeEventListener('touchend', this.onTouchEndHandler);
85+
window.removeEventListener('mousemove', this.onMouseMoveHandler, false);
86+
window.removeEventListener('touchmove', this.onTouchMoveHandler, false);
87+
window.removeEventListener('mouseup', this.onMouseUpHandler, false);
88+
window.removeEventListener('touchend', this.onTouchEndHandler, false);
89+
window.removeEventListener('touchstart', this.onTouchEndHandler, false);
8090

81-
this.state.behavior.onEnd();
91+
this.state.behavior.onEnd(interrupt);
8292
this.state = undefined;
8393
}
8494
}

src/behaviors/behavior.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ import { Vector } from '../core/vector';
33
export interface Behavior {
44
onStart(position: Vector): void;
55
onMove(delta: Vector): Behavior | void;
6-
onEnd(): void;
6+
onEnd(interrupt: boolean): void;
77
}

src/behaviors/drag-step-behavior.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,11 @@ export class DragStepBehavior implements Behavior {
6767
}
6868
}
6969

70-
public onEnd() {
70+
public onEnd(interrupt: boolean) {
7171
this.view.remove();
7272
this.context.setIsDragging(false);
7373

74-
if (this.currentPlaceholder) {
74+
if (!interrupt && this.currentPlaceholder) {
7575
if (this.pressedStepComponent) {
7676
SequenceModifier.moveStep(
7777
this.pressedStepComponent.parentSequence,
@@ -87,6 +87,9 @@ export class DragStepBehavior implements Behavior {
8787
if (this.pressedStepComponent) {
8888
this.pressedStepComponent.setState(StepComponentState.default);
8989
}
90+
if (this.currentPlaceholder) {
91+
this.currentPlaceholder.setIsHover(false);
92+
}
9093
}
9194
this.currentPlaceholder = undefined;
9295

src/behaviors/placeholder-finder.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export class PlaceholderFinder {
66
public static create(placeholders: Placeholder[], context: DesignerContext): PlaceholderFinder {
77
const checker = new PlaceholderFinder(placeholders, context);
88
context.onViewPortChanged.subscribe(checker.clearCacheHandler);
9-
window.addEventListener('scroll', checker.clearCacheHandler);
9+
window.addEventListener('scroll', checker.clearCacheHandler, false);
1010
return checker;
1111
}
1212

@@ -42,7 +42,7 @@ export class PlaceholderFinder {
4242

4343
public destroy() {
4444
this.context.onViewPortChanged.unsubscribe(this.clearCacheHandler);
45-
window.removeEventListener('scroll', this.clearCacheHandler);
45+
window.removeEventListener('scroll', this.clearCacheHandler, false);
4646
}
4747

4848
private clearCache() {

src/behaviors/select-step-behavior.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ describe('SelectStepBehavior', () => {
1717
const behavior = SelectStepBehavior.create(stepComponent, context);
1818

1919
behavior.onStart();
20-
behavior.onEnd();
20+
behavior.onEnd(false);
2121

2222
expect<Step | null>(selectedStep).toEqual(step);
2323
});

src/behaviors/select-step-behavior.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ export class SelectStepBehavior implements Behavior {
99
return new SelectStepBehavior(pressedStepComponent, context);
1010
}
1111

12-
private isCanceled = false;
13-
1412
private constructor(private readonly pressedStepComponent: StepComponent, private readonly context: DesignerContext) {}
1513

1614
public onStart() {
@@ -19,14 +17,13 @@ export class SelectStepBehavior implements Behavior {
1917

2018
public onMove(delta: Vector): Behavior | void {
2119
if (!this.context.isReadonly && delta.distance() > 2) {
22-
this.isCanceled = true;
2320
this.context.setSelectedStep(null);
2421
return DragStepBehavior.create(this.context, this.pressedStepComponent.step, this.pressedStepComponent);
2522
}
2623
}
2724

28-
public onEnd() {
29-
if (!this.isCanceled) {
25+
public onEnd(interrupt: boolean) {
26+
if (!interrupt) {
3027
this.context.setSelectedStep(this.pressedStepComponent.step);
3128
}
3229
}

src/control-bar/control-bar-view.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,14 @@ export class ControlBarView {
6565
}
6666

6767
function bindClick(element: HTMLElement, handler: () => void) {
68-
element.addEventListener('click', e => {
69-
e.preventDefault();
70-
handler();
71-
});
68+
element.addEventListener(
69+
'click',
70+
e => {
71+
e.preventDefault();
72+
handler();
73+
},
74+
false
75+
);
7276
}
7377

7478
function createButton(iconContent: string, title: string): HTMLElement {

src/designer-view.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export class DesignerView {
2828
}
2929
const view = new DesignerView(root, context.layoutController, workspace, toolbox);
3030
view.reloadLayout();
31-
window.addEventListener('resize', view.onResizeHandler);
31+
window.addEventListener('resize', view.onResizeHandler, false);
3232
return view;
3333
}
3434

src/smart-editor/smart-editor-view.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,14 @@ export class SmartEditorView {
3030
) {}
3131

3232
public bindToggleIsCollapsedClick(handler: () => void) {
33-
this.toggle.addEventListener('click', e => {
34-
e.preventDefault();
35-
handler();
36-
});
33+
this.toggle.addEventListener(
34+
'click',
35+
e => {
36+
e.preventDefault();
37+
handler();
38+
},
39+
false
40+
);
3741
}
3842

3943
public setIsCollapsed(isCollapsed: boolean) {

0 commit comments

Comments
 (0)