@media-quest/engine 0.0.1 → 0.0.3
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/dist/public-api.d.mts +543 -0
- package/dist/public-api.d.ts +543 -0
- package/dist/public-api.js +2187 -0
- package/dist/public-api.mjs +2150 -0
- package/package.json +10 -3
- package/src/Delement/AudioContainer.ts +169 -0
- package/src/Delement/DAuto-play.ts +36 -0
- package/src/Delement/DElement.ts +263 -0
- package/src/Delement/DImg.ts +78 -0
- package/src/Delement/DStyle-utils.ts +616 -0
- package/src/Delement/DStyle.ts +165 -0
- package/src/Delement/DText.ts +29 -0
- package/src/Delement/Ddiv.ts +38 -0
- package/src/Delement/VideoContainer.ts +199 -0
- package/src/Delement/css.spec.ts +36 -0
- package/src/Delement/css.ts +46 -0
- package/src/commands/DCommand.ts +62 -0
- package/src/commands/DCommandBus.ts +60 -0
- package/src/common/DMaybe.ts +46 -0
- package/src/common/DTimestamp.ts +20 -0
- package/src/common/DTmestamp.spec.ts +11 -0
- package/src/common/result.ts +41 -0
- package/src/dto/AnimationDto.ts +4 -0
- package/src/dto/DElement.dto.ts +50 -0
- package/src/dto/SchemaDto.ts +65 -0
- package/src/engine/DPage.ts +55 -0
- package/src/engine/SchemaEngine.ts +210 -0
- package/src/engine/element-factory.ts +52 -0
- package/src/engine/scale.spec.ts +38 -0
- package/src/engine/scale.ts +70 -0
- package/src/event-handlers/DEventHandler.ts +29 -0
- package/src/events/DEvents.ts +94 -0
- package/src/events/event-bus.spec.ts +21 -0
- package/src/events/event-bus.ts +81 -0
- package/src/kladd/context-menu-manager.ts +56 -0
- package/src/player/dplayer.spec.ts +108 -0
- package/src/player/dplayer.ts +70 -0
- package/src/player/history-que.spec.ts +45 -0
- package/src/player/history-que.ts +38 -0
- package/src/player/next-que.spec.ts +108 -0
- package/src/player/next-que.ts +93 -0
- package/src/public-api.ts +18 -5
- package/src/rules/__test__/complex-condition.spec.ts +15 -0
- package/src/rules/__test__/conditon.spec.ts +124 -0
- package/src/rules/__test__/numeric-condition.spec.ts +84 -0
- package/src/rules/__test__/rule-engine.spec.ts +354 -0
- package/src/rules/__test__/rule-evaluation.spec.ts +140 -0
- package/src/rules/__test__/string-condition.spec.ts +41 -0
- package/src/rules/condition.ts +191 -0
- package/src/rules/fact.ts +18 -0
- package/src/rules/rule-engine.ts +46 -0
- package/src/rules/rule.ts +40 -0
- package/src/services/DMedia-manager.spec.ts +27 -0
- package/src/services/DMedia-manager.ts +182 -0
- package/src/services/resource-provider.ts +33 -0
- package/src/services/sequence-manager.spec.ts +168 -0
- package/src/services/sequence-manager.ts +132 -0
- package/src/state/Dstate.spec.ts +7 -0
- package/src/state/Dstate.ts +105 -0
- package/src/state/boolean-property.ts +69 -0
- package/src/state/state-service.spec.ts +307 -0
- package/src/state/state-service.ts +251 -0
- package/src/state/state-testing-helpers.ts +59 -0
- package/src/utils/DUtil.ts +109 -0
- package/tsconfig.json +4 -3
package/package.json
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@media-quest/engine",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "Rendering engine for media-quest schemas.",
|
|
5
|
-
"main": "
|
|
6
|
-
"
|
|
5
|
+
"main": "dist/public-api.js",
|
|
6
|
+
"module": "dist/public-api.mjs",
|
|
7
|
+
"types": "dist/public-api.d.ts",
|
|
8
|
+
"license": "MIT",
|
|
9
|
+
"scripts": {
|
|
10
|
+
"clean": "rimraf dist",
|
|
11
|
+
"build": "npm run clean && tsup src/public-api.ts --format cjs,esm --dts",
|
|
12
|
+
"prepublishOnly": "npm run build"
|
|
13
|
+
}
|
|
7
14
|
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { CanPlayToEnd } from "./VideoContainer";
|
|
2
|
+
import { DAudioDto } from "../dto/DElement.dto";
|
|
3
|
+
import { DEventDispatcher } from "../events/event-bus";
|
|
4
|
+
import { DTimestamp } from "../common/DTimestamp";
|
|
5
|
+
|
|
6
|
+
export class AudioContainer implements CanPlayToEnd {
|
|
7
|
+
private readonly TAG = "[ DAudio ]: ";
|
|
8
|
+
protected dto: DAudioDto | null = null;
|
|
9
|
+
private el: HTMLAudioElement;
|
|
10
|
+
constructor(private readonly eventBus: DEventDispatcher) {
|
|
11
|
+
this.el = document.createElement("audio");
|
|
12
|
+
this.el.style.position = "absolute";
|
|
13
|
+
this.el.style.visibility = "hidden";
|
|
14
|
+
// this.el.on
|
|
15
|
+
this.onLoad = this.onLoad.bind(this);
|
|
16
|
+
this.el.onload = this.onLoad;
|
|
17
|
+
this.onLoadedMetadata = this.onLoadedMetadata.bind(this);
|
|
18
|
+
this.el.onloadedmetadata = this.onLoadedMetadata;
|
|
19
|
+
this.el.onplay = () => {
|
|
20
|
+
// TODO
|
|
21
|
+
};
|
|
22
|
+
this.onCanPlayThrough = this.onCanPlayThrough.bind(this);
|
|
23
|
+
this.el.oncanplaythrough = this.onCanPlayThrough;
|
|
24
|
+
this.el.onended = (_) => {
|
|
25
|
+
const url = this.el.src;
|
|
26
|
+
this.eventBus.emit({
|
|
27
|
+
kind: "AUDIO_ENDED_EVENT",
|
|
28
|
+
data: { url },
|
|
29
|
+
producer: "DAudio",
|
|
30
|
+
timestamp: DTimestamp.now(),
|
|
31
|
+
producerId: this.id,
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
this.el.ondurationchange = (_: Event) => {
|
|
35
|
+
const duration = this.el.duration;
|
|
36
|
+
const isInfinity = duration === Number.POSITIVE_INFINITY;
|
|
37
|
+
this.eventBus.emit({
|
|
38
|
+
kind: "AUDIO_DURATION_CHANGE_EVENT",
|
|
39
|
+
timestamp: DTimestamp.now(),
|
|
40
|
+
producer: "DAudio",
|
|
41
|
+
producerId: this.id,
|
|
42
|
+
data: { duration: this.el.duration, isInfinity },
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
setAudio(dto: DAudioDto) {
|
|
48
|
+
this.dto = dto;
|
|
49
|
+
this.el.src = dto.url;
|
|
50
|
+
this.el.load();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
destroy() {
|
|
54
|
+
try {
|
|
55
|
+
this.el.pause();
|
|
56
|
+
this.el.src = "";
|
|
57
|
+
this.el.load();
|
|
58
|
+
} catch (e) {
|
|
59
|
+
console.log(e);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
pause() {
|
|
64
|
+
try {
|
|
65
|
+
this.el.pause();
|
|
66
|
+
} catch (e) {
|
|
67
|
+
// TODO EMIT ERROR EVENT.
|
|
68
|
+
console.log(e);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
play(url: string) {
|
|
73
|
+
if (this.el.src !== url) {
|
|
74
|
+
this.el.src = url;
|
|
75
|
+
}
|
|
76
|
+
this.eventBus.emit({
|
|
77
|
+
kind: "AUDIO_PLAY_EVENT",
|
|
78
|
+
producerId: this.id,
|
|
79
|
+
data: {},
|
|
80
|
+
producer: "DAudio",
|
|
81
|
+
timestamp: DTimestamp.now(),
|
|
82
|
+
});
|
|
83
|
+
this.el
|
|
84
|
+
.play()
|
|
85
|
+
.then((res) => {
|
|
86
|
+
console.log(res);
|
|
87
|
+
})
|
|
88
|
+
.catch((e) => {
|
|
89
|
+
console.log(e);
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
onLoadedMetadata(_: Event) {
|
|
94
|
+
this.eventBus.emit({
|
|
95
|
+
kind: "AUDIO_METADATA_LOADED_EVENT",
|
|
96
|
+
timestamp: DTimestamp.now(),
|
|
97
|
+
producer: "DAudio",
|
|
98
|
+
producerId: this.id,
|
|
99
|
+
data: {},
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
onLoad(_: Event) {
|
|
104
|
+
this.eventBus.emit({
|
|
105
|
+
kind: "AUDIO_LOAD_EVENT",
|
|
106
|
+
timestamp: DTimestamp.now(),
|
|
107
|
+
producer: "DAudio",
|
|
108
|
+
producerId: this.id,
|
|
109
|
+
data: {},
|
|
110
|
+
});
|
|
111
|
+
// console.log(this.TAG + event.type);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
get id() {
|
|
115
|
+
return this.dto?.id ?? "DAudio";
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
private onCanPlayThrough(_: Event) {
|
|
119
|
+
this.eventBus.emit({
|
|
120
|
+
kind: "AUDIO_CAN_PLAY_THROUGH_EVENT",
|
|
121
|
+
data: {},
|
|
122
|
+
producer: "DAudio",
|
|
123
|
+
timestamp: DTimestamp.now(),
|
|
124
|
+
producerId: this.id,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// private onPlay(_: Event) {}
|
|
129
|
+
|
|
130
|
+
async playToEnd(): Promise<boolean> {
|
|
131
|
+
const endedOrErrored = new Promise<boolean>((resolve) => {
|
|
132
|
+
this.el.addEventListener(
|
|
133
|
+
"ended",
|
|
134
|
+
(_) => {
|
|
135
|
+
// console.log(e);
|
|
136
|
+
resolve(true);
|
|
137
|
+
},
|
|
138
|
+
{ once: true }
|
|
139
|
+
);
|
|
140
|
+
this.el.addEventListener(
|
|
141
|
+
"error",
|
|
142
|
+
(_) => {
|
|
143
|
+
// console.log(e);
|
|
144
|
+
resolve(false);
|
|
145
|
+
},
|
|
146
|
+
{ once: true }
|
|
147
|
+
);
|
|
148
|
+
});
|
|
149
|
+
try {
|
|
150
|
+
this.play(this.el.src);
|
|
151
|
+
await endedOrErrored;
|
|
152
|
+
return true;
|
|
153
|
+
} catch (e) {
|
|
154
|
+
// TODO LET PARENT DEAL WITH ERRORS? THE MANAGER?? MANAGERS CALL ABORT.
|
|
155
|
+
console.log(e);
|
|
156
|
+
this.eventBus.emit({
|
|
157
|
+
kind: "AUDIO_ERROR_EVENT",
|
|
158
|
+
timestamp: DTimestamp.now(),
|
|
159
|
+
producer: "DAudio",
|
|
160
|
+
producerId: this.id,
|
|
161
|
+
data: { error: e },
|
|
162
|
+
});
|
|
163
|
+
return false;
|
|
164
|
+
} finally {
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return Promise.resolve(false);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { DCommand } from "../commands/DCommand";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Autoplay video by Id.
|
|
5
|
+
*/
|
|
6
|
+
export interface AutoPlayVideo {
|
|
7
|
+
readonly kind: "autoplay-video";
|
|
8
|
+
readonly muted?: boolean;
|
|
9
|
+
readonly startAt?: number;
|
|
10
|
+
readonly videoId: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Add a pause between auto-play elements.
|
|
15
|
+
* TODO Not implemented
|
|
16
|
+
*/
|
|
17
|
+
export interface AutoPlayPause {
|
|
18
|
+
readonly kind: "autoplay-pause";
|
|
19
|
+
readonly duration: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface AutoPlayAudio {
|
|
23
|
+
readonly kind: "autoplay-audio";
|
|
24
|
+
readonly audioId: string;
|
|
25
|
+
readonly startAt?: number;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export type AutoPlayElement = AutoPlayVideo | AutoPlayAudio | AutoPlayPause;
|
|
29
|
+
|
|
30
|
+
export interface DAutoPlaySequence {
|
|
31
|
+
readonly id: string;
|
|
32
|
+
readonly blockUserInput: boolean;
|
|
33
|
+
readonly items: Array<AutoPlayAudio | AutoPlayVideo | AutoPlayPause>;
|
|
34
|
+
readonly startCommands: ReadonlyArray<DCommand>;
|
|
35
|
+
readonly endCommands: ReadonlyArray<DCommand>;
|
|
36
|
+
}
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import { DStyle } from "./DStyle";
|
|
2
|
+
import { DElementBaseDto } from "../dto/DElement.dto";
|
|
3
|
+
import { DCommand, ElementCommand } from "../commands/DCommand";
|
|
4
|
+
import { DCommandBus } from "../commands/DCommandBus";
|
|
5
|
+
import { DEventHandler } from "../event-handlers/DEventHandler";
|
|
6
|
+
import { DUtil } from "../utils/DUtil";
|
|
7
|
+
import { EventBus } from "../events/event-bus";
|
|
8
|
+
import { DTimestamp } from "../common/DTimestamp";
|
|
9
|
+
import { AnimationDto } from "../dto/AnimationDto";
|
|
10
|
+
import { ScaleService } from "../engine/scale";
|
|
11
|
+
import { DState } from "../state/Dstate";
|
|
12
|
+
|
|
13
|
+
export abstract class DElement<T extends HTMLElement> {
|
|
14
|
+
protected readonly el: T;
|
|
15
|
+
private clickHandlerIsEnabled = true;
|
|
16
|
+
readonly id: string;
|
|
17
|
+
private isAnimatingSelf = false;
|
|
18
|
+
protected currStyle: Partial<DStyle> = {
|
|
19
|
+
fontSize: { _unit: "px", value: 100 },
|
|
20
|
+
fontWeight: 500,
|
|
21
|
+
textColor: "black",
|
|
22
|
+
opacity: 1,
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// private readonly onQueryChangedHandlers =
|
|
26
|
+
private readonly eventHandlers: DEventHandler.LookUp;
|
|
27
|
+
protected readonly commandBus: DCommandBus;
|
|
28
|
+
protected readonly eventBus: EventBus;
|
|
29
|
+
protected scale: ScaleService;
|
|
30
|
+
private readonly baseDto: DElementBaseDto;
|
|
31
|
+
protected readonly subscriptions = new Set<() => void>();
|
|
32
|
+
|
|
33
|
+
protected constructor(
|
|
34
|
+
el: T,
|
|
35
|
+
eventBus: EventBus,
|
|
36
|
+
commandBus: DCommandBus,
|
|
37
|
+
dto: DElementBaseDto,
|
|
38
|
+
scale: ScaleService
|
|
39
|
+
) {
|
|
40
|
+
this.el = el;
|
|
41
|
+
this.id = dto.id;
|
|
42
|
+
this.baseDto = dto;
|
|
43
|
+
// this.el.style.position = "absolute";
|
|
44
|
+
this.commandBus = commandBus;
|
|
45
|
+
this.eventBus = eventBus;
|
|
46
|
+
this.eventHandlers = DEventHandler.createLookUp(dto.eventHandlers);
|
|
47
|
+
this.scale = scale;
|
|
48
|
+
// CLICK
|
|
49
|
+
this.onClickHandler = this.onClickHandler.bind(this);
|
|
50
|
+
this.el.onclick = this.onClickHandler;
|
|
51
|
+
|
|
52
|
+
// HOVER
|
|
53
|
+
this.onMouseOver = this.onMouseOver.bind(this);
|
|
54
|
+
this.el.onmouseover = this.onMouseOver;
|
|
55
|
+
|
|
56
|
+
if (dto) {
|
|
57
|
+
this.updateStyles(dto?.style);
|
|
58
|
+
}
|
|
59
|
+
const commandSubscription = this.commandBus.subscribe((c) => {
|
|
60
|
+
if (c.kind === "ELEMENT_STYLE_COMMAND" && c.targetId === this.id) {
|
|
61
|
+
this.setStyle(c.payload.changes);
|
|
62
|
+
}
|
|
63
|
+
if (c.kind === "ELEMENT_DISABLE_CLICK_COMMAND" && c.targetId === this.id) {
|
|
64
|
+
this.clickHandlerIsEnabled = false;
|
|
65
|
+
}
|
|
66
|
+
if (c.kind === "ELEMENT_ENABLE_CLICK_COMMAND" && c.targetId === this.id) {
|
|
67
|
+
this.clickHandlerIsEnabled = true;
|
|
68
|
+
}
|
|
69
|
+
if (c.kind === "ELEMENT_ANIMATE_COMMAND" && c.targetId === this.id) {
|
|
70
|
+
console.log("TODO IMPLEMENT ANIMATION_HANDLER IN DElement.");
|
|
71
|
+
}
|
|
72
|
+
}, this.id);
|
|
73
|
+
// TODO MEMORY LEAK
|
|
74
|
+
const eventSubscription = this.eventBus.subscribe((event) => {
|
|
75
|
+
const handlers = this.eventHandlers.get(event.kind) ?? [];
|
|
76
|
+
// TODO Apply Conditions in WHEN.
|
|
77
|
+
const commands = handlers.map((h) => h.thenExecute).flat(1);
|
|
78
|
+
commands.forEach((command) => {
|
|
79
|
+
this.commandBus.emit(command);
|
|
80
|
+
// this.doAction(command);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
if (event.kind === "HOST_SCALE_CHANGED_EVENT") {
|
|
84
|
+
console.log("HANDLE THIS SCALE CHANGE!!");
|
|
85
|
+
this.updateStyles({});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (event.kind === "STATE_QUERY_RESULT_CHANGED_EVENT") {
|
|
89
|
+
this.queryChangedHandler(event.data);
|
|
90
|
+
}
|
|
91
|
+
}, "ELEMENT: ");
|
|
92
|
+
this.normalize();
|
|
93
|
+
this.subscriptions.add(commandSubscription);
|
|
94
|
+
this.subscriptions.add(eventSubscription);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
abstract destroy(): void;
|
|
98
|
+
|
|
99
|
+
// abstract setScale(scale: number): void;
|
|
100
|
+
|
|
101
|
+
// /**
|
|
102
|
+
// * The purpose of this function is to re-emit commands from event-handlers?
|
|
103
|
+
// * @param command
|
|
104
|
+
// * @private
|
|
105
|
+
// */
|
|
106
|
+
// private handleCommandsEmittedByPrivateEventHandlers(command: DCommand) {
|
|
107
|
+
// console.log(command);
|
|
108
|
+
// switch (command.kind) {
|
|
109
|
+
// case "ELEMENT_STYLE_COMMAND":
|
|
110
|
+
// if (command.targetId === this.id) {
|
|
111
|
+
// this.updateStyles(command.payload.changes);
|
|
112
|
+
// }
|
|
113
|
+
// break;
|
|
114
|
+
// case "ELEMENT_ANIMATE_COMMAND":
|
|
115
|
+
// // TODO CHECK FOR TARGET ID
|
|
116
|
+
// this.handleAnimateSelfAction(command.payload);
|
|
117
|
+
// break;
|
|
118
|
+
// case "ELEMENT_ENABLE_CLICK_COMMAND":
|
|
119
|
+
// this.clickHandlerIsEnabled = true;
|
|
120
|
+
// // this.updateStyles(command.payload.changes);
|
|
121
|
+
// break;
|
|
122
|
+
// case "ELEMENT_DISABLE_CLICK_COMMAND":
|
|
123
|
+
// this.clickHandlerIsEnabled = false;
|
|
124
|
+
// // this.handleAnimateSelfAction(command.payload);
|
|
125
|
+
// break;
|
|
126
|
+
// case "VIDEO_PLAY_COMMAND":
|
|
127
|
+
// this.commandBus.emit(command);
|
|
128
|
+
// break;
|
|
129
|
+
// case "VIDEO_PAUSE_COMMAND":
|
|
130
|
+
// this.commandBus.emit(command);
|
|
131
|
+
// break;
|
|
132
|
+
// case "ENGINE_LEAVE_PAGE_COMMAND":
|
|
133
|
+
// this.commandBus.emit(command);
|
|
134
|
+
// break;
|
|
135
|
+
// case "VIDEO_JUMP_TO_COMMAND":
|
|
136
|
+
// this.commandBus.emit(command);
|
|
137
|
+
// break;
|
|
138
|
+
// case "VIDEO_SET_VOLUME_COMMAND":
|
|
139
|
+
// this.commandBus.emit(command);
|
|
140
|
+
// break;
|
|
141
|
+
// case "AUDIO_PLAY_COMMAND":
|
|
142
|
+
// this.commandBus.emit(command);
|
|
143
|
+
// break;
|
|
144
|
+
// case "AUDIO_PAUSE_COMMAND":
|
|
145
|
+
// this.commandBus.emit(command);
|
|
146
|
+
// break;
|
|
147
|
+
// case "AUDIO_SET_VOLUME_COMMAND":
|
|
148
|
+
// this.commandBus.emit(command);
|
|
149
|
+
// break;
|
|
150
|
+
// case "PAGE_QUE_NEXT_PAGE_COMMAND":
|
|
151
|
+
// this.commandBus.emit(command);
|
|
152
|
+
// break;
|
|
153
|
+
// case "PAGE_QUE_GO_TO_SEQUENCE_COMMAND":
|
|
154
|
+
// this.commandBus.emit(command);
|
|
155
|
+
// break;
|
|
156
|
+
// case "PAGE_QUE_GO_TO_PAGE_COMMAND":
|
|
157
|
+
// this.commandBus.emit(command);
|
|
158
|
+
// break;
|
|
159
|
+
// case "PAGE_QUE_EXCLUDE_BY_PAGE_ID_COMMAND":
|
|
160
|
+
// this.commandBus.emit(command);
|
|
161
|
+
// break;
|
|
162
|
+
// case "PAGE_QUE_JUMP_TO_PAGE_COMMAND":
|
|
163
|
+
// this.commandBus.emit(command);
|
|
164
|
+
// break;
|
|
165
|
+
// case "PAGE_QUE_EXCLUDE_BY_TAG_COMMAND":
|
|
166
|
+
// this.commandBus.emit(command);
|
|
167
|
+
// break;
|
|
168
|
+
// case "STATE_MUTATE_COMMAND":
|
|
169
|
+
// this.commandBus.emit(command);
|
|
170
|
+
// break;
|
|
171
|
+
// default:
|
|
172
|
+
// DUtil.neverCheck(command);
|
|
173
|
+
// }
|
|
174
|
+
// }
|
|
175
|
+
|
|
176
|
+
private queryChangedHandler(result: DState.StateQueryResult) {
|
|
177
|
+
const maybeHandlers = this.baseDto.onStateChange;
|
|
178
|
+
if (!maybeHandlers) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
const queryHandlers = maybeHandlers.filter((h) => h.queryName === result.queryName);
|
|
182
|
+
queryHandlers.forEach((h) => {
|
|
183
|
+
if (result.curr) {
|
|
184
|
+
h.whenTrue.forEach((command) => {
|
|
185
|
+
// this.doAction(command);
|
|
186
|
+
this.commandBus.emit(command);
|
|
187
|
+
});
|
|
188
|
+
} else {
|
|
189
|
+
h.whenFalse.forEach((command) => {
|
|
190
|
+
// this.doAction(command);
|
|
191
|
+
this.commandBus.emit(command);
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
// console.log(findByQuery, value);
|
|
196
|
+
// const all = this.baseDto.stateQueryChange ?? [];
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
private onClickHandler(_: MouseEvent) {
|
|
200
|
+
// console.log();
|
|
201
|
+
if (!this.clickHandlerIsEnabled) {
|
|
202
|
+
console.log(this.id + "Click disabled");
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
const clickAction = this.baseDto.onClick;
|
|
206
|
+
// console.log("NATIVE CLICK ELEMENT: Handlers " + clickAction?.length);
|
|
207
|
+
if (clickAction && clickAction.length > 0) {
|
|
208
|
+
// console.log("TARGETID: " + clickAction[0].targetId + " " + this.id);
|
|
209
|
+
this.eventBus.emit({
|
|
210
|
+
kind: "USER_CLICKED_EVENT",
|
|
211
|
+
producer: "DUser",
|
|
212
|
+
producerId: this.id,
|
|
213
|
+
data: { elementId: this.id },
|
|
214
|
+
timestamp: DTimestamp.now(),
|
|
215
|
+
});
|
|
216
|
+
clickAction.forEach((command) => {
|
|
217
|
+
this.commandBus.emit(command);
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
private onMouseOver(_: MouseEvent) {
|
|
223
|
+
// console.log(ev);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
setStyle(style: Partial<DStyle>) {
|
|
227
|
+
this.updateStyles(style);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
appendYourself(parent: HTMLElement) {
|
|
231
|
+
parent.append(this.el);
|
|
232
|
+
// console.log(parent);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
private handleAnimateSelfAction(dto: AnimationDto) {
|
|
236
|
+
this.isAnimatingSelf = true;
|
|
237
|
+
const { keyframes, options } = dto;
|
|
238
|
+
|
|
239
|
+
const animation = this.el.animate(keyframes, options.duration);
|
|
240
|
+
animation.onfinish = (e: AnimationPlaybackEvent) => {
|
|
241
|
+
console.log(e.type);
|
|
242
|
+
this.isAnimatingSelf = false;
|
|
243
|
+
};
|
|
244
|
+
animation.onremove = () => {
|
|
245
|
+
console.warn("ANIMATION REMOVED: " + animation.id);
|
|
246
|
+
this.isAnimatingSelf = false;
|
|
247
|
+
};
|
|
248
|
+
animation.oncancel = () => {
|
|
249
|
+
console.warn("ANIMATION CANCELED: " + animation.id);
|
|
250
|
+
this.isAnimatingSelf = false;
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
private normalize() {
|
|
255
|
+
DStyle.normalize(this.el);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
protected updateStyles(style: Partial<DStyle>) {
|
|
259
|
+
this.currStyle = Object.assign(this.currStyle, style);
|
|
260
|
+
DStyle.applyStyles(this.el, this.currStyle, this.scale.scale);
|
|
261
|
+
window.getComputedStyle(this.el);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { DElement } from "./DElement";
|
|
2
|
+
import { DImgDto } from "../dto/DElement.dto";
|
|
3
|
+
import { DCommandBus } from "../commands/DCommandBus";
|
|
4
|
+
import { EventBus } from "../events/event-bus";
|
|
5
|
+
import { ScaleService } from "../engine/scale";
|
|
6
|
+
import { DTimestamp } from "../common/DTimestamp";
|
|
7
|
+
|
|
8
|
+
export class DImg extends DElement<HTMLImageElement> {
|
|
9
|
+
private static IMAGE_COUNT = 0;
|
|
10
|
+
private readonly imageCount: number;
|
|
11
|
+
readonly TAG: string;
|
|
12
|
+
readonly TIMING_TAG: string;
|
|
13
|
+
private readonly loadStart: DTimestamp;
|
|
14
|
+
|
|
15
|
+
constructor(
|
|
16
|
+
private readonly dto: DImgDto,
|
|
17
|
+
private readonly actionSubject: DCommandBus,
|
|
18
|
+
readonly eventBus: EventBus,
|
|
19
|
+
readonly scaleService: ScaleService
|
|
20
|
+
) {
|
|
21
|
+
super(document.createElement("img"), eventBus, actionSubject, dto, scaleService);
|
|
22
|
+
DImg.IMAGE_COUNT += 1;
|
|
23
|
+
this.imageCount = DImg.IMAGE_COUNT;
|
|
24
|
+
this.TAG = "[D_IMG " + DImg.IMAGE_COUNT + " ]: ";
|
|
25
|
+
this.TIMING_TAG = "load-time (" + DImg.IMAGE_COUNT + ") ";
|
|
26
|
+
this.el.loading = "eager";
|
|
27
|
+
this.el.style.position = "absolute";
|
|
28
|
+
this.setStyle(dto.style);
|
|
29
|
+
this.loadStart = DTimestamp.now();
|
|
30
|
+
// Bind Handlers
|
|
31
|
+
this.onError = this.onError.bind(this);
|
|
32
|
+
this.onLoad = this.onLoad.bind(this);
|
|
33
|
+
// this.onClick = this.onClick.bind(this);
|
|
34
|
+
this.el.onload = this.onLoad;
|
|
35
|
+
this.el.onerror = this.onError;
|
|
36
|
+
// this.el.onclick = this.onClick;
|
|
37
|
+
this.el.src = dto.url;
|
|
38
|
+
console.time(this.TIMING_TAG);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
log(): void {}
|
|
42
|
+
|
|
43
|
+
setScale(scale: number) {
|
|
44
|
+
console.log(scale);
|
|
45
|
+
this.setStyle(this.currStyle);
|
|
46
|
+
}
|
|
47
|
+
destroy() {
|
|
48
|
+
this.subscriptions.forEach((unsubscribe) => {
|
|
49
|
+
unsubscribe();
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
private onError(ev: Event | string) {
|
|
54
|
+
if (ev instanceof Event) {
|
|
55
|
+
console.log(this.TAG + " " + ev.type);
|
|
56
|
+
} else {
|
|
57
|
+
console.log(this.TAG + ev);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
private onLoad(_: Event) {
|
|
62
|
+
const loadTime = DTimestamp.diffNow(this.loadStart);
|
|
63
|
+
|
|
64
|
+
this.eventBus.emit({
|
|
65
|
+
kind: "IMAGE_LOADED_EVENT",
|
|
66
|
+
producer: "DImage",
|
|
67
|
+
producerId: this.id,
|
|
68
|
+
timestamp: DTimestamp.now(),
|
|
69
|
+
data: {
|
|
70
|
+
loadTime,
|
|
71
|
+
naturalHeight: this.el.naturalHeight,
|
|
72
|
+
naturalWidth: this.el.naturalWidth,
|
|
73
|
+
height: this.el.height,
|
|
74
|
+
width: this.el.width,
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|