From cfaecf6460f5e5897a258d8cb3dbc9b89d8f683f Mon Sep 17 00:00:00 2001 From: maoznir Date: Wed, 5 Jan 2022 18:19:54 +0200 Subject: [PATCH 1/3] Fix transparent video on safari 14.1 by using fetch instead of XHR --- src/util/xhr/getBlobFromURL.js | 80 +++++++++++++++++++++++++++------- 1 file changed, 64 insertions(+), 16 deletions(-) diff --git a/src/util/xhr/getBlobFromURL.js b/src/util/xhr/getBlobFromURL.js index 685ffbf0..47e46aab 100644 --- a/src/util/xhr/getBlobFromURL.js +++ b/src/util/xhr/getBlobFromURL.js @@ -1,3 +1,18 @@ +/** + * Reject on timeout + * @param maxTimeoutMS + * @param reject + * @returns {number} timerID + */ +function rejectOnTimeout(maxTimeoutMS, reject) { + return setTimeout(() => { + reject({ + status: 'error', + message: 'Timeout loading Blob URL' + }); + }, maxTimeoutMS); +} + /** * @description Converts a URL to a BLOB URL * @param {string} urlToLoad @@ -10,34 +25,67 @@ * } * }>} */ -function getBlobFromURL(urlToLoad, max_timeout_ms) { +function getBlobFromURL(urlToLoad, maxTimeoutMS) { return new Promise((resolve, reject) => { - let timerID = setTimeout(() => { - reject({ - status: 'error', - message: 'Timeout loading Blob URL' - }); - }, max_timeout_ms); + const timerID = rejectOnTimeout(maxTimeoutMS, reject); - let xhr = new XMLHttpRequest(); - xhr.responseType = 'blob'; - xhr.onload = function (response) { - clearTimeout(timerID); // clear timeout reject error + // If fetch exists, use it to fetch blob, otherwise use XHR. + // XHR causes issues on safari 14.1 so we prefer fetch + const fetchBlob = fetch ? loadUrlUsingFetch : loadUrlUsingXhr; + + fetchBlob(urlToLoad).then((blob) => { resolve({ status: 'success', payload: { - blobURL: URL.createObjectURL(xhr.response) + blobURL: URL.createObjectURL(blob) } }); - }; - - xhr.onerror = function () { - clearTimeout(timerID); // clear timeout reject error + }).catch(() => { reject({ status: 'error', message: 'Error loading Blob URL' }); + }).finally(() => { + // Clear the timeout timer on fail or success. + clearTimeout(timerID); + }); + }); +} + +/** + * Use fetch function to fetch file + * @param urlToLoad + * @returns {Promise} + */ +function loadUrlUsingFetch(urlToLoad) { + return new Promise((resolve, reject) => { + fetch(urlToLoad).then((response) => { + response.blob().then((blob) => { + resolve(blob); + }); + }).catch(() => { + reject('error'); + }); + }); +} + +/** + * Use XHR to fetch file + * @param urlToLoad + * @returns {Promise} + */ +function loadUrlUsingXhr(urlToLoad) { + return new Promise((resolve, reject) => { + let xhr = new XMLHttpRequest(); + xhr.responseType = 'blob'; + xhr.onload = function (response) { + resolve(xhr.response); }; + + xhr.onerror = function () { + reject('error'); + }; + xhr.open('GET', urlToLoad, true); xhr.send(); }); From 291cb5f3351f21cb1fe35b5cd81e4457d28a474b Mon Sep 17 00:00:00 2001 From: maoznir Date: Wed, 5 Jan 2022 18:23:56 +0200 Subject: [PATCH 2/3] Update cloudinary-core-shrinkwrap.min.js bundle size to be 32kb --- bundlewatch.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundlewatch.config.js b/bundlewatch.config.js index 07f07004..ebbf2cb3 100644 --- a/bundlewatch.config.js +++ b/bundlewatch.config.js @@ -6,7 +6,7 @@ const bundlewatchConfig = { }, { path: './dist/cloudinary-core-shrinkwrap.min.js', - maxSize: '31kb' + maxSize: '32kb' }, { path: './dist/cloudinary-jquery.min.js', From 899e56a669685d60f02bab90082018d764b2f158 Mon Sep 17 00:00:00 2001 From: maoznir Date: Thu, 6 Jan 2022 07:49:10 +0200 Subject: [PATCH 3/3] Only use fetch if it's defined and truthy --- src/util/xhr/getBlobFromURL.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/util/xhr/getBlobFromURL.js b/src/util/xhr/getBlobFromURL.js index 47e46aab..10978f56 100644 --- a/src/util/xhr/getBlobFromURL.js +++ b/src/util/xhr/getBlobFromURL.js @@ -31,7 +31,7 @@ function getBlobFromURL(urlToLoad, maxTimeoutMS) { // If fetch exists, use it to fetch blob, otherwise use XHR. // XHR causes issues on safari 14.1 so we prefer fetch - const fetchBlob = fetch ? loadUrlUsingFetch : loadUrlUsingXhr; + const fetchBlob = (typeof fetch !== 'undefined' && fetch) ? loadUrlUsingFetch : loadUrlUsingXhr; fetchBlob(urlToLoad).then((blob) => { resolve({ @@ -76,7 +76,7 @@ function loadUrlUsingFetch(urlToLoad) { */ function loadUrlUsingXhr(urlToLoad) { return new Promise((resolve, reject) => { - let xhr = new XMLHttpRequest(); + const xhr = new XMLHttpRequest(); xhr.responseType = 'blob'; xhr.onload = function (response) { resolve(xhr.response);