@v-c/util 0.0.4 → 0.0.5
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/props-util/index.cjs +1 -1
- package/dist/props-util/index.d.ts +1 -1
- package/dist/props-util/index.js +17 -17
- package/package.json +5 -1
- package/src/Children/isFragment.ts +0 -6
- package/src/Children/tests/isFragment.test.tsx +0 -15
- package/src/Children/tests/toArray.test.tsx +0 -101
- package/src/Children/toArray.ts +0 -27
- package/src/Dom/addEventListener.ts +0 -20
- package/src/Dom/canUseDom.ts +0 -7
- package/src/Dom/class.ts +0 -29
- package/src/Dom/contains.ts +0 -19
- package/src/Dom/css.ts +0 -113
- package/src/Dom/dynamicCSS.ts +0 -173
- package/src/Dom/findDOMNode.ts +0 -23
- package/src/Dom/focus.ts +0 -96
- package/src/Dom/isVisible.ts +0 -23
- package/src/Dom/scrollLocker.ts +0 -144
- package/src/Dom/shadow.ts +0 -17
- package/src/Dom/styleChecker.ts +0 -31
- package/src/Dom/support.ts +0 -27
- package/src/EventInterface.ts +0 -19
- package/src/KeyCode.ts +0 -517
- package/src/Portal.tsx +0 -50
- package/src/PortalWrapper.tsx +0 -217
- package/src/composeProps.ts +0 -23
- package/src/createRef.ts +0 -32
- package/src/debug/diff.ts +0 -66
- package/src/deprecated.ts +0 -8
- package/src/getScrollBarSize.tsx +0 -57
- package/src/guid.ts +0 -4
- package/src/hooks/useEvent.ts +0 -3
- package/src/hooks/useId.ts +0 -20
- package/src/hooks/useLayoutEffect.ts +0 -61
- package/src/hooks/useMemo.ts +0 -21
- package/src/hooks/useMergedState.ts +0 -44
- package/src/hooks/useMobile.ts +0 -16
- package/src/hooks/useState.ts +0 -17
- package/src/index.ts +0 -3
- package/src/isEqual.ts +0 -50
- package/src/isMobile.ts +0 -15
- package/src/isValid.ts +0 -4
- package/src/omit.ts +0 -14
- package/src/pickAttrs.ts +0 -79
- package/src/props-util/index.ts +0 -57
- package/src/props-util/initDefaultProps.ts +0 -34
- package/src/raf.ts +0 -55
- package/src/setStyle.ts +0 -38
- package/src/switchScrollingEffect.ts +0 -48
- package/src/test/domHook.ts +0 -66
- package/src/type.ts +0 -94
- package/src/utils/checkSlotProp.ts +0 -10
- package/src/utils/get.ts +0 -15
- package/src/utils/omit.ts +0 -9
- package/src/utils/set.ts +0 -110
- package/src/utils/transition.ts +0 -128
- package/src/vnode.ts +0 -86
- package/src/vueuse/unref-element.ts +0 -13
- package/src/warning.ts +0 -79
- package/tests/Portal.spec.tsx +0 -199
- package/tsconfig.json +0 -8
- package/vite.config.ts +0 -18
- package/vitest.config.ts +0 -11
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=require("vue"),i=require("../isValid.cjs"),y=require("./initDefaultProps.cjs");function
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=require("vue"),i=require("../isValid.cjs"),y=require("./initDefaultProps.cjs");function a(t){return t&&(t.type===u.Comment||t.type===u.Fragment&&t.children.length===0||t.type===u.Text&&t.children.trim()==="")}function f(t=[]){const n=[];return t.forEach(r=>{Array.isArray(r)?n.push(...r):r?.type===u.Fragment?n.push(...f(r.children)):n.push(r)}),n.filter(r=>!a(r))}const o=Symbol("skipFlatten");function p(t,n=!0){const r=Array.isArray(t)?t:[t],s=[];return r.forEach(e=>{Array.isArray(e)?s.push(...p(e,n)):i.default(e)?s.push(e):e&&typeof e=="object"&&e.type===u.Fragment?e.key===o?s.push(e):s.push(...p(e.children,n)):e&&u.isVNode(e)&&(f&&!a(e)?s.push(e):f||s.push(e))}),n?f(s):s}exports.initDefaultProps=y.default;exports.filterEmpty=f;exports.flattenChildren=p;exports.isEmptyElement=a;exports.skipFlattenKey=o;
|
|
@@ -3,5 +3,5 @@ import { default as initDefaultProps } from './initDefaultProps';
|
|
|
3
3
|
export declare function isEmptyElement(c: any): boolean;
|
|
4
4
|
export declare function filterEmpty(children?: any[]): any[];
|
|
5
5
|
export declare const skipFlattenKey: unique symbol;
|
|
6
|
-
declare function flattenChildren(children?: VNode | VNodeNormalizedChildren,
|
|
6
|
+
declare function flattenChildren(children?: VNode | VNodeNormalizedChildren, isFilterEmpty?: boolean): any[];
|
|
7
7
|
export { flattenChildren, initDefaultProps };
|
package/dist/props-util/index.js
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
import { Comment as
|
|
2
|
-
import
|
|
1
|
+
import { Comment as a, Fragment as p, Text as y, isVNode as m } from "vue";
|
|
2
|
+
import i from "../isValid.js";
|
|
3
3
|
import { default as g } from "./initDefaultProps.js";
|
|
4
|
-
function
|
|
5
|
-
return t && (t.type ===
|
|
4
|
+
function u(t) {
|
|
5
|
+
return t && (t.type === a || t.type === p && t.children.length === 0 || t.type === y && t.children.trim() === "");
|
|
6
6
|
}
|
|
7
|
-
function
|
|
8
|
-
const
|
|
9
|
-
return t.forEach((
|
|
10
|
-
Array.isArray(
|
|
11
|
-
}),
|
|
7
|
+
function f(t = []) {
|
|
8
|
+
const s = [];
|
|
9
|
+
return t.forEach((r) => {
|
|
10
|
+
Array.isArray(r) ? s.push(...r) : r?.type === p ? s.push(...f(r.children)) : s.push(r);
|
|
11
|
+
}), s.filter((r) => !u(r));
|
|
12
12
|
}
|
|
13
13
|
const A = Symbol("skipFlatten");
|
|
14
|
-
function
|
|
15
|
-
const
|
|
16
|
-
return
|
|
17
|
-
Array.isArray(e) ? n.push(...
|
|
18
|
-
}), n;
|
|
14
|
+
function o(t, s = !0) {
|
|
15
|
+
const r = Array.isArray(t) ? t : [t], n = [];
|
|
16
|
+
return r.forEach((e) => {
|
|
17
|
+
Array.isArray(e) ? n.push(...o(e, s)) : i(e) ? n.push(e) : e && typeof e == "object" && e.type === p ? e.key === A ? n.push(e) : n.push(...o(e.children, s)) : e && m(e) && (f && !u(e) ? n.push(e) : f || n.push(e));
|
|
18
|
+
}), s ? f(n) : n;
|
|
19
19
|
}
|
|
20
20
|
export {
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
f as filterEmpty,
|
|
22
|
+
o as flattenChildren,
|
|
23
23
|
g as initDefaultProps,
|
|
24
|
-
|
|
24
|
+
u as isEmptyElement,
|
|
25
25
|
A as skipFlattenKey
|
|
26
26
|
};
|
package/package.json
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@v-c/util",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.5",
|
|
5
5
|
"description": "Vue3 components utils",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|
|
8
8
|
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"package.json"
|
|
12
|
+
],
|
|
9
13
|
"author": {
|
|
10
14
|
"name": "aibayanyu20",
|
|
11
15
|
"email": "aibayanyu@qq.com",
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { isFragment } from '@v-c/util/dist/Children/isFragment.ts'
|
|
2
|
-
import { describe, expect, it } from 'vitest'
|
|
3
|
-
import { createVNode } from 'vue'
|
|
4
|
-
|
|
5
|
-
describe('isFragment', () => {
|
|
6
|
-
it('should ', () => {
|
|
7
|
-
const Dom = createVNode('div', null, '1')
|
|
8
|
-
|
|
9
|
-
const dom = isFragment(Dom)
|
|
10
|
-
const dom1 = isFragment(<>1</>)
|
|
11
|
-
|
|
12
|
-
expect(dom).toBe(false)
|
|
13
|
-
expect(dom1).toBe(true)
|
|
14
|
-
})
|
|
15
|
-
})
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
import { toArray } from '@v-c/util/dist/Children/toArray.ts'
|
|
2
|
-
import { mount } from '@vue/test-utils'
|
|
3
|
-
import { describe, expect, it } from 'vitest'
|
|
4
|
-
import { defineComponent, Fragment } from 'vue'
|
|
5
|
-
|
|
6
|
-
describe('toArray', () => {
|
|
7
|
-
let children: any
|
|
8
|
-
const UL = defineComponent({
|
|
9
|
-
setup(_, { slots }) {
|
|
10
|
-
return () => {
|
|
11
|
-
children = slots.default?.()
|
|
12
|
-
return <ul>{slots.default?.()}</ul>
|
|
13
|
-
}
|
|
14
|
-
},
|
|
15
|
-
})
|
|
16
|
-
it('basic', () => {
|
|
17
|
-
const wrapper = mount(
|
|
18
|
-
<UL>
|
|
19
|
-
<li key={1}>1</li>
|
|
20
|
-
<li key={2}>2</li>
|
|
21
|
-
<li key={3}>3</li>
|
|
22
|
-
</UL>,
|
|
23
|
-
)
|
|
24
|
-
const nodes = toArray(children)
|
|
25
|
-
expect(nodes).toHaveLength(3)
|
|
26
|
-
expect(nodes.map(v => v.key)).toEqual([1, 2, 3])
|
|
27
|
-
wrapper.unmount()
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
it('array', () => {
|
|
31
|
-
const wrapper = mount(
|
|
32
|
-
<UL>
|
|
33
|
-
<li key={1}>1</li>
|
|
34
|
-
{[<li key={2}>2</li>, <li key={3}>3</li>]}
|
|
35
|
-
</UL>,
|
|
36
|
-
)
|
|
37
|
-
const nodes = toArray(children)
|
|
38
|
-
expect(nodes).toHaveLength(3)
|
|
39
|
-
expect(nodes.map(v => v.key)).toEqual([1, 2, 3])
|
|
40
|
-
wrapper.unmount()
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
it('fragment', () => {
|
|
44
|
-
const wrapper = mount(
|
|
45
|
-
<UL>
|
|
46
|
-
<li key={1}>1</li>
|
|
47
|
-
<>
|
|
48
|
-
<li key="2">2</li>
|
|
49
|
-
<li key="3">3</li>
|
|
50
|
-
</>
|
|
51
|
-
<Fragment>
|
|
52
|
-
<>
|
|
53
|
-
<li key="4">4</li>
|
|
54
|
-
<li key="5">5</li>
|
|
55
|
-
</>
|
|
56
|
-
</Fragment>
|
|
57
|
-
</UL>,
|
|
58
|
-
)
|
|
59
|
-
const nodes = toArray(children)
|
|
60
|
-
expect(nodes).toHaveLength(5)
|
|
61
|
-
expect(nodes.map(v => v.key)).toEqual([1, '2', '3', '4', '5'])
|
|
62
|
-
wrapper.unmount()
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
it('keep empty', () => {
|
|
66
|
-
const wrapper = mount(
|
|
67
|
-
<UL>
|
|
68
|
-
{null}
|
|
69
|
-
<li key="1">1</li>
|
|
70
|
-
<>
|
|
71
|
-
<li key="2">2</li>
|
|
72
|
-
{null}
|
|
73
|
-
<li key="3">3</li>
|
|
74
|
-
</>
|
|
75
|
-
<Fragment>
|
|
76
|
-
<>
|
|
77
|
-
<li key="4">4</li>
|
|
78
|
-
{undefined}
|
|
79
|
-
<li key="5">5</li>
|
|
80
|
-
</>
|
|
81
|
-
</Fragment>
|
|
82
|
-
{undefined}
|
|
83
|
-
</UL>,
|
|
84
|
-
)
|
|
85
|
-
|
|
86
|
-
const nodes = toArray(children, { keepEmpty: true })
|
|
87
|
-
expect(nodes).toHaveLength(9)
|
|
88
|
-
expect(nodes.map(c => c && c.key)).toEqual([
|
|
89
|
-
null,
|
|
90
|
-
'1',
|
|
91
|
-
'2',
|
|
92
|
-
null,
|
|
93
|
-
'3',
|
|
94
|
-
'4',
|
|
95
|
-
undefined,
|
|
96
|
-
'5',
|
|
97
|
-
null,
|
|
98
|
-
])
|
|
99
|
-
wrapper.unmount()
|
|
100
|
-
})
|
|
101
|
-
})
|
package/src/Children/toArray.ts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import type { VNode } from 'vue'
|
|
2
|
-
import { isFragment } from './isFragment'
|
|
3
|
-
|
|
4
|
-
export interface Option {
|
|
5
|
-
keepEmpty?: boolean
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export function toArray(children: any, option: Option = {}) {
|
|
9
|
-
// 从slots中获取的必定是数组
|
|
10
|
-
let ret: VNode[] = []
|
|
11
|
-
// 判断children是否是一个数组,如果不是就把它放到一个数组中
|
|
12
|
-
if (!Array.isArray(children))
|
|
13
|
-
children = [children]
|
|
14
|
-
for (const child of children) {
|
|
15
|
-
if ((child === undefined || child === null) && !option.keepEmpty)
|
|
16
|
-
continue
|
|
17
|
-
|
|
18
|
-
if (Array.isArray(child))
|
|
19
|
-
ret = ret.concat(toArray(child, option))
|
|
20
|
-
|
|
21
|
-
else if (isFragment(child) && child.children)
|
|
22
|
-
ret = ret.concat(toArray(child.children, option))
|
|
23
|
-
else
|
|
24
|
-
ret.push(child)
|
|
25
|
-
}
|
|
26
|
-
return ret
|
|
27
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
export type WindowEventName = keyof WindowEventMap
|
|
2
|
-
export type DocumentEventName = keyof DocumentEventMap
|
|
3
|
-
export function addEventListener<E extends WindowEventName = WindowEventName>(target: Window, eventType: E, cb: WindowEventMap[E], option?: AddEventListenerOptions): {
|
|
4
|
-
remove: () => void
|
|
5
|
-
}
|
|
6
|
-
export function addEventListener<E extends DocumentEventName = DocumentEventName>(target: Document, eventType: E, cb: DocumentEventMap[E], option?: AddEventListenerOptions): {
|
|
7
|
-
remove: () => void
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export function addEventListener(...args: any[]) {
|
|
11
|
-
const [target, eventType, cb, option] = args
|
|
12
|
-
if (target?.addEventListener)
|
|
13
|
-
target.addEventListener(eventType as any, cb, option)
|
|
14
|
-
|
|
15
|
-
return {
|
|
16
|
-
remove() {
|
|
17
|
-
target?.removeEventListener?.(eventType as any, cb, option)
|
|
18
|
-
},
|
|
19
|
-
}
|
|
20
|
-
}
|
package/src/Dom/canUseDom.ts
DELETED
package/src/Dom/class.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
export function hasClass(node: Element, className: string) {
|
|
2
|
-
if (node.classList)
|
|
3
|
-
return node.classList.contains(className)
|
|
4
|
-
|
|
5
|
-
const originClass = node.className
|
|
6
|
-
return ` ${originClass} `.includes(` ${className} `)
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export function addClass(node: Element, className: string) {
|
|
10
|
-
if (node.classList) {
|
|
11
|
-
node.classList.add(className)
|
|
12
|
-
}
|
|
13
|
-
else {
|
|
14
|
-
if (!hasClass(node, className))
|
|
15
|
-
node.className = `${node.className} ${className}`
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export function removeClass(node: Element, className: string) {
|
|
20
|
-
if (node.classList) {
|
|
21
|
-
node.classList.remove(className)
|
|
22
|
-
}
|
|
23
|
-
else {
|
|
24
|
-
if (hasClass(node, className)) {
|
|
25
|
-
const originClass = node.className
|
|
26
|
-
node.className = ` ${originClass} `.replace(` ${className} `, ' ')
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
package/src/Dom/contains.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
export default function contains(root: Node | null | undefined, n?: Node) {
|
|
2
|
-
if (!root)
|
|
3
|
-
return false
|
|
4
|
-
|
|
5
|
-
// Use native if support
|
|
6
|
-
if (root.contains)
|
|
7
|
-
return root.contains(n as any)
|
|
8
|
-
|
|
9
|
-
// `document.contains` not support with IE11
|
|
10
|
-
let node: any = n
|
|
11
|
-
while (node) {
|
|
12
|
-
if (node === root)
|
|
13
|
-
return true
|
|
14
|
-
|
|
15
|
-
node = node.parentNode
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
return false
|
|
19
|
-
}
|
package/src/Dom/css.ts
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
const PIXEL_PATTERN = /margin|padding|width|height|max|min|offset/
|
|
2
|
-
|
|
3
|
-
const removePixel: any = {
|
|
4
|
-
left: true,
|
|
5
|
-
top: true,
|
|
6
|
-
}
|
|
7
|
-
const floatMap: any = {
|
|
8
|
-
cssFloat: 1,
|
|
9
|
-
styleFloat: 1,
|
|
10
|
-
float: 1,
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
function getComputedStyle(node: HTMLElement) {
|
|
14
|
-
return node.nodeType === 1 ? (node as any).ownerDocument.defaultView.getComputedStyle(node, null) : {}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function getStyleValue(node: HTMLElement, type: string, value: string) {
|
|
18
|
-
type = type.toLowerCase()
|
|
19
|
-
if (value === 'auto') {
|
|
20
|
-
if (type === 'height')
|
|
21
|
-
return node.offsetHeight
|
|
22
|
-
|
|
23
|
-
if (type === 'width')
|
|
24
|
-
return node.offsetWidth
|
|
25
|
-
}
|
|
26
|
-
if (!(type in removePixel))
|
|
27
|
-
removePixel[type] = PIXEL_PATTERN.test(type)
|
|
28
|
-
|
|
29
|
-
return removePixel[type] ? Number.parseFloat(value) || 0 : value
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export function get(node: HTMLElement, name: any) {
|
|
33
|
-
const length = arguments.length
|
|
34
|
-
const style = getComputedStyle(node)
|
|
35
|
-
|
|
36
|
-
name = floatMap[name] ? ('cssFloat' in node.style ? 'cssFloat' : 'styleFloat') : name
|
|
37
|
-
|
|
38
|
-
return length === 1 ? style : getStyleValue(node, name, style[name] || node.style[name])
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export function set(node: HTMLElement, name: any, value: string | number) {
|
|
42
|
-
const length = arguments.length
|
|
43
|
-
name = floatMap[name] ? ('cssFloat' in node.style ? 'cssFloat' : 'styleFloat') : name
|
|
44
|
-
if (length === 3) {
|
|
45
|
-
if (typeof value === 'number' && PIXEL_PATTERN.test(name))
|
|
46
|
-
value = `${value}px`
|
|
47
|
-
|
|
48
|
-
;(node.style as any)[name] = value // Number
|
|
49
|
-
return value
|
|
50
|
-
}
|
|
51
|
-
for (const x in name) {
|
|
52
|
-
if (x in name)
|
|
53
|
-
set(node, x, name[x])
|
|
54
|
-
}
|
|
55
|
-
return getComputedStyle(node)
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export function getOuterWidth(el: HTMLElement) {
|
|
59
|
-
if (el === document.body)
|
|
60
|
-
return document.documentElement.clientWidth
|
|
61
|
-
|
|
62
|
-
return el.offsetWidth
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export function getOuterHeight(el: HTMLElement) {
|
|
66
|
-
if (el === document.body)
|
|
67
|
-
return window.innerHeight || document.documentElement.clientHeight
|
|
68
|
-
|
|
69
|
-
return el.offsetHeight
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export function getDocSize() {
|
|
73
|
-
const width = Math.max(document.documentElement.scrollWidth, document.body.scrollWidth)
|
|
74
|
-
const height = Math.max(document.documentElement.scrollHeight, document.body.scrollHeight)
|
|
75
|
-
|
|
76
|
-
return {
|
|
77
|
-
width,
|
|
78
|
-
height,
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
export function getClientSize() {
|
|
83
|
-
const width = document.documentElement.clientWidth
|
|
84
|
-
const height = window.innerHeight || document.documentElement.clientHeight
|
|
85
|
-
return {
|
|
86
|
-
width,
|
|
87
|
-
height,
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export function getScroll() {
|
|
92
|
-
return {
|
|
93
|
-
scrollLeft: Math.max(document.documentElement.scrollLeft, document.body.scrollLeft),
|
|
94
|
-
scrollTop: Math.max(document.documentElement.scrollTop, document.body.scrollTop),
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
export function getOffset(node: any) {
|
|
99
|
-
const box = node.getBoundingClientRect()
|
|
100
|
-
const docElem = document.documentElement
|
|
101
|
-
|
|
102
|
-
// < ie8 不支持 win.pageXOffset, 则使用 docElem.scrollLeft
|
|
103
|
-
return {
|
|
104
|
-
left:
|
|
105
|
-
box.left
|
|
106
|
-
+ (window.pageXOffset || docElem.scrollLeft)
|
|
107
|
-
- (docElem.clientLeft || document.body.clientLeft || 0),
|
|
108
|
-
top:
|
|
109
|
-
box.top
|
|
110
|
-
+ (window.pageYOffset || docElem.scrollTop)
|
|
111
|
-
- (docElem.clientTop || document.body.clientTop || 0),
|
|
112
|
-
}
|
|
113
|
-
}
|
package/src/Dom/dynamicCSS.ts
DELETED
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
import canUseDom from './canUseDom'
|
|
2
|
-
import contains from './contains'
|
|
3
|
-
|
|
4
|
-
const APPEND_ORDER = 'data-vc-order'
|
|
5
|
-
const APPEND_PRIORITY = 'data-vc-priority'
|
|
6
|
-
const MARK_KEY = `vc-util-key`
|
|
7
|
-
|
|
8
|
-
const containerCache = new Map<ContainerType, Node & ParentNode>()
|
|
9
|
-
|
|
10
|
-
export type ContainerType = Element | ShadowRoot
|
|
11
|
-
export type Prepend = boolean | 'queue'
|
|
12
|
-
export type AppendType = 'prependQueue' | 'append' | 'prepend'
|
|
13
|
-
|
|
14
|
-
interface Options {
|
|
15
|
-
attachTo?: ContainerType
|
|
16
|
-
csp?: { nonce?: string }
|
|
17
|
-
prepend?: Prepend
|
|
18
|
-
/**
|
|
19
|
-
* Config the `priority` of `prependQueue`. Default is `0`.
|
|
20
|
-
* It's useful if you need to insert style before other style.
|
|
21
|
-
*/
|
|
22
|
-
priority?: number
|
|
23
|
-
mark?: string
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function getMark({ mark }: Options = {}) {
|
|
27
|
-
if (mark)
|
|
28
|
-
return mark.startsWith('data-') ? mark : `data-${mark}`
|
|
29
|
-
|
|
30
|
-
return MARK_KEY
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function getContainer(option: Options) {
|
|
34
|
-
if (option.attachTo)
|
|
35
|
-
return option.attachTo
|
|
36
|
-
|
|
37
|
-
const head = document.querySelector('head')
|
|
38
|
-
return head || document.body
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function getOrder(prepend?: Prepend): AppendType {
|
|
42
|
-
if (prepend === 'queue')
|
|
43
|
-
return 'prependQueue'
|
|
44
|
-
|
|
45
|
-
return prepend ? 'prepend' : 'append'
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Find style which inject by rc-util
|
|
50
|
-
*/
|
|
51
|
-
function findStyles(container: ContainerType) {
|
|
52
|
-
return Array.from(
|
|
53
|
-
(containerCache.get(container) || container).children,
|
|
54
|
-
).filter(node => node.tagName === 'STYLE') as HTMLStyleElement[]
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export function injectCSS(css: string, option: Options = {}) {
|
|
58
|
-
if (!canUseDom())
|
|
59
|
-
return null
|
|
60
|
-
|
|
61
|
-
const { csp, prepend, priority = 0 } = option
|
|
62
|
-
const mergedOrder = getOrder(prepend)
|
|
63
|
-
const isPrependQueue = mergedOrder === 'prependQueue'
|
|
64
|
-
|
|
65
|
-
const styleNode = document.createElement('style')
|
|
66
|
-
styleNode.setAttribute(APPEND_ORDER, mergedOrder)
|
|
67
|
-
|
|
68
|
-
if (isPrependQueue && priority)
|
|
69
|
-
styleNode.setAttribute(APPEND_PRIORITY, `${priority}`)
|
|
70
|
-
|
|
71
|
-
if (csp?.nonce)
|
|
72
|
-
styleNode.nonce = csp?.nonce
|
|
73
|
-
|
|
74
|
-
styleNode.innerHTML = css
|
|
75
|
-
|
|
76
|
-
const container = getContainer(option)
|
|
77
|
-
const { firstChild } = container
|
|
78
|
-
|
|
79
|
-
if (prepend) {
|
|
80
|
-
// If is queue `prepend`, it will prepend first style and then append rest style
|
|
81
|
-
if (isPrependQueue) {
|
|
82
|
-
const existStyle = findStyles(container).filter((node: any) => {
|
|
83
|
-
// Ignore style which not injected by rc-util with prepend
|
|
84
|
-
if (
|
|
85
|
-
!['prepend', 'prependQueue'].includes(node.getAttribute(APPEND_ORDER))
|
|
86
|
-
)
|
|
87
|
-
return false
|
|
88
|
-
|
|
89
|
-
// Ignore style which priority less then new style
|
|
90
|
-
const nodePriority = Number(node.getAttribute(APPEND_PRIORITY) || 0)
|
|
91
|
-
return priority >= nodePriority
|
|
92
|
-
})
|
|
93
|
-
|
|
94
|
-
if (existStyle.length) {
|
|
95
|
-
container.insertBefore(
|
|
96
|
-
styleNode,
|
|
97
|
-
existStyle[existStyle.length - 1].nextSibling,
|
|
98
|
-
)
|
|
99
|
-
|
|
100
|
-
return styleNode
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// Use `insertBefore` as `prepend`
|
|
105
|
-
container.insertBefore(styleNode, firstChild)
|
|
106
|
-
}
|
|
107
|
-
else {
|
|
108
|
-
container.appendChild(styleNode)
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
return styleNode
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
function findExistNode(key: string, option: Options = {}) {
|
|
115
|
-
const container = getContainer(option)
|
|
116
|
-
|
|
117
|
-
return findStyles(container).find(
|
|
118
|
-
node => node.getAttribute(getMark(option)) === key,
|
|
119
|
-
)
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
export function removeCSS(key: string, option: Options = {}) {
|
|
123
|
-
const existNode = findExistNode(key, option)
|
|
124
|
-
if (existNode) {
|
|
125
|
-
const container = getContainer(option)
|
|
126
|
-
container.removeChild(existNode)
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* qiankun will inject `appendChild` to insert into other
|
|
132
|
-
*/
|
|
133
|
-
function syncRealContainer(container: ContainerType, option: Options) {
|
|
134
|
-
const cachedRealContainer = containerCache.get(container)
|
|
135
|
-
|
|
136
|
-
// Find real container when not cached or cached container removed
|
|
137
|
-
if (!cachedRealContainer || !contains(document, cachedRealContainer)) {
|
|
138
|
-
const placeholderStyle: any = injectCSS('', option)
|
|
139
|
-
const { parentNode } = placeholderStyle
|
|
140
|
-
containerCache.set(container, parentNode)
|
|
141
|
-
container.removeChild(placeholderStyle)
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* manually clear container cache to avoid global cache in unit testes
|
|
147
|
-
*/
|
|
148
|
-
export function clearContainerCache() {
|
|
149
|
-
containerCache.clear()
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
export function updateCSS(css: string, key: string, option: Options = {}) {
|
|
153
|
-
const container = getContainer(option)
|
|
154
|
-
|
|
155
|
-
// Sync real parent
|
|
156
|
-
syncRealContainer(container, option)
|
|
157
|
-
|
|
158
|
-
const existNode = findExistNode(key, option)
|
|
159
|
-
|
|
160
|
-
if (existNode) {
|
|
161
|
-
if (option.csp?.nonce && existNode.nonce !== option.csp?.nonce)
|
|
162
|
-
existNode.nonce = option.csp?.nonce
|
|
163
|
-
|
|
164
|
-
if (existNode.innerHTML !== css)
|
|
165
|
-
existNode.innerHTML = css
|
|
166
|
-
|
|
167
|
-
return existNode
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
const newNode: any = injectCSS(css, option)
|
|
171
|
-
newNode.setAttribute(getMark(option), key)
|
|
172
|
-
return newNode
|
|
173
|
-
}
|
package/src/Dom/findDOMNode.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import type { ComponentPublicInstance, MaybeRef } from 'vue'
|
|
2
|
-
import { unref } from 'vue'
|
|
3
|
-
|
|
4
|
-
export function isDOM(node: any): node is HTMLElement | SVGElement {
|
|
5
|
-
// https://developer.mozilla.org/en-US/docs/Web/API/Element
|
|
6
|
-
// Since XULElement is also subclass of Element, we only need HTMLElement and SVGElement
|
|
7
|
-
return node instanceof HTMLElement || node instanceof SVGElement
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Return if a node is a DOM node. Else will return by `findDOMNode`
|
|
12
|
-
*/
|
|
13
|
-
export default function findDOMNode<T = Element | Text>(
|
|
14
|
-
_node: MaybeRef<ComponentPublicInstance | HTMLElement | SVGElement>,
|
|
15
|
-
): T | null {
|
|
16
|
-
const node = unref(_node)
|
|
17
|
-
if (isDOM(node))
|
|
18
|
-
return (node as unknown) as T
|
|
19
|
-
else if (node && '$el' in node)
|
|
20
|
-
return (node.$el as unknown) as T
|
|
21
|
-
|
|
22
|
-
return null
|
|
23
|
-
}
|