@n8n/composables 1.21.0 → 1.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/injectionKeys.cjs +3 -0
- package/dist/injectionKeys.d.cts +7 -0
- package/dist/injectionKeys.d.mts +7 -0
- package/dist/injectionKeys.mjs +3 -0
- package/dist/injectionKeys2.cjs +17 -0
- package/dist/injectionKeys2.cjs.map +1 -0
- package/dist/injectionKeys2.mjs +11 -0
- package/dist/injectionKeys2.mjs.map +1 -0
- package/dist/structuralComputed.cjs +1 -0
- package/dist/structuralComputed.cjs.map +1 -1
- package/dist/useClipboard.cjs +61 -0
- package/dist/useClipboard.cjs.map +1 -0
- package/dist/useClipboard.d.cts +18 -0
- package/dist/useClipboard.d.mts +18 -0
- package/dist/useClipboard.mjs +60 -0
- package/dist/useClipboard.mjs.map +1 -0
- package/dist/useDebounce.cjs +65 -0
- package/dist/useDebounce.cjs.map +1 -0
- package/dist/useDebounce.d.cts +17 -0
- package/dist/useDebounce.d.mts +17 -0
- package/dist/useDebounce.mjs +39 -0
- package/dist/useDebounce.mjs.map +1 -0
- package/dist/useDeviceSupport.cjs +1 -0
- package/dist/useDeviceSupport.cjs.map +1 -1
- package/dist/useDeviceSupport.d.cts +2 -2
- package/dist/useDeviceSupport.d.mts +2 -2
- package/dist/useDocumentTitle.cjs +1 -0
- package/dist/useDocumentTitle.cjs.map +1 -1
- package/dist/useShortKeyPress.cjs +1 -0
- package/dist/useShortKeyPress.cjs.map +1 -1
- package/dist/useThrottleWithReactiveDelay.cjs +1 -0
- package/dist/useThrottleWithReactiveDelay.cjs.map +1 -1
- package/package.json +8 -6
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/injectionKeys.ts
|
|
3
|
+
/**
|
|
4
|
+
* Injection key for an optional pop-out window. Consumers `provide` it from the
|
|
5
|
+
* host that owns the detached window; `useClipboard` reads it so a copy issued
|
|
6
|
+
* inside the pop-out targets that window's `navigator.clipboard`.
|
|
7
|
+
*/
|
|
8
|
+
const PopOutWindowKey = Symbol("PopOutWindow");
|
|
9
|
+
|
|
10
|
+
//#endregion
|
|
11
|
+
Object.defineProperty(exports, 'PopOutWindowKey', {
|
|
12
|
+
enumerable: true,
|
|
13
|
+
get: function () {
|
|
14
|
+
return PopOutWindowKey;
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
//# sourceMappingURL=injectionKeys2.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"injectionKeys2.cjs","names":["PopOutWindowKey: InjectionKey<Ref<Window | undefined>>"],"sources":["../src/injectionKeys.ts"],"sourcesContent":["import type { InjectionKey, Ref } from 'vue';\n\n/**\n * Injection key for an optional pop-out window. Consumers `provide` it from the\n * host that owns the detached window; `useClipboard` reads it so a copy issued\n * inside the pop-out targets that window's `navigator.clipboard`.\n */\nexport const PopOutWindowKey: InjectionKey<Ref<Window | undefined>> = Symbol('PopOutWindow');\n"],"mappings":";;;;;;;AAOA,MAAaA,kBAAyD,OAAO,eAAe"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//#region src/injectionKeys.ts
|
|
2
|
+
/**
|
|
3
|
+
* Injection key for an optional pop-out window. Consumers `provide` it from the
|
|
4
|
+
* host that owns the detached window; `useClipboard` reads it so a copy issued
|
|
5
|
+
* inside the pop-out targets that window's `navigator.clipboard`.
|
|
6
|
+
*/
|
|
7
|
+
const PopOutWindowKey = Symbol("PopOutWindow");
|
|
8
|
+
|
|
9
|
+
//#endregion
|
|
10
|
+
export { PopOutWindowKey as t };
|
|
11
|
+
//# sourceMappingURL=injectionKeys2.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"injectionKeys2.mjs","names":["PopOutWindowKey: InjectionKey<Ref<Window | undefined>>"],"sources":["../src/injectionKeys.ts"],"sourcesContent":["import type { InjectionKey, Ref } from 'vue';\n\n/**\n * Injection key for an optional pop-out window. Consumers `provide` it from the\n * host that owns the detached window; `useClipboard` reads it so a copy issued\n * inside the pop-out targets that window's `navigator.clipboard`.\n */\nexport const PopOutWindowKey: InjectionKey<Ref<Window | undefined>> = Symbol('PopOutWindow');\n"],"mappings":";;;;;;AAOA,MAAaA,kBAAyD,OAAO,eAAe"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"structuralComputed.cjs","names":["cached: T"],"sources":["../src/structuralComputed.ts"],"sourcesContent":["import { computed, type ComputedRef } from 'vue';\n\n/**\n * Wraps a derivation in a `computed` that returns the same reference when the\n * new value is considered equal to the previous one by the provided `isEqual`\n * function (defaults to `Object.is`).\n *\n * Vue's `computed` uses `Object.is` on return values to decide whether to\n * notify subscribers. By returning a stable reference on equal content,\n * consumers only re-render when the value actually changes — without each\n * consumer writing its own equality gate.\n *\n * Typical use: pass a deep-equality function (e.g. `lodash/isEqual`) for\n * derivations that produce fresh objects/arrays on every evaluation but are\n * structurally identical most of the time.\n *\n * @example\n * import isEqual from 'lodash/isEqual';\n * const ports = structuralComputed(() => computePorts(...), isEqual);\n */\nexport function structuralComputed<T>(\n\tderive: () => T,\n\tisEqual: (a: T, b: T) => boolean = Object.is,\n): ComputedRef<T> {\n\tlet cached: T;\n\tlet primed = false;\n\treturn computed<T>(() => {\n\t\tconst next = derive();\n\t\tif (primed && isEqual(cached, next)) return cached;\n\t\tcached = next;\n\t\tprimed = true;\n\t\treturn cached;\n\t});\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"structuralComputed.cjs","names":["cached: T"],"sources":["../src/structuralComputed.ts"],"sourcesContent":["import { computed, type ComputedRef } from 'vue';\n\n/**\n * Wraps a derivation in a `computed` that returns the same reference when the\n * new value is considered equal to the previous one by the provided `isEqual`\n * function (defaults to `Object.is`).\n *\n * Vue's `computed` uses `Object.is` on return values to decide whether to\n * notify subscribers. By returning a stable reference on equal content,\n * consumers only re-render when the value actually changes — without each\n * consumer writing its own equality gate.\n *\n * Typical use: pass a deep-equality function (e.g. `lodash/isEqual`) for\n * derivations that produce fresh objects/arrays on every evaluation but are\n * structurally identical most of the time.\n *\n * @example\n * import isEqual from 'lodash/isEqual';\n * const ports = structuralComputed(() => computePorts(...), isEqual);\n */\nexport function structuralComputed<T>(\n\tderive: () => T,\n\tisEqual: (a: T, b: T) => boolean = Object.is,\n): ComputedRef<T> {\n\tlet cached: T;\n\tlet primed = false;\n\treturn computed<T>(() => {\n\t\tconst next = derive();\n\t\tif (primed && isEqual(cached, next)) return cached;\n\t\tcached = next;\n\t\tprimed = true;\n\t\treturn cached;\n\t});\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAoBA,SAAgB,mBACf,QACA,UAAmC,OAAO,IACzB;CACjB,IAAIA;CACJ,IAAI,SAAS;AACb,gCAAyB;EACxB,MAAM,OAAO,QAAQ;AACrB,MAAI,UAAU,QAAQ,QAAQ,KAAK,CAAE,QAAO;AAC5C,WAAS;AACT,WAAS;AACT,SAAO;GACN"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
const require_injectionKeys = require('./injectionKeys2.cjs');
|
|
2
|
+
const require_useDebounce = require('./useDebounce.cjs');
|
|
3
|
+
let vue = require("vue");
|
|
4
|
+
let __vueuse_core = require("@vueuse/core");
|
|
5
|
+
|
|
6
|
+
//#region src/useClipboard.ts
|
|
7
|
+
function useClipboard({ onPaste: onPasteFn = () => {} } = {}) {
|
|
8
|
+
const popOutWindow = (0, vue.inject)(require_injectionKeys.PopOutWindowKey, (0, vue.ref)());
|
|
9
|
+
const { copy: coreCopy, copied, isSupported, text } = (0, __vueuse_core.useClipboard)({ legacy: true });
|
|
10
|
+
async function copy(value) {
|
|
11
|
+
const nav = popOutWindow?.value?.navigator;
|
|
12
|
+
if (nav?.clipboard) try {
|
|
13
|
+
await nav.clipboard.writeText(value);
|
|
14
|
+
return;
|
|
15
|
+
} catch {}
|
|
16
|
+
await coreCopy(value);
|
|
17
|
+
}
|
|
18
|
+
const ignoreClasses = ["el-messsage-box", "ignore-key-press-canvas"];
|
|
19
|
+
const initialized = (0, vue.ref)(false);
|
|
20
|
+
const onPasteCallback = (0, vue.ref)(onPasteFn || null);
|
|
21
|
+
/**
|
|
22
|
+
* Handles copy/paste events
|
|
23
|
+
* @param event
|
|
24
|
+
*/
|
|
25
|
+
function onPaste(event) {
|
|
26
|
+
if (!onPasteCallback.value) return;
|
|
27
|
+
const path = event.composedPath?.();
|
|
28
|
+
for (const pathElement of path) if (pathElement.className && ignoreClasses.some((className) => pathElement.className.includes?.(className))) return;
|
|
29
|
+
const clipboardData = event.clipboardData;
|
|
30
|
+
if (clipboardData !== null) {
|
|
31
|
+
const clipboardValue = clipboardData.getData("text/plain");
|
|
32
|
+
onPasteCallback.value(clipboardValue, event);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const throttledOnPaste = (0, __vueuse_core.useThrottleFn)(onPaste, 1e3);
|
|
36
|
+
/**
|
|
37
|
+
* Initialize copy/paste elements and events
|
|
38
|
+
*/
|
|
39
|
+
(0, vue.onMounted)(() => {
|
|
40
|
+
if (initialized.value) return;
|
|
41
|
+
document.addEventListener("paste", throttledOnPaste);
|
|
42
|
+
initialized.value = true;
|
|
43
|
+
});
|
|
44
|
+
/**
|
|
45
|
+
* Remove copy/paste elements and events
|
|
46
|
+
*/
|
|
47
|
+
(0, vue.onBeforeUnmount)(() => {
|
|
48
|
+
if (initialized.value) document.removeEventListener("paste", throttledOnPaste);
|
|
49
|
+
});
|
|
50
|
+
return {
|
|
51
|
+
copy,
|
|
52
|
+
copied,
|
|
53
|
+
isSupported,
|
|
54
|
+
text,
|
|
55
|
+
onPaste: onPasteCallback
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
//#endregion
|
|
60
|
+
exports.useClipboard = useClipboard;
|
|
61
|
+
//# sourceMappingURL=useClipboard.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useClipboard.cjs","names":["PopOutWindowKey"],"sources":["../src/useClipboard.ts"],"sourcesContent":["import { useClipboard as useClipboardCore, useThrottleFn } from '@vueuse/core';\nimport { inject, onBeforeUnmount, onMounted, ref } from 'vue';\n\nimport { PopOutWindowKey } from './injectionKeys';\n\ntype ClipboardEventFn = (data: string, event?: ClipboardEvent) => void;\n\nexport function useClipboard({\n\tonPaste: onPasteFn = () => {},\n}: {\n\tonPaste?: ClipboardEventFn;\n} = {}) {\n\tconst popOutWindow = inject(PopOutWindowKey, ref<Window | undefined>());\n\tconst {\n\t\tcopy: coreCopy,\n\t\tcopied,\n\t\tisSupported,\n\t\ttext,\n\t} = useClipboardCore({\n\t\tlegacy: true,\n\t});\n\n\t// Find the correct navigator at copy-time so it works even when the\n\t// pop-out window opens after the composable was created.\n\tasync function copy(value: string) {\n\t\tconst nav = popOutWindow?.value?.navigator;\n\t\tif (nav?.clipboard) {\n\t\t\ttry {\n\t\t\t\tawait nav.clipboard.writeText(value);\n\t\t\t\treturn;\n\t\t\t} catch {\n\t\t\t\t// Fall back to the core clipboard copy below.\n\t\t\t}\n\t\t}\n\t\tawait coreCopy(value);\n\t}\n\n\tconst ignoreClasses = ['el-messsage-box', 'ignore-key-press-canvas'];\n\tconst initialized = ref(false);\n\n\tconst onPasteCallback = ref<ClipboardEventFn | null>(onPasteFn || null);\n\n\t/**\n\t * Handles copy/paste events\n\t * @param event\n\t */\n\tfunction onPaste(event: ClipboardEvent) {\n\t\tif (!onPasteCallback.value) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if the event got emitted from a message box or from something\n\t\t// else which should ignore the copy/paste\n\t\tconst path = event.composedPath?.() as HTMLElement[];\n\t\tfor (const pathElement of path) {\n\t\t\tif (\n\t\t\t\tpathElement.className &&\n\t\t\t\tignoreClasses.some((className) => pathElement.className.includes?.(className))\n\t\t\t) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tconst clipboardData = event.clipboardData;\n\t\tif (clipboardData !== null) {\n\t\t\tconst clipboardValue = clipboardData.getData('text/plain');\n\t\t\tonPasteCallback.value(clipboardValue, event);\n\t\t}\n\t}\n\n\tconst throttledOnPaste = useThrottleFn(onPaste, 1000);\n\n\t/**\n\t * Initialize copy/paste elements and events\n\t */\n\tonMounted(() => {\n\t\tif (initialized.value) {\n\t\t\treturn;\n\t\t}\n\n\t\tdocument.addEventListener('paste', throttledOnPaste);\n\n\t\tinitialized.value = true;\n\t});\n\n\t/**\n\t * Remove copy/paste elements and events\n\t */\n\tonBeforeUnmount(() => {\n\t\tif (initialized.value) {\n\t\t\tdocument.removeEventListener('paste', throttledOnPaste);\n\t\t}\n\t});\n\n\treturn {\n\t\tcopy,\n\t\tcopied,\n\t\tisSupported,\n\t\ttext,\n\t\tonPaste: onPasteCallback,\n\t};\n}\n"],"mappings":";;;;;;AAOA,SAAgB,aAAa,EAC5B,SAAS,kBAAkB,OAGxB,EAAE,EAAE;CACP,MAAM,+BAAsBA,qDAA0C,CAAC;CACvE,MAAM,EACL,MAAM,UACN,QACA,aACA,yCACoB,EACpB,QAAQ,MACR,CAAC;CAIF,eAAe,KAAK,OAAe;EAClC,MAAM,MAAM,cAAc,OAAO;AACjC,MAAI,KAAK,UACR,KAAI;AACH,SAAM,IAAI,UAAU,UAAU,MAAM;AACpC;UACO;AAIT,QAAM,SAAS,MAAM;;CAGtB,MAAM,gBAAgB,CAAC,mBAAmB,0BAA0B;CACpE,MAAM,2BAAkB,MAAM;CAE9B,MAAM,+BAA+C,aAAa,KAAK;;;;;CAMvE,SAAS,QAAQ,OAAuB;AACvC,MAAI,CAAC,gBAAgB,MACpB;EAKD,MAAM,OAAO,MAAM,gBAAgB;AACnC,OAAK,MAAM,eAAe,KACzB,KACC,YAAY,aACZ,cAAc,MAAM,cAAc,YAAY,UAAU,WAAW,UAAU,CAAC,CAE9E;EAIF,MAAM,gBAAgB,MAAM;AAC5B,MAAI,kBAAkB,MAAM;GAC3B,MAAM,iBAAiB,cAAc,QAAQ,aAAa;AAC1D,mBAAgB,MAAM,gBAAgB,MAAM;;;CAI9C,MAAM,oDAAiC,SAAS,IAAK;;;;AAKrD,0BAAgB;AACf,MAAI,YAAY,MACf;AAGD,WAAS,iBAAiB,SAAS,iBAAiB;AAEpD,cAAY,QAAQ;GACnB;;;;AAKF,gCAAsB;AACrB,MAAI,YAAY,MACf,UAAS,oBAAoB,SAAS,iBAAiB;GAEvD;AAEF,QAAO;EACN;EACA;EACA;EACA;EACA,SAAS;EACT"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as vue0 from "vue";
|
|
2
|
+
|
|
3
|
+
//#region src/useClipboard.d.ts
|
|
4
|
+
type ClipboardEventFn = (data: string, event?: ClipboardEvent) => void;
|
|
5
|
+
declare function useClipboard({
|
|
6
|
+
onPaste: onPasteFn
|
|
7
|
+
}?: {
|
|
8
|
+
onPaste?: ClipboardEventFn;
|
|
9
|
+
}): {
|
|
10
|
+
copy: (value: string) => Promise<void>;
|
|
11
|
+
copied: Readonly<vue0.ShallowRef<boolean>>;
|
|
12
|
+
isSupported: vue0.ComputedRef<boolean>;
|
|
13
|
+
text: Readonly<vue0.ShallowRef<string>>;
|
|
14
|
+
onPaste: vue0.Ref<ClipboardEventFn | null, ClipboardEventFn | null>;
|
|
15
|
+
};
|
|
16
|
+
//#endregion
|
|
17
|
+
export { useClipboard };
|
|
18
|
+
//# sourceMappingURL=useClipboard.d.cts.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as vue0 from "vue";
|
|
2
|
+
|
|
3
|
+
//#region src/useClipboard.d.ts
|
|
4
|
+
type ClipboardEventFn = (data: string, event?: ClipboardEvent) => void;
|
|
5
|
+
declare function useClipboard({
|
|
6
|
+
onPaste: onPasteFn
|
|
7
|
+
}?: {
|
|
8
|
+
onPaste?: ClipboardEventFn;
|
|
9
|
+
}): {
|
|
10
|
+
copy: (value: string) => Promise<void>;
|
|
11
|
+
copied: Readonly<vue0.ShallowRef<boolean>>;
|
|
12
|
+
isSupported: vue0.ComputedRef<boolean>;
|
|
13
|
+
text: Readonly<vue0.ShallowRef<string>>;
|
|
14
|
+
onPaste: vue0.Ref<ClipboardEventFn | null, ClipboardEventFn | null>;
|
|
15
|
+
};
|
|
16
|
+
//#endregion
|
|
17
|
+
export { useClipboard };
|
|
18
|
+
//# sourceMappingURL=useClipboard.d.mts.map
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { t as PopOutWindowKey } from "./injectionKeys2.mjs";
|
|
2
|
+
import { inject, onBeforeUnmount, onMounted, ref } from "vue";
|
|
3
|
+
import { useClipboard as useClipboard$1, useThrottleFn } from "@vueuse/core";
|
|
4
|
+
|
|
5
|
+
//#region src/useClipboard.ts
|
|
6
|
+
function useClipboard({ onPaste: onPasteFn = () => {} } = {}) {
|
|
7
|
+
const popOutWindow = inject(PopOutWindowKey, ref());
|
|
8
|
+
const { copy: coreCopy, copied, isSupported, text } = useClipboard$1({ legacy: true });
|
|
9
|
+
async function copy(value) {
|
|
10
|
+
const nav = popOutWindow?.value?.navigator;
|
|
11
|
+
if (nav?.clipboard) try {
|
|
12
|
+
await nav.clipboard.writeText(value);
|
|
13
|
+
return;
|
|
14
|
+
} catch {}
|
|
15
|
+
await coreCopy(value);
|
|
16
|
+
}
|
|
17
|
+
const ignoreClasses = ["el-messsage-box", "ignore-key-press-canvas"];
|
|
18
|
+
const initialized = ref(false);
|
|
19
|
+
const onPasteCallback = ref(onPasteFn || null);
|
|
20
|
+
/**
|
|
21
|
+
* Handles copy/paste events
|
|
22
|
+
* @param event
|
|
23
|
+
*/
|
|
24
|
+
function onPaste(event) {
|
|
25
|
+
if (!onPasteCallback.value) return;
|
|
26
|
+
const path = event.composedPath?.();
|
|
27
|
+
for (const pathElement of path) if (pathElement.className && ignoreClasses.some((className) => pathElement.className.includes?.(className))) return;
|
|
28
|
+
const clipboardData = event.clipboardData;
|
|
29
|
+
if (clipboardData !== null) {
|
|
30
|
+
const clipboardValue = clipboardData.getData("text/plain");
|
|
31
|
+
onPasteCallback.value(clipboardValue, event);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const throttledOnPaste = useThrottleFn(onPaste, 1e3);
|
|
35
|
+
/**
|
|
36
|
+
* Initialize copy/paste elements and events
|
|
37
|
+
*/
|
|
38
|
+
onMounted(() => {
|
|
39
|
+
if (initialized.value) return;
|
|
40
|
+
document.addEventListener("paste", throttledOnPaste);
|
|
41
|
+
initialized.value = true;
|
|
42
|
+
});
|
|
43
|
+
/**
|
|
44
|
+
* Remove copy/paste elements and events
|
|
45
|
+
*/
|
|
46
|
+
onBeforeUnmount(() => {
|
|
47
|
+
if (initialized.value) document.removeEventListener("paste", throttledOnPaste);
|
|
48
|
+
});
|
|
49
|
+
return {
|
|
50
|
+
copy,
|
|
51
|
+
copied,
|
|
52
|
+
isSupported,
|
|
53
|
+
text,
|
|
54
|
+
onPaste: onPasteCallback
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
//#endregion
|
|
59
|
+
export { useClipboard };
|
|
60
|
+
//# sourceMappingURL=useClipboard.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useClipboard.mjs","names":["useClipboardCore"],"sources":["../src/useClipboard.ts"],"sourcesContent":["import { useClipboard as useClipboardCore, useThrottleFn } from '@vueuse/core';\nimport { inject, onBeforeUnmount, onMounted, ref } from 'vue';\n\nimport { PopOutWindowKey } from './injectionKeys';\n\ntype ClipboardEventFn = (data: string, event?: ClipboardEvent) => void;\n\nexport function useClipboard({\n\tonPaste: onPasteFn = () => {},\n}: {\n\tonPaste?: ClipboardEventFn;\n} = {}) {\n\tconst popOutWindow = inject(PopOutWindowKey, ref<Window | undefined>());\n\tconst {\n\t\tcopy: coreCopy,\n\t\tcopied,\n\t\tisSupported,\n\t\ttext,\n\t} = useClipboardCore({\n\t\tlegacy: true,\n\t});\n\n\t// Find the correct navigator at copy-time so it works even when the\n\t// pop-out window opens after the composable was created.\n\tasync function copy(value: string) {\n\t\tconst nav = popOutWindow?.value?.navigator;\n\t\tif (nav?.clipboard) {\n\t\t\ttry {\n\t\t\t\tawait nav.clipboard.writeText(value);\n\t\t\t\treturn;\n\t\t\t} catch {\n\t\t\t\t// Fall back to the core clipboard copy below.\n\t\t\t}\n\t\t}\n\t\tawait coreCopy(value);\n\t}\n\n\tconst ignoreClasses = ['el-messsage-box', 'ignore-key-press-canvas'];\n\tconst initialized = ref(false);\n\n\tconst onPasteCallback = ref<ClipboardEventFn | null>(onPasteFn || null);\n\n\t/**\n\t * Handles copy/paste events\n\t * @param event\n\t */\n\tfunction onPaste(event: ClipboardEvent) {\n\t\tif (!onPasteCallback.value) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if the event got emitted from a message box or from something\n\t\t// else which should ignore the copy/paste\n\t\tconst path = event.composedPath?.() as HTMLElement[];\n\t\tfor (const pathElement of path) {\n\t\t\tif (\n\t\t\t\tpathElement.className &&\n\t\t\t\tignoreClasses.some((className) => pathElement.className.includes?.(className))\n\t\t\t) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tconst clipboardData = event.clipboardData;\n\t\tif (clipboardData !== null) {\n\t\t\tconst clipboardValue = clipboardData.getData('text/plain');\n\t\t\tonPasteCallback.value(clipboardValue, event);\n\t\t}\n\t}\n\n\tconst throttledOnPaste = useThrottleFn(onPaste, 1000);\n\n\t/**\n\t * Initialize copy/paste elements and events\n\t */\n\tonMounted(() => {\n\t\tif (initialized.value) {\n\t\t\treturn;\n\t\t}\n\n\t\tdocument.addEventListener('paste', throttledOnPaste);\n\n\t\tinitialized.value = true;\n\t});\n\n\t/**\n\t * Remove copy/paste elements and events\n\t */\n\tonBeforeUnmount(() => {\n\t\tif (initialized.value) {\n\t\t\tdocument.removeEventListener('paste', throttledOnPaste);\n\t\t}\n\t});\n\n\treturn {\n\t\tcopy,\n\t\tcopied,\n\t\tisSupported,\n\t\ttext,\n\t\tonPaste: onPasteCallback,\n\t};\n}\n"],"mappings":";;;;;AAOA,SAAgB,aAAa,EAC5B,SAAS,kBAAkB,OAGxB,EAAE,EAAE;CACP,MAAM,eAAe,OAAO,iBAAiB,KAAyB,CAAC;CACvE,MAAM,EACL,MAAM,UACN,QACA,aACA,SACGA,eAAiB,EACpB,QAAQ,MACR,CAAC;CAIF,eAAe,KAAK,OAAe;EAClC,MAAM,MAAM,cAAc,OAAO;AACjC,MAAI,KAAK,UACR,KAAI;AACH,SAAM,IAAI,UAAU,UAAU,MAAM;AACpC;UACO;AAIT,QAAM,SAAS,MAAM;;CAGtB,MAAM,gBAAgB,CAAC,mBAAmB,0BAA0B;CACpE,MAAM,cAAc,IAAI,MAAM;CAE9B,MAAM,kBAAkB,IAA6B,aAAa,KAAK;;;;;CAMvE,SAAS,QAAQ,OAAuB;AACvC,MAAI,CAAC,gBAAgB,MACpB;EAKD,MAAM,OAAO,MAAM,gBAAgB;AACnC,OAAK,MAAM,eAAe,KACzB,KACC,YAAY,aACZ,cAAc,MAAM,cAAc,YAAY,UAAU,WAAW,UAAU,CAAC,CAE9E;EAIF,MAAM,gBAAgB,MAAM;AAC5B,MAAI,kBAAkB,MAAM;GAC3B,MAAM,iBAAiB,cAAc,QAAQ,aAAa;AAC1D,mBAAgB,MAAM,gBAAgB,MAAM;;;CAI9C,MAAM,mBAAmB,cAAc,SAAS,IAAK;;;;AAKrD,iBAAgB;AACf,MAAI,YAAY,MACf;AAGD,WAAS,iBAAiB,SAAS,iBAAiB;AAEpD,cAAY,QAAQ;GACnB;;;;AAKF,uBAAsB;AACrB,MAAI,YAAY,MACf,UAAS,oBAAoB,SAAS,iBAAiB;GAEvD;AAEF,QAAO;EACN;EACA;EACA;EACA;EACA,SAAS;EACT"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
//#region rolldown:runtime
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __copyProps = (to, from, except, desc) => {
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
10
|
+
key = keys[i];
|
|
11
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
12
|
+
get: ((k) => from[k]).bind(null, key),
|
|
13
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
19
|
+
value: mod,
|
|
20
|
+
enumerable: true
|
|
21
|
+
}) : target, mod));
|
|
22
|
+
|
|
23
|
+
//#endregion
|
|
24
|
+
let vue = require("vue");
|
|
25
|
+
let lodash_debounce = require("lodash/debounce");
|
|
26
|
+
lodash_debounce = __toESM(lodash_debounce);
|
|
27
|
+
|
|
28
|
+
//#region src/useDebounce.ts
|
|
29
|
+
/**
|
|
30
|
+
* Get debounce time with optional multiplier from sessionStorage.
|
|
31
|
+
* Reads 'N8N_DEBOUNCE_MULTIPLIER' - defaults to 1 if not set.
|
|
32
|
+
*/
|
|
33
|
+
function getDebounceTime(time) {
|
|
34
|
+
const stored = sessionStorage.getItem("N8N_DEBOUNCE_MULTIPLIER");
|
|
35
|
+
const multiplier = stored !== null ? parseFloat(stored) : 1;
|
|
36
|
+
return Math.round(time * (Number.isNaN(multiplier) ? 1 : multiplier));
|
|
37
|
+
}
|
|
38
|
+
function useDebounce() {
|
|
39
|
+
const debounceCache = (0, vue.ref)(/* @__PURE__ */ new WeakMap());
|
|
40
|
+
const debounce = (fn, options) => {
|
|
41
|
+
const { trailing, debounceTime } = options;
|
|
42
|
+
const effectiveDebounceTime = getDebounceTime(debounceTime);
|
|
43
|
+
let debouncedFn = debounceCache.value.get(fn);
|
|
44
|
+
if (debouncedFn === void 0) {
|
|
45
|
+
debouncedFn = (0, lodash_debounce.default)(async (...args) => {
|
|
46
|
+
return fn(...args);
|
|
47
|
+
}, effectiveDebounceTime, trailing ? { trailing } : { leading: true });
|
|
48
|
+
debounceCache.value.set(fn, debouncedFn);
|
|
49
|
+
}
|
|
50
|
+
return debouncedFn;
|
|
51
|
+
};
|
|
52
|
+
const callDebounced = (fn, options, ...inputParameters) => {
|
|
53
|
+
return debounce(fn, options)(...inputParameters);
|
|
54
|
+
};
|
|
55
|
+
return {
|
|
56
|
+
debounce,
|
|
57
|
+
callDebounced
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
//#endregion
|
|
62
|
+
exports.__toESM = __toESM;
|
|
63
|
+
exports.getDebounceTime = getDebounceTime;
|
|
64
|
+
exports.useDebounce = useDebounce;
|
|
65
|
+
//# sourceMappingURL=useDebounce.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDebounce.cjs","names":[],"sources":["../src/useDebounce.ts"],"sourcesContent":["import lodashDebounce from 'lodash/debounce';\nimport { ref } from 'vue';\n\n/**\n * Get debounce time with optional multiplier from sessionStorage.\n * Reads 'N8N_DEBOUNCE_MULTIPLIER' - defaults to 1 if not set.\n */\nexport function getDebounceTime(time: number): number {\n\tconst stored = sessionStorage.getItem('N8N_DEBOUNCE_MULTIPLIER');\n\tconst multiplier = stored !== null ? parseFloat(stored) : 1;\n\treturn Math.round(time * (Number.isNaN(multiplier) ? 1 : multiplier));\n}\n\nexport interface DebounceOptions {\n\tdebounceTime: number;\n\ttrailing?: boolean;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyFunction = (...args: any) => any;\ntype DebouncedFunc<T extends AnyFunction> = ReturnType<typeof lodashDebounce<T>>;\n\nexport function useDebounce() {\n\t// Create a ref for the WeakMap to store debounced functions.\n\tconst debounceCache = ref(new WeakMap<AnyFunction, DebouncedFunc<AnyFunction>>());\n\n\tconst debounce = <T extends AnyFunction>(fn: T, options: DebounceOptions): DebouncedFunc<T> => {\n\t\tconst { trailing, debounceTime } = options;\n\n\t\tconst effectiveDebounceTime = getDebounceTime(debounceTime);\n\n\t\t// Check if a debounced version of the function is already stored in the WeakMap.\n\t\tlet debouncedFn = debounceCache.value.get(fn);\n\n\t\t// If a debounced version is not found, create one and store it in the WeakMap.\n\t\tif (debouncedFn === undefined) {\n\t\t\tdebouncedFn = lodashDebounce(\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/require-await -- kept async so the debounced wrapper always returns a promise\n\t\t\t\tasync (...args: Parameters<T>) => {\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return -- AnyFunction return is intentionally `any`\n\t\t\t\t\treturn fn(...args);\n\t\t\t\t},\n\t\t\t\teffectiveDebounceTime,\n\t\t\t\ttrailing ? { trailing } : { leading: true },\n\t\t\t);\n\n\t\t\tdebounceCache.value.set(fn, debouncedFn);\n\t\t}\n\n\t\treturn debouncedFn;\n\t};\n\n\tconst callDebounced = <T extends AnyFunction>(\n\t\tfn: T,\n\t\toptions: DebounceOptions,\n\t\t...inputParameters: Parameters<T>\n\t): ReturnType<T> | undefined => {\n\t\tconst debouncedFn = debounce(fn, options);\n\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return -- AnyFunction return is intentionally `any`\n\t\treturn debouncedFn(...inputParameters);\n\t};\n\n\treturn {\n\t\tdebounce,\n\t\tcallDebounced,\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAOA,SAAgB,gBAAgB,MAAsB;CACrD,MAAM,SAAS,eAAe,QAAQ,0BAA0B;CAChE,MAAM,aAAa,WAAW,OAAO,WAAW,OAAO,GAAG;AAC1D,QAAO,KAAK,MAAM,QAAQ,OAAO,MAAM,WAAW,GAAG,IAAI,YAAY;;AAYtE,SAAgB,cAAc;CAE7B,MAAM,6CAAoB,IAAI,SAAkD,CAAC;CAEjF,MAAM,YAAmC,IAAO,YAA+C;EAC9F,MAAM,EAAE,UAAU,iBAAiB;EAEnC,MAAM,wBAAwB,gBAAgB,aAAa;EAG3D,IAAI,cAAc,cAAc,MAAM,IAAI,GAAG;AAG7C,MAAI,gBAAgB,QAAW;AAC9B,8CAEC,OAAO,GAAG,SAAwB;AAEjC,WAAO,GAAG,GAAG,KAAK;MAEnB,uBACA,WAAW,EAAE,UAAU,GAAG,EAAE,SAAS,MAAM,CAC3C;AAED,iBAAc,MAAM,IAAI,IAAI,YAAY;;AAGzC,SAAO;;CAGR,MAAM,iBACL,IACA,SACA,GAAG,oBAC4B;AAI/B,SAHoB,SAAS,IAAI,QAAQ,CAGtB,GAAG,gBAAgB;;AAGvC,QAAO;EACN;EACA;EACA"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import lodashDebounce from "lodash/debounce";
|
|
2
|
+
|
|
3
|
+
//#region src/useDebounce.d.ts
|
|
4
|
+
declare function getDebounceTime(time: number): number;
|
|
5
|
+
interface DebounceOptions {
|
|
6
|
+
debounceTime: number;
|
|
7
|
+
trailing?: boolean;
|
|
8
|
+
}
|
|
9
|
+
type AnyFunction = (...args: any) => any;
|
|
10
|
+
type DebouncedFunc<T extends AnyFunction> = ReturnType<typeof lodashDebounce<T>>;
|
|
11
|
+
declare function useDebounce(): {
|
|
12
|
+
debounce: <T extends AnyFunction>(fn: T, options: DebounceOptions) => DebouncedFunc<T>;
|
|
13
|
+
callDebounced: <T extends AnyFunction>(fn: T, options: DebounceOptions, ...inputParameters: Parameters<T>) => ReturnType<T> | undefined;
|
|
14
|
+
};
|
|
15
|
+
//#endregion
|
|
16
|
+
export { DebounceOptions, getDebounceTime, useDebounce };
|
|
17
|
+
//# sourceMappingURL=useDebounce.d.cts.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import lodashDebounce from "lodash/debounce";
|
|
2
|
+
|
|
3
|
+
//#region src/useDebounce.d.ts
|
|
4
|
+
declare function getDebounceTime(time: number): number;
|
|
5
|
+
interface DebounceOptions {
|
|
6
|
+
debounceTime: number;
|
|
7
|
+
trailing?: boolean;
|
|
8
|
+
}
|
|
9
|
+
type AnyFunction = (...args: any) => any;
|
|
10
|
+
type DebouncedFunc<T extends AnyFunction> = ReturnType<typeof lodashDebounce<T>>;
|
|
11
|
+
declare function useDebounce(): {
|
|
12
|
+
debounce: <T extends AnyFunction>(fn: T, options: DebounceOptions) => DebouncedFunc<T>;
|
|
13
|
+
callDebounced: <T extends AnyFunction>(fn: T, options: DebounceOptions, ...inputParameters: Parameters<T>) => ReturnType<T> | undefined;
|
|
14
|
+
};
|
|
15
|
+
//#endregion
|
|
16
|
+
export { DebounceOptions, getDebounceTime, useDebounce };
|
|
17
|
+
//# sourceMappingURL=useDebounce.d.mts.map
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { ref } from "vue";
|
|
2
|
+
import lodashDebounce from "lodash/debounce";
|
|
3
|
+
|
|
4
|
+
//#region src/useDebounce.ts
|
|
5
|
+
/**
|
|
6
|
+
* Get debounce time with optional multiplier from sessionStorage.
|
|
7
|
+
* Reads 'N8N_DEBOUNCE_MULTIPLIER' - defaults to 1 if not set.
|
|
8
|
+
*/
|
|
9
|
+
function getDebounceTime(time) {
|
|
10
|
+
const stored = sessionStorage.getItem("N8N_DEBOUNCE_MULTIPLIER");
|
|
11
|
+
const multiplier = stored !== null ? parseFloat(stored) : 1;
|
|
12
|
+
return Math.round(time * (Number.isNaN(multiplier) ? 1 : multiplier));
|
|
13
|
+
}
|
|
14
|
+
function useDebounce() {
|
|
15
|
+
const debounceCache = ref(/* @__PURE__ */ new WeakMap());
|
|
16
|
+
const debounce = (fn, options) => {
|
|
17
|
+
const { trailing, debounceTime } = options;
|
|
18
|
+
const effectiveDebounceTime = getDebounceTime(debounceTime);
|
|
19
|
+
let debouncedFn = debounceCache.value.get(fn);
|
|
20
|
+
if (debouncedFn === void 0) {
|
|
21
|
+
debouncedFn = lodashDebounce(async (...args) => {
|
|
22
|
+
return fn(...args);
|
|
23
|
+
}, effectiveDebounceTime, trailing ? { trailing } : { leading: true });
|
|
24
|
+
debounceCache.value.set(fn, debouncedFn);
|
|
25
|
+
}
|
|
26
|
+
return debouncedFn;
|
|
27
|
+
};
|
|
28
|
+
const callDebounced = (fn, options, ...inputParameters) => {
|
|
29
|
+
return debounce(fn, options)(...inputParameters);
|
|
30
|
+
};
|
|
31
|
+
return {
|
|
32
|
+
debounce,
|
|
33
|
+
callDebounced
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
//#endregion
|
|
38
|
+
export { getDebounceTime, useDebounce };
|
|
39
|
+
//# sourceMappingURL=useDebounce.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDebounce.mjs","names":[],"sources":["../src/useDebounce.ts"],"sourcesContent":["import lodashDebounce from 'lodash/debounce';\nimport { ref } from 'vue';\n\n/**\n * Get debounce time with optional multiplier from sessionStorage.\n * Reads 'N8N_DEBOUNCE_MULTIPLIER' - defaults to 1 if not set.\n */\nexport function getDebounceTime(time: number): number {\n\tconst stored = sessionStorage.getItem('N8N_DEBOUNCE_MULTIPLIER');\n\tconst multiplier = stored !== null ? parseFloat(stored) : 1;\n\treturn Math.round(time * (Number.isNaN(multiplier) ? 1 : multiplier));\n}\n\nexport interface DebounceOptions {\n\tdebounceTime: number;\n\ttrailing?: boolean;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyFunction = (...args: any) => any;\ntype DebouncedFunc<T extends AnyFunction> = ReturnType<typeof lodashDebounce<T>>;\n\nexport function useDebounce() {\n\t// Create a ref for the WeakMap to store debounced functions.\n\tconst debounceCache = ref(new WeakMap<AnyFunction, DebouncedFunc<AnyFunction>>());\n\n\tconst debounce = <T extends AnyFunction>(fn: T, options: DebounceOptions): DebouncedFunc<T> => {\n\t\tconst { trailing, debounceTime } = options;\n\n\t\tconst effectiveDebounceTime = getDebounceTime(debounceTime);\n\n\t\t// Check if a debounced version of the function is already stored in the WeakMap.\n\t\tlet debouncedFn = debounceCache.value.get(fn);\n\n\t\t// If a debounced version is not found, create one and store it in the WeakMap.\n\t\tif (debouncedFn === undefined) {\n\t\t\tdebouncedFn = lodashDebounce(\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/require-await -- kept async so the debounced wrapper always returns a promise\n\t\t\t\tasync (...args: Parameters<T>) => {\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return -- AnyFunction return is intentionally `any`\n\t\t\t\t\treturn fn(...args);\n\t\t\t\t},\n\t\t\t\teffectiveDebounceTime,\n\t\t\t\ttrailing ? { trailing } : { leading: true },\n\t\t\t);\n\n\t\t\tdebounceCache.value.set(fn, debouncedFn);\n\t\t}\n\n\t\treturn debouncedFn;\n\t};\n\n\tconst callDebounced = <T extends AnyFunction>(\n\t\tfn: T,\n\t\toptions: DebounceOptions,\n\t\t...inputParameters: Parameters<T>\n\t): ReturnType<T> | undefined => {\n\t\tconst debouncedFn = debounce(fn, options);\n\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return -- AnyFunction return is intentionally `any`\n\t\treturn debouncedFn(...inputParameters);\n\t};\n\n\treturn {\n\t\tdebounce,\n\t\tcallDebounced,\n\t};\n}\n"],"mappings":";;;;;;;;AAOA,SAAgB,gBAAgB,MAAsB;CACrD,MAAM,SAAS,eAAe,QAAQ,0BAA0B;CAChE,MAAM,aAAa,WAAW,OAAO,WAAW,OAAO,GAAG;AAC1D,QAAO,KAAK,MAAM,QAAQ,OAAO,MAAM,WAAW,GAAG,IAAI,YAAY;;AAYtE,SAAgB,cAAc;CAE7B,MAAM,gBAAgB,oBAAI,IAAI,SAAkD,CAAC;CAEjF,MAAM,YAAmC,IAAO,YAA+C;EAC9F,MAAM,EAAE,UAAU,iBAAiB;EAEnC,MAAM,wBAAwB,gBAAgB,aAAa;EAG3D,IAAI,cAAc,cAAc,MAAM,IAAI,GAAG;AAG7C,MAAI,gBAAgB,QAAW;AAC9B,iBAAc,eAEb,OAAO,GAAG,SAAwB;AAEjC,WAAO,GAAG,GAAG,KAAK;MAEnB,uBACA,WAAW,EAAE,UAAU,GAAG,EAAE,SAAS,MAAM,CAC3C;AAED,iBAAc,MAAM,IAAI,IAAI,YAAY;;AAGzC,SAAO;;CAGR,MAAM,iBACL,IACA,SACA,GAAG,oBAC4B;AAI/B,SAHoB,SAAS,IAAI,QAAQ,CAGtB,GAAG,gBAAgB;;AAGvC,QAAO;EACN;EACA;EACA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDeviceSupport.cjs","names":[],"sources":["../src/useDeviceSupport.ts"],"sourcesContent":["import { computed, ref } from 'vue';\n\nexport function useDeviceSupport() {\n\t/**\n\t * Check if the device is a touch device but exclude devices that have a fine pointer (mouse or track-pad)\n\t * - `fine` will check for an accurate pointing device. Examples include mice, touch-pads, and drawing styluses\n\t * - `coarse` will check for a pointing device of limited accuracy. Examples include touchscreens and motion-detection sensors\n\t * - `any-pointer` will check for the presence of any pointing device, if there are multiple of them\n\t */\n\tconst isTouchDevice = ref(\n\t\twindow.matchMedia('(any-pointer: coarse)').matches &&\n\t\t\t!window.matchMedia('(any-pointer: fine)').matches,\n\t);\n\tconst userAgent = ref(navigator.userAgent.toLowerCase());\n\n\tconst isIOs = ref(\n\t\tuserAgent.value.includes('iphone') ||\n\t\t\tuserAgent.value.includes('ipad') ||\n\t\t\tuserAgent.value.includes('ipod'),\n\t);\n\tconst isAndroidOs = ref(userAgent.value.includes('android'));\n\tconst isMacOs = ref(userAgent.value.includes('macintosh') || isIOs.value);\n\tconst isMobileDevice = ref(isIOs.value || isAndroidOs.value);\n\n\tconst controlKeyCode = ref(isMacOs.value ? 'Meta' : 'Control');\n\tconst controlKeyText = computed(() => (isMacOs.value ? '⌘' : 'Ctrl'));\n\n\tfunction isCtrlKeyPressed(e: MouseEvent | KeyboardEvent): boolean {\n\t\tif (isMacOs.value) {\n\t\t\treturn (e as KeyboardEvent).metaKey;\n\t\t}\n\t\treturn (e as KeyboardEvent).ctrlKey;\n\t}\n\n\treturn {\n\t\tuserAgent: userAgent.value,\n\t\tisTouchDevice: isTouchDevice.value,\n\t\tisAndroidOs: isAndroidOs.value,\n\t\tisIOs: isIOs.value,\n\t\tisMacOs: isMacOs.value,\n\t\tisMobileDevice: isMobileDevice.value,\n\t\tcontrolKeyCode: controlKeyCode.value,\n\t\tcontrolKeyText,\n\t\tisCtrlKeyPressed,\n\t};\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"useDeviceSupport.cjs","names":[],"sources":["../src/useDeviceSupport.ts"],"sourcesContent":["import { computed, ref } from 'vue';\n\nexport function useDeviceSupport() {\n\t/**\n\t * Check if the device is a touch device but exclude devices that have a fine pointer (mouse or track-pad)\n\t * - `fine` will check for an accurate pointing device. Examples include mice, touch-pads, and drawing styluses\n\t * - `coarse` will check for a pointing device of limited accuracy. Examples include touchscreens and motion-detection sensors\n\t * - `any-pointer` will check for the presence of any pointing device, if there are multiple of them\n\t */\n\tconst isTouchDevice = ref(\n\t\twindow.matchMedia('(any-pointer: coarse)').matches &&\n\t\t\t!window.matchMedia('(any-pointer: fine)').matches,\n\t);\n\tconst userAgent = ref(navigator.userAgent.toLowerCase());\n\n\tconst isIOs = ref(\n\t\tuserAgent.value.includes('iphone') ||\n\t\t\tuserAgent.value.includes('ipad') ||\n\t\t\tuserAgent.value.includes('ipod'),\n\t);\n\tconst isAndroidOs = ref(userAgent.value.includes('android'));\n\tconst isMacOs = ref(userAgent.value.includes('macintosh') || isIOs.value);\n\tconst isMobileDevice = ref(isIOs.value || isAndroidOs.value);\n\n\tconst controlKeyCode = ref(isMacOs.value ? 'Meta' : 'Control');\n\tconst controlKeyText = computed(() => (isMacOs.value ? '⌘' : 'Ctrl'));\n\n\tfunction isCtrlKeyPressed(e: MouseEvent | KeyboardEvent): boolean {\n\t\tif (isMacOs.value) {\n\t\t\treturn (e as KeyboardEvent).metaKey;\n\t\t}\n\t\treturn (e as KeyboardEvent).ctrlKey;\n\t}\n\n\treturn {\n\t\tuserAgent: userAgent.value,\n\t\tisTouchDevice: isTouchDevice.value,\n\t\tisAndroidOs: isAndroidOs.value,\n\t\tisIOs: isIOs.value,\n\t\tisMacOs: isMacOs.value,\n\t\tisMobileDevice: isMobileDevice.value,\n\t\tcontrolKeyCode: controlKeyCode.value,\n\t\tcontrolKeyText,\n\t\tisCtrlKeyPressed,\n\t};\n}\n"],"mappings":";;;;AAEA,SAAgB,mBAAmB;;;;;;;CAOlC,MAAM,6BACL,OAAO,WAAW,wBAAwB,CAAC,WAC1C,CAAC,OAAO,WAAW,sBAAsB,CAAC,QAC3C;CACD,MAAM,yBAAgB,UAAU,UAAU,aAAa,CAAC;CAExD,MAAM,qBACL,UAAU,MAAM,SAAS,SAAS,IACjC,UAAU,MAAM,SAAS,OAAO,IAChC,UAAU,MAAM,SAAS,OAAO,CACjC;CACD,MAAM,2BAAkB,UAAU,MAAM,SAAS,UAAU,CAAC;CAC5D,MAAM,uBAAc,UAAU,MAAM,SAAS,YAAY,IAAI,MAAM,MAAM;CACzE,MAAM,8BAAqB,MAAM,SAAS,YAAY,MAAM;CAE5D,MAAM,8BAAqB,QAAQ,QAAQ,SAAS,UAAU;CAC9D,MAAM,yCAAiC,QAAQ,QAAQ,MAAM,OAAQ;CAErE,SAAS,iBAAiB,GAAwC;AACjE,MAAI,QAAQ,MACX,QAAQ,EAAoB;AAE7B,SAAQ,EAAoB;;AAG7B,QAAO;EACN,WAAW,UAAU;EACrB,eAAe,cAAc;EAC7B,aAAa,YAAY;EACzB,OAAO,MAAM;EACb,SAAS,QAAQ;EACjB,gBAAgB,eAAe;EAC/B,gBAAgB,eAAe;EAC/B;EACA;EACA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as vue3 from "vue";
|
|
2
2
|
|
|
3
3
|
//#region src/useDeviceSupport.d.ts
|
|
4
4
|
declare function useDeviceSupport(): {
|
|
@@ -9,7 +9,7 @@ declare function useDeviceSupport(): {
|
|
|
9
9
|
isMacOs: boolean;
|
|
10
10
|
isMobileDevice: boolean;
|
|
11
11
|
controlKeyCode: string;
|
|
12
|
-
controlKeyText:
|
|
12
|
+
controlKeyText: vue3.ComputedRef<"⌘" | "Ctrl">;
|
|
13
13
|
isCtrlKeyPressed: (e: MouseEvent | KeyboardEvent) => boolean;
|
|
14
14
|
};
|
|
15
15
|
//#endregion
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as vue3 from "vue";
|
|
2
2
|
|
|
3
3
|
//#region src/useDeviceSupport.d.ts
|
|
4
4
|
declare function useDeviceSupport(): {
|
|
@@ -9,7 +9,7 @@ declare function useDeviceSupport(): {
|
|
|
9
9
|
isMacOs: boolean;
|
|
10
10
|
isMobileDevice: boolean;
|
|
11
11
|
controlKeyCode: string;
|
|
12
|
-
controlKeyText:
|
|
12
|
+
controlKeyText: vue3.ComputedRef<"⌘" | "Ctrl">;
|
|
13
13
|
isCtrlKeyPressed: (e: MouseEvent | KeyboardEvent) => boolean;
|
|
14
14
|
};
|
|
15
15
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDocumentTitle.cjs","names":[],"sources":["../src/useDocumentTitle.ts"],"sourcesContent":["import { ref, type Ref } from 'vue';\n\nconst DEFAULT_TITLE = 'n8n';\nconst DEFAULT_TAGLINE = 'Workflow Automation';\n\nexport type WorkflowTitleStatus =\n\t| 'EXECUTING'\n\t| 'IDLE'\n\t| 'ERROR'\n\t| 'DEBUG'\n\t| 'AI_BUILDING'\n\t| 'AI_DONE';\n\nexport interface UseDocumentTitleOptions {\n\t/**\n\t * The release channel (e.g., 'stable', 'beta', 'dev').\n\t * If not provided or 'stable', the title will be 'n8n'.\n\t * Otherwise, it will be 'n8n[CHANNEL]'.\n\t */\n\treleaseChannel?: string;\n\t/**\n\t * Optional window reference for setting the document title.\n\t * Useful for pop-out windows.\n\t */\n\twindowRef?: Ref<Window | undefined>;\n}\n\nexport function useDocumentTitle(options: UseDocumentTitleOptions = {}) {\n\tconst { releaseChannel, windowRef } = options;\n\tconst suffix =\n\t\t!releaseChannel || releaseChannel === 'stable'\n\t\t\t? DEFAULT_TITLE\n\t\t\t: `${DEFAULT_TITLE}[${releaseChannel.toUpperCase()}]`;\n\n\tconst currentState = ref<WorkflowTitleStatus | undefined>(undefined);\n\n\tconst set = (title: string) => {\n\t\tconst sections = [title || DEFAULT_TAGLINE, suffix];\n\t\t(windowRef?.value?.document ?? document).title = sections.join(' - ');\n\t};\n\n\tconst reset = () => {\n\t\tcurrentState.value = undefined;\n\t\tset('');\n\t};\n\n\tconst setDocumentTitle = (workflowName: string, status: WorkflowTitleStatus) => {\n\t\tcurrentState.value = status;\n\t\tlet prefix = '⚠️';\n\t\tif (status === 'EXECUTING') {\n\t\t\tprefix = '🔄';\n\t\t} else if (status === 'IDLE') {\n\t\t\tprefix = '▶️';\n\t\t} else if (status === 'AI_BUILDING') {\n\t\t\tprefix = '[Building]';\n\t\t} else if (status === 'AI_DONE') {\n\t\t\tprefix = '[Done]';\n\t\t}\n\t\tset(`${prefix} ${workflowName}`);\n\t};\n\n\tconst getDocumentState = () => currentState.value;\n\n\treturn { set, reset, setDocumentTitle, getDocumentState };\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"useDocumentTitle.cjs","names":[],"sources":["../src/useDocumentTitle.ts"],"sourcesContent":["import { ref, type Ref } from 'vue';\n\nconst DEFAULT_TITLE = 'n8n';\nconst DEFAULT_TAGLINE = 'Workflow Automation';\n\nexport type WorkflowTitleStatus =\n\t| 'EXECUTING'\n\t| 'IDLE'\n\t| 'ERROR'\n\t| 'DEBUG'\n\t| 'AI_BUILDING'\n\t| 'AI_DONE';\n\nexport interface UseDocumentTitleOptions {\n\t/**\n\t * The release channel (e.g., 'stable', 'beta', 'dev').\n\t * If not provided or 'stable', the title will be 'n8n'.\n\t * Otherwise, it will be 'n8n[CHANNEL]'.\n\t */\n\treleaseChannel?: string;\n\t/**\n\t * Optional window reference for setting the document title.\n\t * Useful for pop-out windows.\n\t */\n\twindowRef?: Ref<Window | undefined>;\n}\n\nexport function useDocumentTitle(options: UseDocumentTitleOptions = {}) {\n\tconst { releaseChannel, windowRef } = options;\n\tconst suffix =\n\t\t!releaseChannel || releaseChannel === 'stable'\n\t\t\t? DEFAULT_TITLE\n\t\t\t: `${DEFAULT_TITLE}[${releaseChannel.toUpperCase()}]`;\n\n\tconst currentState = ref<WorkflowTitleStatus | undefined>(undefined);\n\n\tconst set = (title: string) => {\n\t\tconst sections = [title || DEFAULT_TAGLINE, suffix];\n\t\t(windowRef?.value?.document ?? document).title = sections.join(' - ');\n\t};\n\n\tconst reset = () => {\n\t\tcurrentState.value = undefined;\n\t\tset('');\n\t};\n\n\tconst setDocumentTitle = (workflowName: string, status: WorkflowTitleStatus) => {\n\t\tcurrentState.value = status;\n\t\tlet prefix = '⚠️';\n\t\tif (status === 'EXECUTING') {\n\t\t\tprefix = '🔄';\n\t\t} else if (status === 'IDLE') {\n\t\t\tprefix = '▶️';\n\t\t} else if (status === 'AI_BUILDING') {\n\t\t\tprefix = '[Building]';\n\t\t} else if (status === 'AI_DONE') {\n\t\t\tprefix = '[Done]';\n\t\t}\n\t\tset(`${prefix} ${workflowName}`);\n\t};\n\n\tconst getDocumentState = () => currentState.value;\n\n\treturn { set, reset, setDocumentTitle, getDocumentState };\n}\n"],"mappings":";;;;AAEA,MAAM,gBAAgB;AACtB,MAAM,kBAAkB;AAwBxB,SAAgB,iBAAiB,UAAmC,EAAE,EAAE;CACvE,MAAM,EAAE,gBAAgB,cAAc;CACtC,MAAM,SACL,CAAC,kBAAkB,mBAAmB,WACnC,gBACA,GAAG,cAAc,GAAG,eAAe,aAAa,CAAC;CAErD,MAAM,4BAAoD,OAAU;CAEpE,MAAM,OAAO,UAAkB;EAC9B,MAAM,WAAW,CAAC,SAAS,iBAAiB,OAAO;AACnD,GAAC,WAAW,OAAO,YAAY,UAAU,QAAQ,SAAS,KAAK,MAAM;;CAGtE,MAAM,cAAc;AACnB,eAAa,QAAQ;AACrB,MAAI,GAAG;;CAGR,MAAM,oBAAoB,cAAsB,WAAgC;AAC/E,eAAa,QAAQ;EACrB,IAAI,SAAS;AACb,MAAI,WAAW,YACd,UAAS;WACC,WAAW,OACrB,UAAS;WACC,WAAW,cACrB,UAAS;WACC,WAAW,UACrB,UAAS;AAEV,MAAI,GAAG,OAAO,GAAG,eAAe;;CAGjC,MAAM,yBAAyB,aAAa;AAE5C,QAAO;EAAE;EAAK;EAAO;EAAkB;EAAkB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useShortKeyPress.cjs","names":[],"sources":["../src/useShortKeyPress.ts"],"sourcesContent":["import { onKeyDown, onKeyUp } from '@vueuse/core';\nimport type { KeyFilter } from '@vueuse/core';\nimport { ref, unref } from 'vue';\nimport type { MaybeRefOrGetter } from 'vue';\n\nexport function useShortKeyPress(\n\tkey: KeyFilter,\n\tfn: () => void,\n\t{\n\t\tdedupe = true,\n\t\tthreshold = 300,\n\t\tdisabled = false,\n\t}: {\n\t\tdedupe?: boolean;\n\t\tthreshold?: number;\n\t\tdisabled?: MaybeRefOrGetter<boolean>;\n\t},\n) {\n\tconst keyDownTime = ref<number | null>(null);\n\n\tonKeyDown(\n\t\tkey,\n\t\t() => {\n\t\t\tif (unref(disabled)) return;\n\n\t\t\tkeyDownTime.value = Date.now();\n\t\t},\n\t\t{\n\t\t\tdedupe,\n\t\t},\n\t);\n\n\tonKeyUp(key, () => {\n\t\tif (unref(disabled) || !keyDownTime.value) return;\n\n\t\tconst isShortPress = Date.now() - keyDownTime.value < threshold;\n\t\tif (isShortPress) {\n\t\t\tfn();\n\t\t}\n\t});\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"useShortKeyPress.cjs","names":[],"sources":["../src/useShortKeyPress.ts"],"sourcesContent":["import { onKeyDown, onKeyUp } from '@vueuse/core';\nimport type { KeyFilter } from '@vueuse/core';\nimport { ref, unref } from 'vue';\nimport type { MaybeRefOrGetter } from 'vue';\n\nexport function useShortKeyPress(\n\tkey: KeyFilter,\n\tfn: () => void,\n\t{\n\t\tdedupe = true,\n\t\tthreshold = 300,\n\t\tdisabled = false,\n\t}: {\n\t\tdedupe?: boolean;\n\t\tthreshold?: number;\n\t\tdisabled?: MaybeRefOrGetter<boolean>;\n\t},\n) {\n\tconst keyDownTime = ref<number | null>(null);\n\n\tonKeyDown(\n\t\tkey,\n\t\t() => {\n\t\t\tif (unref(disabled)) return;\n\n\t\t\tkeyDownTime.value = Date.now();\n\t\t},\n\t\t{\n\t\t\tdedupe,\n\t\t},\n\t);\n\n\tonKeyUp(key, () => {\n\t\tif (unref(disabled) || !keyDownTime.value) return;\n\n\t\tconst isShortPress = Date.now() - keyDownTime.value < threshold;\n\t\tif (isShortPress) {\n\t\t\tfn();\n\t\t}\n\t});\n}\n"],"mappings":";;;;;AAKA,SAAgB,iBACf,KACA,IACA,EACC,SAAS,MACT,YAAY,KACZ,WAAW,SAMX;CACD,MAAM,2BAAiC,KAAK;AAE5C,8BACC,WACM;AACL,qBAAU,SAAS,CAAE;AAErB,cAAY,QAAQ,KAAK,KAAK;IAE/B,EACC,QACA,CACD;AAED,4BAAQ,WAAW;AAClB,qBAAU,SAAS,IAAI,CAAC,YAAY,MAAO;AAG3C,MADqB,KAAK,KAAK,GAAG,YAAY,QAAQ,UAErD,KAAI;GAEJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useThrottleWithReactiveDelay.cjs","names":[],"sources":["../src/useThrottleWithReactiveDelay.ts"],"sourcesContent":["import { useThrottleFn } from '@vueuse/core';\nimport { shallowRef, watch, type Ref, type ShallowRef } from 'vue';\n\n/**\n * Similar to `useThrottle` from @vueuse/core, but with changeable delay\n */\nexport function useThrottleWithReactiveDelay<T>(state: Ref<T>, delay: Ref<number>): ShallowRef<T> {\n\tconst throttled = shallowRef(state.value);\n\n\twatch(\n\t\tstate,\n\t\tuseThrottleFn(\n\t\t\t(latest: T) => {\n\t\t\t\tthrottled.value = latest;\n\t\t\t},\n\t\t\tdelay,\n\t\t\ttrue,\n\t\t\ttrue,\n\t\t),\n\t\t{ immediate: true },\n\t);\n\n\treturn throttled;\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"useThrottleWithReactiveDelay.cjs","names":[],"sources":["../src/useThrottleWithReactiveDelay.ts"],"sourcesContent":["import { useThrottleFn } from '@vueuse/core';\nimport { shallowRef, watch, type Ref, type ShallowRef } from 'vue';\n\n/**\n * Similar to `useThrottle` from @vueuse/core, but with changeable delay\n */\nexport function useThrottleWithReactiveDelay<T>(state: Ref<T>, delay: Ref<number>): ShallowRef<T> {\n\tconst throttled = shallowRef(state.value);\n\n\twatch(\n\t\tstate,\n\t\tuseThrottleFn(\n\t\t\t(latest: T) => {\n\t\t\t\tthrottled.value = latest;\n\t\t\t},\n\t\t\tdelay,\n\t\t\ttrue,\n\t\t\ttrue,\n\t\t),\n\t\t{ immediate: true },\n\t);\n\n\treturn throttled;\n}\n"],"mappings":";;;;;;;;AAMA,SAAgB,6BAAgC,OAAe,OAAmC;CACjG,MAAM,gCAAuB,MAAM,MAAM;AAEzC,gBACC,yCAEE,WAAc;AACd,YAAU,QAAQ;IAEnB,OACA,MACA,KACA,EACD,EAAE,WAAW,MAAM,CACnB;AAED,QAAO"}
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@n8n/composables",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.22.0",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
7
|
-
"
|
|
8
|
-
"
|
|
7
|
+
"LICENSE_EE.md",
|
|
8
|
+
"LICENSE.md"
|
|
9
9
|
],
|
|
10
10
|
"exports": {
|
|
11
11
|
"./*": {
|
|
@@ -15,13 +15,15 @@
|
|
|
15
15
|
}
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@vueuse/core": "^
|
|
18
|
+
"@vueuse/core": "^14.3.0",
|
|
19
|
+
"lodash": "4.18.1",
|
|
19
20
|
"vue": "^3.5.13"
|
|
20
21
|
},
|
|
21
22
|
"devDependencies": {
|
|
22
23
|
"@testing-library/vue": "^8.1.0",
|
|
23
24
|
"@testing-library/jest-dom": "^6.6.3",
|
|
24
25
|
"@testing-library/user-event": "^14.6.1",
|
|
26
|
+
"@types/lodash": "4.17.17",
|
|
25
27
|
"@vitejs/plugin-vue": "^5.2.4",
|
|
26
28
|
"@vue/tsconfig": "^0.7.0",
|
|
27
29
|
"tsdown": "^0.16.5",
|
|
@@ -29,10 +31,10 @@
|
|
|
29
31
|
"vite": "^8.0.2",
|
|
30
32
|
"vitest": "^4.1.9",
|
|
31
33
|
"vue-tsc": "^2.2.8",
|
|
32
|
-
"@n8n/eslint-config": "0.0.1",
|
|
33
34
|
"@n8n/playwright-janitor": "0.1.0",
|
|
35
|
+
"@n8n/eslint-config": "0.0.1",
|
|
34
36
|
"@n8n/typescript-config": "1.9.0",
|
|
35
|
-
"@n8n/vitest-config": "1.
|
|
37
|
+
"@n8n/vitest-config": "1.19.0"
|
|
36
38
|
},
|
|
37
39
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
38
40
|
"homepage": "https://n8n.io",
|