@simplysm/core-browser 13.0.0-beta.6 → 13.0.1
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/extensions/element-ext.d.ts.map +1 -0
- package/dist/extensions/element-ext.js.map +0 -1
- package/dist/extensions/html-element-ext.d.ts.map +1 -0
- package/dist/extensions/html-element-ext.js.map +0 -1
- package/dist/{core-browser/src/index.d.ts → index.d.ts} +2 -1
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -6
- package/dist/index.js.map +1 -2
- package/dist/utils/download.d.ts +8 -0
- package/dist/utils/download.d.ts.map +1 -0
- package/dist/utils/download.js +8 -40
- package/dist/utils/download.js.map +2 -3
- package/dist/{core-browser/src/utils/download.d.ts → utils/fetch.d.ts} +2 -2
- package/dist/utils/fetch.d.ts.map +1 -0
- package/dist/utils/fetch.js +47 -0
- package/dist/utils/fetch.js.map +6 -0
- package/dist/utils/file-dialog.d.ts +8 -0
- package/dist/utils/file-dialog.d.ts.map +1 -0
- package/dist/utils/file-dialog.js +18 -0
- package/dist/utils/file-dialog.js.map +6 -0
- package/package.json +9 -5
- package/src/index.ts +2 -1
- package/src/utils/download.ts +11 -60
- package/src/utils/fetch.ts +66 -0
- package/src/utils/file-dialog.ts +17 -0
- package/.cache/typecheck-browser.tsbuildinfo +0 -1
- package/.cache/typecheck-tests-browser.tsbuildinfo +0 -1
- package/dist/core-browser/src/extensions/element-ext.d.ts.map +0 -1
- package/dist/core-browser/src/extensions/html-element-ext.d.ts.map +0 -1
- package/dist/core-browser/src/index.d.ts.map +0 -1
- package/dist/core-browser/src/utils/blob.d.ts +0 -10
- package/dist/core-browser/src/utils/blob.d.ts.map +0 -1
- package/dist/core-browser/src/utils/download.d.ts.map +0 -1
- package/dist/core-common/src/common.types.d.ts +0 -74
- package/dist/core-common/src/common.types.d.ts.map +0 -1
- package/dist/core-common/src/env.d.ts +0 -6
- package/dist/core-common/src/env.d.ts.map +0 -1
- package/dist/core-common/src/errors/argument-error.d.ts +0 -25
- package/dist/core-common/src/errors/argument-error.d.ts.map +0 -1
- package/dist/core-common/src/errors/not-implemented-error.d.ts +0 -29
- package/dist/core-common/src/errors/not-implemented-error.d.ts.map +0 -1
- package/dist/core-common/src/errors/sd-error.d.ts +0 -27
- package/dist/core-common/src/errors/sd-error.d.ts.map +0 -1
- package/dist/core-common/src/errors/timeout-error.d.ts +0 -31
- package/dist/core-common/src/errors/timeout-error.d.ts.map +0 -1
- package/dist/core-common/src/extensions/arr-ext.d.ts +0 -15
- package/dist/core-common/src/extensions/arr-ext.d.ts.map +0 -1
- package/dist/core-common/src/extensions/arr-ext.helpers.d.ts +0 -19
- package/dist/core-common/src/extensions/arr-ext.helpers.d.ts.map +0 -1
- package/dist/core-common/src/extensions/arr-ext.types.d.ts +0 -215
- package/dist/core-common/src/extensions/arr-ext.types.d.ts.map +0 -1
- package/dist/core-common/src/extensions/map-ext.d.ts +0 -57
- package/dist/core-common/src/extensions/map-ext.d.ts.map +0 -1
- package/dist/core-common/src/extensions/set-ext.d.ts +0 -36
- package/dist/core-common/src/extensions/set-ext.d.ts.map +0 -1
- package/dist/core-common/src/features/debounce-queue.d.ts +0 -53
- package/dist/core-common/src/features/debounce-queue.d.ts.map +0 -1
- package/dist/core-common/src/features/event-emitter.d.ts +0 -66
- package/dist/core-common/src/features/event-emitter.d.ts.map +0 -1
- package/dist/core-common/src/features/serial-queue.d.ts +0 -47
- package/dist/core-common/src/features/serial-queue.d.ts.map +0 -1
- package/dist/core-common/src/index.d.ts +0 -32
- package/dist/core-common/src/index.d.ts.map +0 -1
- package/dist/core-common/src/types/date-only.d.ts +0 -152
- package/dist/core-common/src/types/date-only.d.ts.map +0 -1
- package/dist/core-common/src/types/date-time.d.ts +0 -96
- package/dist/core-common/src/types/date-time.d.ts.map +0 -1
- package/dist/core-common/src/types/lazy-gc-map.d.ts +0 -80
- package/dist/core-common/src/types/lazy-gc-map.d.ts.map +0 -1
- package/dist/core-common/src/types/time.d.ts +0 -68
- package/dist/core-common/src/types/time.d.ts.map +0 -1
- package/dist/core-common/src/types/uuid.d.ts +0 -35
- package/dist/core-common/src/types/uuid.d.ts.map +0 -1
- package/dist/core-common/src/utils/bytes.d.ts +0 -51
- package/dist/core-common/src/utils/bytes.d.ts.map +0 -1
- package/dist/core-common/src/utils/date-format.d.ts +0 -90
- package/dist/core-common/src/utils/date-format.d.ts.map +0 -1
- package/dist/core-common/src/utils/json.d.ts +0 -34
- package/dist/core-common/src/utils/json.d.ts.map +0 -1
- package/dist/core-common/src/utils/num.d.ts +0 -60
- package/dist/core-common/src/utils/num.d.ts.map +0 -1
- package/dist/core-common/src/utils/obj.d.ts +0 -258
- package/dist/core-common/src/utils/obj.d.ts.map +0 -1
- package/dist/core-common/src/utils/path.d.ts +0 -23
- package/dist/core-common/src/utils/path.d.ts.map +0 -1
- package/dist/core-common/src/utils/primitive.d.ts +0 -18
- package/dist/core-common/src/utils/primitive.d.ts.map +0 -1
- package/dist/core-common/src/utils/str.d.ts +0 -103
- package/dist/core-common/src/utils/str.d.ts.map +0 -1
- package/dist/core-common/src/utils/template-strings.d.ts +0 -84
- package/dist/core-common/src/utils/template-strings.d.ts.map +0 -1
- package/dist/core-common/src/utils/transferable.d.ts +0 -47
- package/dist/core-common/src/utils/transferable.d.ts.map +0 -1
- package/dist/core-common/src/utils/wait.d.ts +0 -19
- package/dist/core-common/src/utils/wait.d.ts.map +0 -1
- package/dist/core-common/src/utils/xml.d.ts +0 -36
- package/dist/core-common/src/utils/xml.d.ts.map +0 -1
- package/dist/core-common/src/zip/sd-zip.d.ts +0 -80
- package/dist/core-common/src/zip/sd-zip.d.ts.map +0 -1
- package/dist/utils/blob.js +0 -19
- package/dist/utils/blob.js.map +0 -7
- package/src/utils/blob.ts +0 -19
- package/tests/extensions/element-ext.spec.ts +0 -729
- package/tests/extensions/html-element-ext.spec.ts +0 -190
- package/tests/utils/blob.spec.ts +0 -68
- /package/dist/{core-browser/src/extensions → extensions}/element-ext.d.ts +0 -0
- /package/dist/{core-browser/src/extensions → extensions}/html-element-ext.d.ts +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"element-ext.d.ts","sourceRoot":"","sources":["../../src/extensions/element-ext.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,eAAe;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,mBAAmB;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,YAAY;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,OAAO;QACf;;;;;WAKG;QACH,OAAO,CAAC,CAAC,SAAS,OAAO,GAAG,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC;QAE5D;;;;;WAKG;QACH,SAAS,CAAC,CAAC,SAAS,OAAO,GAAG,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS,CAAC;QAExE;;;;;WAKG;QACH,YAAY,CAAC,CAAC,SAAS,OAAO,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC;QAE7C;;;;WAIG;QACH,UAAU,IAAI,OAAO,EAAE,CAAC;QAExB;;;;WAIG;QACH,mBAAmB,IAAI,WAAW,GAAG,SAAS,CAAC;QAE/C;;;;WAIG;QACH,uBAAuB,IAAI,WAAW,GAAG,SAAS,CAAC;QAEnD;;;;WAIG;QACH,eAAe,IAAI,OAAO,CAAC;QAE3B;;;;;;;WAOG;QACH,SAAS,IAAI,OAAO,CAAC;KACtB;CACF;AAgED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAUvD;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAa1D;AAED;;;;;;GAMG;AACH,wBAAsB,SAAS,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,OAAO,GAAE,MAAa,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAkDhG"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/extensions/element-ext.ts"],
|
|
4
|
-
"sourcesContent": ["import { isFocusable } from \"tabbable\";\nimport { TimeoutError } from \"@simplysm/core-common\";\n\n/**\n * \uC694\uC18C bounds \uC815\uBCF4 \uD0C0\uC785\n */\nexport interface ElementBounds {\n /** \uCE21\uC815 \uB300\uC0C1 \uC694\uC18C */\n target: Element;\n /** \uBDF0\uD3EC\uD2B8 \uAE30\uC900 \uC0C1\uB2E8 \uC704\uCE58 */\n top: number;\n /** \uBDF0\uD3EC\uD2B8 \uAE30\uC900 \uC67C\uCABD \uC704\uCE58 */\n left: number;\n /** \uC694\uC18C \uB108\uBE44 */\n width: number;\n /** \uC694\uC18C \uB192\uC774 */\n height: number;\n}\n\ndeclare global {\n interface Element {\n /**\n * \uC140\uB809\uD130\uB85C \uD558\uC704 \uC694\uC18C \uC804\uCCB4 \uAC80\uC0C9\n *\n * @param selector - CSS \uC140\uB809\uD130\n * @returns \uB9E4\uCE6D\uB41C \uC694\uC18C \uBC30\uC5F4 (\uBE48 \uC140\uB809\uD130\uB294 \uBE48 \uBC30\uC5F4 \uBC18\uD658)\n */\n findAll<T extends Element = Element>(selector: string): T[];\n\n /**\n * \uC140\uB809\uD130\uB85C \uCCAB \uBC88\uC9F8 \uB9E4\uCE6D \uC694\uC18C \uAC80\uC0C9\n *\n * @param selector - CSS \uC140\uB809\uD130\n * @returns \uCCAB \uBC88\uC9F8 \uB9E4\uCE6D \uC694\uC18C \uB610\uB294 undefined (\uBE48 \uC140\uB809\uD130\uB294 undefined \uBC18\uD658)\n */\n findFirst<T extends Element = Element>(selector: string): T | undefined;\n\n /**\n * \uC694\uC18C\uB97C \uCCAB \uBC88\uC9F8 \uC790\uC2DD\uC73C\uB85C \uC0BD\uC785\n *\n * @param child - \uC0BD\uC785\uD560 \uC790\uC2DD \uC694\uC18C\n * @returns \uC0BD\uC785\uB41C \uC790\uC2DD \uC694\uC18C\n */\n prependChild<T extends Element>(child: T): T;\n\n /**\n * \uBAA8\uB4E0 \uBD80\uBAA8 \uC694\uC18C \uBAA9\uB85D \uBC18\uD658 (\uAC00\uAE4C\uC6B4 \uC21C\uC11C)\n *\n * @returns \uBD80\uBAA8 \uC694\uC18C \uBC30\uC5F4 (\uAC00\uAE4C\uC6B4 \uBD80\uBAA8\uBD80\uD130 \uC21C\uC11C\uB300\uB85C)\n */\n getParents(): Element[];\n\n /**\n * \uBD80\uBAA8 \uC911 \uCCAB \uBC88\uC9F8 \uD3EC\uCEE4\uC2A4 \uAC00\uB2A5 \uC694\uC18C \uAC80\uC0C9 (tabbable \uC0AC\uC6A9)\n *\n * @returns \uD3EC\uCEE4\uC2A4 \uAC00\uB2A5\uD55C \uCCAB \uBC88\uC9F8 \uBD80\uBAA8 \uC694\uC18C \uB610\uB294 undefined\n */\n findFocusableParent(): HTMLElement | undefined;\n\n /**\n * \uC790\uC2DD \uC911 \uCCAB \uBC88\uC9F8 \uD3EC\uCEE4\uC2A4 \uAC00\uB2A5 \uC694\uC18C \uAC80\uC0C9 (tabbable \uC0AC\uC6A9)\n *\n * @returns \uD3EC\uCEE4\uC2A4 \uAC00\uB2A5\uD55C \uCCAB \uBC88\uC9F8 \uC790\uC2DD \uC694\uC18C \uB610\uB294 undefined\n */\n findFirstFocusableChild(): HTMLElement | undefined;\n\n /**\n * \uC694\uC18C\uAC00 offset \uAE30\uC900 \uC694\uC18C\uC778\uC9C0 \uD655\uC778 (position: relative/absolute/fixed/sticky)\n *\n * @returns position \uC18D\uC131\uC774 relative, absolute, fixed, sticky \uC911 \uD558\uB098\uBA74 true\n */\n isOffsetElement(): boolean;\n\n /**\n * \uC694\uC18C\uAC00 \uD654\uBA74\uC5D0 \uBCF4\uC774\uB294\uC9C0 \uD655\uC778\n *\n * @remarks\n * clientRects \uC874\uC7AC \uC5EC\uBD80, visibility: hidden, opacity: 0 \uC5EC\uBD80\uB97C \uD655\uC778\uD55C\uB2E4.\n *\n * @returns \uC694\uC18C\uAC00 \uD654\uBA74\uC5D0 \uBCF4\uC774\uBA74 true\n */\n isVisible(): boolean;\n }\n}\n\nElement.prototype.findAll = function <T extends Element = Element>(selector: string): T[] {\n const trimmed = selector.trim();\n if (trimmed === \"\") return [];\n return Array.from(this.querySelectorAll<T>(trimmed));\n};\n\nElement.prototype.findFirst = function <T extends Element = Element>(selector: string): T | undefined {\n const trimmed = selector.trim();\n if (trimmed === \"\") return undefined;\n return this.querySelector<T>(trimmed) ?? undefined;\n};\n\nElement.prototype.prependChild = function <T extends Element>(child: T): T {\n return this.insertBefore(child, this.firstElementChild);\n};\n\nElement.prototype.getParents = function (): Element[] {\n const result: Element[] = [];\n let cursor = this.parentNode;\n while (cursor !== null && cursor instanceof Element) {\n result.push(cursor);\n cursor = cursor.parentNode;\n }\n return result;\n};\n\nElement.prototype.findFocusableParent = function (): HTMLElement | undefined {\n let parentEl = this.parentElement;\n while (parentEl !== null) {\n if (isFocusable(parentEl)) {\n return parentEl;\n }\n parentEl = parentEl.parentElement;\n }\n return undefined;\n};\n\nElement.prototype.findFirstFocusableChild = function (): HTMLElement | undefined {\n const walker = document.createTreeWalker(this, NodeFilter.SHOW_ELEMENT);\n let node = walker.nextNode();\n while (node !== null) {\n if (node instanceof HTMLElement && isFocusable(node)) {\n return node;\n }\n node = walker.nextNode();\n }\n return undefined;\n};\n\nElement.prototype.isOffsetElement = function (): boolean {\n return [\"relative\", \"absolute\", \"fixed\", \"sticky\"].includes(getComputedStyle(this).position);\n};\n\nElement.prototype.isVisible = function (): boolean {\n const style = getComputedStyle(this);\n return this.getClientRects().length > 0 && style.visibility !== \"hidden\" && style.opacity !== \"0\";\n};\n\n// ============================================================================\n// \uC815\uC801 \uD568\uC218 (\uC774\uBCA4\uD2B8 \uD578\uB4E4\uB7EC\uC6A9 \uB610\uB294 \uC5EC\uB7EC \uC694\uC18C \uB300\uC0C1)\n// ============================================================================\n\n/**\n * \uC694\uC18C \uB0B4\uC6A9\uC744 \uD074\uB9BD\uBCF4\uB4DC\uC5D0 \uBCF5\uC0AC (copy \uC774\uBCA4\uD2B8 \uD578\uB4E4\uB7EC\uC5D0\uC11C \uC0AC\uC6A9)\n *\n * @param event - copy \uC774\uBCA4\uD2B8 \uAC1D\uCCB4\n */\nexport function copyElement(event: ClipboardEvent): void {\n const clipboardData = event.clipboardData;\n const target = event.target;\n if (clipboardData == null || !(target instanceof Element)) return;\n\n const firstInputEl = target.querySelector<HTMLInputElement | HTMLTextAreaElement>(\"input, textarea\");\n if (firstInputEl != null) {\n clipboardData.setData(\"text/plain\", firstInputEl.value);\n event.preventDefault();\n }\n}\n\n/**\n * \uD074\uB9BD\uBCF4\uB4DC \uB0B4\uC6A9\uC744 \uC694\uC18C\uC5D0 \uBD99\uC5EC\uB123\uAE30 (paste \uC774\uBCA4\uD2B8 \uD578\uB4E4\uB7EC\uC5D0\uC11C \uC0AC\uC6A9)\n *\n * @remarks\n * \uB300\uC0C1 \uC694\uC18C \uB0B4\uC758 \uCCAB \uBC88\uC9F8 input/textarea\uB97C \uCC3E\uC544 \uC804\uCCB4 \uAC12\uC744 \uD074\uB9BD\uBCF4\uB4DC \uB0B4\uC6A9\uC73C\uB85C \uAD50\uCCB4\uD55C\uB2E4.\n * \uCEE4\uC11C \uC704\uCE58\uB098 \uC120\uD0DD \uC601\uC5ED\uC744 \uACE0\uB824\uD558\uC9C0 \uC54A\uB294\uB2E4.\n *\n * @param event - paste \uC774\uBCA4\uD2B8 \uAC1D\uCCB4\n */\nexport function pasteToElement(event: ClipboardEvent): void {\n const clipboardData = event.clipboardData;\n const target = event.target;\n if (clipboardData == null || !(target instanceof Element)) return;\n\n const contentText = clipboardData.getData(\"text/plain\");\n\n const firstInputEl = target.findFirst<HTMLInputElement | HTMLTextAreaElement>(\"input, textarea\");\n if (firstInputEl !== undefined) {\n firstInputEl.value = contentText;\n firstInputEl.dispatchEvent(new Event(\"input\", { bubbles: true }));\n event.preventDefault();\n }\n}\n\n/**\n * IntersectionObserver\uB97C \uC0AC\uC6A9\uD558\uC5EC \uC694\uC18C\uB4E4\uC758 bounds \uC815\uBCF4 \uC870\uD68C\n *\n * @param els - \uB300\uC0C1 \uC694\uC18C \uBC30\uC5F4\n * @param timeout - \uD0C0\uC784\uC544\uC6C3 (\uBC00\uB9AC\uCD08, \uAE30\uBCF8: 5000)\n * @throws {TimeoutError} \uD0C0\uC784\uC544\uC6C3 \uC2DC\uAC04 \uB0B4\uC5D0 \uC751\uB2F5\uC774 \uC5C6\uC744 \uACBD\uC6B0\n */\nexport async function getBounds(els: Element[], timeout: number = 5000): Promise<ElementBounds[]> {\n // \uC911\uBCF5 \uC81C\uAC70 \uBC0F \uC785\uB825 \uC21C\uC11C\uB300\uB85C \uACB0\uACFC\uB97C \uC815\uB82C\uD558\uAE30 \uC704\uD55C \uC778\uB371\uC2A4 \uB9F5\n const indexMap = new Map(els.map((el, i) => [el, i] as const));\n if (indexMap.size === 0) {\n return [];\n }\n\n // \uC815\uB82C \uC131\uB2A5 \uCD5C\uC801\uD654\uB97C \uC704\uD55C \uC778\uB371\uC2A4 \uB9F5\n const sortIndexMap = new Map(els.map((el, i) => [el, i] as const));\n\n let observer: IntersectionObserver | undefined;\n\n try {\n return await Promise.race([\n new Promise<ElementBounds[]>((resolve) => {\n const results: ElementBounds[] = [];\n\n observer = new IntersectionObserver((entries) => {\n for (const entry of entries) {\n const target = entry.target;\n if (indexMap.has(target)) {\n indexMap.delete(target);\n results.push({\n target,\n top: entry.boundingClientRect.top,\n left: entry.boundingClientRect.left,\n width: entry.boundingClientRect.width,\n height: entry.boundingClientRect.height,\n });\n }\n }\n\n if (indexMap.size === 0) {\n observer?.disconnect();\n // \uC785\uB825 \uC21C\uC11C\uB300\uB85C \uC815\uB82C\n resolve(results.sort((a, b) => sortIndexMap.get(a.target)! - sortIndexMap.get(b.target)!));\n }\n });\n\n for (const el of indexMap.keys()) {\n observer.observe(el);\n }\n }),\n new Promise<ElementBounds[]>((_, reject) =>\n setTimeout(() => reject(new TimeoutError(undefined, `${timeout}ms \uCD08\uACFC`)), timeout),\n ),\n ]);\n } finally {\n observer?.disconnect();\n }\n}\n"],
|
|
5
4
|
"mappings": "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",
|
|
6
5
|
"names": []
|
|
7
6
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html-element-ext.d.ts","sourceRoot":"","sources":["../../src/extensions/html-element-ext.ts"],"names":[],"mappings":"AAEA,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,WAAW;QACnB;;WAEG;QACH,OAAO,IAAI,IAAI,CAAC;QAEhB;;;;;;;;;;;;;;;;;;;;;WAqBG;QACH,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,GAAG;YAAE,GAAG,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC;QAE/E;;;;;;;;;;WAUG;QACH,sBAAsB,CAAC,MAAM,EAAE;YAAE,GAAG,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,EAAE,MAAM,CAAC,EAAE;YAAE,GAAG,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,GAAG,IAAI,CAAC;KAC7G;CACF"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/extensions/html-element-ext.ts"],
|
|
4
|
-
"sourcesContent": ["import { ArgumentError } from \"@simplysm/core-common\";\n\ndeclare global {\n interface HTMLElement {\n /**\n * \uAC15\uC81C \uB9AC\uD398\uC778\uD2B8 (reflow \uD2B8\uB9AC\uAC70)\n */\n repaint(): void;\n\n /**\n * \uBD80\uBAA8 \uC694\uC18C \uAE30\uC900 \uC0C1\uB300 \uC704\uCE58 \uACC4\uC0B0 (CSS \uD3EC\uC9C0\uC154\uB2DD\uC6A9)\n *\n * @remarks\n * \uC774 \uD568\uC218\uB294 \uC694\uC18C\uC758 \uC704\uCE58\uB97C \uBD80\uBAA8 \uC694\uC18C \uAE30\uC900\uC73C\uB85C \uACC4\uC0B0\uD558\uB418, `window.scrollX/Y`\uB97C \uD3EC\uD568\uD558\uC5EC\n * CSS `top`/`left` \uC18D\uC131\uC5D0 \uC9C1\uC811 \uC0AC\uC6A9\uD560 \uC218 \uC788\uB294 \uBB38\uC11C \uAE30\uC900 \uC88C\uD45C\uB97C \uBC18\uD658\uD55C\uB2E4.\n *\n * \uC8FC\uC694 \uC0AC\uC6A9 \uC0AC\uB840:\n * - \uB4DC\uB86D\uB2E4\uC6B4, \uD31D\uC5C5 \uB4F1\uC744 `document.body`\uC5D0 append \uD6C4 \uC704\uCE58 \uC9C0\uC815\n * - \uC2A4\uD06C\uB864\uB41C \uD398\uC774\uC9C0\uC5D0\uC11C\uB3C4 \uC62C\uBC14\uB974\uAC8C \uB3D9\uC791\n *\n * \uACC4\uC0B0\uC5D0 \uD3EC\uD568\uB418\uB294 \uC694\uC18C:\n * - \uBDF0\uD3EC\uD2B8 \uAE30\uC900 \uC704\uCE58 (getBoundingClientRect)\n * - \uBB38\uC11C \uC2A4\uD06C\uB864 \uC704\uCE58 (window.scrollX/Y)\n * - \uBD80\uBAA8 \uC694\uC18C \uB0B4\uBD80 \uC2A4\uD06C\uB864 (parentEl.scrollTop/Left)\n * - \uC911\uAC04 \uC694\uC18C\uB4E4\uC758 border \uB450\uAED8\n * - CSS transform \uBCC0\uD658\n *\n * @param parent - \uAE30\uC900\uC774 \uB420 \uBD80\uBAA8 \uC694\uC18C \uB610\uB294 \uC140\uB809\uD130 (\uC608: document.body, \".container\")\n * @returns CSS top/left \uC18D\uC131\uC5D0 \uC0AC\uC6A9\uD560 \uC218 \uC788\uB294 \uC88C\uD45C\n * @throws {ArgumentError} \uBD80\uBAA8 \uC694\uC18C\uB97C \uCC3E\uC744 \uC218 \uC5C6\uB294 \uACBD\uC6B0\n */\n getRelativeOffset(parent: HTMLElement | string): { top: number; left: number };\n\n /**\n * \uB300\uC0C1\uC774 offset \uC601\uC5ED(\uACE0\uC815 \uD5E4\uB354/\uACE0\uC815 \uC5F4 \uB4F1)\uC5D0 \uAC00\uB824\uC9C4 \uACBD\uC6B0, \uBCF4\uC774\uB3C4\uB85D \uC2A4\uD06C\uB864\n *\n * @remarks\n * \uC774 \uD568\uC218\uB294 \uB300\uC0C1\uC774 \uC2A4\uD06C\uB864 \uC601\uC5ED\uC758 \uC704\uCABD/\uC67C\uCABD \uACBD\uACC4\uB97C \uBC97\uC5B4\uB09C \uACBD\uC6B0\uB9CC \uCC98\uB9AC\uD55C\uB2E4.\n * \uC544\uB798\uCABD/\uC624\uB978\uCABD\uC73C\uB85C \uC2A4\uD06C\uB864\uC774 \uD544\uC694\uD55C \uACBD\uC6B0\uB294 \uBE0C\uB77C\uC6B0\uC800\uC758 \uAE30\uBCF8 \uD3EC\uCEE4\uC2A4 \uC2A4\uD06C\uB864 \uB3D9\uC791\uC5D0 \uC758\uC874\uD55C\uB2E4.\n * \uC8FC\uB85C \uACE0\uC815 \uD5E4\uB354\uB098 \uACE0\uC815 \uC5F4\uC774 \uC788\uB294 \uD14C\uC774\uBE14\uC5D0\uC11C \uD3EC\uCEE4\uC2A4 \uC774\uBCA4\uD2B8\uC640 \uD568\uAED8 \uC0AC\uC6A9\uB41C\uB2E4.\n *\n * @param target - \uB300\uC0C1\uC758 \uCEE8\uD14C\uC774\uB108 \uB0B4 \uC704\uCE58 (offsetTop, offsetLeft)\n * @param offset - \uAC00\uB824\uC9C0\uBA74 \uC548 \uB418\uB294 \uC601\uC5ED \uD06C\uAE30 (\uC608: \uACE0\uC815 \uD5E4\uB354 \uB192\uC774, \uACE0\uC815 \uC5F4 \uB108\uBE44)\n */\n scrollIntoViewIfNeeded(target: { top: number; left: number }, offset?: { top: number; left: number }): void;\n }\n}\n\nHTMLElement.prototype.repaint = function (): void {\n // offsetHeight \uC811\uADFC \uC2DC \uBE0C\uB77C\uC6B0\uC800\uB294 \uB3D9\uAE30\uC801 \uB808\uC774\uC544\uC6C3 \uACC4\uC0B0(forced synchronous layout)\uC744 \uC218\uD589\uD558\uBA70,\n // \uC774\uB85C \uC778\uD574 \uD604\uC7AC \uBC30\uCE58\uB41C \uC2A4\uD0C0\uC77C \uBCC0\uACBD\uC0AC\uD56D\uC774 \uC989\uC2DC \uC801\uC6A9\uB418\uC5B4 \uB9AC\uD398\uC778\uD2B8\uAC00 \uD2B8\uB9AC\uAC70\uB41C\uB2E4.\n void this.offsetHeight;\n};\n\nHTMLElement.prototype.getRelativeOffset = function (parent: HTMLElement | string): { top: number; left: number } {\n const parentEl = typeof parent === \"string\" ? this.closest(parent) : parent;\n\n if (!(parentEl instanceof HTMLElement)) {\n throw new ArgumentError({ parent });\n }\n\n const elementRect = this.getBoundingClientRect();\n const parentRect = parentEl.getBoundingClientRect();\n\n const scrollLeft = window.scrollX;\n const scrollTop = window.scrollY;\n\n const relativeOffset = {\n top: elementRect.top - parentRect.top + scrollTop + (parentEl.scrollTop || 0),\n left: elementRect.left - parentRect.left + scrollLeft + (parentEl.scrollLeft || 0),\n };\n\n let currentEl = this.parentElement;\n while (currentEl !== null && currentEl !== parentEl) {\n const style = getComputedStyle(currentEl);\n relativeOffset.top += parseFloat(style.borderTopWidth) || 0;\n relativeOffset.left += parseFloat(style.borderLeftWidth) || 0;\n currentEl = currentEl.parentElement;\n }\n\n const elTransform = getComputedStyle(this).transform;\n const parentTransform = getComputedStyle(parentEl).transform;\n\n if (elTransform !== \"none\" || parentTransform !== \"none\") {\n const elementMatrix = new DOMMatrix(elTransform);\n const parentMatrix = new DOMMatrix(parentTransform);\n\n if (!elementMatrix.isIdentity || !parentMatrix.isIdentity) {\n const transformedPoint = parentMatrix\n .inverse()\n .multiply(elementMatrix)\n .transformPoint(new DOMPoint(relativeOffset.left, relativeOffset.top));\n\n relativeOffset.left = transformedPoint.x;\n relativeOffset.top = transformedPoint.y;\n }\n }\n\n return relativeOffset;\n};\n\nHTMLElement.prototype.scrollIntoViewIfNeeded = function (\n target: { top: number; left: number },\n offset: { top: number; left: number } = { top: 0, left: 0 },\n): void {\n const scroll = {\n top: this.scrollTop,\n left: this.scrollLeft,\n };\n\n if (target.top - scroll.top < offset.top) {\n this.scrollTop = target.top - offset.top;\n }\n if (target.left - scroll.left < offset.left) {\n this.scrollLeft = target.left - offset.left;\n }\n};\n"],
|
|
5
4
|
"mappings": "AAAA,SAAS,qBAAqB;AAgD9B,YAAY,UAAU,UAAU,WAAkB;AAGhD,OAAK,KAAK;AACZ;AAEA,YAAY,UAAU,oBAAoB,SAAU,QAA6D;AAC/G,QAAM,WAAW,OAAO,WAAW,WAAW,KAAK,QAAQ,MAAM,IAAI;AAErE,MAAI,EAAE,oBAAoB,cAAc;AACtC,UAAM,IAAI,cAAc,EAAE,OAAO,CAAC;AAAA,EACpC;AAEA,QAAM,cAAc,KAAK,sBAAsB;AAC/C,QAAM,aAAa,SAAS,sBAAsB;AAElD,QAAM,aAAa,OAAO;AAC1B,QAAM,YAAY,OAAO;AAEzB,QAAM,iBAAiB;AAAA,IACrB,KAAK,YAAY,MAAM,WAAW,MAAM,aAAa,SAAS,aAAa;AAAA,IAC3E,MAAM,YAAY,OAAO,WAAW,OAAO,cAAc,SAAS,cAAc;AAAA,EAClF;AAEA,MAAI,YAAY,KAAK;AACrB,SAAO,cAAc,QAAQ,cAAc,UAAU;AACnD,UAAM,QAAQ,iBAAiB,SAAS;AACxC,mBAAe,OAAO,WAAW,MAAM,cAAc,KAAK;AAC1D,mBAAe,QAAQ,WAAW,MAAM,eAAe,KAAK;AAC5D,gBAAY,UAAU;AAAA,EACxB;AAEA,QAAM,cAAc,iBAAiB,IAAI,EAAE;AAC3C,QAAM,kBAAkB,iBAAiB,QAAQ,EAAE;AAEnD,MAAI,gBAAgB,UAAU,oBAAoB,QAAQ;AACxD,UAAM,gBAAgB,IAAI,UAAU,WAAW;AAC/C,UAAM,eAAe,IAAI,UAAU,eAAe;AAElD,QAAI,CAAC,cAAc,cAAc,CAAC,aAAa,YAAY;AACzD,YAAM,mBAAmB,aACtB,QAAQ,EACR,SAAS,aAAa,EACtB,eAAe,IAAI,SAAS,eAAe,MAAM,eAAe,GAAG,CAAC;AAEvE,qBAAe,OAAO,iBAAiB;AACvC,qBAAe,MAAM,iBAAiB;AAAA,IACxC;AAAA,EACF;AAEA,SAAO;AACT;AAEA,YAAY,UAAU,yBAAyB,SAC7C,QACA,SAAwC,EAAE,KAAK,GAAG,MAAM,EAAE,GACpD;AACN,QAAM,SAAS;AAAA,IACb,KAAK,KAAK;AAAA,IACV,MAAM,KAAK;AAAA,EACb;AAEA,MAAI,OAAO,MAAM,OAAO,MAAM,OAAO,KAAK;AACxC,SAAK,YAAY,OAAO,MAAM,OAAO;AAAA,EACvC;AACA,MAAI,OAAO,OAAO,OAAO,OAAO,OAAO,MAAM;AAC3C,SAAK,aAAa,OAAO,OAAO,OAAO;AAAA,EACzC;AACF;",
|
|
6
5
|
"names": []
|
|
7
6
|
}
|
|
@@ -2,6 +2,7 @@ import "./extensions/element-ext";
|
|
|
2
2
|
import "./extensions/html-element-ext";
|
|
3
3
|
export * from "./extensions/element-ext";
|
|
4
4
|
export * from "./extensions/html-element-ext";
|
|
5
|
-
export * from "./utils/blob";
|
|
6
5
|
export * from "./utils/download";
|
|
6
|
+
export * from "./utils/fetch";
|
|
7
|
+
export * from "./utils/file-dialog";
|
|
7
8
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,0BAA0B,CAAC;AAClC,OAAO,+BAA+B,CAAC;AAGvC,cAAc,0BAA0B,CAAC;AACzC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import "./extensions/element-ext";
|
|
2
|
-
import "./extensions/html-element-ext";
|
|
3
|
-
export * from "./extensions/element-ext";
|
|
4
|
-
export * from "./extensions/html-element-ext";
|
|
5
|
-
export * from "./utils/
|
|
6
|
-
export * from "./utils/
|
|
1
|
+
import "./extensions/element-ext.js";
|
|
2
|
+
import "./extensions/html-element-ext.js";
|
|
3
|
+
export * from "./extensions/element-ext.js";
|
|
4
|
+
export * from "./extensions/html-element-ext.js";
|
|
5
|
+
export * from "./utils/download.js";
|
|
6
|
+
export * from "./utils/fetch.js";
|
|
7
|
+
export * from "./utils/file-dialog.js";
|
|
7
8
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.ts"],
|
|
4
|
-
"
|
|
5
|
-
"mappings": "AAGA,OAAO;AACP,OAAO;AAGP,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;",
|
|
4
|
+
"mappings": "AAGA,OAAO;AACP,OAAO;AAGP,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;",
|
|
6
5
|
"names": []
|
|
7
6
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../../src/utils/download.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAU/D"}
|
package/dist/utils/download.js
CHANGED
|
@@ -1,47 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const response = await fetch(url);
|
|
4
|
-
if (!response.ok) {
|
|
5
|
-
throw new Error(`Download failed: ${response.status} ${response.statusText}`);
|
|
6
|
-
}
|
|
7
|
-
const contentLength = Number(response.headers.get("Content-Length") ?? 0);
|
|
8
|
-
const reader = (_a = response.body) == null ? void 0 : _a.getReader();
|
|
9
|
-
if (!reader) {
|
|
10
|
-
throw new Error("Response body is not readable");
|
|
11
|
-
}
|
|
1
|
+
function downloadBlob(blob, fileName) {
|
|
2
|
+
const url = URL.createObjectURL(blob);
|
|
12
3
|
try {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const { done, value } = await reader.read();
|
|
18
|
-
if (done) break;
|
|
19
|
-
result2.set(value, receivedLength2);
|
|
20
|
-
receivedLength2 += value.length;
|
|
21
|
-
(_b = options == null ? void 0 : options.onProgress) == null ? void 0 : _b.call(options, { receivedLength: receivedLength2, contentLength });
|
|
22
|
-
}
|
|
23
|
-
return result2;
|
|
24
|
-
}
|
|
25
|
-
const chunks = [];
|
|
26
|
-
let receivedLength = 0;
|
|
27
|
-
while (true) {
|
|
28
|
-
const { done, value } = await reader.read();
|
|
29
|
-
if (done) break;
|
|
30
|
-
chunks.push(value);
|
|
31
|
-
receivedLength += value.length;
|
|
32
|
-
}
|
|
33
|
-
const result = new Uint8Array(receivedLength);
|
|
34
|
-
let position = 0;
|
|
35
|
-
for (const chunk of chunks) {
|
|
36
|
-
result.set(chunk, position);
|
|
37
|
-
position += chunk.length;
|
|
38
|
-
}
|
|
39
|
-
return result;
|
|
4
|
+
const link = document.createElement("a");
|
|
5
|
+
link.href = url;
|
|
6
|
+
link.download = fileName;
|
|
7
|
+
link.click();
|
|
40
8
|
} finally {
|
|
41
|
-
|
|
9
|
+
setTimeout(() => URL.revokeObjectURL(url), 1e3);
|
|
42
10
|
}
|
|
43
11
|
}
|
|
44
12
|
export {
|
|
45
|
-
|
|
13
|
+
downloadBlob
|
|
46
14
|
};
|
|
47
15
|
//# sourceMappingURL=download.js.map
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/download.ts"],
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
"names": ["result", "receivedLength"]
|
|
4
|
+
"mappings": "AAMO,SAAS,aAAa,MAAY,UAAwB;AAC/D,QAAM,MAAM,IAAI,gBAAgB,IAAI;AACpC,MAAI;AACF,UAAM,OAAO,SAAS,cAAc,GAAG;AACvC,SAAK,OAAO;AACZ,SAAK,WAAW;AAChB,SAAK,MAAM;AAAA,EACb,UAAE;AACA,eAAW,MAAM,IAAI,gBAAgB,GAAG,GAAG,GAAI;AAAA,EACjD;AACF;",
|
|
5
|
+
"names": []
|
|
7
6
|
}
|
|
@@ -5,7 +5,7 @@ export interface DownloadProgress {
|
|
|
5
5
|
/**
|
|
6
6
|
* URL에서 바이너리 데이터 다운로드 (진행률 콜백 지원)
|
|
7
7
|
*/
|
|
8
|
-
export declare function
|
|
8
|
+
export declare function fetchUrlBytes(url: string, options?: {
|
|
9
9
|
onProgress?: (progress: DownloadProgress) => void;
|
|
10
10
|
}): Promise<Uint8Array>;
|
|
11
|
-
//# sourceMappingURL=
|
|
11
|
+
//# sourceMappingURL=fetch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/utils/fetch.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,CAAA;CAAE,GAC9D,OAAO,CAAC,UAAU,CAAC,CAsDrB"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
async function fetchUrlBytes(url, options) {
|
|
2
|
+
var _a, _b;
|
|
3
|
+
const response = await fetch(url);
|
|
4
|
+
if (!response.ok) {
|
|
5
|
+
throw new Error(`Download failed: ${response.status} ${response.statusText}`);
|
|
6
|
+
}
|
|
7
|
+
const contentLength = Number(response.headers.get("Content-Length") ?? 0);
|
|
8
|
+
const reader = (_a = response.body) == null ? void 0 : _a.getReader();
|
|
9
|
+
if (!reader) {
|
|
10
|
+
throw new Error("Response body is not readable");
|
|
11
|
+
}
|
|
12
|
+
try {
|
|
13
|
+
if (contentLength > 0) {
|
|
14
|
+
const result2 = new Uint8Array(contentLength);
|
|
15
|
+
let receivedLength2 = 0;
|
|
16
|
+
while (true) {
|
|
17
|
+
const { done, value } = await reader.read();
|
|
18
|
+
if (done) break;
|
|
19
|
+
result2.set(value, receivedLength2);
|
|
20
|
+
receivedLength2 += value.length;
|
|
21
|
+
(_b = options == null ? void 0 : options.onProgress) == null ? void 0 : _b.call(options, { receivedLength: receivedLength2, contentLength });
|
|
22
|
+
}
|
|
23
|
+
return result2;
|
|
24
|
+
}
|
|
25
|
+
const chunks = [];
|
|
26
|
+
let receivedLength = 0;
|
|
27
|
+
while (true) {
|
|
28
|
+
const { done, value } = await reader.read();
|
|
29
|
+
if (done) break;
|
|
30
|
+
chunks.push(value);
|
|
31
|
+
receivedLength += value.length;
|
|
32
|
+
}
|
|
33
|
+
const result = new Uint8Array(receivedLength);
|
|
34
|
+
let position = 0;
|
|
35
|
+
for (const chunk of chunks) {
|
|
36
|
+
result.set(chunk, position);
|
|
37
|
+
position += chunk.length;
|
|
38
|
+
}
|
|
39
|
+
return result;
|
|
40
|
+
} finally {
|
|
41
|
+
reader.releaseLock();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
export {
|
|
45
|
+
fetchUrlBytes
|
|
46
|
+
};
|
|
47
|
+
//# sourceMappingURL=fetch.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/utils/fetch.ts"],
|
|
4
|
+
"mappings": "AAQA,eAAsB,cACpB,KACA,SACqB;AAXvB;AAYE,QAAM,WAAW,MAAM,MAAM,GAAG;AAChC,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,IAAI,MAAM,oBAAoB,SAAS,MAAM,IAAI,SAAS,UAAU,EAAE;AAAA,EAC9E;AAEA,QAAM,gBAAgB,OAAO,SAAS,QAAQ,IAAI,gBAAgB,KAAK,CAAC;AACxE,QAAM,UAAS,cAAS,SAAT,mBAAe;AAC9B,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,+BAA+B;AAAA,EACjD;AAEA,MAAI;AAEF,QAAI,gBAAgB,GAAG;AACrB,YAAMA,UAAS,IAAI,WAAW,aAAa;AAC3C,UAAIC,kBAAiB;AAErB,aAAO,MAAM;AACX,cAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,YAAI,KAAM;AAEV,QAAAD,QAAO,IAAI,OAAOC,eAAc;AAChC,QAAAA,mBAAkB,MAAM;AACxB,iDAAS,eAAT,iCAAsB,EAAE,gBAAAA,iBAAgB,cAAc;AAAA,MACxD;AAEA,aAAOD;AAAA,IACT;AAGA,UAAM,SAAuB,CAAC;AAC9B,QAAI,iBAAiB;AAErB,WAAO,MAAM;AACX,YAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,UAAI,KAAM;AAEV,aAAO,KAAK,KAAK;AACjB,wBAAkB,MAAM;AAAA,IAC1B;AAGA,UAAM,SAAS,IAAI,WAAW,cAAc;AAC5C,QAAI,WAAW;AACf,eAAW,SAAS,QAAQ;AAC1B,aAAO,IAAI,OAAO,QAAQ;AAC1B,kBAAY,MAAM;AAAA,IACpB;AAEA,WAAO;AAAA,EACT,UAAE;AACA,WAAO,YAAY;AAAA,EACrB;AACF;",
|
|
5
|
+
"names": ["result", "receivedLength"]
|
|
6
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-dialog.d.ts","sourceRoot":"","sources":["../../src/utils/file-dialog.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,EAAE,GAAG,SAAS,CAAC,CAa7G"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
function openFileDialog(options) {
|
|
2
|
+
return new Promise((resolve) => {
|
|
3
|
+
const input = document.createElement("input");
|
|
4
|
+
input.type = "file";
|
|
5
|
+
input.multiple = (options == null ? void 0 : options.multiple) ?? false;
|
|
6
|
+
if ((options == null ? void 0 : options.accept) != null) {
|
|
7
|
+
input.accept = options.accept;
|
|
8
|
+
}
|
|
9
|
+
input.onchange = () => {
|
|
10
|
+
resolve(input.files != null && input.files.length > 0 ? [...input.files] : void 0);
|
|
11
|
+
};
|
|
12
|
+
input.click();
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
export {
|
|
16
|
+
openFileDialog
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=file-dialog.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/utils/file-dialog.ts"],
|
|
4
|
+
"mappings": "AAGO,SAAS,eAAe,SAAgF;AAC7G,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,UAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,UAAM,OAAO;AACb,UAAM,YAAW,mCAAS,aAAY;AACtC,SAAI,mCAAS,WAAU,MAAM;AAC3B,YAAM,SAAS,QAAQ;AAAA,IACzB;AACA,UAAM,WAAW,MAAM;AACrB,cAAQ,MAAM,SAAS,QAAQ,MAAM,MAAM,SAAS,IAAI,CAAC,GAAG,MAAM,KAAK,IAAI,MAAS;AAAA,IACtF;AACA,UAAM,MAAM;AAAA,EACd,CAAC;AACH;",
|
|
5
|
+
"names": []
|
|
6
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simplysm/core-browser",
|
|
3
|
-
"version": "13.0.
|
|
3
|
+
"version": "13.0.1",
|
|
4
4
|
"description": "심플리즘 패키지 - 코어 모듈 (browser)",
|
|
5
5
|
"author": "김석래",
|
|
6
6
|
"repository": {
|
|
@@ -12,15 +12,19 @@
|
|
|
12
12
|
"type": "module",
|
|
13
13
|
"main": "./dist/index.js",
|
|
14
14
|
"types": "./dist/index.d.ts",
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"src"
|
|
18
|
+
],
|
|
15
19
|
"sideEffects": [
|
|
16
20
|
"./dist/extensions/element-ext.js",
|
|
17
21
|
"./dist/extensions/html-element-ext.js"
|
|
18
22
|
],
|
|
19
23
|
"dependencies": {
|
|
20
|
-
"
|
|
21
|
-
"
|
|
24
|
+
"tabbable": "^6.4.0",
|
|
25
|
+
"@simplysm/core-common": "13.0.1"
|
|
22
26
|
},
|
|
23
27
|
"devDependencies": {
|
|
24
|
-
"happy-dom": "^20.
|
|
28
|
+
"happy-dom": "^20.6.1"
|
|
25
29
|
}
|
|
26
|
-
}
|
|
30
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -7,5 +7,6 @@ import "./extensions/html-element-ext";
|
|
|
7
7
|
// re-exports
|
|
8
8
|
export * from "./extensions/element-ext";
|
|
9
9
|
export * from "./extensions/html-element-ext";
|
|
10
|
-
export * from "./utils/blob";
|
|
11
10
|
export * from "./utils/download";
|
|
11
|
+
export * from "./utils/fetch";
|
|
12
|
+
export * from "./utils/file-dialog";
|
package/src/utils/download.ts
CHANGED
|
@@ -1,66 +1,17 @@
|
|
|
1
|
-
export interface DownloadProgress {
|
|
2
|
-
receivedLength: number;
|
|
3
|
-
contentLength: number;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
1
|
/**
|
|
7
|
-
*
|
|
2
|
+
* Blob을 파일로 다운로드
|
|
3
|
+
*
|
|
4
|
+
* @param blob - 다운로드할 Blob 객체
|
|
5
|
+
* @param fileName - 저장될 파일 이름
|
|
8
6
|
*/
|
|
9
|
-
export
|
|
10
|
-
url
|
|
11
|
-
options?: { onProgress?: (progress: DownloadProgress) => void },
|
|
12
|
-
): Promise<Uint8Array> {
|
|
13
|
-
const response = await fetch(url);
|
|
14
|
-
if (!response.ok) {
|
|
15
|
-
throw new Error(`Download failed: ${response.status} ${response.statusText}`);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const contentLength = Number(response.headers.get("Content-Length") ?? 0);
|
|
19
|
-
const reader = response.body?.getReader();
|
|
20
|
-
if (!reader) {
|
|
21
|
-
throw new Error("Response body is not readable");
|
|
22
|
-
}
|
|
23
|
-
|
|
7
|
+
export function downloadBlob(blob: Blob, fileName: string): void {
|
|
8
|
+
const url = URL.createObjectURL(blob);
|
|
24
9
|
try {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
while (true) {
|
|
31
|
-
const { done, value } = await reader.read();
|
|
32
|
-
if (done) break;
|
|
33
|
-
|
|
34
|
-
result.set(value, receivedLength);
|
|
35
|
-
receivedLength += value.length;
|
|
36
|
-
options?.onProgress?.({ receivedLength, contentLength });
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return result;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// Content-Length를 모르면 청크 수집 후 병합 (chunked encoding)
|
|
43
|
-
const chunks: Uint8Array[] = [];
|
|
44
|
-
let receivedLength = 0;
|
|
45
|
-
|
|
46
|
-
while (true) {
|
|
47
|
-
const { done, value } = await reader.read();
|
|
48
|
-
if (done) break;
|
|
49
|
-
|
|
50
|
-
chunks.push(value);
|
|
51
|
-
receivedLength += value.length;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// 청크 병합
|
|
55
|
-
const result = new Uint8Array(receivedLength);
|
|
56
|
-
let position = 0;
|
|
57
|
-
for (const chunk of chunks) {
|
|
58
|
-
result.set(chunk, position);
|
|
59
|
-
position += chunk.length;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
return result;
|
|
10
|
+
const link = document.createElement("a");
|
|
11
|
+
link.href = url;
|
|
12
|
+
link.download = fileName;
|
|
13
|
+
link.click();
|
|
63
14
|
} finally {
|
|
64
|
-
|
|
15
|
+
setTimeout(() => URL.revokeObjectURL(url), 1000);
|
|
65
16
|
}
|
|
66
17
|
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
export interface DownloadProgress {
|
|
2
|
+
receivedLength: number;
|
|
3
|
+
contentLength: number;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* URL에서 바이너리 데이터 다운로드 (진행률 콜백 지원)
|
|
8
|
+
*/
|
|
9
|
+
export async function fetchUrlBytes(
|
|
10
|
+
url: string,
|
|
11
|
+
options?: { onProgress?: (progress: DownloadProgress) => void },
|
|
12
|
+
): Promise<Uint8Array> {
|
|
13
|
+
const response = await fetch(url);
|
|
14
|
+
if (!response.ok) {
|
|
15
|
+
throw new Error(`Download failed: ${response.status} ${response.statusText}`);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const contentLength = Number(response.headers.get("Content-Length") ?? 0);
|
|
19
|
+
const reader = response.body?.getReader();
|
|
20
|
+
if (!reader) {
|
|
21
|
+
throw new Error("Response body is not readable");
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
// Content-Length를 알 수 있으면 미리 할당하여 메모리 효율성 향상
|
|
26
|
+
if (contentLength > 0) {
|
|
27
|
+
const result = new Uint8Array(contentLength);
|
|
28
|
+
let receivedLength = 0;
|
|
29
|
+
|
|
30
|
+
while (true) {
|
|
31
|
+
const { done, value } = await reader.read();
|
|
32
|
+
if (done) break;
|
|
33
|
+
|
|
34
|
+
result.set(value, receivedLength);
|
|
35
|
+
receivedLength += value.length;
|
|
36
|
+
options?.onProgress?.({ receivedLength, contentLength });
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Content-Length를 모르면 청크 수집 후 병합 (chunked encoding)
|
|
43
|
+
const chunks: Uint8Array[] = [];
|
|
44
|
+
let receivedLength = 0;
|
|
45
|
+
|
|
46
|
+
while (true) {
|
|
47
|
+
const { done, value } = await reader.read();
|
|
48
|
+
if (done) break;
|
|
49
|
+
|
|
50
|
+
chunks.push(value);
|
|
51
|
+
receivedLength += value.length;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// 청크 병합
|
|
55
|
+
const result = new Uint8Array(receivedLength);
|
|
56
|
+
let position = 0;
|
|
57
|
+
for (const chunk of chunks) {
|
|
58
|
+
result.set(chunk, position);
|
|
59
|
+
position += chunk.length;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return result;
|
|
63
|
+
} finally {
|
|
64
|
+
reader.releaseLock();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 파일 선택 다이얼로그를 프로그래밍 방식으로 열기
|
|
3
|
+
*/
|
|
4
|
+
export function openFileDialog(options?: { accept?: string; multiple?: boolean }): Promise<File[] | undefined> {
|
|
5
|
+
return new Promise((resolve) => {
|
|
6
|
+
const input = document.createElement("input");
|
|
7
|
+
input.type = "file";
|
|
8
|
+
input.multiple = options?.multiple ?? false;
|
|
9
|
+
if (options?.accept != null) {
|
|
10
|
+
input.accept = options.accept;
|
|
11
|
+
}
|
|
12
|
+
input.onchange = () => {
|
|
13
|
+
resolve(input.files != null && input.files.length > 0 ? [...input.files] : undefined);
|
|
14
|
+
};
|
|
15
|
+
input.click();
|
|
16
|
+
});
|
|
17
|
+
}
|