@opendaw/lib-dom 0.0.6
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/README.md +1 -0
- package/dist/browser.d.ts +10 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +19 -0
- package/dist/compression.d.ts +5 -0
- package/dist/compression.d.ts.map +1 -0
- package/dist/compression.js +17 -0
- package/dist/console-commands.d.ts +8 -0
- package/dist/console-commands.d.ts.map +1 -0
- package/dist/console-commands.js +55 -0
- package/dist/context-2d.d.ts +7 -0
- package/dist/context-2d.d.ts.map +1 -0
- package/dist/context-2d.js +31 -0
- package/dist/css-utils.d.ts +7 -0
- package/dist/css-utils.d.ts.map +1 -0
- package/dist/css-utils.js +36 -0
- package/dist/dragging.d.ts +25 -0
- package/dist/dragging.d.ts.map +1 -0
- package/dist/dragging.js +105 -0
- package/dist/errors.d.ts +5 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +6 -0
- package/dist/events.d.ts +15 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +26 -0
- package/dist/files.d.ts +5 -0
- package/dist/files.d.ts.map +1 -0
- package/dist/files.js +62 -0
- package/dist/fonts.d.ts +8 -0
- package/dist/fonts.d.ts.map +1 -0
- package/dist/fonts.js +17 -0
- package/dist/frames.d.ts +17 -0
- package/dist/frames.d.ts.map +1 -0
- package/dist/frames.js +63 -0
- package/dist/html.d.ts +21 -0
- package/dist/html.d.ts.map +1 -0
- package/dist/html.js +121 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/keyboard.d.ts +15 -0
- package/dist/keyboard.d.ts.map +1 -0
- package/dist/keyboard.js +12 -0
- package/dist/modfier-keys.d.ts +18 -0
- package/dist/modfier-keys.d.ts.map +1 -0
- package/dist/modfier-keys.js +6 -0
- package/dist/stream.d.ts +4 -0
- package/dist/stream.d.ts.map +1 -0
- package/dist/stream.js +21 -0
- package/dist/svg.d.ts +15 -0
- package/dist/svg.d.ts.map +1 -0
- package/dist/svg.js +45 -0
- package/dist/terminable.d.ts +13 -0
- package/dist/terminable.d.ts.map +1 -0
- package/dist/terminable.js +38 -0
- package/package.json +34 -0
package/README.md
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
This package is part of the openDAW SDK
|
@@ -0,0 +1,10 @@
|
|
1
|
+
export declare namespace Browser {
|
2
|
+
const isLocalHost: () => boolean;
|
3
|
+
const isMacOS: () => boolean;
|
4
|
+
const isWindows: () => boolean;
|
5
|
+
const isFirefox: () => boolean;
|
6
|
+
const isWeb: () => boolean;
|
7
|
+
const isTauriApp: () => boolean;
|
8
|
+
const userAgent: string;
|
9
|
+
}
|
10
|
+
//# sourceMappingURL=browser.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAEA,yBAAiB,OAAO,CAAC;IAGd,MAAM,WAAW,eAA2D,CAAA;IAC5E,MAAM,OAAO,eAAiE,CAAA;IAC9E,MAAM,SAAS,eAAgE,CAAA;IAC/E,MAAM,SAAS,eAA8E,CAAA;IAC7F,MAAM,KAAK,eAAsB,CAAA;IACjC,MAAM,UAAU,eAA8B,CAAA;IAC9C,MAAM,SAAS,QAMH,CAAA;CACtB"}
|
package/dist/browser.js
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
// noinspection PlatformDetectionJS
|
2
|
+
export var Browser;
|
3
|
+
(function (Browser) {
|
4
|
+
const hasLocation = typeof self !== "undefined" && "location" in self && typeof self.location !== undefined;
|
5
|
+
const hasNavigator = typeof self !== "undefined" && "navigator" in self && typeof self.navigator !== undefined;
|
6
|
+
Browser.isLocalHost = () => hasLocation && location.host.includes("localhost");
|
7
|
+
Browser.isMacOS = () => hasNavigator && navigator.userAgent.includes("Mac OS X");
|
8
|
+
Browser.isWindows = () => hasNavigator && navigator.userAgent.includes("Windows");
|
9
|
+
Browser.isFirefox = () => hasNavigator && navigator.userAgent.toLowerCase().includes("firefox");
|
10
|
+
Browser.isWeb = () => !Browser.isTauriApp();
|
11
|
+
Browser.isTauriApp = () => "__TAURI__" in window;
|
12
|
+
Browser.userAgent = hasNavigator ? navigator.userAgent
|
13
|
+
.replace(/^Mozilla\/[\d.]+\s*/, "")
|
14
|
+
.replace(/\bAppleWebKit\/[\d.]+\s*/g, "")
|
15
|
+
.replace(/\(KHTML, like Gecko\)\s*/g, "")
|
16
|
+
.replace(/\bSafari\/[\d.]+\s*/g, "")
|
17
|
+
.replace(/\s+/g, " ")
|
18
|
+
.trim() : "N/A";
|
19
|
+
})(Browser || (Browser = {}));
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"compression.d.ts","sourceRoot":"","sources":["../src/compression.ts"],"names":[],"mappings":"AAAA,yBAAiB,WAAW,CAAC;IAClB,MAAM,MAAM,GAAU,QAAQ,WAAW,EAAE,SAAQ,iBAA0B,KAAG,OAAO,CAAC,WAAW,CAMzG,CAAA;IAEM,MAAM,MAAM,GAAU,QAAQ,WAAW,EAAE,SAAQ,iBAA0B,KAAG,OAAO,CAAC,WAAW,CAMzG,CAAA;CACJ"}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
export var Compression;
|
2
|
+
(function (Compression) {
|
3
|
+
Compression.encode = async (buffer, format = "gzip") => {
|
4
|
+
const stream = new CompressionStream(format);
|
5
|
+
const writer = stream.writable.getWriter();
|
6
|
+
writer.write(new Uint8Array(buffer));
|
7
|
+
writer.close();
|
8
|
+
return new Response(stream.readable).arrayBuffer();
|
9
|
+
};
|
10
|
+
Compression.decode = async (buffer, format = "gzip") => {
|
11
|
+
const stream = new DecompressionStream(format);
|
12
|
+
const writer = stream.writable.getWriter();
|
13
|
+
writer.write(new Uint8Array(buffer));
|
14
|
+
writer.close();
|
15
|
+
return new Response(stream.readable).arrayBuffer();
|
16
|
+
};
|
17
|
+
})(Compression || (Compression = {}));
|
@@ -0,0 +1,8 @@
|
|
1
|
+
import { AnyFunc, ObservableValue, Procedure, Provider } from "@opendaw/lib-std";
|
2
|
+
export type DotPath = string;
|
3
|
+
export declare namespace ConsoleCommands {
|
4
|
+
const exportMethod: (path: DotPath, callback: AnyFunc) => void;
|
5
|
+
const exportBoolean: (path: DotPath, init?: boolean) => ObservableValue<boolean>;
|
6
|
+
const exportAccessor: (path: DotPath, getter: Provider<unknown>, setter?: Procedure<any>) => void;
|
7
|
+
}
|
8
|
+
//# sourceMappingURL=console-commands.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"console-commands.d.ts","sourceRoot":"","sources":["../src/console-commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAA0C,eAAe,EAAE,SAAS,EAAE,QAAQ,EAAC,MAAM,kBAAkB,CAAA;AAEtH,MAAM,MAAM,OAAO,GAAG,MAAM,CAAA;AAE5B,yBAAiB,eAAe,CAAC;IACtB,MAAM,YAAY,GAAI,MAAM,OAAO,EAAE,UAAU,OAAO,KAAG,IAC9B,CAAA;IAE3B,MAAM,aAAa,GAAI,MAAM,OAAO,EAAE,OAAM,OAAe,KAAG,eAAe,CAAC,OAAO,CAQ3F,CAAA;IAEM,MAAM,cAAc,GAAI,MAAM,OAAO,EAAE,QAAQ,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAQ,SAAS,CAAC,GAAG,CAAkB,KAAG,IAsB7G,CAAA;CAcT"}
|
@@ -0,0 +1,55 @@
|
|
1
|
+
import { DefaultObservableValue, EmptyProcedure } from "@opendaw/lib-std";
|
2
|
+
export var ConsoleCommands;
|
3
|
+
(function (ConsoleCommands) {
|
4
|
+
ConsoleCommands.exportMethod = (path, callback) => store(path, { value: callback });
|
5
|
+
ConsoleCommands.exportBoolean = (path, init = false) => {
|
6
|
+
const observableValue = new DefaultObservableValue(init);
|
7
|
+
ConsoleCommands.exportAccessor(path, () => observableValue.getValue(), input => {
|
8
|
+
const value = Boolean(input);
|
9
|
+
console.debug(`set to ${value}`);
|
10
|
+
observableValue.setValue(value);
|
11
|
+
});
|
12
|
+
return observableValue;
|
13
|
+
};
|
14
|
+
ConsoleCommands.exportAccessor = (path, getter, setter = EmptyProcedure) => store(path, {
|
15
|
+
get: () => {
|
16
|
+
try {
|
17
|
+
console.debug(getter());
|
18
|
+
return 0;
|
19
|
+
}
|
20
|
+
catch (error) {
|
21
|
+
console.error(error);
|
22
|
+
return 1;
|
23
|
+
}
|
24
|
+
},
|
25
|
+
set: (value) => {
|
26
|
+
try {
|
27
|
+
setter(value);
|
28
|
+
return getter();
|
29
|
+
}
|
30
|
+
catch (error) {
|
31
|
+
console.error(error);
|
32
|
+
return 1;
|
33
|
+
}
|
34
|
+
},
|
35
|
+
enumerable: false,
|
36
|
+
configurable: false
|
37
|
+
});
|
38
|
+
const global = (() => { try {
|
39
|
+
return self;
|
40
|
+
}
|
41
|
+
catch (_) {
|
42
|
+
return {};
|
43
|
+
} })();
|
44
|
+
const scope = (global["opendaw"] ??= {});
|
45
|
+
const store = (path, attributes) => {
|
46
|
+
const levels = path.split(".");
|
47
|
+
const name = levels.splice(-1)[0];
|
48
|
+
let current = scope;
|
49
|
+
for (const level of levels) {
|
50
|
+
current = (current[level] ??= {});
|
51
|
+
}
|
52
|
+
Object.defineProperty(current, name, attributes);
|
53
|
+
console.debug(`Console command 'opendaw.${path}' exported`);
|
54
|
+
};
|
55
|
+
})(ConsoleCommands || (ConsoleCommands = {}));
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"context-2d.d.ts","sourceRoot":"","sources":["../src/context-2d.ts"],"names":[],"mappings":"AAIA,yBAAiB,SAAS,CAAC;IAChB,MAAM,YAAY,GAAI,SAAS,wBAAwB,EAAE,MAAM,MAAM,EAAE,UAAU,MAAM,KAAG;QAC7F,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAA;KAoBhB,CAAA;CACJ"}
|
@@ -0,0 +1,31 @@
|
|
1
|
+
const ellipsis = "…";
|
2
|
+
export var Context2d;
|
3
|
+
(function (Context2d) {
|
4
|
+
Context2d.truncateText = (context, text, maxWidth) => {
|
5
|
+
if (text.length === 0) {
|
6
|
+
return { text: "", width: 0 };
|
7
|
+
}
|
8
|
+
let width = context.measureText(text).width;
|
9
|
+
if (width <= maxWidth) {
|
10
|
+
return { text, width };
|
11
|
+
}
|
12
|
+
const ellipseWidth = context.measureText(ellipsis).width;
|
13
|
+
let l = 0 | 0;
|
14
|
+
let r = text.length | 0;
|
15
|
+
while (l < r) {
|
16
|
+
const mid = (r + l) >>> 1;
|
17
|
+
width = context.measureText(text.substring(0, mid + 1)).width + ellipseWidth;
|
18
|
+
if (width <= maxWidth) {
|
19
|
+
l = mid + 1;
|
20
|
+
}
|
21
|
+
else {
|
22
|
+
r = mid;
|
23
|
+
}
|
24
|
+
}
|
25
|
+
if (l === 0) {
|
26
|
+
return { text: "", width: 0 };
|
27
|
+
}
|
28
|
+
const result = text.substring(0, l);
|
29
|
+
return { text: result + ellipsis, width: context.measureText(result).width + ellipseWidth };
|
30
|
+
};
|
31
|
+
})(Context2d || (Context2d = {}));
|
@@ -0,0 +1,7 @@
|
|
1
|
+
export declare namespace CssUtils {
|
2
|
+
const calc: (term: string, size: number, em: number) => number;
|
3
|
+
const registerCustomCursor: (identifier: number, data: string) => Map<number, string>;
|
4
|
+
const setCursor: (identifier: CssUtils.Cursor | number, doc?: Document) => void;
|
5
|
+
type Cursor = "alias" | "all-scroll" | "auto" | "cell" | "context-menu" | "col-resize" | "copy" | "crosshair" | "default" | "e-resize" | "ew-resize" | "grab" | "grabbing" | "help" | "move" | "n-resize" | "ne-resize" | "nesw-resize" | "ns-resize" | "nw-resize" | "nwse-resize" | "no-drop" | "none" | "not-allowed" | "pointer" | "progress" | "row-resize" | "s-resize" | "se-resize" | "sw-resize" | "text" | "url" | "w-resize" | "wait" | "zoom-in" | "zoom-out";
|
6
|
+
}
|
7
|
+
//# sourceMappingURL=css-utils.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"css-utils.d.ts","sourceRoot":"","sources":["../src/css-utils.ts"],"names":[],"mappings":"AAEA,yBAAiB,QAAQ,CAAC;IACf,MAAM,IAAI,GAAI,MAAM,MAAM,EAAE,MAAM,MAAM,EAAE,IAAI,MAAM,KAAG,MAmB7D,CAAA;IAIM,MAAM,oBAAoB,GAAI,YAAY,MAAM,EAAE,MAAM,MAAM,wBAAwC,CAAA;IAEtG,MAAM,SAAS,GAAI,YAAY,QAAQ,CAAC,MAAM,GAAG,MAAM,EAAE,MAAK,QAAmB,SAIvF,CAAA;IAED,KAAY,MAAM,GACZ,OAAO,GACP,YAAY,GACZ,MAAM,GACN,MAAM,GACN,cAAc,GACd,YAAY,GACZ,MAAM,GACN,WAAW,GACX,SAAS,GACT,UAAU,GACV,WAAW,GACX,MAAM,GACN,UAAU,GACV,MAAM,GACN,MAAM,GACN,UAAU,GACV,WAAW,GACX,aAAa,GACb,WAAW,GACX,WAAW,GACX,aAAa,GACb,SAAS,GACT,MAAM,GACN,aAAa,GACb,SAAS,GACT,UAAU,GACV,YAAY,GACZ,UAAU,GACV,WAAW,GACX,WAAW,GACX,MAAM,GACN,KAAK,GACL,UAAU,GACV,MAAM,GACN,SAAS,GACT,UAAU,CAAA;CACnB"}
|
@@ -0,0 +1,36 @@
|
|
1
|
+
import { panic } from "@opendaw/lib-std";
|
2
|
+
export var CssUtils;
|
3
|
+
(function (CssUtils) {
|
4
|
+
CssUtils.calc = (term, size, em) => {
|
5
|
+
const regex = /([0-9]*\.?[0-9]+)([a-zA-Z%]*)/g;
|
6
|
+
let result = term;
|
7
|
+
result.split(/\+|(?<!\d)-/)
|
8
|
+
.flatMap(result => Array.from(result.matchAll(regex)))
|
9
|
+
.forEach(([replace, digits, unit]) => {
|
10
|
+
const number = parseFloat(digits);
|
11
|
+
if (isNaN(number)) {
|
12
|
+
return panic(`${replace} does not contain a number`);
|
13
|
+
}
|
14
|
+
if (unit === "em") {
|
15
|
+
result = result.replaceAll(replace, `${number * em}`);
|
16
|
+
}
|
17
|
+
else if (unit === "%") {
|
18
|
+
result = result.replaceAll(replace, `${number / 100.0 * size}`);
|
19
|
+
}
|
20
|
+
else if (unit === "px") {
|
21
|
+
result = result.replaceAll(replace, `${number}`);
|
22
|
+
}
|
23
|
+
else {
|
24
|
+
return panic(`Unknown unit '${unit}'`);
|
25
|
+
}
|
26
|
+
});
|
27
|
+
return Function(`return ${result}`)();
|
28
|
+
};
|
29
|
+
const customCursors = new Map();
|
30
|
+
CssUtils.registerCustomCursor = (identifier, data) => customCursors.set(identifier, data);
|
31
|
+
CssUtils.setCursor = (identifier, doc = document) => {
|
32
|
+
doc.documentElement.style.cursor = typeof identifier === "number"
|
33
|
+
? customCursors.get(identifier) ?? "auto"
|
34
|
+
: identifier;
|
35
|
+
};
|
36
|
+
})(CssUtils || (CssUtils = {}));
|
@@ -0,0 +1,25 @@
|
|
1
|
+
import { Func, Option, Terminable } from "@opendaw/lib-std";
|
2
|
+
import { PointerCaptureTarget } from "./events";
|
3
|
+
export declare namespace Dragging {
|
4
|
+
interface Process {
|
5
|
+
update(event: Event): void;
|
6
|
+
cancel?(): void;
|
7
|
+
approve?(): void;
|
8
|
+
finally?(): void;
|
9
|
+
abortSignal?: AbortSignal;
|
10
|
+
}
|
11
|
+
interface Event {
|
12
|
+
readonly clientX: number;
|
13
|
+
readonly clientY: number;
|
14
|
+
readonly altKey: boolean;
|
15
|
+
readonly shiftKey: boolean;
|
16
|
+
readonly ctrlKey: boolean;
|
17
|
+
}
|
18
|
+
interface ProcessOptions {
|
19
|
+
multiTouch?: boolean;
|
20
|
+
immediate?: boolean;
|
21
|
+
permanentUpdates?: boolean;
|
22
|
+
}
|
23
|
+
const attach: <T extends PointerCaptureTarget>(target: T, factory: Func<PointerEvent, Option<Process>>, options?: ProcessOptions) => Terminable;
|
24
|
+
}
|
25
|
+
//# sourceMappingURL=dragging.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"dragging.d.ts","sourceRoot":"","sources":["../src/dragging.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAa,MAAM,kBAAkB,CAAA;AAGrE,OAAO,EAAS,oBAAoB,EAAC,MAAM,UAAU,CAAA;AAGrD,yBAAiB,QAAQ,CAAC;IACtB,UAAiB,OAAO;QACpB,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAA;QAC1B,MAAM,CAAC,IAAI,IAAI,CAAA;QACf,OAAO,CAAC,IAAI,IAAI,CAAA;QAChB,OAAO,CAAC,IAAI,IAAI,CAAA;QAChB,WAAW,CAAC,EAAE,WAAW,CAAA;KAC5B;IAED,UAAiB,KAAK;QAClB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;QACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;QACxB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;QACxB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;QAC1B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;KAC5B;IAED,UAAiB,cAAc;QAC3B,UAAU,CAAC,EAAE,OAAO,CAAA;QACpB,SAAS,CAAC,EAAE,OAAO,CAAA;QACnB,gBAAgB,CAAC,EAAE,OAAO,CAAA;KAC7B;IAEM,MAAM,MAAM,GAAI,CAAC,SAAS,oBAAoB,EAAE,QAAQ,CAAC,EACT,SAAS,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,EAC5C,UAAU,cAAc,KAAG,UA0FjF,CAAA;CACJ"}
|
package/dist/dragging.js
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
import { Terminable, Terminator } from "@opendaw/lib-std";
|
2
|
+
import { Browser } from "./browser";
|
3
|
+
import { AnimationFrame } from "./frames";
|
4
|
+
import { Events } from "./events";
|
5
|
+
import { Keyboard } from "./keyboard";
|
6
|
+
export var Dragging;
|
7
|
+
(function (Dragging) {
|
8
|
+
Dragging.attach = (target, factory, options) => {
|
9
|
+
const processCycle = new Terminator();
|
10
|
+
return Terminable.many(processCycle, Events.subscribe(target, "pointerdown", (event) => {
|
11
|
+
if (options?.multiTouch !== true && !event.isPrimary) {
|
12
|
+
return;
|
13
|
+
}
|
14
|
+
if (event.buttons !== 1 || (Browser.isMacOS() && event.ctrlKey)) {
|
15
|
+
return;
|
16
|
+
}
|
17
|
+
const option = factory(event);
|
18
|
+
if (option.isEmpty()) {
|
19
|
+
return;
|
20
|
+
}
|
21
|
+
const process = option.unwrap();
|
22
|
+
const pointerId = event.pointerId;
|
23
|
+
event.stopPropagation();
|
24
|
+
event.stopImmediatePropagation();
|
25
|
+
target.setPointerCapture(pointerId);
|
26
|
+
const moveEvent = {
|
27
|
+
clientX: event.clientX,
|
28
|
+
clientY: event.clientY,
|
29
|
+
altKey: event.altKey,
|
30
|
+
shiftKey: event.shiftKey,
|
31
|
+
ctrlKey: Keyboard.isControlKey(event)
|
32
|
+
};
|
33
|
+
if (options?.immediate === true) {
|
34
|
+
process.update(moveEvent);
|
35
|
+
}
|
36
|
+
if (options?.permanentUpdates === true) {
|
37
|
+
processCycle.own(AnimationFrame.add(() => process.update(moveEvent)));
|
38
|
+
processCycle.own(Events.subscribe(target, "pointermove", (event) => {
|
39
|
+
if (event.pointerId === pointerId) {
|
40
|
+
moveEvent.clientX = event.clientX;
|
41
|
+
moveEvent.clientY = event.clientY;
|
42
|
+
moveEvent.altKey = event.altKey;
|
43
|
+
moveEvent.shiftKey = event.shiftKey;
|
44
|
+
moveEvent.ctrlKey = Keyboard.isControlKey(event);
|
45
|
+
}
|
46
|
+
}));
|
47
|
+
}
|
48
|
+
else {
|
49
|
+
processCycle.own(Events.subscribe(target, "pointermove", (event) => {
|
50
|
+
if (event.pointerId === pointerId) {
|
51
|
+
moveEvent.clientX = event.clientX;
|
52
|
+
moveEvent.clientY = event.clientY;
|
53
|
+
moveEvent.altKey = event.altKey;
|
54
|
+
moveEvent.shiftKey = event.shiftKey;
|
55
|
+
moveEvent.ctrlKey = Keyboard.isControlKey(event);
|
56
|
+
process.update(moveEvent);
|
57
|
+
}
|
58
|
+
}));
|
59
|
+
}
|
60
|
+
const cancel = () => {
|
61
|
+
process.cancel?.call(process);
|
62
|
+
process.finally?.call(process);
|
63
|
+
processCycle.terminate();
|
64
|
+
};
|
65
|
+
processCycle.ownAll(Events.subscribe(target, "pointerup", (event) => {
|
66
|
+
if (event.pointerId === pointerId) {
|
67
|
+
process.approve?.call(process);
|
68
|
+
process.finally?.call(process);
|
69
|
+
processCycle.terminate();
|
70
|
+
}
|
71
|
+
}, { capture: true }), Events.subscribe(target, "pointercancel", (event) => {
|
72
|
+
console.debug(event.type);
|
73
|
+
if (event.pointerId === pointerId) {
|
74
|
+
target.releasePointerCapture(pointerId);
|
75
|
+
cancel();
|
76
|
+
}
|
77
|
+
}, { capture: true }), Events.subscribe(self, "beforeunload", (_event) => {
|
78
|
+
// Workaround for Chrome (does not release or cancel pointer)
|
79
|
+
target.releasePointerCapture(pointerId);
|
80
|
+
cancel();
|
81
|
+
}, { capture: true }), Events.subscribe(window, "keydown", (event) => {
|
82
|
+
moveEvent.altKey = event.altKey;
|
83
|
+
moveEvent.shiftKey = event.shiftKey;
|
84
|
+
moveEvent.ctrlKey = Keyboard.isControlKey(event);
|
85
|
+
if (event.key === "Escape") {
|
86
|
+
cancel();
|
87
|
+
}
|
88
|
+
else {
|
89
|
+
process.update(moveEvent);
|
90
|
+
}
|
91
|
+
}), Events.subscribe(window, "keyup", (event) => {
|
92
|
+
moveEvent.altKey = event.altKey;
|
93
|
+
moveEvent.shiftKey = event.shiftKey;
|
94
|
+
moveEvent.ctrlKey = Keyboard.isControlKey(event);
|
95
|
+
process.update(moveEvent);
|
96
|
+
}));
|
97
|
+
if (process.abortSignal) {
|
98
|
+
processCycle.own(Events.subscribe(process.abortSignal, "abort", () => {
|
99
|
+
target.releasePointerCapture(pointerId);
|
100
|
+
cancel();
|
101
|
+
}));
|
102
|
+
}
|
103
|
+
}));
|
104
|
+
};
|
105
|
+
})(Dragging || (Dragging = {}));
|
package/dist/errors.d.ts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,yBAAiB,MAAM,CAAC;IACb,MAAM,UAAU,iCACkC,CAAA;IAElD,MAAM,OAAO,GAAI,OAAO,OAAO,YACoD,CAAA;CAC7F"}
|
package/dist/errors.js
ADDED
@@ -0,0 +1,6 @@
|
|
1
|
+
export var Errors;
|
2
|
+
(function (Errors) {
|
3
|
+
Errors.AbortError = typeof DOMException === "undefined"
|
4
|
+
? NaN : Object.freeze(new DOMException("AbortError"));
|
5
|
+
Errors.isAbort = (error) => error === Errors.AbortError || (error instanceof DOMException && error.name === "AbortError");
|
6
|
+
})(Errors || (Errors = {}));
|
package/dist/events.d.ts
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
import { Nullable, Procedure, Subscription } from "@opendaw/lib-std";
|
2
|
+
export declare class Events {
|
3
|
+
static subscribe<K extends keyof WindowEventMap>(eventTarget: EventTarget, type: K, listener: (ev: WindowEventMap[K]) => void, options?: boolean | AddEventListenerOptions): Subscription;
|
4
|
+
static subscribeAny<E extends Event>(eventTarget: EventTarget, type: string, listener: (event: E) => void, options?: boolean | AddEventListenerOptions): Subscription;
|
5
|
+
static DOUBLE_DOWN_THRESHOLD: 200;
|
6
|
+
static subscribeDblDwn: (eventTarget: EventTarget, listener: (event: PointerEvent) => void) => Subscription;
|
7
|
+
static readonly PreventDefault: Procedure<Event>;
|
8
|
+
static readonly isTextInput: (target: Nullable<EventTarget>) => boolean;
|
9
|
+
}
|
10
|
+
export interface PointerCaptureTarget extends EventTarget {
|
11
|
+
setPointerCapture(pointerId: number): void;
|
12
|
+
releasePointerCapture(pointerId: number): void;
|
13
|
+
hasPointerCapture(pointerId: number): boolean;
|
14
|
+
}
|
15
|
+
//# sourceMappingURL=events.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,QAAQ,EAAE,SAAS,EAAE,YAAY,EAAC,MAAM,kBAAkB,CAAA;AAE7E,qBAAa,MAAM;IACf,MAAM,CAAC,SAAS,CAAC,CAAC,SAAS,MAAM,cAAc,EAAE,WAAW,EAAE,WAAW,EACxB,IAAI,EAAE,CAAC,EACP,QAAQ,EAAE,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC,CAAC,KAAK,IAAI,EACzC,OAAO,CAAC,EAAE,OAAO,GAAG,uBAAuB,GAAG,YAAY;IAK3G,MAAM,CAAC,YAAY,CAAC,CAAC,SAAS,KAAK,EAAE,WAAW,EAAE,WAAW,EACxB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,EAC5B,OAAO,CAAC,EAAE,OAAO,GAAG,uBAAuB,GAAG,YAAY;IAK/F,MAAM,CAAC,qBAAqB,EAAG,GAAG,CAAS;IAE3C,MAAM,CAAC,eAAe,GAAI,aAAa,WAAW,EAAE,UAAU,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,KAAG,YAAY,CASzG;IAED,MAAM,CAAC,QAAQ,CAAC,cAAc,EAAE,SAAS,CAAC,KAAK,CAAC,CAAkC;IAElF,MAAM,CAAC,QAAQ,CAAC,WAAW,GAAI,QAAQ,QAAQ,CAAC,WAAW,CAAC,KAAG,OAAO,CAEqB;CAC9F;AAED,MAAM,WAAW,oBAAqB,SAAQ,WAAW;IACrD,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1C,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9C,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAA;CAChD"}
|
package/dist/events.js
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
import { isDefined } from "@opendaw/lib-std";
|
2
|
+
export class Events {
|
3
|
+
static subscribe(eventTarget, type, listener, options) {
|
4
|
+
eventTarget.addEventListener(type, listener, options);
|
5
|
+
return { terminate: () => eventTarget.removeEventListener(type, listener, options) };
|
6
|
+
}
|
7
|
+
static subscribeAny(eventTarget, type, listener, options) {
|
8
|
+
eventTarget.addEventListener(type, listener, options);
|
9
|
+
return { terminate: () => eventTarget.removeEventListener(type, listener, options) };
|
10
|
+
}
|
11
|
+
static DOUBLE_DOWN_THRESHOLD = 200;
|
12
|
+
static subscribeDblDwn = (eventTarget, listener) => {
|
13
|
+
let lastDownTime = 0.0;
|
14
|
+
return this.subscribe(eventTarget, "pointerdown", event => {
|
15
|
+
const now = performance.now();
|
16
|
+
if (now - lastDownTime < this.DOUBLE_DOWN_THRESHOLD) {
|
17
|
+
listener(event);
|
18
|
+
}
|
19
|
+
lastDownTime = now;
|
20
|
+
}, { capture: true });
|
21
|
+
};
|
22
|
+
static PreventDefault = event => event.preventDefault();
|
23
|
+
static isTextInput = (target) => target instanceof HTMLInputElement
|
24
|
+
|| target instanceof HTMLTextAreaElement
|
25
|
+
|| (target instanceof HTMLElement && isDefined(target.getAttribute("contenteditable")));
|
26
|
+
}
|
package/dist/files.d.ts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../src/files.ts"],"names":[],"mappings":"AAGA,yBAAiB,KAAK,CAAC;IACZ,MAAM,IAAI,GAAU,aAAa,WAAW,EAAE,UAAU,qBAAqB,KAAG,OAAO,CAAC,MAAM,CAkBpG,CAAA;IAEM,MAAM,IAAI,GAAU,UAAU,qBAAqB,KAAG,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,CAgCvF,CAAA;CACJ"}
|
package/dist/files.js
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
import { Arrays, asDefined, isDefined } from "@opendaw/lib-std";
|
2
|
+
import { Promises } from "@opendaw/lib-runtime";
|
3
|
+
export var Files;
|
4
|
+
(function (Files) {
|
5
|
+
Files.save = async (arrayBuffer, options) => {
|
6
|
+
if (isDefined(window.showSaveFilePicker)) {
|
7
|
+
const handle = await window.showSaveFilePicker(options);
|
8
|
+
const writable = await handle.createWritable();
|
9
|
+
await writable.truncate(0);
|
10
|
+
await writable.write(arrayBuffer);
|
11
|
+
await writable.close();
|
12
|
+
return handle.name ?? "unknown";
|
13
|
+
}
|
14
|
+
else {
|
15
|
+
const blob = new Blob([arrayBuffer]);
|
16
|
+
const url = URL.createObjectURL(blob);
|
17
|
+
const anchor = document.createElement("a");
|
18
|
+
anchor.href = url;
|
19
|
+
anchor.download = options?.suggestedName ?? `unknown`;
|
20
|
+
anchor.click();
|
21
|
+
URL.revokeObjectURL(url);
|
22
|
+
return options?.suggestedName ?? "Unknown";
|
23
|
+
}
|
24
|
+
};
|
25
|
+
Files.open = async (options) => {
|
26
|
+
if (isDefined(window.showOpenFilePicker)) {
|
27
|
+
const { status, value: fileHandles, error } = await Promises.tryCatch(window.showOpenFilePicker(options));
|
28
|
+
if (status === "rejected") {
|
29
|
+
return Promise.reject(error);
|
30
|
+
}
|
31
|
+
return Promise.all(fileHandles.map(fileHandle => fileHandle.getFile()));
|
32
|
+
}
|
33
|
+
else {
|
34
|
+
return new Promise((resolve, reject) => {
|
35
|
+
if (isDefined(options)) {
|
36
|
+
console.warn("FileApi.showOpenFilePicker is emulated in this browser. OpenFilePickerOptions are ignored.");
|
37
|
+
}
|
38
|
+
const fileInput = document.createElement("input");
|
39
|
+
fileInput.type = "file";
|
40
|
+
fileInput.multiple = options?.multiple ?? false;
|
41
|
+
fileInput.style.display = "none";
|
42
|
+
fileInput.addEventListener("cancel", async () => {
|
43
|
+
fileInput.remove();
|
44
|
+
reject(new DOMException("cancel", "AbortError"));
|
45
|
+
});
|
46
|
+
fileInput.addEventListener("change", async (event) => {
|
47
|
+
const target = event.target;
|
48
|
+
const files = target.files;
|
49
|
+
if (isDefined(files)) {
|
50
|
+
resolve(Arrays.create(index => asDefined(files.item(index), `No file at index ${index}`), files.length));
|
51
|
+
}
|
52
|
+
else {
|
53
|
+
reject(new DOMException("cancel", "AbortError"));
|
54
|
+
}
|
55
|
+
fileInput.remove();
|
56
|
+
});
|
57
|
+
document.body.appendChild(fileInput);
|
58
|
+
fileInput.click();
|
59
|
+
});
|
60
|
+
}
|
61
|
+
};
|
62
|
+
})(Files || (Files = {}));
|
package/dist/fonts.d.ts
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
export type FontFaceProperties = {
|
2
|
+
"font-family": string;
|
3
|
+
"font-style": "normal" | "italic" | "oblique";
|
4
|
+
"font-weight": 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 1000 | "normal" | "bold" | "bolder" | "lighter";
|
5
|
+
"src": string;
|
6
|
+
};
|
7
|
+
export declare const loadFont: (properties: FontFaceProperties) => Promise<void>;
|
8
|
+
//# sourceMappingURL=fonts.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"fonts.d.ts","sourceRoot":"","sources":["../src/fonts.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAAG;IAC7B,aAAa,EAAE,MAAM,CAAA;IACrB,YAAY,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAA;IAC7C,aAAa,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAA;IACpH,KAAK,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,eAAO,MAAM,QAAQ,GAAU,YAAY,kBAAkB,kBAe5D,CAAA"}
|
package/dist/fonts.js
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
export const loadFont = async (properties) => {
|
2
|
+
try {
|
3
|
+
const response = await fetch(properties.src, { credentials: "omit" });
|
4
|
+
const fontData = await response.arrayBuffer();
|
5
|
+
const fontFace = new FontFace(properties["font-family"], fontData, {
|
6
|
+
display: "block",
|
7
|
+
weight: String(properties["font-weight"]),
|
8
|
+
style: properties["font-style"]
|
9
|
+
});
|
10
|
+
await fontFace.load();
|
11
|
+
document.fonts.add(fontFace);
|
12
|
+
console.debug(`font-family: '${fontFace.family}'`);
|
13
|
+
}
|
14
|
+
catch (error) {
|
15
|
+
console.error(error);
|
16
|
+
}
|
17
|
+
};
|
package/dist/frames.d.ts
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
import { Exec, Terminable } from "@opendaw/lib-std";
|
2
|
+
export declare namespace AnimationFrame {
|
3
|
+
const add: (exec: Exec) => Terminable;
|
4
|
+
const once: (exec: Exec) => void;
|
5
|
+
const start: () => void;
|
6
|
+
const terminate: () => void;
|
7
|
+
}
|
8
|
+
export declare const deferNextFrame: (exec: Exec) => DeferExec;
|
9
|
+
export declare class DeferExec implements Terminable {
|
10
|
+
#private;
|
11
|
+
constructor(exec: Exec);
|
12
|
+
readonly request: () => void;
|
13
|
+
readonly immediate: () => void;
|
14
|
+
cancel(): void;
|
15
|
+
terminate(): void;
|
16
|
+
}
|
17
|
+
//# sourceMappingURL=frames.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"frames.d.ts","sourceRoot":"","sources":["../src/frames.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAO,UAAU,EAAC,MAAM,kBAAkB,CAAA;AAEtD,yBAAiB,cAAc,CAAC;IAOrB,MAAM,GAAG,GAAI,MAAM,IAAI,KAAG,UAGhC,CAAA;IAEM,MAAM,IAAI,GAAI,MAAM,IAAI,KAAG,IAAgC,CAAA;IAE3D,MAAM,KAAK,QAAO,IAaxB,CAAA;IAEM,MAAM,SAAS,QAAO,IAM5B,CAAA;CACJ;AAED,eAAO,MAAM,cAAc,GAAI,MAAM,IAAI,KAAG,SAAgC,CAAA;AAE5E,qBAAa,SAAU,YAAW,UAAU;;gBAM5B,IAAI,EAAE,IAAI;IAEtB,QAAQ,CAAC,OAAO,QAAO,IAAI,CAI1B;IAED,QAAQ,CAAC,SAAS,QAAO,IAAI,CAI5B;IAED,MAAM,IAAI,IAAI;IACd,SAAS,IAAI,IAAI;CAOpB"}
|
package/dist/frames.js
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
export var AnimationFrame;
|
2
|
+
(function (AnimationFrame) {
|
3
|
+
const nonrecurring = new Set();
|
4
|
+
const recurring = new Set();
|
5
|
+
const queue = new Array();
|
6
|
+
let id = -1;
|
7
|
+
AnimationFrame.add = (exec) => {
|
8
|
+
recurring.add(exec);
|
9
|
+
return { terminate: () => recurring.delete(exec) };
|
10
|
+
};
|
11
|
+
AnimationFrame.once = (exec) => { nonrecurring.add(exec); };
|
12
|
+
AnimationFrame.start = () => {
|
13
|
+
console.debug("AnimationFrame start");
|
14
|
+
const exe = () => {
|
15
|
+
if (recurring.size > 0 || nonrecurring.size > 0) {
|
16
|
+
recurring.forEach((exec) => queue.push(exec));
|
17
|
+
nonrecurring.forEach((exec) => queue.push(exec));
|
18
|
+
nonrecurring.clear();
|
19
|
+
queue.forEach((exec) => exec());
|
20
|
+
queue.length = 0;
|
21
|
+
}
|
22
|
+
id = requestAnimationFrame(exe);
|
23
|
+
};
|
24
|
+
id = requestAnimationFrame(exe);
|
25
|
+
};
|
26
|
+
AnimationFrame.terminate = () => {
|
27
|
+
console.debug("AnimationFrame terminate");
|
28
|
+
nonrecurring.clear();
|
29
|
+
recurring.clear();
|
30
|
+
queue.length = 0;
|
31
|
+
cancelAnimationFrame(id);
|
32
|
+
};
|
33
|
+
})(AnimationFrame || (AnimationFrame = {}));
|
34
|
+
export const deferNextFrame = (exec) => new DeferExec(exec);
|
35
|
+
export class DeferExec {
|
36
|
+
#exec;
|
37
|
+
#requested = false;
|
38
|
+
#disabled = false;
|
39
|
+
constructor(exec) { this.#exec = exec; }
|
40
|
+
request = () => {
|
41
|
+
if (this.#requested || this.#disabled) {
|
42
|
+
return;
|
43
|
+
}
|
44
|
+
this.#requested = true;
|
45
|
+
AnimationFrame.once(this.#fire);
|
46
|
+
};
|
47
|
+
immediate = () => {
|
48
|
+
if (this.#disabled) {
|
49
|
+
return;
|
50
|
+
}
|
51
|
+
this.#requested = true;
|
52
|
+
this.#fire();
|
53
|
+
};
|
54
|
+
cancel() { this.#requested = false; }
|
55
|
+
terminate() { this.#disabled = true; }
|
56
|
+
#fire = () => {
|
57
|
+
if (this.#disabled || !this.#requested) {
|
58
|
+
return;
|
59
|
+
}
|
60
|
+
this.#requested = false;
|
61
|
+
this.#exec();
|
62
|
+
};
|
63
|
+
}
|
package/dist/html.d.ts
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
import { Color, int, Subscription } from "@opendaw/lib-std";
|
2
|
+
export declare namespace Html {
|
3
|
+
const parse: (source: string) => HTMLOrSVGElement & Element;
|
4
|
+
const empty: (element: Element) => void;
|
5
|
+
const replace: (element: Element, ...elements: ReadonlyArray<string | Element>) => void;
|
6
|
+
const query: <E extends Element>(selectors: string, parent?: ParentNode) => E;
|
7
|
+
const queryAll: <E extends Element>(selectors: string, parent?: ParentNode) => ReadonlyArray<E>;
|
8
|
+
const nextID: () => string;
|
9
|
+
const adoptStyleSheet: (classDefinition: string, prefix?: string) => string;
|
10
|
+
const buildClassList: (...input: Array<string | false | undefined>) => string;
|
11
|
+
const readCssVarColor: (...cssValues: Array<string>) => Array<Color.RGBA>;
|
12
|
+
const watchResize: (target: Element, callback: (entry: ResizeObserverEntry, observer: ResizeObserver) => void, options?: ResizeObserverOptions) => Subscription;
|
13
|
+
const watchIntersection: (target: Element, callback: IntersectionObserverCallback, options?: IntersectionObserverInit) => Subscription;
|
14
|
+
const secureBoundingBox: (element: Element) => DOMRect;
|
15
|
+
const unfocus: (owner?: Window) => void;
|
16
|
+
const selectContent: (element: HTMLElement) => void;
|
17
|
+
const unselectContent: (element: HTMLElement) => void;
|
18
|
+
const limitChars: <T extends HTMLElement, K extends keyof T & string>(element: T, property: K, limit: int) => undefined;
|
19
|
+
const EmptyGif: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=";
|
20
|
+
}
|
21
|
+
//# sourceMappingURL=html.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../src/html.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,EAAE,GAAG,EAA0B,YAAY,EAAC,MAAM,kBAAkB,CAAA;AAEpG,yBAAiB,IAAI,CAAC;IACX,MAAM,KAAK,GAAI,QAAQ,MAAM,KAAG,gBAAgB,GAAG,OAUzD,CAAA;IAEM,MAAM,KAAK,GAAI,SAAS,OAAO,KAAG,IAA2E,CAAA;IAE7G,MAAM,OAAO,GAAI,SAAS,OAAO,EAAE,GAAG,UAAU,aAAa,CAAC,MAAM,GAAG,OAAO,CAAC,KAAG,IAGxF,CAAA;IAEM,MAAM,KAAK,GAAI,CAAC,SAAS,OAAO,EAAE,WAAW,MAAM,EAAE,SAAQ,UAAqB,KAAG,CACzC,CAAA;IAE5C,MAAM,QAAQ,GAAI,CAAC,SAAS,OAAO,EAAE,WAAW,MAAM,EAAE,SAAQ,UAAqB,KAAG,aAAa,CAAC,CAAC,CAC5D,CAAA;IAE3C,MAAM,MAAM,QAEJ,MACX,CAAA;IAEG,MAAM,eAAe,GAAI,iBAAiB,MAAM,EAAE,SAAS,MAAM,KAAG,MAU1E,CAAA;IAGM,MAAM,cAAc,GAAI,GAAG,OAAO,KAAK,CAAC,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC,WACX,CAAA;IAExD,MAAM,eAAe,GAAI,GAAG,WAAW,KAAK,CAAC,MAAM,CAAC,KAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAS7E,CAAA;IAEM,MAAM,WAAW,GAAI,QAAQ,OAAO,EACf,UAAU,CAAC,KAAK,EAAE,mBAAmB,EAAE,QAAQ,EAAE,cAAc,KAAK,IAAI,EACxE,UAAU,qBAAqB,KAAG,YAI7D,CAAA;IAEM,MAAM,iBAAiB,GAAI,QAAQ,OAAO,EACf,UAAU,4BAA4B,EACtC,UAAU,wBAAwB,KAAG,YAItE,CAAA;IAGM,MAAM,iBAAiB,GAAI,SAAS,OAAO,KAAG,OASpD,CAAA;IAEM,MAAM,OAAO,GAAI,QAAO,MAAa,SAK3C,CAAA;IAEM,MAAM,aAAa,GAAI,SAAS,WAAW,SAQjD,CAAA;IAEM,MAAM,eAAe,GAAI,SAAS,WAAW,SAMnD,CAAA;IAEM,MAAM,UAAU,GAAI,CAAC,SAAS,WAAW,EAAE,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAAE,SAAS,CAAC,EAAE,UAAU,CAAC,EAAE,OAAO,GAAG,cAkBhH,CAAA;IAEM,MAAM,QAAQ,EAAG,oHAA6H,CAAA;CACxJ"}
|
package/dist/html.js
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
import { asDefined, assert, Color, isDefined, panic, Rect } from "@opendaw/lib-std";
|
2
|
+
export var Html;
|
3
|
+
(function (Html) {
|
4
|
+
Html.parse = (source) => {
|
5
|
+
const template = document.createElement("div");
|
6
|
+
template.innerHTML = source;
|
7
|
+
if (template.childElementCount !== 1) {
|
8
|
+
return panic(`Source html has more than one root elements: '${source}'`);
|
9
|
+
}
|
10
|
+
const child = template.firstChild;
|
11
|
+
return child instanceof HTMLElement || child instanceof SVGSVGElement
|
12
|
+
? child
|
13
|
+
: panic(`Cannot parse to HTMLOrSVGElement from '${source}'`);
|
14
|
+
};
|
15
|
+
Html.empty = (element) => { while (element.firstChild !== null) {
|
16
|
+
element.firstChild.remove();
|
17
|
+
} };
|
18
|
+
Html.replace = (element, ...elements) => {
|
19
|
+
Html.empty(element);
|
20
|
+
element.append(...elements);
|
21
|
+
};
|
22
|
+
Html.query = (selectors, parent = document) => asDefined(parent.querySelector(selectors));
|
23
|
+
Html.queryAll = (selectors, parent = document) => Array.from(parent.querySelectorAll(selectors));
|
24
|
+
Html.nextID = (() => {
|
25
|
+
let id = 0 | 0;
|
26
|
+
return () => (++id).toString(16).padStart(4, "0");
|
27
|
+
})();
|
28
|
+
Html.adoptStyleSheet = (classDefinition, prefix) => {
|
29
|
+
assert(classDefinition.includes("component"), `No 'component' found in: ${classDefinition}`);
|
30
|
+
const className = `${prefix ?? "C"}${Html.nextID()}`;
|
31
|
+
const sheet = new CSSStyleSheet();
|
32
|
+
sheet.replaceSync(classDefinition.replaceAll("component", `.${className}`));
|
33
|
+
if (sheet.cssRules.length === 0) {
|
34
|
+
return panic(`No cssRules found in: ${classDefinition}`);
|
35
|
+
}
|
36
|
+
document.adoptedStyleSheets.push(sheet);
|
37
|
+
return className;
|
38
|
+
};
|
39
|
+
// Allows conditional accumulation of classNames
|
40
|
+
Html.buildClassList = (...input) => input.filter(x => x !== false && x !== undefined).join(" ");
|
41
|
+
Html.readCssVarColor = (...cssValues) => {
|
42
|
+
const element = document.createElement("div");
|
43
|
+
document.body.appendChild(element);
|
44
|
+
const colors = cssValues.map(value => {
|
45
|
+
element.style.color = value;
|
46
|
+
return Color.parseCssRgbOrRgba(getComputedStyle(element).color);
|
47
|
+
});
|
48
|
+
element.remove();
|
49
|
+
return colors;
|
50
|
+
};
|
51
|
+
Html.watchResize = (target, callback, options) => {
|
52
|
+
const observer = new ResizeObserver(([first], observer) => callback(first, observer));
|
53
|
+
observer.observe(target, options);
|
54
|
+
return { terminate: () => observer.disconnect() };
|
55
|
+
};
|
56
|
+
Html.watchIntersection = (target, callback, options) => {
|
57
|
+
const observer = new IntersectionObserver(callback, options);
|
58
|
+
observer.observe(target);
|
59
|
+
return { terminate: () => observer.disconnect() };
|
60
|
+
};
|
61
|
+
// handles cases like 'display: contents', where the bounding box is always empty, although the children have dimensions
|
62
|
+
Html.secureBoundingBox = (element) => {
|
63
|
+
let elemRect = element.getBoundingClientRect();
|
64
|
+
if (!Rect.isEmpty(elemRect)) {
|
65
|
+
return elemRect;
|
66
|
+
}
|
67
|
+
for (const child of element.children) {
|
68
|
+
Rect.union(elemRect, Html.secureBoundingBox(child));
|
69
|
+
}
|
70
|
+
return elemRect;
|
71
|
+
};
|
72
|
+
Html.unfocus = (owner = self) => {
|
73
|
+
const element = owner.document.activeElement;
|
74
|
+
if (element !== null && "blur" in element && typeof element.blur === "function") {
|
75
|
+
element.blur();
|
76
|
+
}
|
77
|
+
};
|
78
|
+
Html.selectContent = (element) => {
|
79
|
+
const range = document.createRange();
|
80
|
+
const selection = window.getSelection();
|
81
|
+
if (isDefined(selection)) {
|
82
|
+
range.selectNodeContents(element);
|
83
|
+
selection.removeAllRanges();
|
84
|
+
selection.addRange(range);
|
85
|
+
}
|
86
|
+
};
|
87
|
+
Html.unselectContent = (element) => {
|
88
|
+
const selection = window.getSelection();
|
89
|
+
if (!isDefined(selection) || selection.rangeCount === 0) {
|
90
|
+
return;
|
91
|
+
}
|
92
|
+
if (element.contains(selection.getRangeAt(0).commonAncestorContainer)) {
|
93
|
+
selection.removeAllRanges();
|
94
|
+
}
|
95
|
+
};
|
96
|
+
Html.limitChars = (element, property, limit) => {
|
97
|
+
if (!(property in element))
|
98
|
+
return panic(`${property} not found in ${element}`);
|
99
|
+
if (typeof element[property] !== "string")
|
100
|
+
return panic(`${property} in ${element} is not a string`);
|
101
|
+
if (element[property].length > limit) {
|
102
|
+
element[property] = element[property].substring(0, limit);
|
103
|
+
if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement) {
|
104
|
+
element.setSelectionRange(limit, limit);
|
105
|
+
}
|
106
|
+
else {
|
107
|
+
const document = element.ownerDocument;
|
108
|
+
const range = document.createRange();
|
109
|
+
const selection = document.defaultView?.getSelection();
|
110
|
+
if (!isDefined(selection)) {
|
111
|
+
return;
|
112
|
+
}
|
113
|
+
range.selectNodeContents(element);
|
114
|
+
range.collapse(false);
|
115
|
+
selection.removeAllRanges();
|
116
|
+
selection.addRange(range);
|
117
|
+
}
|
118
|
+
}
|
119
|
+
};
|
120
|
+
Html.EmptyGif = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=";
|
121
|
+
})(Html || (Html = {}));
|
package/dist/index.d.ts
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
export * from "./browser";
|
2
|
+
export * from "./compression";
|
3
|
+
export * from "./console-commands";
|
4
|
+
export * from "./context-2d";
|
5
|
+
export * from "./css-utils";
|
6
|
+
export * from "./dragging";
|
7
|
+
export * from "./events";
|
8
|
+
export * from "./errors";
|
9
|
+
export * from "./files";
|
10
|
+
export * from "./fonts";
|
11
|
+
export * from "./frames";
|
12
|
+
export * from "./html";
|
13
|
+
export * from "./keyboard";
|
14
|
+
export * from "./modfier-keys";
|
15
|
+
export * from "./stream";
|
16
|
+
export * from "./svg";
|
17
|
+
export * from "./terminable";
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,cAAc,WAAW,CAAA;AACzB,cAAc,eAAe,CAAA;AAC7B,cAAc,oBAAoB,CAAA;AAClC,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,UAAU,CAAA;AACxB,cAAc,UAAU,CAAA;AACxB,cAAc,SAAS,CAAA;AACvB,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA;AACxB,cAAc,QAAQ,CAAA;AACtB,cAAc,YAAY,CAAA;AAC1B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,UAAU,CAAA;AACxB,cAAc,OAAO,CAAA;AACrB,cAAc,cAAc,CAAA"}
|
package/dist/index.js
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
const key = Symbol.for("@openDAW/lib-dom");
|
2
|
+
if (globalThis[key]) {
|
3
|
+
console.debug(`%c${key.description}%c is already available in ${globalThis.constructor.name}.`, "color: hsl(10, 83%, 60%)", "color: inherit");
|
4
|
+
}
|
5
|
+
else {
|
6
|
+
globalThis[key] = true;
|
7
|
+
console.debug(`%c${key.description}%c is now available in ${globalThis.constructor.name}.`, "color: hsl(200, 83%, 60%)", "color: inherit");
|
8
|
+
}
|
9
|
+
export * from "./browser";
|
10
|
+
export * from "./compression";
|
11
|
+
export * from "./console-commands";
|
12
|
+
export * from "./context-2d";
|
13
|
+
export * from "./css-utils";
|
14
|
+
export * from "./dragging";
|
15
|
+
export * from "./events";
|
16
|
+
export * from "./errors";
|
17
|
+
export * from "./files";
|
18
|
+
export * from "./fonts";
|
19
|
+
export * from "./frames";
|
20
|
+
export * from "./html";
|
21
|
+
export * from "./keyboard";
|
22
|
+
export * from "./modfier-keys";
|
23
|
+
export * from "./stream";
|
24
|
+
export * from "./svg";
|
25
|
+
export * from "./terminable";
|
@@ -0,0 +1,15 @@
|
|
1
|
+
export declare namespace Keyboard {
|
2
|
+
const isControlKey: ({ ctrlKey, metaKey }: {
|
3
|
+
ctrlKey: boolean;
|
4
|
+
metaKey: boolean;
|
5
|
+
}) => boolean;
|
6
|
+
const isCopyKey: ({ altKey }: {
|
7
|
+
altKey: boolean;
|
8
|
+
}) => boolean;
|
9
|
+
const GlobalShortcut: Readonly<{
|
10
|
+
isDelete: (event: KeyboardEvent) => boolean;
|
11
|
+
isSelectAll: (event: KeyboardEvent) => boolean;
|
12
|
+
isDeselectAll: (event: KeyboardEvent) => boolean;
|
13
|
+
}>;
|
14
|
+
}
|
15
|
+
//# sourceMappingURL=keyboard.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"keyboard.d.ts","sourceRoot":"","sources":["../src/keyboard.ts"],"names":[],"mappings":"AAGA,yBAAiB,QAAQ,CAAC;IACf,MAAM,YAAY,GAAI,sBAAoB;QAC7C,OAAO,EAAE,OAAO,CAAC;QACjB,OAAO,EAAE,OAAO,CAAA;KACnB,YAA0C,CAAA;IAEpC,MAAM,SAAS,GAAI,YAAU;QAAE,MAAM,EAAE,OAAO,CAAA;KAAE,YAAW,CAAA;IAE3D,MAAM,cAAc;0BACL,aAAa;6BACV,aAAa;+BACX,aAAa;MACtC,CAAA;CACL"}
|
package/dist/keyboard.js
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
import { Browser } from "./browser";
|
2
|
+
import { Events } from "./events";
|
3
|
+
export var Keyboard;
|
4
|
+
(function (Keyboard) {
|
5
|
+
Keyboard.isControlKey = ({ ctrlKey, metaKey }) => Browser.isMacOS() ? metaKey : ctrlKey;
|
6
|
+
Keyboard.isCopyKey = ({ altKey }) => altKey;
|
7
|
+
Keyboard.GlobalShortcut = Object.freeze({
|
8
|
+
isDelete: (event) => !Events.isTextInput(event.target) && (event.code === "Delete" || event.code === "Backspace"),
|
9
|
+
isSelectAll: (event) => Keyboard.isControlKey(event) && !event.shiftKey && event.code === "KeyA",
|
10
|
+
isDeselectAll: (event) => Keyboard.isControlKey(event) && event.shiftKey && event.code === "KeyA"
|
11
|
+
});
|
12
|
+
})(Keyboard || (Keyboard = {}));
|
@@ -0,0 +1,18 @@
|
|
1
|
+
export declare const ModfierKeys: Readonly<{
|
2
|
+
Mac: {
|
3
|
+
Cmd: string;
|
4
|
+
Opt: string;
|
5
|
+
Shift: string;
|
6
|
+
};
|
7
|
+
Win: {
|
8
|
+
Cmd: string;
|
9
|
+
Opt: string;
|
10
|
+
Shift: string;
|
11
|
+
};
|
12
|
+
System: {
|
13
|
+
Cmd: string;
|
14
|
+
Opt: string;
|
15
|
+
Shift: string;
|
16
|
+
};
|
17
|
+
}>;
|
18
|
+
//# sourceMappingURL=modfier-keys.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"modfier-keys.d.ts","sourceRoot":"","sources":["../src/modfier-keys.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;EAIpB,CAAA"}
|
package/dist/stream.d.ts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AAEA,yBAAiB,MAAM,CAAC;IACb,MAAM,IAAI,GAAU,QAAQ,2BAA2B,CAAC,UAAU,CAAC,KAAG,OAAO,CAAC,WAAW,CAe/F,CAAA;CACJ"}
|
package/dist/stream.js
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
export var Stream;
|
2
|
+
(function (Stream) {
|
3
|
+
Stream.read = async (reader) => {
|
4
|
+
const chunks = [];
|
5
|
+
while (true) {
|
6
|
+
const { done, value } = await reader.read();
|
7
|
+
if (done) {
|
8
|
+
break;
|
9
|
+
}
|
10
|
+
chunks.push(value);
|
11
|
+
}
|
12
|
+
const length = chunks.reduce((acc, val) => acc + val.length, 0);
|
13
|
+
const output = new Uint8Array(length);
|
14
|
+
let position = 0 | 0;
|
15
|
+
for (let chunk of chunks) {
|
16
|
+
output.set(chunk, position);
|
17
|
+
position += chunk.length;
|
18
|
+
}
|
19
|
+
return output.buffer;
|
20
|
+
};
|
21
|
+
})(Stream || (Stream = {}));
|
package/dist/svg.d.ts
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
export declare namespace Svg {
|
2
|
+
interface PathBuilder {
|
3
|
+
moveTo(x: number, y: number): this;
|
4
|
+
lineTo(x: number, y: number): this;
|
5
|
+
quadratic(x1: number, y1: number, x: number, y: number): this;
|
6
|
+
quadraticTo(x: number, y: number): this;
|
7
|
+
cubic(x1: number, y1: number, x2: number, y2: number, x: number, y: number): this;
|
8
|
+
arc(rx: number, ry: number, deg: number, largeArc: boolean, sweep: boolean, x: number, y: number): this;
|
9
|
+
circleSegment(cx: number, cy: number, radius: number, a0: number, a1: number): this;
|
10
|
+
close(): this;
|
11
|
+
get(): string;
|
12
|
+
}
|
13
|
+
const pathBuilder: () => PathBuilder;
|
14
|
+
}
|
15
|
+
//# sourceMappingURL=svg.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"svg.d.ts","sourceRoot":"","sources":["../src/svg.ts"],"names":[],"mappings":"AAAA,yBAAiB,GAAG,CAAC;IACjB,UAAiB,WAAW;QACxB,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QAClC,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QAClC,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QAC7D,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QACvC,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QACjF,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QACvG,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAAA;QACnF,KAAK,IAAI,IAAI,CAAA;QACb,GAAG,IAAI,MAAM,CAAA;KAChB;IAEM,MAAM,WAAW,QAAO,WAkD9B,CAAA;CACJ"}
|
package/dist/svg.js
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
export var Svg;
|
2
|
+
(function (Svg) {
|
3
|
+
Svg.pathBuilder = () => new class {
|
4
|
+
#d = "";
|
5
|
+
moveTo(x, y) {
|
6
|
+
this.#d += `M${x.toFixed(3)} ${y.toFixed(3)}`;
|
7
|
+
return this;
|
8
|
+
}
|
9
|
+
lineTo(x, y) {
|
10
|
+
this.#d += `L${x.toFixed(3)} ${y.toFixed(3)}`;
|
11
|
+
return this;
|
12
|
+
}
|
13
|
+
quadratic(x1, y1, x, y) {
|
14
|
+
this.#d += `Q${x1.toFixed(3)} ${y1.toFixed(3)} ${x.toFixed(3)} ${y.toFixed(3)}`;
|
15
|
+
return this;
|
16
|
+
}
|
17
|
+
quadraticTo(x, y) {
|
18
|
+
this.#d += `T${x.toFixed(3)} ${y.toFixed(3)}`;
|
19
|
+
return this;
|
20
|
+
}
|
21
|
+
cubic(x1, y1, x2, y2, x, y) {
|
22
|
+
this.#d += `Q${x1.toFixed(3)} ${y1.toFixed(3)} ${x2.toFixed(3)} ${y2.toFixed(3)} ${x.toFixed(3)} ${y.toFixed(3)}`;
|
23
|
+
return this;
|
24
|
+
}
|
25
|
+
arc(rx, ry, deg, largeArc, sweep, x, y) {
|
26
|
+
this.#d += `A${rx} ${ry} ${deg} ${largeArc ? 1 : 0} ${sweep ? 1 : 0} ${x.toFixed(3)} ${y.toFixed(3)}`;
|
27
|
+
return this;
|
28
|
+
}
|
29
|
+
circleSegment(cx, cy, radius, a0, a1) {
|
30
|
+
const x0 = cx + Math.cos(a0) * radius;
|
31
|
+
const y0 = cy + Math.sin(a0) * radius;
|
32
|
+
const x1 = cx + Math.cos(a1) * radius;
|
33
|
+
const y1 = cy + Math.sin(a1) * radius;
|
34
|
+
let range = a1 - a0;
|
35
|
+
while (range < 0.0)
|
36
|
+
range += Math.PI * 2.0;
|
37
|
+
return this.moveTo(x0, y0).arc(radius, radius, 0, range > Math.PI, true, x1, y1);
|
38
|
+
}
|
39
|
+
close() {
|
40
|
+
this.#d += "Z";
|
41
|
+
return this;
|
42
|
+
}
|
43
|
+
get() { return this.#d; }
|
44
|
+
};
|
45
|
+
})(Svg || (Svg = {}));
|
@@ -0,0 +1,13 @@
|
|
1
|
+
import { Func, Terminable } from "@opendaw/lib-std";
|
2
|
+
export declare namespace TerminatorUtils {
|
3
|
+
/**
|
4
|
+
* Terminates if the key is no longer referenced to.
|
5
|
+
* Make sure that the Terminable does not include other references
|
6
|
+
* that would prevent the key from being gc collected.
|
7
|
+
* That means the key must not appear in the Terminable!
|
8
|
+
* @param key WeakKey
|
9
|
+
* @param subscribe Sends a WeakRef to be able to be gc collected
|
10
|
+
*/
|
11
|
+
const watchWeak: <K extends WeakKey>(key: K, subscribe: Func<WeakRef<K>, Terminable>) => K;
|
12
|
+
}
|
13
|
+
//# sourceMappingURL=terminable.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"terminable.d.ts","sourceRoot":"","sources":["../src/terminable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAE,UAAU,EAAC,MAAM,kBAAkB,CAAA;AAEjD,yBAAiB,eAAe,CAAC;IAE7B;;;;;;;OAOG;IACI,MAAM,SAAS,GAAI,CAAC,SAAS,OAAO,EAAE,KAAK,CAAC,EAAE,WAAW,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,KAAG,CAQ9F,CAAA;CAmBJ"}
|
@@ -0,0 +1,38 @@
|
|
1
|
+
export var TerminatorUtils;
|
2
|
+
(function (TerminatorUtils) {
|
3
|
+
const weakRefs = new Array();
|
4
|
+
/**
|
5
|
+
* Terminates if the key is no longer referenced to.
|
6
|
+
* Make sure that the Terminable does not include other references
|
7
|
+
* that would prevent the key from being gc collected.
|
8
|
+
* That means the key must not appear in the Terminable!
|
9
|
+
* @param key WeakKey
|
10
|
+
* @param subscribe Sends a WeakRef to be able to be gc collected
|
11
|
+
*/
|
12
|
+
TerminatorUtils.watchWeak = (key, subscribe) => {
|
13
|
+
const weakRef = new WeakRef(key);
|
14
|
+
const terminable = subscribe(weakRef);
|
15
|
+
weakRefs.push([weakRef, terminable]);
|
16
|
+
if (weakRefs.length === 1) {
|
17
|
+
startWatchWeak();
|
18
|
+
}
|
19
|
+
return key;
|
20
|
+
};
|
21
|
+
const startWatchWeak = () => {
|
22
|
+
console.debug("start weak watching");
|
23
|
+
const id = setInterval(() => {
|
24
|
+
let index = weakRefs.length;
|
25
|
+
while (--index >= 0) {
|
26
|
+
const entry = weakRefs[index];
|
27
|
+
if (entry[0].deref() === undefined) {
|
28
|
+
entry[1].terminate();
|
29
|
+
weakRefs.splice(index, 1);
|
30
|
+
if (weakRefs.length === 0) {
|
31
|
+
console.debug("stop weak watching");
|
32
|
+
clearInterval(id);
|
33
|
+
}
|
34
|
+
}
|
35
|
+
}
|
36
|
+
}, 1000);
|
37
|
+
};
|
38
|
+
})(TerminatorUtils || (TerminatorUtils = {}));
|
package/package.json
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
{
|
2
|
+
"name": "@opendaw/lib-dom",
|
3
|
+
"version": "0.0.6",
|
4
|
+
"main": "./dist/index.js",
|
5
|
+
"types": "./dist/index.d.ts",
|
6
|
+
"license": "LGPL-3.0-or-later",
|
7
|
+
"publishConfig": {
|
8
|
+
"access": "public"
|
9
|
+
},
|
10
|
+
"exports": {
|
11
|
+
".": {
|
12
|
+
"types": "./dist/index.d.ts",
|
13
|
+
"default": "./dist/index.js"
|
14
|
+
}
|
15
|
+
},
|
16
|
+
"files": [
|
17
|
+
"dist/**/*"
|
18
|
+
],
|
19
|
+
"scripts": {
|
20
|
+
"build": "tsc",
|
21
|
+
"lint": "eslint \"**/*.ts\"",
|
22
|
+
"test": "vitest run"
|
23
|
+
},
|
24
|
+
"dependencies": {
|
25
|
+
"@opendaw/lib-runtime": "^0.0.6",
|
26
|
+
"@opendaw/lib-std": "^0.0.6",
|
27
|
+
"@types/wicg-file-system-access": "^2023.10.6"
|
28
|
+
},
|
29
|
+
"devDependencies": {
|
30
|
+
"@opendaw/eslint-config": "^0.0.6",
|
31
|
+
"@opendaw/typescript-config": "^0.0.6"
|
32
|
+
},
|
33
|
+
"gitHead": "04e5363a9851c7e116a306c2e933c5f410980fbe"
|
34
|
+
}
|