@simplysm/core-browser 13.0.100 → 14.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 +36 -36
- package/dist/extensions/element-ext.d.ts.map +1 -1
- package/dist/extensions/element-ext.js +132 -111
- package/dist/extensions/element-ext.js.map +1 -6
- package/dist/extensions/html-element-ext.d.ts +22 -22
- package/dist/extensions/html-element-ext.js +50 -45
- package/dist/extensions/html-element-ext.js.map +1 -6
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -6
- package/dist/utils/IndexedDbStore.js +115 -112
- package/dist/utils/IndexedDbStore.js.map +1 -6
- package/dist/utils/IndexedDbVirtualFs.js +81 -83
- package/dist/utils/IndexedDbVirtualFs.js.map +1 -6
- package/dist/utils/download.d.ts +3 -3
- package/dist/utils/download.js +18 -14
- package/dist/utils/download.js.map +1 -6
- package/dist/utils/fetch.d.ts +1 -1
- package/dist/utils/fetch.d.ts.map +1 -1
- package/dist/utils/fetch.js +46 -36
- package/dist/utils/fetch.js.map +1 -6
- package/dist/utils/file-dialog.d.ts +1 -1
- package/dist/utils/file-dialog.js +19 -19
- package/dist/utils/file-dialog.js.map +1 -6
- package/package.json +7 -10
- package/src/extensions/element-ext.ts +40 -40
- package/src/extensions/html-element-ext.ts +24 -24
- package/src/index.ts +3 -3
- package/src/utils/IndexedDbStore.ts +3 -3
- package/src/utils/download.ts +3 -3
- package/src/utils/fetch.ts +17 -5
- package/src/utils/file-dialog.ts +1 -1
- package/README.md +0 -106
- package/docs/classes.md +0 -184
- package/docs/element-extensions.md +0 -134
- package/docs/html-element-extensions.md +0 -56
- package/docs/utilities.md +0 -71
- package/tests/extensions/element-ext.spec.ts +0 -693
- package/tests/extensions/html-element-ext.spec.ts +0 -175
- package/tests/utils/IndexedDbStore.spec.ts +0 -103
- package/tests/utils/IndexedDbVirtualFs.spec.ts +0 -171
- package/tests/utils/download.spec.ts +0 -66
- package/tests/utils/fetch.spec.ts +0 -154
|
@@ -1,98 +1,98 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* 요소 경계 정보 타입
|
|
3
3
|
*/
|
|
4
4
|
export interface ElementBounds {
|
|
5
|
-
/**
|
|
5
|
+
/** 측정 대상 요소 */
|
|
6
6
|
target: Element;
|
|
7
|
-
/**
|
|
7
|
+
/** 뷰포트 기준 상단 위치 */
|
|
8
8
|
top: number;
|
|
9
|
-
/**
|
|
9
|
+
/** 뷰포트 기준 좌측 위치 */
|
|
10
10
|
left: number;
|
|
11
|
-
/**
|
|
11
|
+
/** 요소 너비 */
|
|
12
12
|
width: number;
|
|
13
|
-
/**
|
|
13
|
+
/** 요소 높이 */
|
|
14
14
|
height: number;
|
|
15
15
|
}
|
|
16
16
|
declare global {
|
|
17
17
|
interface Element {
|
|
18
18
|
/**
|
|
19
|
-
*
|
|
19
|
+
* 선택자와 일치하는 모든 하위 요소 검색
|
|
20
20
|
*
|
|
21
|
-
* @param selector - CSS
|
|
22
|
-
* @returns
|
|
21
|
+
* @param selector - CSS 선택자
|
|
22
|
+
* @returns 일치하는 요소 배열 (빈 선택자는 빈 배열 반환)
|
|
23
23
|
*/
|
|
24
24
|
findAll<TEl extends Element = Element>(selector: string): TEl[];
|
|
25
25
|
/**
|
|
26
|
-
*
|
|
26
|
+
* 선택자와 일치하는 첫 번째 요소 검색
|
|
27
27
|
*
|
|
28
|
-
* @param selector - CSS
|
|
29
|
-
* @returns
|
|
28
|
+
* @param selector - CSS 선택자
|
|
29
|
+
* @returns 첫 번째 일치 요소 또는 undefined (빈 선택자는 undefined 반환)
|
|
30
30
|
*/
|
|
31
31
|
findFirst<TEl extends Element = Element>(selector: string): TEl | undefined;
|
|
32
32
|
/**
|
|
33
|
-
*
|
|
33
|
+
* 요소를 첫 번째 자식으로 삽입
|
|
34
34
|
*
|
|
35
|
-
* @param child -
|
|
36
|
-
* @returns
|
|
35
|
+
* @param child - 삽입할 자식 요소
|
|
36
|
+
* @returns 삽입된 자식 요소
|
|
37
37
|
*/
|
|
38
38
|
prependChild<TEl extends Element>(child: TEl): TEl;
|
|
39
39
|
/**
|
|
40
|
-
*
|
|
40
|
+
* 모든 부모 요소 조회 (가까운 순서)
|
|
41
41
|
*
|
|
42
|
-
* @returns
|
|
42
|
+
* @returns 부모 요소 배열 (가장 가까운 것부터 먼 것 순)
|
|
43
43
|
*/
|
|
44
44
|
getParents(): Element[];
|
|
45
45
|
/**
|
|
46
|
-
*
|
|
46
|
+
* 첫 번째 포커스 가능한 부모 요소 검색 (tabbable 사용)
|
|
47
47
|
*
|
|
48
|
-
* @returns
|
|
48
|
+
* @returns 첫 번째 포커스 가능한 부모 요소 또는 undefined
|
|
49
49
|
*/
|
|
50
50
|
findFocusableParent(): HTMLElement | undefined;
|
|
51
51
|
/**
|
|
52
|
-
*
|
|
52
|
+
* 첫 번째 포커스 가능한 자식 요소 검색 (tabbable 사용)
|
|
53
53
|
*
|
|
54
|
-
* @returns
|
|
54
|
+
* @returns 첫 번째 포커스 가능한 자식 요소 또는 undefined
|
|
55
55
|
*/
|
|
56
56
|
findFirstFocusableChild(): HTMLElement | undefined;
|
|
57
57
|
/**
|
|
58
|
-
*
|
|
58
|
+
* 요소가 offset parent인지 확인 (position: relative/absolute/fixed/sticky)
|
|
59
59
|
*
|
|
60
|
-
* @returns
|
|
60
|
+
* @returns position 속성이 relative, absolute, fixed, sticky 중 하나이면 true
|
|
61
61
|
*/
|
|
62
62
|
isOffsetElement(): boolean;
|
|
63
63
|
/**
|
|
64
|
-
*
|
|
64
|
+
* 요소가 화면에 보이는지 확인
|
|
65
65
|
*
|
|
66
66
|
* @remarks
|
|
67
|
-
*
|
|
67
|
+
* clientRects 존재 여부, visibility: hidden, opacity: 0을 확인합니다.
|
|
68
68
|
*
|
|
69
|
-
* @returns
|
|
69
|
+
* @returns 요소가 화면에 보이면 true
|
|
70
70
|
*/
|
|
71
71
|
isVisible(): boolean;
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
/**
|
|
75
|
-
*
|
|
75
|
+
* 요소 내용을 클립보드에 복사 (copy 이벤트 핸들러와 함께 사용)
|
|
76
76
|
*
|
|
77
|
-
* @param event - copy
|
|
77
|
+
* @param event - copy 이벤트 객체
|
|
78
78
|
*/
|
|
79
79
|
export declare function copyElement(event: ClipboardEvent): void;
|
|
80
80
|
/**
|
|
81
|
-
*
|
|
81
|
+
* 클립보드 내용을 요소에 붙여넣기 (paste 이벤트 핸들러와 함께 사용)
|
|
82
82
|
*
|
|
83
83
|
* @remarks
|
|
84
|
-
*
|
|
85
|
-
*
|
|
84
|
+
* 대상 요소 내의 첫 번째 input/textarea를 찾아 전체 값을 클립보드 내용으로 교체합니다.
|
|
85
|
+
* 커서 위치나 선택 영역은 고려하지 않습니다.
|
|
86
86
|
*
|
|
87
|
-
* @param event - paste
|
|
87
|
+
* @param event - paste 이벤트 객체
|
|
88
88
|
*/
|
|
89
89
|
export declare function pasteToElement(event: ClipboardEvent): void;
|
|
90
90
|
/**
|
|
91
|
-
*
|
|
91
|
+
* IntersectionObserver를 사용하여 요소의 경계 정보 조회
|
|
92
92
|
*
|
|
93
|
-
* @param els -
|
|
94
|
-
* @param timeout -
|
|
95
|
-
* @throws {TimeoutError}
|
|
93
|
+
* @param els - 대상 요소 배열
|
|
94
|
+
* @param timeout - 타임아웃 밀리초 (기본값: 5000)
|
|
95
|
+
* @throws {TimeoutError} 타임아웃 시간 내에 응답이 없는 경우
|
|
96
96
|
*/
|
|
97
97
|
export declare function getBounds(els: Element[], timeout?: number): Promise<ElementBounds[]>;
|
|
98
98
|
//# sourceMappingURL=element-ext.d.ts.map
|
|
@@ -1 +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,
|
|
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,GAAG,SAAS,OAAO,GAAG,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,GAAG,EAAE,CAAC;QAEhE;;;;;WAKG;QACH,SAAS,CAAC,GAAG,SAAS,OAAO,GAAG,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,GAAG,GAAG,SAAS,CAAC;QAE5E;;;;;WAKG;QACH,YAAY,CAAC,GAAG,SAAS,OAAO,EAAE,KAAK,EAAE,GAAG,GAAG,GAAG,CAAC;QAEnD;;;;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;AAkED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAYvD;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,CAoDhG"}
|
|
@@ -1,126 +1,147 @@
|
|
|
1
1
|
import { isFocusable } from "tabbable";
|
|
2
2
|
import { TimeoutError } from "@simplysm/core-common";
|
|
3
|
-
Element.prototype.findAll = function(selector) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
Element.prototype.findAll = function (selector) {
|
|
4
|
+
const trimmed = selector.trim();
|
|
5
|
+
if (trimmed === "")
|
|
6
|
+
return [];
|
|
7
|
+
return Array.from(this.querySelectorAll(trimmed));
|
|
7
8
|
};
|
|
8
|
-
Element.prototype.findFirst = function(selector) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
Element.prototype.findFirst = function (selector) {
|
|
10
|
+
const trimmed = selector.trim();
|
|
11
|
+
if (trimmed === "")
|
|
12
|
+
return undefined;
|
|
13
|
+
return this.querySelector(trimmed) ?? undefined;
|
|
12
14
|
};
|
|
13
|
-
Element.prototype.prependChild = function(child) {
|
|
14
|
-
|
|
15
|
+
Element.prototype.prependChild = function (child) {
|
|
16
|
+
return this.insertBefore(child, this.firstElementChild);
|
|
15
17
|
};
|
|
16
|
-
Element.prototype.getParents = function() {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
Element.prototype.getParents = function () {
|
|
19
|
+
const result = [];
|
|
20
|
+
let cursor = this.parentNode;
|
|
21
|
+
while (cursor !== null && cursor instanceof Element) {
|
|
22
|
+
result.push(cursor);
|
|
23
|
+
cursor = cursor.parentNode;
|
|
24
|
+
}
|
|
25
|
+
return result;
|
|
24
26
|
};
|
|
25
|
-
Element.prototype.findFocusableParent = function() {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
Element.prototype.findFocusableParent = function () {
|
|
28
|
+
let parentEl = this.parentElement;
|
|
29
|
+
while (parentEl !== null) {
|
|
30
|
+
if (isFocusable(parentEl)) {
|
|
31
|
+
return parentEl;
|
|
32
|
+
}
|
|
33
|
+
parentEl = parentEl.parentElement;
|
|
30
34
|
}
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
return void 0;
|
|
35
|
+
return undefined;
|
|
34
36
|
};
|
|
35
|
-
Element.prototype.findFirstFocusableChild = function() {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
37
|
+
Element.prototype.findFirstFocusableChild = function () {
|
|
38
|
+
const walker = document.createTreeWalker(this, NodeFilter.SHOW_ELEMENT);
|
|
39
|
+
let node = walker.nextNode();
|
|
40
|
+
while (node !== null) {
|
|
41
|
+
if (node instanceof HTMLElement && isFocusable(node)) {
|
|
42
|
+
return node;
|
|
43
|
+
}
|
|
44
|
+
node = walker.nextNode();
|
|
41
45
|
}
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
return void 0;
|
|
46
|
+
return undefined;
|
|
45
47
|
};
|
|
46
|
-
Element.prototype.isOffsetElement = function() {
|
|
47
|
-
|
|
48
|
+
Element.prototype.isOffsetElement = function () {
|
|
49
|
+
return ["relative", "absolute", "fixed", "sticky"].includes(getComputedStyle(this).position);
|
|
48
50
|
};
|
|
49
|
-
Element.prototype.isVisible = function() {
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
Element.prototype.isVisible = function () {
|
|
52
|
+
const style = getComputedStyle(this);
|
|
53
|
+
return this.getClientRects().length > 0 && style.visibility !== "hidden" && style.opacity !== "0";
|
|
52
54
|
};
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
event.
|
|
63
|
-
|
|
55
|
+
// ============================================================================
|
|
56
|
+
// 정적 함수 (이벤트 핸들러 또는 다중 요소용)
|
|
57
|
+
// ============================================================================
|
|
58
|
+
/**
|
|
59
|
+
* 요소 내용을 클립보드에 복사 (copy 이벤트 핸들러와 함께 사용)
|
|
60
|
+
*
|
|
61
|
+
* @param event - copy 이벤트 객체
|
|
62
|
+
*/
|
|
63
|
+
export function copyElement(event) {
|
|
64
|
+
const clipboardData = event.clipboardData;
|
|
65
|
+
const target = event.target;
|
|
66
|
+
if (clipboardData == null || !(target instanceof Element))
|
|
67
|
+
return;
|
|
68
|
+
const firstInputEl = target.findFirst("input, textarea");
|
|
69
|
+
if (firstInputEl !== undefined) {
|
|
70
|
+
clipboardData.setData("text/plain", firstInputEl.value);
|
|
71
|
+
event.preventDefault();
|
|
72
|
+
}
|
|
64
73
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
74
|
+
/**
|
|
75
|
+
* 클립보드 내용을 요소에 붙여넣기 (paste 이벤트 핸들러와 함께 사용)
|
|
76
|
+
*
|
|
77
|
+
* @remarks
|
|
78
|
+
* 대상 요소 내의 첫 번째 input/textarea를 찾아 전체 값을 클립보드 내용으로 교체합니다.
|
|
79
|
+
* 커서 위치나 선택 영역은 고려하지 않습니다.
|
|
80
|
+
*
|
|
81
|
+
* @param event - paste 이벤트 객체
|
|
82
|
+
*/
|
|
83
|
+
export function pasteToElement(event) {
|
|
84
|
+
const clipboardData = event.clipboardData;
|
|
85
|
+
const target = event.target;
|
|
86
|
+
if (clipboardData == null || !(target instanceof Element))
|
|
87
|
+
return;
|
|
88
|
+
const contentText = clipboardData.getData("text/plain");
|
|
89
|
+
const firstInputEl = target.findFirst("input, textarea");
|
|
90
|
+
if (firstInputEl !== undefined) {
|
|
91
|
+
firstInputEl.value = contentText;
|
|
92
|
+
firstInputEl.dispatchEvent(new Event("input", { bubbles: true }));
|
|
93
|
+
event.preventDefault();
|
|
94
|
+
}
|
|
76
95
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
96
|
+
/**
|
|
97
|
+
* IntersectionObserver를 사용하여 요소의 경계 정보 조회
|
|
98
|
+
*
|
|
99
|
+
* @param els - 대상 요소 배열
|
|
100
|
+
* @param timeout - 타임아웃 밀리초 (기본값: 5000)
|
|
101
|
+
* @throws {TimeoutError} 타임아웃 시간 내에 응답이 없는 경우
|
|
102
|
+
*/
|
|
103
|
+
export async function getBounds(els, timeout = 5000) {
|
|
104
|
+
// 중복 제거 및 입력 순서대로 결과 정렬을 위한 인덱스 맵
|
|
105
|
+
const indexMap = new Map(els.map((el, i) => [el, i]));
|
|
106
|
+
if (indexMap.size === 0) {
|
|
107
|
+
return [];
|
|
108
|
+
}
|
|
109
|
+
// 남은 요소를 추적하기 위한 Set
|
|
110
|
+
const remaining = new Set(indexMap.keys());
|
|
111
|
+
let observer;
|
|
112
|
+
try {
|
|
113
|
+
return await Promise.race([
|
|
114
|
+
new Promise((resolve) => {
|
|
115
|
+
const results = [];
|
|
116
|
+
observer = new IntersectionObserver((entries) => {
|
|
117
|
+
for (const entry of entries) {
|
|
118
|
+
const target = entry.target;
|
|
119
|
+
if (remaining.has(target)) {
|
|
120
|
+
remaining.delete(target);
|
|
121
|
+
results.push({
|
|
122
|
+
target,
|
|
123
|
+
top: entry.boundingClientRect.top,
|
|
124
|
+
left: entry.boundingClientRect.left,
|
|
125
|
+
width: entry.boundingClientRect.width,
|
|
126
|
+
height: entry.boundingClientRect.height,
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (remaining.size === 0) {
|
|
131
|
+
observer?.disconnect();
|
|
132
|
+
// 입력 순서대로 정렬
|
|
133
|
+
resolve(results.sort((a, b) => indexMap.get(a.target) - indexMap.get(b.target)));
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
for (const el of indexMap.keys()) {
|
|
137
|
+
observer.observe(el);
|
|
138
|
+
}
|
|
139
|
+
}),
|
|
140
|
+
new Promise((_, reject) => setTimeout(() => reject(new TimeoutError(undefined, `${timeout}ms timeout`)), timeout)),
|
|
141
|
+
]);
|
|
142
|
+
}
|
|
143
|
+
finally {
|
|
144
|
+
observer?.disconnect();
|
|
145
|
+
}
|
|
120
146
|
}
|
|
121
|
-
|
|
122
|
-
copyElement,
|
|
123
|
-
getBounds,
|
|
124
|
-
pasteToElement
|
|
125
|
-
};
|
|
126
|
-
//# sourceMappingURL=element-ext.js.map
|
|
147
|
+
//# sourceMappingURL=element-ext.js.map
|
|
@@ -1,6 +1 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/extensions/element-ext.ts"],
|
|
4
|
-
"mappings": "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",
|
|
5
|
-
"names": []
|
|
6
|
-
}
|
|
1
|
+
{"version":3,"file":"element-ext.js","sourceRoot":"","sources":["..\\..\\src\\extensions\\element-ext.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,45 +1,45 @@
|
|
|
1
1
|
declare global {
|
|
2
2
|
interface HTMLElement {
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* 강제 리페인트 (reflow 트리거)
|
|
5
5
|
*/
|
|
6
6
|
repaint(): void;
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* 부모 요소 기준 상대 위치 계산 (CSS 포지셔닝용)
|
|
9
9
|
*
|
|
10
10
|
* @remarks
|
|
11
|
-
*
|
|
12
|
-
*
|
|
11
|
+
* 부모 요소 기준으로 요소 위치를 계산하며, CSS `top`/`left` 속성에 바로 사용할 수 있는
|
|
12
|
+
* `window.scrollX/Y`를 포함한 문서 기반 좌표를 반환합니다.
|
|
13
13
|
*
|
|
14
|
-
*
|
|
15
|
-
* -
|
|
16
|
-
* -
|
|
14
|
+
* 주요 사용 사례:
|
|
15
|
+
* - `document.body`에 append한 후 드롭다운, 팝업 위치 지정
|
|
16
|
+
* - 스크롤된 페이지에서도 정상 동작
|
|
17
17
|
*
|
|
18
|
-
*
|
|
19
|
-
* -
|
|
20
|
-
* -
|
|
21
|
-
* -
|
|
22
|
-
* -
|
|
23
|
-
* - CSS transform
|
|
18
|
+
* 계산에 포함되는 요소:
|
|
19
|
+
* - 뷰포트 기준 위치 (getBoundingClientRect)
|
|
20
|
+
* - 문서 스크롤 위치 (window.scrollX/Y)
|
|
21
|
+
* - 부모 요소 내부 스크롤 (parentEl.scrollTop/Left)
|
|
22
|
+
* - 중간 요소의 border 두께
|
|
23
|
+
* - CSS transform 변환
|
|
24
24
|
*
|
|
25
|
-
* @param parent -
|
|
26
|
-
* @returns
|
|
27
|
-
* @throws {ArgumentError}
|
|
25
|
+
* @param parent - 기준이 되는 부모 요소 또는 선택자 (예: document.body, ".container")
|
|
26
|
+
* @returns CSS top/left 속성에 사용 가능한 좌표
|
|
27
|
+
* @throws {ArgumentError} 부모 요소를 찾을 수 없는 경우
|
|
28
28
|
*/
|
|
29
29
|
getRelativeOffset(parent: HTMLElement | string): {
|
|
30
30
|
top: number;
|
|
31
31
|
left: number;
|
|
32
32
|
};
|
|
33
33
|
/**
|
|
34
|
-
*
|
|
34
|
+
* offset 영역(예: 고정 헤더/컬럼)에 가려진 경우 대상이 보이도록 스크롤
|
|
35
35
|
*
|
|
36
36
|
* @remarks
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
37
|
+
* 대상이 스크롤 영역의 상단/좌측 경계를 벗어나는 경우만 처리합니다.
|
|
38
|
+
* 하단/우측 방향 스크롤이 필요한 경우는 브라우저의 기본 포커스 스크롤 동작에 의존합니다.
|
|
39
|
+
* 주로 고정 헤더나 컬럼이 있는 테이블의 포커스 이벤트에서 사용됩니다.
|
|
40
40
|
*
|
|
41
|
-
* @param target -
|
|
42
|
-
* @param offset -
|
|
41
|
+
* @param target - 컨테이너 내 대상 위치 (offsetTop, offsetLeft)
|
|
42
|
+
* @param offset - 가려지면 안 되는 영역의 크기 (예: 고정 헤더 높이, 고정 컬럼 너비)
|
|
43
43
|
*/
|
|
44
44
|
scrollIntoViewIfNeeded(target: {
|
|
45
45
|
top: number;
|
|
@@ -1,50 +1,55 @@
|
|
|
1
1
|
import { ArgumentError } from "@simplysm/core-common";
|
|
2
|
-
HTMLElement.prototype.repaint = function() {
|
|
3
|
-
|
|
2
|
+
HTMLElement.prototype.repaint = function () {
|
|
3
|
+
// offsetHeight에 접근하면 브라우저에서 강제 동기 레이아웃이 트리거되어,
|
|
4
|
+
// 현재 레이아웃의 스타일 변경이 즉시 적용되고 리페인트가 발생합니다.
|
|
5
|
+
void this.offsetHeight;
|
|
4
6
|
};
|
|
5
|
-
HTMLElement.prototype.getRelativeOffset = function(parent) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
const elementRect = this.getBoundingClientRect();
|
|
11
|
-
const parentRect = parentEl.getBoundingClientRect();
|
|
12
|
-
const scrollLeft = window.scrollX;
|
|
13
|
-
const scrollTop = window.scrollY;
|
|
14
|
-
const relativeOffset = {
|
|
15
|
-
top: elementRect.top - parentRect.top + scrollTop + (parentEl.scrollTop || 0),
|
|
16
|
-
left: elementRect.left - parentRect.left + scrollLeft + (parentEl.scrollLeft || 0)
|
|
17
|
-
};
|
|
18
|
-
let currentEl = this.parentElement;
|
|
19
|
-
while (currentEl !== null && currentEl !== parentEl) {
|
|
20
|
-
const style = getComputedStyle(currentEl);
|
|
21
|
-
relativeOffset.top += parseFloat(style.borderTopWidth) || 0;
|
|
22
|
-
relativeOffset.left += parseFloat(style.borderLeftWidth) || 0;
|
|
23
|
-
currentEl = currentEl.parentElement;
|
|
24
|
-
}
|
|
25
|
-
const elTransform = getComputedStyle(this).transform;
|
|
26
|
-
const parentTransform = getComputedStyle(parentEl).transform;
|
|
27
|
-
if (elTransform !== "none" || parentTransform !== "none") {
|
|
28
|
-
const elementMatrix = new DOMMatrix(elTransform);
|
|
29
|
-
const parentMatrix = new DOMMatrix(parentTransform);
|
|
30
|
-
if (!elementMatrix.isIdentity || !parentMatrix.isIdentity) {
|
|
31
|
-
const transformedPoint = parentMatrix.inverse().multiply(elementMatrix).transformPoint(new DOMPoint(relativeOffset.left, relativeOffset.top));
|
|
32
|
-
relativeOffset.left = transformedPoint.x;
|
|
33
|
-
relativeOffset.top = transformedPoint.y;
|
|
7
|
+
HTMLElement.prototype.getRelativeOffset = function (parent) {
|
|
8
|
+
const parentEl = typeof parent === "string" ? this.closest(parent) : parent;
|
|
9
|
+
if (!(parentEl instanceof HTMLElement)) {
|
|
10
|
+
throw new ArgumentError({ parent });
|
|
34
11
|
}
|
|
35
|
-
|
|
36
|
-
|
|
12
|
+
const elementRect = this.getBoundingClientRect();
|
|
13
|
+
const parentRect = parentEl.getBoundingClientRect();
|
|
14
|
+
const scrollLeft = window.scrollX;
|
|
15
|
+
const scrollTop = window.scrollY;
|
|
16
|
+
const relativeOffset = {
|
|
17
|
+
top: elementRect.top - parentRect.top + scrollTop + (parentEl.scrollTop || 0),
|
|
18
|
+
left: elementRect.left - parentRect.left + scrollLeft + (parentEl.scrollLeft || 0),
|
|
19
|
+
};
|
|
20
|
+
let currentEl = this.parentElement;
|
|
21
|
+
while (currentEl !== null && currentEl !== parentEl) {
|
|
22
|
+
const style = getComputedStyle(currentEl);
|
|
23
|
+
relativeOffset.top += parseFloat(style.borderTopWidth) || 0;
|
|
24
|
+
relativeOffset.left += parseFloat(style.borderLeftWidth) || 0;
|
|
25
|
+
currentEl = currentEl.parentElement;
|
|
26
|
+
}
|
|
27
|
+
const elTransform = getComputedStyle(this).transform;
|
|
28
|
+
const parentTransform = getComputedStyle(parentEl).transform;
|
|
29
|
+
if (elTransform !== "none" || parentTransform !== "none") {
|
|
30
|
+
const elementMatrix = new DOMMatrix(elTransform);
|
|
31
|
+
const parentMatrix = new DOMMatrix(parentTransform);
|
|
32
|
+
if (!elementMatrix.isIdentity || !parentMatrix.isIdentity) {
|
|
33
|
+
const transformedPoint = parentMatrix
|
|
34
|
+
.inverse()
|
|
35
|
+
.multiply(elementMatrix)
|
|
36
|
+
.transformPoint(new DOMPoint(relativeOffset.left, relativeOffset.top));
|
|
37
|
+
relativeOffset.left = transformedPoint.x;
|
|
38
|
+
relativeOffset.top = transformedPoint.y;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return relativeOffset;
|
|
37
42
|
};
|
|
38
|
-
HTMLElement.prototype.scrollIntoViewIfNeeded = function(target, offset = { top: 0, left: 0 }) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
43
|
+
HTMLElement.prototype.scrollIntoViewIfNeeded = function (target, offset = { top: 0, left: 0 }) {
|
|
44
|
+
const scroll = {
|
|
45
|
+
top: this.scrollTop,
|
|
46
|
+
left: this.scrollLeft,
|
|
47
|
+
};
|
|
48
|
+
if (target.top - scroll.top < offset.top) {
|
|
49
|
+
this.scrollTop = target.top - offset.top;
|
|
50
|
+
}
|
|
51
|
+
if (target.left - scroll.left < offset.left) {
|
|
52
|
+
this.scrollLeft = target.left - offset.left;
|
|
53
|
+
}
|
|
49
54
|
};
|
|
50
|
-
//# sourceMappingURL=html-element-ext.js.map
|
|
55
|
+
//# sourceMappingURL=html-element-ext.js.map
|
|
@@ -1,6 +1 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/extensions/html-element-ext.ts"],
|
|
4
|
-
"mappings": "AAAA,SAAS,qBAAqB;AAmD9B,YAAY,UAAU,UAAU,WAAkB;AAGhD,OAAK,KAAK;AACZ;AAEA,YAAY,UAAU,oBAAoB,SAAU,QAGlD;AACA,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;",
|
|
5
|
-
"names": []
|
|
6
|
-
}
|
|
1
|
+
{"version":3,"file":"html-element-ext.js","sourceRoot":"","sources":["..\\..\\src\\extensions\\html-element-ext.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
// core-browser: 브라우저 전용 유틸리티
|
|
2
|
+
// 확장 (사이드 이펙트)
|
|
1
3
|
import "./extensions/element-ext.js";
|
|
2
4
|
import "./extensions/html-element-ext.js";
|
|
5
|
+
// 재내보내기
|
|
3
6
|
export * from "./extensions/element-ext.js";
|
|
4
7
|
export * from "./extensions/html-element-ext.js";
|
|
5
8
|
export * from "./utils/download.js";
|
|
@@ -7,4 +10,4 @@ export * from "./utils/fetch.js";
|
|
|
7
10
|
export * from "./utils/file-dialog.js";
|
|
8
11
|
export * from "./utils/IndexedDbStore.js";
|
|
9
12
|
export * from "./utils/IndexedDbVirtualFs.js";
|
|
10
|
-
//# sourceMappingURL=index.js.map
|
|
13
|
+
//# sourceMappingURL=index.js.map
|