Compare commits

..

9 Commits

9 changed files with 2114 additions and 641 deletions

View File

@ -1,5 +1,13 @@
### Changelog ###
#### v1.0.0-alpha.12 - 5.4.2018 ####
* Fix white space appearing on element rendering (Fix #1438)
* Reset canvas transform on finish (Fix #1494)
#### v1.0.0-alpha.11 - 1.4.2018 ####
* Fix IE11 member not found error
* Support blob image resources in non-foreignObjectRendering mode
#### v1.0.0-alpha.10 - 15.2.2018 ####
* Re-introduce `onclone` option (Fix #1434)
* Add `ignoreElements` predicate function option

View File

@ -66,13 +66,6 @@ module.exports = function(config) {
platform: 'iOS',
version: '9.3',
device: 'iPhone 6 Plus Simulator'
},
'sl_ios_8.4_safari': {
base: 'SauceLabs',
browserName: 'Safari',
platform: 'iOS',
version: '8.4',
device: 'iPhone 5s Simulator'
}
};

2652
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,7 @@
"name": "html2canvas",
"description": "Screenshots with JavaScript",
"main": "dist/npm/index.js",
"version": "1.0.0-alpha.10",
"version": "1.0.0-alpha.12",
"author": {
"name": "Niklas von Hertzen",
"email": "niklasvh@gmail.com",

View File

@ -230,9 +230,17 @@ export class DocumentCloner {
}
if (node instanceof HTMLStyleElement && node.sheet && node.sheet.cssRules) {
const css = [].slice
.call(node.sheet.cssRules, 0)
.reduce((css, rule) => css + rule.cssText, '');
const css = [].slice.call(node.sheet.cssRules, 0).reduce((css, rule) => {
try {
if (rule && rule.cssText) {
return css + rule.cssText;
}
return css;
} catch (err) {
this.logger.log('Unable to access cssText property', rule.name);
return css;
}
}, '');
const style = node.cloneNode(false);
style.textContent = css;
return style;

View File

@ -33,6 +33,10 @@ export default class ResourceLoader {
if (this.hasResourceInCache(src)) {
return src;
}
if (isBlobImage(src)) {
this.cache[src] = loadImage(src, this.options.imageTimeout || 0);
return src;
}
if (!isSVG(src) || FEATURES.SUPPORT_SVG_DRAWING) {
if (this.options.allowTaint === true || isInlineImage(src) || this.isSameOrigin(src)) {
@ -215,6 +219,7 @@ const INLINE_IMG = /^data:image\/.*/i;
const isInlineImage = (src: string): boolean => INLINE_IMG.test(src);
const isInlineBase64Image = (src: string): boolean => INLINE_BASE64.test(src);
const isBlobImage = (src: string): boolean => src.substr(0, 4) === 'blob';
const isSVG = (src: string): boolean =>
src.substr(-3).toLowerCase() === 'svg' || INLINE_SVG.test(src);

View File

@ -14,6 +14,7 @@ import {Bounds} from './Bounds';
import {cloneWindow, DocumentCloner} from './Clone';
import {FontMetrics} from './Font';
import Color, {TRANSPARENT} from './Color';
import {parseBounds, parseDocumentSize} from './Bounds';
export const renderElement = (
element: HTMLElement,
@ -62,14 +63,32 @@ export const renderElement = (
.then(() => cloner.resourceLoader.ready())
.then(() => {
const renderer = new ForeignObjectRenderer(cloner.documentElement);
const defaultView = ownerDocument.defaultView;
const scrollX = defaultView.pageXOffset;
const scrollY = defaultView.pageYOffset;
const isDocument =
element.tagName === 'HTML' || element.tagName === 'BODY';
const {width, height, left, top} = isDocument
? parseDocumentSize(ownerDocument)
: parseBounds(element, scrollX, scrollY);
return renderer.render({
backgroundColor,
logger,
scale: options.scale,
x: options.x,
y: options.y,
width: options.width,
height: options.height,
x: typeof options.x === 'number' ? options.x : left,
y: typeof options.y === 'number' ? options.y : top,
width:
typeof options.width === 'number'
? options.width
: Math.ceil(width),
height:
typeof options.height === 'number'
? options.height
: Math.ceil(height),
windowWidth: options.windowWidth,
windowHeight: options.windowHeight,
scrollX: options.scrollX,
@ -102,16 +121,33 @@ export const renderElement = (
logger.log(`Starting renderer`);
}
const defaultView = clonedDocument.defaultView;
const scrollX = defaultView.pageXOffset;
const scrollY = defaultView.pageYOffset;
const isDocument =
clonedElement.tagName === 'HTML' || clonedElement.tagName === 'BODY';
const {width, height, left, top} = isDocument
? parseDocumentSize(ownerDocument)
: parseBounds(clonedElement, scrollX, scrollY);
const renderOptions = {
backgroundColor,
fontMetrics,
imageStore,
logger,
scale: options.scale,
x: options.x,
y: options.y,
width: options.width,
height: options.height
x: typeof options.x === 'number' ? options.x : left,
y: typeof options.y === 'number' ? options.y : top,
width:
typeof options.width === 'number'
? options.width
: Math.ceil(width),
height:
typeof options.height === 'number'
? options.height
: Math.ceil(height)
};
if (Array.isArray(options.target)) {

View File

@ -6,7 +6,6 @@ import type {RenderTarget} from './Renderer';
import CanvasRenderer from './renderer/CanvasRenderer';
import Logger from './Logger';
import {renderElement} from './Window';
import {parseBounds, parseDocumentSize} from './Bounds';
export type Options = {
async: ?boolean,
@ -50,15 +49,6 @@ const html2canvas = (element: HTMLElement, conf: ?Options): Promise<*> => {
}
const defaultView = ownerDocument.defaultView;
const scrollX = defaultView.pageXOffset;
const scrollY = defaultView.pageYOffset;
const isDocument = element.tagName === 'HTML' || element.tagName === 'BODY';
const {width, height, left, top} = isDocument
? parseDocumentSize(ownerDocument)
: parseBounds(element, scrollX, scrollY);
const defaultOptions = {
async: true,
allowTaint: false,
@ -71,10 +61,6 @@ const html2canvas = (element: HTMLElement, conf: ?Options): Promise<*> => {
scale: defaultView.devicePixelRatio || 1,
target: new CanvasRenderer(config.canvas),
useCORS: false,
x: left,
y: top,
width: Math.ceil(width),
height: Math.ceil(height),
windowWidth: defaultView.innerWidth,
windowHeight: defaultView.innerHeight,
scrollX: defaultView.pageXOffset,

View File

@ -98,6 +98,7 @@ export default class CanvasRenderer implements RenderTarget<HTMLCanvasElement> {
}
getTarget(): Promise<HTMLCanvasElement> {
this.canvas.getContext('2d').setTransform(1, 0, 0, 1, 0, 0);
return Promise.resolve(this.canvas);
}