mirror of
https://github.com/niklasvh/html2canvas.git
synced 2023-08-10 21:13:10 +03:00
fix: external styles on svg elements (#2320)
This commit is contained in:

committed by
GitHub

parent
d07b6811c6
commit
1514220812
@ -6,26 +6,19 @@ const fontFamilyParse = (value: string) => fontFamily.parse(Parser.parseValues(v
|
||||
|
||||
describe('property-descriptors', () => {
|
||||
describe('font-family', () => {
|
||||
it('sans-serif', () =>
|
||||
deepEqual(fontFamilyParse('sans-serif'), [
|
||||
"sans-serif",
|
||||
]));
|
||||
it('sans-serif', () => deepEqual(fontFamilyParse('sans-serif'), ['sans-serif']));
|
||||
|
||||
it('great fonts 40 library', () =>
|
||||
deepEqual(fontFamilyParse('great fonts 40 library'), [
|
||||
"'great fonts 40 library'",
|
||||
]));
|
||||
deepEqual(fontFamilyParse('great fonts 40 library'), ["'great fonts 40 library'"]));
|
||||
|
||||
it('preferred font, "quoted fallback font", font', () =>
|
||||
deepEqual(fontFamilyParse('preferred font, "quoted fallback font", font'), [
|
||||
"'preferred font'",
|
||||
"'quoted fallback font'",
|
||||
"font"
|
||||
'font'
|
||||
]));
|
||||
|
||||
it("'escaping test\\'s font'", () =>
|
||||
deepEqual(fontFamilyParse("'escaping test\\'s font'"), [
|
||||
"'escaping test\'s font'",
|
||||
]));
|
||||
deepEqual(fontFamilyParse("'escaping test\\'s font'"), ["'escaping test's font'"]));
|
||||
});
|
||||
});
|
||||
|
@ -32,6 +32,6 @@ export const fontFamily: IPropertyListDescriptor<FontFamily> = {
|
||||
if (accumulator.length) {
|
||||
results.push(accumulator.join(' '));
|
||||
}
|
||||
return results.map(result => result.indexOf(' ') === -1 ? result : `'${result}'`);
|
||||
return results.map(result => (result.indexOf(' ') === -1 ? result : `'${result}'`));
|
||||
}
|
||||
};
|
||||
|
@ -116,7 +116,7 @@ export class DocumentCloner {
|
||||
return iframeLoad;
|
||||
}
|
||||
|
||||
createElementClone(node: HTMLElement): HTMLElement {
|
||||
createElementClone<T extends HTMLElement | SVGElement>(node: T): HTMLElement | SVGElement {
|
||||
if (isCanvasElement(node)) {
|
||||
return this.createCanvasClone(node);
|
||||
}
|
||||
@ -129,8 +129,7 @@ export class DocumentCloner {
|
||||
return this.createStyleClone(node);
|
||||
}
|
||||
|
||||
const clone = node.cloneNode(false) as HTMLElement;
|
||||
|
||||
const clone = node.cloneNode(false) as T;
|
||||
// @ts-ignore
|
||||
if (isImageElement(clone) && clone.loading === 'lazy') {
|
||||
// @ts-ignore
|
||||
@ -266,14 +265,14 @@ export class DocumentCloner {
|
||||
|
||||
const window = node.ownerDocument.defaultView;
|
||||
|
||||
if (isHTMLElementNode(node) && window) {
|
||||
if (window && isElementNode(node) && (isHTMLElementNode(node) || isSVGElementNode(node))) {
|
||||
const clone = this.createElementClone(node);
|
||||
|
||||
const style = window.getComputedStyle(node);
|
||||
const styleBefore = window.getComputedStyle(node, ':before');
|
||||
const styleAfter = window.getComputedStyle(node, ':after');
|
||||
|
||||
if (this.referenceElement === node) {
|
||||
if (this.referenceElement === node && isHTMLElementNode(clone)) {
|
||||
this.clonedReferenceElement = clone;
|
||||
}
|
||||
if (isBodyElement(clone)) {
|
||||
@ -307,7 +306,7 @@ export class DocumentCloner {
|
||||
|
||||
this.counters.pop(counters);
|
||||
|
||||
if (style && this.options.copyStyles && !isIFrameElement(node)) {
|
||||
if (style && (this.options.copyStyles || isSVGElementNode(node)) && !isIFrameElement(node)) {
|
||||
copyCSSStyles(style, clone);
|
||||
}
|
||||
|
||||
@ -487,7 +486,7 @@ const iframeLoader = (iframe: HTMLIFrameElement): Promise<HTMLIFrameElement> =>
|
||||
});
|
||||
};
|
||||
|
||||
export const copyCSSStyles = (style: CSSStyleDeclaration, target: HTMLElement): HTMLElement => {
|
||||
export const copyCSSStyles = <T extends HTMLElement | SVGElement>(style: CSSStyleDeclaration, target: T): T => {
|
||||
// Edge does not provide value for cssText
|
||||
for (let i = style.length - 1; i >= 0; i--) {
|
||||
const property = style.item(i);
|
||||
|
@ -102,7 +102,7 @@ const createsStackingContext = (styles: CSSParsedDeclaration): boolean => styles
|
||||
export const isTextNode = (node: Node): node is Text => node.nodeType === Node.TEXT_NODE;
|
||||
export const isElementNode = (node: Node): node is Element => node.nodeType === Node.ELEMENT_NODE;
|
||||
export const isHTMLElementNode = (node: Node): node is HTMLElement =>
|
||||
typeof (node as HTMLElement).style !== 'undefined';
|
||||
isElementNode(node) && typeof (node as HTMLElement).style !== 'undefined' && !isSVGElementNode(node);
|
||||
export const isSVGElementNode = (element: Element): element is SVGElement =>
|
||||
typeof (element as SVGElement).className === 'object';
|
||||
export const isLIElement = (node: Element): node is HTMLLIElement => node.tagName === 'LI';
|
||||
|
Reference in New Issue
Block a user