-
Notifications
You must be signed in to change notification settings - Fork 43
/
copy-css-styles.ts
64 lines (59 loc) · 2 KB
/
copy-css-styles.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
import type { Context } from './context'
import { getDefaultStyle } from './get-default-style'
import { getDiffStyle } from './get-diff-style'
import { IN_CHROME } from './utils'
export function copyCssStyles<T extends HTMLElement | SVGElement>(
node: T,
cloned: T,
isRoot: boolean,
context: Context,
): Map<string, [string, string]> {
const { ownerWindow, includeStyleProperties, currentParentNodeStyle } = context
const clonedStyle = cloned.style
const computedStyle = ownerWindow!.getComputedStyle(node)
const defaultStyle = getDefaultStyle(node, null, context)
currentParentNodeStyle?.forEach((_, key) => {
defaultStyle.delete(key)
})
const style = getDiffStyle(computedStyle, defaultStyle, includeStyleProperties)
// fix
style.delete('transition-property')
style.delete('all') // svg: all
style.delete('d') // svg: d
style.delete('content') // Safari shows pseudoelements if content is set
if (isRoot) {
style.delete('margin-top')
style.delete('margin-right')
style.delete('margin-bottom')
style.delete('margin-left')
style.delete('margin-block-start')
style.delete('margin-block-end')
style.delete('margin-inline-start')
style.delete('margin-inline-end')
style.set('box-sizing', ['border-box', ''])
}
// fix background-clip: text
if (style.get('background-clip')?.[0] === 'text') {
cloned.classList.add('______background-clip--text')
}
// fix chromium
// https://github.com/RigoCorp/html-to-image/blob/master/src/cssFixes.ts
if (IN_CHROME) {
if (!style.has('font-kerning'))
style.set('font-kerning', ['normal', ''])
if (
(
style.get('overflow-x')?.[0] === 'hidden'
|| style.get('overflow-y')?.[0] === 'hidden'
)
&& style.get('text-overflow')?.[0] === 'ellipsis'
&& node.scrollWidth === node.clientWidth
) {
style.set('text-overflow', ['clip', ''])
}
}
style.forEach(([value, priority], name) => {
clonedStyle.setProperty(name, value, priority)
})
return style
}