Skip to content

Commit 7654e56

Browse files
author
Nir Maoz
authored
Fix transparent video on safari 14.1 by using fetch instead of XHR (#282)
1 parent e97d198 commit 7654e56

2 files changed

Lines changed: 65 additions & 17 deletions

File tree

bundlewatch.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const bundlewatchConfig = {
66
},
77
{
88
path: './dist/cloudinary-core-shrinkwrap.min.js',
9-
maxSize: '31kb'
9+
maxSize: '32kb'
1010
},
1111
{
1212
path: './dist/cloudinary-jquery.min.js',

src/util/xhr/getBlobFromURL.js

Lines changed: 64 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
/**
2+
* Reject on timeout
3+
* @param maxTimeoutMS
4+
* @param reject
5+
* @returns {number} timerID
6+
*/
7+
function rejectOnTimeout(maxTimeoutMS, reject) {
8+
return setTimeout(() => {
9+
reject({
10+
status: 'error',
11+
message: 'Timeout loading Blob URL'
12+
});
13+
}, maxTimeoutMS);
14+
}
15+
116
/**
217
* @description Converts a URL to a BLOB URL
318
* @param {string} urlToLoad
@@ -10,34 +25,67 @@
1025
* }
1126
* }>}
1227
*/
13-
function getBlobFromURL(urlToLoad, max_timeout_ms) {
28+
function getBlobFromURL(urlToLoad, maxTimeoutMS) {
1429
return new Promise((resolve, reject) => {
15-
let timerID = setTimeout(() => {
16-
reject({
17-
status: 'error',
18-
message: 'Timeout loading Blob URL'
19-
});
20-
}, max_timeout_ms);
30+
const timerID = rejectOnTimeout(maxTimeoutMS, reject);
2131

22-
let xhr = new XMLHttpRequest();
23-
xhr.responseType = 'blob';
24-
xhr.onload = function (response) {
25-
clearTimeout(timerID); // clear timeout reject error
32+
// If fetch exists, use it to fetch blob, otherwise use XHR.
33+
// XHR causes issues on safari 14.1 so we prefer fetch
34+
const fetchBlob = (typeof fetch !== 'undefined' && fetch) ? loadUrlUsingFetch : loadUrlUsingXhr;
35+
36+
fetchBlob(urlToLoad).then((blob) => {
2637
resolve({
2738
status: 'success',
2839
payload: {
29-
blobURL: URL.createObjectURL(xhr.response)
40+
blobURL: URL.createObjectURL(blob)
3041
}
3142
});
32-
};
33-
34-
xhr.onerror = function () {
35-
clearTimeout(timerID); // clear timeout reject error
43+
}).catch(() => {
3644
reject({
3745
status: 'error',
3846
message: 'Error loading Blob URL'
3947
});
48+
}).finally(() => {
49+
// Clear the timeout timer on fail or success.
50+
clearTimeout(timerID);
51+
});
52+
});
53+
}
54+
55+
/**
56+
* Use fetch function to fetch file
57+
* @param urlToLoad
58+
* @returns {Promise<unknown>}
59+
*/
60+
function loadUrlUsingFetch(urlToLoad) {
61+
return new Promise((resolve, reject) => {
62+
fetch(urlToLoad).then((response) => {
63+
response.blob().then((blob) => {
64+
resolve(blob);
65+
});
66+
}).catch(() => {
67+
reject('error');
68+
});
69+
});
70+
}
71+
72+
/**
73+
* Use XHR to fetch file
74+
* @param urlToLoad
75+
* @returns {Promise<unknown>}
76+
*/
77+
function loadUrlUsingXhr(urlToLoad) {
78+
return new Promise((resolve, reject) => {
79+
const xhr = new XMLHttpRequest();
80+
xhr.responseType = 'blob';
81+
xhr.onload = function (response) {
82+
resolve(xhr.response);
4083
};
84+
85+
xhr.onerror = function () {
86+
reject('error');
87+
};
88+
4189
xhr.open('GET', urlToLoad, true);
4290
xhr.send();
4391
});

0 commit comments

Comments
 (0)