Skip to content

Commit

Permalink
feat: add includeStyleProperties option
Browse files Browse the repository at this point in the history
* the full list of computedStyle properties can be cached
* users can now manually specify which style properties are included

This commit is applied from bubkoo/html-to-image#436
  • Loading branch information
aeharding committed Dec 5, 2023
1 parent b0fe2d8 commit 4461d79
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 10 deletions.
2 changes: 1 addition & 1 deletion src/copy-css-styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export function copyCssStyles<T extends HTMLElement | SVGElement>(
const clonedStyle = cloned.style
const computedStyle = ownerWindow!.getComputedStyle(node)
const defaultStyle = getDefaultStyle(node, null, context)
const diffStyle = getDiffStyle(computedStyle, defaultStyle)
const diffStyle = getDiffStyle(computedStyle, defaultStyle, context.includeStyleProperties)

// fix
diffStyle.delete('transition-property')
Expand Down
2 changes: 1 addition & 1 deletion src/copy-pseudo-class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export function copyPseudoClass<T extends HTMLElement | SVGElement>(
`content: '${ content }';`,
]

const diffStyle = getDiffStyle(computedStyle, defaultStyle)
const diffStyle = getDiffStyle(computedStyle, defaultStyle, context.includeStyleProperties)

// fix
diffStyle.delete('content')
Expand Down
1 change: 1 addition & 0 deletions src/create-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export async function createContext<T extends Node>(node: T, options?: Options &
onCloneNode: null,
onEmbedNode: null,
onCreateForeignObjectSvg: null,
includeStyleProperties: null,
autoDestruct: false,
...options,

Expand Down
27 changes: 19 additions & 8 deletions src/get-diff-style.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,29 @@
export function getDiffStyle(
style: CSSStyleDeclaration,
defaultStyle: Map<string, string>,
includeStyleProperties?: string[] | null,
) {
const diffStyle = new Map<string, [string, string]>()
const prefixs: string[] = []
const prefixTree = new Map<string, Map<string, [string, string]>>()

for (let len = style.length, i = 0; i < len; i++) {
const name = style.item(i)
if (includeStyleProperties) {
for (const name of includeStyleProperties) {
applyTo(name)
}
} else {
for (let len = style.length, i = 0; i < len; i++) {
const name = style.item(i)
applyTo(name)
}
}

for (let len = prefixs.length, i = 0; i < len; i++) {
prefixTree.get(prefixs[i])
?.forEach((value, name) => diffStyle.set(name, value))
}

function applyTo(name: string) {
const value = style.getPropertyValue(name)
const priority = style.getPropertyPriority(name)

Expand All @@ -22,7 +38,7 @@ export function getDiffStyle(
map.set(name, [value, priority])
}

if (defaultStyle.get(name) === value && !priority) continue
if (defaultStyle.get(name) === value && !priority) return

if (prefix) {
prefixs.push(prefix)
Expand All @@ -31,10 +47,5 @@ export function getDiffStyle(
}
}

for (let len = prefixs.length, i = 0; i < len; i++) {
prefixTree.get(prefixs[i])
?.forEach((value, name) => diffStyle.set(name, value))
}

return diffStyle
}
8 changes: 8 additions & 0 deletions src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,4 +183,12 @@ export interface Options {
* Triggered after a ForeignObjectSvg is created
*/
onCreateForeignObjectSvg?: ((svg: SVGSVGElement) => void) | null

/**
* An array of style property names.
* Can be used to manually specify which style properties are
* included when cloning nodes.
* This can be useful for performance-critical scenarios.
*/
includeStyleProperties?: string[] | null
}

0 comments on commit 4461d79

Please sign in to comment.