UNPKG

html2canvas

Version:
193 lines (163 loc) 6.2 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _ForeignObjectRenderer = require('./renderer/ForeignObjectRenderer'); var testRangeBounds = function testRangeBounds(document) { var TEST_HEIGHT = 123; if (document.createRange) { var range = document.createRange(); if (range.getBoundingClientRect) { var testElement = document.createElement('boundtest'); testElement.style.height = TEST_HEIGHT + 'px'; testElement.style.display = 'block'; document.body.appendChild(testElement); range.selectNode(testElement); var rangeBounds = range.getBoundingClientRect(); var 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' var testBase64 = function testBase64(document, src) { var img = new Image(); var canvas = document.createElement('canvas'); var ctx = canvas.getContext('2d'); return new Promise(function (resolve) { // Single pixel base64 image renders fine on iOS 10.3??? img.src = src; var onload = function onload() { try { ctx.drawImage(img, 0, 0); canvas.toDataURL(); } catch (e) { return resolve(false); } return resolve(true); }; img.onload = onload; img.onerror = function () { return resolve(false); }; if (img.complete === true) { setTimeout(function () { onload(); }, 500); } }); }; var testCORS = function testCORS() { return typeof new Image().crossOrigin !== 'undefined'; }; var testResponseType = function testResponseType() { return typeof new XMLHttpRequest().responseType === 'string'; }; var testSVG = function testSVG(document) { var img = new Image(); var canvas = document.createElement('canvas'); var 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; }; var isGreenPixel = function isGreenPixel(data) { return data[0] === 0 && data[1] === 255 && data[2] === 0 && data[3] === 255; }; var testForeignObject = function testForeignObject(document) { var canvas = document.createElement('canvas'); var size = 100; canvas.width = size; canvas.height = size; var ctx = canvas.getContext('2d'); ctx.fillStyle = 'rgb(0, 255, 0)'; ctx.fillRect(0, 0, size, size); var img = new Image(); var greenImageSrc = canvas.toDataURL(); img.src = greenImageSrc; var svg = (0, _ForeignObjectRenderer.createForeignObjectSVG)(size, size, 0, 0, img); ctx.fillStyle = 'red'; ctx.fillRect(0, 0, size, size); return (0, _ForeignObjectRenderer.loadSerializedSVG)(svg).then(function (img) { ctx.drawImage(img, 0, 0); var data = ctx.getImageData(0, 0, size, size).data; ctx.fillStyle = 'red'; ctx.fillRect(0, 0, size, size); var node = document.createElement('div'); node.style.backgroundImage = 'url(' + greenImageSrc + ')'; node.style.height = size + 'px'; // Firefox 55 does not render inline <img /> tags return isGreenPixel(data) ? (0, _ForeignObjectRenderer.loadSerializedSVG)((0, _ForeignObjectRenderer.createForeignObjectSVG)(size, size, 0, 0, node)) : Promise.reject(false); }).then(function (img) { ctx.drawImage(img, 0, 0); // Edge does not render background-images return isGreenPixel(ctx.getImageData(0, 0, size, size).data); }).catch(function (e) { return false; }); }; var FEATURES = { // $FlowFixMe - get/set properties not yet supported get SUPPORT_RANGE_BOUNDS() { 'use strict'; var value = testRangeBounds(document); Object.defineProperty(FEATURES, 'SUPPORT_RANGE_BOUNDS', { value: value }); return value; }, // $FlowFixMe - get/set properties not yet supported get SUPPORT_SVG_DRAWING() { 'use strict'; var value = testSVG(document); Object.defineProperty(FEATURES, 'SUPPORT_SVG_DRAWING', { value: value }); return value; }, // $FlowFixMe - get/set properties not yet supported get SUPPORT_BASE64_DRAWING() { 'use strict'; return function (src) { var _value = testBase64(document, src); Object.defineProperty(FEATURES, 'SUPPORT_BASE64_DRAWING', { value: function value() { return _value; } }); return _value; }; }, // $FlowFixMe - get/set properties not yet supported get SUPPORT_FOREIGNOBJECT_DRAWING() { 'use strict'; var value = typeof Array.from === 'function' && typeof window.fetch === 'function' ? testForeignObject(document) : Promise.resolve(false); Object.defineProperty(FEATURES, 'SUPPORT_FOREIGNOBJECT_DRAWING', { value: value }); return value; }, // $FlowFixMe - get/set properties not yet supported get SUPPORT_CORS_IMAGES() { 'use strict'; var value = testCORS(); Object.defineProperty(FEATURES, 'SUPPORT_CORS_IMAGES', { value: value }); return value; }, // $FlowFixMe - get/set properties not yet supported get SUPPORT_RESPONSE_TYPE() { 'use strict'; var value = testResponseType(); Object.defineProperty(FEATURES, 'SUPPORT_RESPONSE_TYPE', { value: value }); return value; }, // $FlowFixMe - get/set properties not yet supported get SUPPORT_CORS_XHR() { 'use strict'; var value = 'withCredentials' in new XMLHttpRequest(); Object.defineProperty(FEATURES, 'SUPPORT_CORS_XHR', { value: value }); return value; } }; exports.default = FEATURES;