From 82dc313617a4f14061f3f7c9575dbcb9b13fd70c Mon Sep 17 00:00:00 2001
From: MoyuScript <i@moyu.moe>
Date: Sun, 3 Sep 2017 21:24:06 +0800
Subject: [PATCH] Use crossOrigin images when useCORS option set

---
 src/Feature.js     | 11 +++++++++++
 src/ImageLoader.js | 23 ++++++++++++++++-------
 2 files changed, 27 insertions(+), 7 deletions(-)

diff --git a/src/Feature.js b/src/Feature.js
index a0cda97..44002c0 100644
--- a/src/Feature.js
+++ b/src/Feature.js
@@ -59,6 +59,10 @@ const testBase64 = (document: Document, src: string): Promise<boolean> => {
     });
 };
 
+const testCORS = () => {
+    return typeof new Image().crossOrigin !== 'undefined';
+};
+
 const testSVG = document => {
     const img = new Image();
     const canvas = document.createElement('canvas');
@@ -145,6 +149,13 @@ const FEATURES = {
         const value = testForeignObject(document);
         Object.defineProperty(FEATURES, 'SUPPORT_FOREIGNOBJECT_DRAWING', {value});
         return value;
+    },
+    // $FlowFixMe - get/set properties not yet supported
+    get SUPPORT_CORS_IMAGES() {
+        'use strict';
+        const value = testCORS();
+        Object.defineProperty(FEATURES, 'SUPPORT_CORS_IMAGES', {value});
+        return value;
     }
 };
 
diff --git a/src/ImageLoader.js b/src/ImageLoader.js
index 1bc69df..016676d 100644
--- a/src/ImageLoader.js
+++ b/src/ImageLoader.js
@@ -35,7 +35,7 @@ export default class ImageLoader<T> {
 
         if (isSVG(src)) {
             if (this.options.allowTaint === true || FEATURES.SUPPORT_SVG_DRAWING) {
-                return this.addImage(src, src);
+                return this.addImage(src, src, false);
             }
         } else {
             if (
@@ -43,9 +43,13 @@ export default class ImageLoader<T> {
                 isInlineBase64Image(src) ||
                 this.isSameOrigin(src)
             ) {
-                return this.addImage(src, src);
-            } else if (typeof this.options.proxy === 'string' && !this.isSameOrigin(src)) {
-                // TODO proxy
+                return this.addImage(src, src, false);
+            } else if (!this.isSameOrigin(src)) {
+                if (typeof this.options.proxy === 'string') {
+                    // TODO proxy
+                } else if (this.options.useCORS === true && FEATURES.SUPPORT_CORS_IMAGES) {
+                    return this.addImage(src, src, true);
+                }
             }
         }
     }
@@ -102,7 +106,7 @@ export default class ImageLoader<T> {
         return typeof this.cache[key] !== 'undefined';
     }
 
-    addImage(key: string, src: string): string {
+    addImage(key: string, src: string, useCORS: boolean): string {
         if (__DEV__) {
             this.logger.log(`Added image ${key.substring(0, 256)}`);
         }
@@ -112,7 +116,7 @@ export default class ImageLoader<T> {
                 const img = new Image();
                 img.onload = () => resolve(img);
                 //ios safari 10.3 taints canvas with data urls unless crossOrigin is set to anonymous
-                if (!supportsDataImages) {
+                if (!supportsDataImages || useCORS) {
                     img.crossOrigin = 'anonymous';
                 }
 
@@ -127,7 +131,12 @@ export default class ImageLoader<T> {
                 if (this.options.imageTimeout) {
                     const timeout = this.options.imageTimeout;
                     setTimeout(
-                        () => reject(__DEV__ ? `Timed out (${timeout}ms) fetching ${src}` : ''),
+                        () =>
+                            reject(
+                                __DEV__
+                                    ? `Timed out (${timeout}ms) fetching ${src.substring(0, 256)}`
+                                    : ''
+                            ),
                         timeout
                     );
                 }