mirror of
https://github.com/niklasvh/html2canvas.git
synced 2023-08-10 21:13:10 +03:00
136 lines
3.8 KiB
JavaScript
136 lines
3.8 KiB
JavaScript
/* @flow */
|
|
'use strict';
|
|
|
|
const testRangeBounds = document => {
|
|
const TEST_HEIGHT = 123;
|
|
|
|
if (document.createRange) {
|
|
const range = document.createRange();
|
|
if (range.getBoundingClientRect) {
|
|
const testElement = document.createElement('boundtest');
|
|
testElement.style.height = `${TEST_HEIGHT}px`;
|
|
testElement.style.display = 'block';
|
|
document.body.appendChild(testElement);
|
|
|
|
range.selectNode(testElement);
|
|
const rangeBounds = range.getBoundingClientRect();
|
|
const rangeHeight = Math.round(rangeBounds.height);
|
|
document.body.removeChild(testElement);
|
|
if (rangeHeight === TEST_HEIGHT) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
};
|
|
|
|
// iOS 10.3 taints canvas with base64 images unless crossOrigin = 'anonymous'
|
|
const testBase64 = (document: Document, src: string): Promise<boolean> => {
|
|
const img = new Image();
|
|
const canvas = document.createElement('canvas');
|
|
const ctx = canvas.getContext('2d');
|
|
|
|
return new Promise(resolve => {
|
|
// Single pixel base64 image renders fine on iOS 10.3???
|
|
img.src = src;
|
|
|
|
const onload = () => {
|
|
try {
|
|
ctx.drawImage(img, 0, 0);
|
|
canvas.toDataURL();
|
|
} catch (e) {
|
|
return resolve(false);
|
|
}
|
|
|
|
return resolve(true);
|
|
};
|
|
|
|
img.onload = onload;
|
|
|
|
if (img.complete === true) {
|
|
setTimeout(() => {
|
|
onload();
|
|
}, 500);
|
|
}
|
|
});
|
|
};
|
|
|
|
const testSVG = document => {
|
|
const img = new Image();
|
|
const canvas = document.createElement('canvas');
|
|
const ctx = canvas.getContext('2d');
|
|
img.src = `data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'></svg>`;
|
|
|
|
try {
|
|
ctx.drawImage(img, 0, 0);
|
|
canvas.toDataURL();
|
|
} catch (e) {
|
|
return false;
|
|
}
|
|
return true;
|
|
};
|
|
|
|
const testForeignObject = document => {
|
|
const img = new Image();
|
|
const canvas = document.createElement('canvas');
|
|
const ctx = canvas.getContext('2d');
|
|
img.src = `data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'><foreignObject><div></div></foreignObject></svg>`;
|
|
|
|
return new Promise(resolve => {
|
|
const onload = () => {
|
|
try {
|
|
ctx.drawImage(img, 0, 0);
|
|
canvas.toDataURL();
|
|
} catch (e) {
|
|
return resolve(false);
|
|
}
|
|
|
|
return resolve(true);
|
|
};
|
|
|
|
img.onload = onload;
|
|
|
|
if (img.complete === true) {
|
|
setTimeout(() => {
|
|
onload();
|
|
}, 50);
|
|
}
|
|
});
|
|
};
|
|
|
|
const FEATURES = {
|
|
// $FlowFixMe - get/set properties not yet supported
|
|
get SUPPORT_RANGE_BOUNDS() {
|
|
'use strict';
|
|
const value = testRangeBounds(document);
|
|
Object.defineProperty(FEATURES, 'SUPPORT_RANGE_BOUNDS', {value});
|
|
return value;
|
|
},
|
|
// $FlowFixMe - get/set properties not yet supported
|
|
get SUPPORT_SVG_DRAWING() {
|
|
'use strict';
|
|
const value = testSVG(document);
|
|
Object.defineProperty(FEATURES, 'SUPPORT_SVG_DRAWING', {value});
|
|
return value;
|
|
},
|
|
// $FlowFixMe - get/set properties not yet supported
|
|
get SUPPORT_BASE64_DRAWING() {
|
|
'use strict';
|
|
return (src: string) => {
|
|
const value = testBase64(document, src);
|
|
Object.defineProperty(FEATURES, 'SUPPORT_BASE64_DRAWING', {value: () => value});
|
|
return value;
|
|
};
|
|
},
|
|
// $FlowFixMe - get/set properties not yet supported
|
|
get SUPPORT_FOREIGNOBJECT_DRAWING() {
|
|
'use strict';
|
|
const value = testForeignObject(document);
|
|
Object.defineProperty(FEATURES, 'SUPPORT_FOREIGNOBJECT_DRAWING', {value});
|
|
return value;
|
|
}
|
|
};
|
|
|
|
export default FEATURES;
|