-
Notifications
You must be signed in to change notification settings - Fork 582
/
Copy pathclone-pseudos.ts
69 lines (59 loc) · 1.81 KB
/
clone-pseudos.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import type { Options } from './types'
import { uuid, getStyleProperties } from './util'
type Pseudo = ':before' | ':after'
function formatCSSText(style: CSSStyleDeclaration) {
const content = style.getPropertyValue('content')
return `${style.cssText} content: '${content.replace(/'|"/g, '')}';`
}
function formatCSSProperties(style: CSSStyleDeclaration, options: Options) {
return getStyleProperties(options)
.map((name) => {
const value = style.getPropertyValue(name)
const priority = style.getPropertyPriority(name)
return `${name}: ${value}${priority ? ' !important' : ''};`
})
.join(' ')
}
function getPseudoElementStyle(
className: string,
pseudo: Pseudo,
style: CSSStyleDeclaration,
options: Options,
): Text {
const selector = `.${className}:${pseudo}`
const cssText = style.cssText
? formatCSSText(style)
: formatCSSProperties(style, options)
return document.createTextNode(`${selector}{${cssText}}`)
}
function clonePseudoElement<T extends HTMLElement>(
nativeNode: T,
clonedNode: T,
pseudo: Pseudo,
options: Options,
) {
const style = window.getComputedStyle(nativeNode, pseudo)
const content = style.getPropertyValue('content')
if (content === '' || content === 'none') {
return
}
const className = uuid()
try {
clonedNode.className = `${clonedNode.className} ${className}`
} catch (err) {
return
}
const styleElement = document.createElement('style')
styleElement.appendChild(
getPseudoElementStyle(className, pseudo, style, options),
)
clonedNode.appendChild(styleElement)
}
export function clonePseudoElements<T extends HTMLElement>(
nativeNode: T,
clonedNode: T,
options: Options,
) {
clonePseudoElement(nativeNode, clonedNode, ':before', options)
clonePseudoElement(nativeNode, clonedNode, ':after', options)
}