/* @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 => { 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,`; 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,
`; 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;