mirror of
https://github.com/niklasvh/html2canvas.git
synced 2023-08-10 21:13:10 +03:00
Compare commits
4 Commits
v1.0.0-rc.
...
v1.0.0-rc.
Author | SHA1 | Date | |
---|---|---|---|
3982df1492 | |||
1514220812 | |||
d07b6811c6 | |||
bacfadff96 |
10
CHANGELOG.md
10
CHANGELOG.md
@ -2,6 +2,16 @@
|
|||||||
|
|
||||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||||
|
|
||||||
|
# [1.0.0-rc.7](https://github.com/niklasvh/html2canvas/compare/v1.0.0-rc.6...v1.0.0-rc.7) (2020-08-09)
|
||||||
|
|
||||||
|
|
||||||
|
### fix
|
||||||
|
|
||||||
|
* concatenate contiguous font-family tokens (#2219) ([bacfadf](https://github.com/niklasvh/html2canvas/commit/bacfadff96d907d9e8ab4ef515ca6487de9e51fc)), closes [#2219](https://github.com/niklasvh/html2canvas/issues/2219)
|
||||||
|
* external styles on svg elements (#2320) ([1514220](https://github.com/niklasvh/html2canvas/commit/1514220812cfb22d64d0974558d9c14fe90a41d3)), closes [#2320](https://github.com/niklasvh/html2canvas/issues/2320)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [1.0.0-rc.6](https://github.com/niklasvh/html2canvas/compare/v1.0.0-rc.5...v1.0.0-rc.6) (2020-08-08)
|
# [1.0.0-rc.6](https://github.com/niklasvh/html2canvas/compare/v1.0.0-rc.5...v1.0.0-rc.6) (2020-08-08)
|
||||||
|
|
||||||
|
|
||||||
|
2
package-lock.json
generated
2
package-lock.json
generated
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "html2canvas",
|
"name": "html2canvas",
|
||||||
"version": "1.0.0-rc.6",
|
"version": "1.0.0-rc.7",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
"module": "dist/html2canvas.esm.js",
|
"module": "dist/html2canvas.esm.js",
|
||||||
"typings": "dist/types/index.d.ts",
|
"typings": "dist/types/index.d.ts",
|
||||||
"browser": "dist/html2canvas.js",
|
"browser": "dist/html2canvas.js",
|
||||||
"version": "1.0.0-rc.6",
|
"version": "1.0.0-rc.7",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Niklas von Hertzen",
|
"name": "Niklas von Hertzen",
|
||||||
"email": "niklasvh@gmail.com",
|
"email": "niklasvh@gmail.com",
|
||||||
|
24
src/css/property-descriptors/__tests__/font-family.ts
Normal file
24
src/css/property-descriptors/__tests__/font-family.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import {deepEqual} from 'assert';
|
||||||
|
import {Parser} from '../../syntax/parser';
|
||||||
|
import {fontFamily} from '../font-family';
|
||||||
|
|
||||||
|
const fontFamilyParse = (value: string) => fontFamily.parse(Parser.parseValues(value));
|
||||||
|
|
||||||
|
describe('property-descriptors', () => {
|
||||||
|
describe('font-family', () => {
|
||||||
|
it('sans-serif', () => deepEqual(fontFamilyParse('sans-serif'), ['sans-serif']));
|
||||||
|
|
||||||
|
it('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'
|
||||||
|
]));
|
||||||
|
|
||||||
|
it("'escaping test\\'s font'", () =>
|
||||||
|
deepEqual(fontFamilyParse("'escaping test\\'s font'"), ["'escaping test's font'"]));
|
||||||
|
});
|
||||||
|
});
|
@ -1,6 +1,6 @@
|
|||||||
import {IPropertyListDescriptor, PropertyDescriptorParsingType} from '../IPropertyDescriptor';
|
import {IPropertyListDescriptor, PropertyDescriptorParsingType} from '../IPropertyDescriptor';
|
||||||
import {CSSValue} from '../syntax/parser';
|
import {CSSValue} from '../syntax/parser';
|
||||||
import {StringValueToken, TokenType} from '../syntax/tokenizer';
|
import {TokenType} from '../syntax/tokenizer';
|
||||||
|
|
||||||
export type FONT_FAMILY = string;
|
export type FONT_FAMILY = string;
|
||||||
|
|
||||||
@ -12,9 +12,26 @@ export const fontFamily: IPropertyListDescriptor<FontFamily> = {
|
|||||||
prefix: false,
|
prefix: false,
|
||||||
type: PropertyDescriptorParsingType.LIST,
|
type: PropertyDescriptorParsingType.LIST,
|
||||||
parse: (tokens: CSSValue[]) => {
|
parse: (tokens: CSSValue[]) => {
|
||||||
return tokens.filter(isStringToken).map(token => token.value);
|
const accumulator: string[] = [];
|
||||||
|
const results: string[] = [];
|
||||||
|
tokens.forEach(token => {
|
||||||
|
switch (token.type) {
|
||||||
|
case TokenType.IDENT_TOKEN:
|
||||||
|
case TokenType.STRING_TOKEN:
|
||||||
|
accumulator.push(token.value);
|
||||||
|
break;
|
||||||
|
case TokenType.NUMBER_TOKEN:
|
||||||
|
accumulator.push(token.number.toString());
|
||||||
|
break;
|
||||||
|
case TokenType.COMMA_TOKEN:
|
||||||
|
results.push(accumulator.join(' '));
|
||||||
|
accumulator.length = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (accumulator.length) {
|
||||||
|
results.push(accumulator.join(' '));
|
||||||
|
}
|
||||||
|
return results.map(result => (result.indexOf(' ') === -1 ? result : `'${result}'`));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const isStringToken = (token: CSSValue): token is StringValueToken =>
|
|
||||||
token.type === TokenType.STRING_TOKEN || token.type === TokenType.IDENT_TOKEN;
|
|
||||||
|
@ -116,7 +116,7 @@ export class DocumentCloner {
|
|||||||
return iframeLoad;
|
return iframeLoad;
|
||||||
}
|
}
|
||||||
|
|
||||||
createElementClone(node: HTMLElement): HTMLElement {
|
createElementClone<T extends HTMLElement | SVGElement>(node: T): HTMLElement | SVGElement {
|
||||||
if (isCanvasElement(node)) {
|
if (isCanvasElement(node)) {
|
||||||
return this.createCanvasClone(node);
|
return this.createCanvasClone(node);
|
||||||
}
|
}
|
||||||
@ -129,8 +129,7 @@ export class DocumentCloner {
|
|||||||
return this.createStyleClone(node);
|
return this.createStyleClone(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
const clone = node.cloneNode(false) as HTMLElement;
|
const clone = node.cloneNode(false) as T;
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
if (isImageElement(clone) && clone.loading === 'lazy') {
|
if (isImageElement(clone) && clone.loading === 'lazy') {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
@ -266,14 +265,14 @@ export class DocumentCloner {
|
|||||||
|
|
||||||
const window = node.ownerDocument.defaultView;
|
const window = node.ownerDocument.defaultView;
|
||||||
|
|
||||||
if (isHTMLElementNode(node) && window) {
|
if (window && isElementNode(node) && (isHTMLElementNode(node) || isSVGElementNode(node))) {
|
||||||
const clone = this.createElementClone(node);
|
const clone = this.createElementClone(node);
|
||||||
|
|
||||||
const style = window.getComputedStyle(node);
|
const style = window.getComputedStyle(node);
|
||||||
const styleBefore = window.getComputedStyle(node, ':before');
|
const styleBefore = window.getComputedStyle(node, ':before');
|
||||||
const styleAfter = window.getComputedStyle(node, ':after');
|
const styleAfter = window.getComputedStyle(node, ':after');
|
||||||
|
|
||||||
if (this.referenceElement === node) {
|
if (this.referenceElement === node && isHTMLElementNode(clone)) {
|
||||||
this.clonedReferenceElement = clone;
|
this.clonedReferenceElement = clone;
|
||||||
}
|
}
|
||||||
if (isBodyElement(clone)) {
|
if (isBodyElement(clone)) {
|
||||||
@ -307,7 +306,7 @@ export class DocumentCloner {
|
|||||||
|
|
||||||
this.counters.pop(counters);
|
this.counters.pop(counters);
|
||||||
|
|
||||||
if (style && this.options.copyStyles && !isIFrameElement(node)) {
|
if (style && (this.options.copyStyles || isSVGElementNode(node)) && !isIFrameElement(node)) {
|
||||||
copyCSSStyles(style, clone);
|
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
|
// Edge does not provide value for cssText
|
||||||
for (let i = style.length - 1; i >= 0; i--) {
|
for (let i = style.length - 1; i >= 0; i--) {
|
||||||
const property = style.item(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 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 isElementNode = (node: Node): node is Element => node.nodeType === Node.ELEMENT_NODE;
|
||||||
export const isHTMLElementNode = (node: Node): node is HTMLElement =>
|
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 =>
|
export const isSVGElementNode = (element: Element): element is SVGElement =>
|
||||||
typeof (element as SVGElement).className === 'object';
|
typeof (element as SVGElement).className === 'object';
|
||||||
export const isLIElement = (node: Element): node is HTMLLIElement => node.tagName === 'LI';
|
export const isLIElement = (node: Element): node is HTMLLIElement => node.tagName === 'LI';
|
||||||
|
@ -115,7 +115,7 @@ const parseStackTree = (
|
|||||||
} else if (order > 0) {
|
} else if (order > 0) {
|
||||||
let index = 0;
|
let index = 0;
|
||||||
parentStack.positiveZIndex.some((current, i) => {
|
parentStack.positiveZIndex.some((current, i) => {
|
||||||
if (order > current.element.container.styles.zIndex.order) {
|
if (order >= current.element.container.styles.zIndex.order) {
|
||||||
index = i + 1;
|
index = i + 1;
|
||||||
return false;
|
return false;
|
||||||
} else if (index > 0) {
|
} else if (index > 0) {
|
||||||
|
@ -15,6 +15,12 @@
|
|||||||
content: " ";
|
content: " ";
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<style>
|
||||||
|
.html { font: italic 13px sans-serif; }
|
||||||
|
.two { font: bold 14px sans-serif; }
|
||||||
|
.canvas { font: italic 15px serif; fill: red; }
|
||||||
|
</style>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div>
|
<div>
|
||||||
@ -28,6 +34,11 @@
|
|||||||
style="fill:#40aa54;fill-opacity:1;stroke:#20552a;stroke-width:7.99999952;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"/>
|
style="fill:#40aa54;fill-opacity:1;stroke:#20552a;stroke-width:7.99999952;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
<svg width="240" height="160" viewBox="0 0 120 80" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<text x="40" y="20" class="html">html</text>
|
||||||
|
<text x="55" y="25" class="two">2</text>
|
||||||
|
<text x="65" y="35" class="canvas">canvas</text>
|
||||||
|
</svg>
|
||||||
<img width="200" height="200" src="data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgd2lkdGg9IjMwNiIgaGVpZ2h0PSIyOTYiPjxkZWZzIGlkPSJkZWZzNCIgLz48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTYyLjQ2OTk1LC00NzcuMjg2MykiIGlkPSJsYXllcjEiPjxwYXRoIGQ9Im0gMzE0LjE1NzQ1LDQ4MS42OTU1OCBjIC01OS4yMDA4OSwwLjUzNzc0IC0xMTQuODA5NzksMzYuNzIyMTkgLTEzNy4zMTI1LDk1LjM0Mzc1IC0yOS4zOTEyOSw3Ni41NjY5MyA4LjgzOTMyLDE2Mi40NTI0NiA4NS40MDYyNSwxOTEuODQzNzUgbCAzNC4wMzEyNSwtODguNjg3NSBjIC0yMC4wNjc4LC03LjcxMzU4IC0zNC4zMTI1LC0yNy4xNTMyNCAtMzQuMzEyNSwtNDkuOTM3NSAwLC0yOS41NDcyMyAyMy45NTI3NywtNTMuNSA1My41LC01My41IDI5LjU0NzIzLDAgNTMuNSwyMy45NTI3NyA1My41LDUzLjUgMCwyMi43ODQyNiAtMTQuMjQ0Nyw0Mi4yMjM5MiAtMzQuMzEyNSw0OS45Mzc1IGwgMzQuMDMxMjUsODguNjg3NSBjIDM5LjI5MDg1LC0xNS4wODIzNCA3MC4zMjM5LC00Ni4xMTU0IDg1LjQwNjI1LC04NS40MDYyNSAyOS4zOTEyOSwtNzYuNTY2OTMgLTguODM5MzIsLTE2Mi40ODM3MSAtODUuNDA2MjUsLTE5MS44NzUgLTE3Ljk0NTM3LC02Ljg4ODU5IC0zNi40MDg1MywtMTAuMDcwODcgLTU0LjUzMTI1LC05LjkwNjI1IHoiIGlkPSJwYXRoMjgzMCIgc3R5bGU9ImZpbGw6IzQwYWE1NDtmaWxsLW9wYWNpdHk6MTtzdHJva2U6IzIwNTUyYTtzdHJva2Utd2lkdGg6Ny45OTk5OTk1MjtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1vcGFjaXR5OjE7c3Ryb2tlLWRhc2hhcnJheTpub25lIiAvPjwvZz48L3N2Zz4=" /></div>
|
<img width="200" height="200" src="data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgd2lkdGg9IjMwNiIgaGVpZ2h0PSIyOTYiPjxkZWZzIGlkPSJkZWZzNCIgLz48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTYyLjQ2OTk1LC00NzcuMjg2MykiIGlkPSJsYXllcjEiPjxwYXRoIGQ9Im0gMzE0LjE1NzQ1LDQ4MS42OTU1OCBjIC01OS4yMDA4OSwwLjUzNzc0IC0xMTQuODA5NzksMzYuNzIyMTkgLTEzNy4zMTI1LDk1LjM0Mzc1IC0yOS4zOTEyOSw3Ni41NjY5MyA4LjgzOTMyLDE2Mi40NTI0NiA4NS40MDYyNSwxOTEuODQzNzUgbCAzNC4wMzEyNSwtODguNjg3NSBjIC0yMC4wNjc4LC03LjcxMzU4IC0zNC4zMTI1LC0yNy4xNTMyNCAtMzQuMzEyNSwtNDkuOTM3NSAwLC0yOS41NDcyMyAyMy45NTI3NywtNTMuNSA1My41LC01My41IDI5LjU0NzIzLDAgNTMuNSwyMy45NTI3NyA1My41LDUzLjUgMCwyMi43ODQyNiAtMTQuMjQ0Nyw0Mi4yMjM5MiAtMzQuMzEyNSw0OS45Mzc1IGwgMzQuMDMxMjUsODguNjg3NSBjIDM5LjI5MDg1LC0xNS4wODIzNCA3MC4zMjM5LC00Ni4xMTU0IDg1LjQwNjI1LC04NS40MDYyNSAyOS4zOTEyOSwtNzYuNTY2OTMgLTguODM5MzIsLTE2Mi40ODM3MSAtODUuNDA2MjUsLTE5MS44NzUgLTE3Ljk0NTM3LC02Ljg4ODU5IC0zNi40MDg1MywtMTAuMDcwODcgLTU0LjUzMTI1LC05LjkwNjI1IHoiIGlkPSJwYXRoMjgzMCIgc3R5bGU9ImZpbGw6IzQwYWE1NDtmaWxsLW9wYWNpdHk6MTtzdHJva2U6IzIwNTUyYTtzdHJva2Utd2lkdGg6Ny45OTk5OTk1MjtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1vcGFjaXR5OjE7c3Ryb2tlLWRhc2hhcnJheTpub25lIiAvPjwvZz48L3N2Zz4=" /></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
41
tests/reftests/zindex/z-index20.html
Normal file
41
tests/reftests/zindex/z-index20.html
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head lang="en">
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title>z-index20</title>
|
||||||
|
<style>
|
||||||
|
.container {
|
||||||
|
width: 375px;
|
||||||
|
height: 603px;
|
||||||
|
background-color: #999;
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
.child1 {
|
||||||
|
height: 500px;
|
||||||
|
width: 200px;
|
||||||
|
background-color: red;
|
||||||
|
z-index: 20;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
.child2 {
|
||||||
|
height: 50px;
|
||||||
|
width: 100px;
|
||||||
|
background-color: blue;
|
||||||
|
z-index: 20;
|
||||||
|
position: absolute;
|
||||||
|
left: 30px;
|
||||||
|
top: 30px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script type="text/javascript" src="../../test.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container" id="___id___">
|
||||||
|
<div class="child1"></div>
|
||||||
|
<div class="child2"></div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
Reference in New Issue
Block a user