From e7514b62fdb0a633d088e9e7101a1ee24b5a8211 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Mon, 21 Dec 2020 10:51:20 +0100 Subject: [PATCH 1/2] Keep going if loading the image blurrer worker fails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Until now it was assumed that loading the image blurrer worker would not fail. However, if the browser does not support the CSP "worker-src" directive (like Safari) trying to load the worker would throw an exception which would interrupt the load of Talk itself. Now the exception is caught and logged instead, and the image blurrer reverts to a synced generation if no worker is available (although that should not happen, as the image blurrer is used only on Chromium and Chromium supports the "worker-src" directive). Note that Firefox does not throw an exception when loading a worker if not allowed by the CSP. Moreover, as the worker object is created, it does not seem to be possible to know if the worker is actually not available. This is not a problem, though; the image blurrer is not used on Firefox, and even if it was Firefox supports the "worker-src" directive. Signed-off-by: Daniel Calviño Sánchez --- src/utils/imageBlurrer.js | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/utils/imageBlurrer.js b/src/utils/imageBlurrer.js index 8f8705cb3ca..d4d39c8031e 100644 --- a/src/utils/imageBlurrer.js +++ b/src/utils/imageBlurrer.js @@ -21,22 +21,27 @@ import { generateFilePath } from '@nextcloud/router' -const worker = new Worker(generateFilePath('spreed', '', 'js/image-blurrer-worker.js')) +let worker = null const pendingResults = {} let pendingResultsNextId = 0 -worker.onmessage = function(message) { - const pendingResult = pendingResults[message.data.id] - if (!pendingResult) { - console.debug('No pending result for blurring image with id ' + message.data.id) +try { + worker = new Worker(generateFilePath('spreed', '', 'js/image-blurrer-worker.js')) + worker.onmessage = function(message) { + const pendingResult = pendingResults[message.data.id] + if (!pendingResult) { + console.debug('No pending result for blurring image with id ' + message.data.id) - return - } + return + } - pendingResult(message.data.blurredImageAsDataUrl) + pendingResult(message.data.blurredImageAsDataUrl) - delete pendingResults[message.data.id] + delete pendingResults[message.data.id] + } +} catch (exception) { + console.error('Image blurrer worker could not be loaded', exception) } function blurSync(image, width, height, blurRadius) { @@ -54,7 +59,7 @@ function blurSync(image, width, height, blurRadius) { } export default function blur(image, width, height, blurRadius) { - if (typeof OffscreenCanvas === 'undefined') { + if (!worker || typeof OffscreenCanvas === 'undefined') { return blurSync(image, width, height, blurRadius) } From 8a6e439037dbec29e9daf86903ad27d0bab6c65a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Mon, 21 Dec 2020 13:48:30 +0100 Subject: [PATCH 2/2] Use lazy load for image blurrer worker MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The image blurrer worker now is loaded only when it is actually needed, so this should prevent the worker to be loaded on browsers other than Chromium, as well as on Chromium if no call is joined. This indirectly fixes the CSP error shown in Safari when the worker was loaded (as the worker is no longer loaded now in Safari) due to Safari not supporting the "worker-src" directive but requiring "child-src" to be used instead. Signed-off-by: Daniel Calviño Sánchez --- src/utils/imageBlurrer.js | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/src/utils/imageBlurrer.js b/src/utils/imageBlurrer.js index d4d39c8031e..2a29e27d117 100644 --- a/src/utils/imageBlurrer.js +++ b/src/utils/imageBlurrer.js @@ -21,27 +21,30 @@ import { generateFilePath } from '@nextcloud/router' -let worker = null +let worker const pendingResults = {} let pendingResultsNextId = 0 -try { - worker = new Worker(generateFilePath('spreed', '', 'js/image-blurrer-worker.js')) - worker.onmessage = function(message) { - const pendingResult = pendingResults[message.data.id] - if (!pendingResult) { - console.debug('No pending result for blurring image with id ' + message.data.id) +function loadWorker() { + try { + worker = new Worker(generateFilePath('spreed', '', 'js/image-blurrer-worker.js')) + worker.onmessage = function(message) { + const pendingResult = pendingResults[message.data.id] + if (!pendingResult) { + console.debug('No pending result for blurring image with id ' + message.data.id) - return - } + return + } - pendingResult(message.data.blurredImageAsDataUrl) + pendingResult(message.data.blurredImageAsDataUrl) - delete pendingResults[message.data.id] + delete pendingResults[message.data.id] + } + } catch (exception) { + worker = null + console.error('Image blurrer worker could not be loaded', exception) } -} catch (exception) { - console.error('Image blurrer worker could not be loaded', exception) } function blurSync(image, width, height, blurRadius) { @@ -59,7 +62,15 @@ function blurSync(image, width, height, blurRadius) { } export default function blur(image, width, height, blurRadius) { - if (!worker || typeof OffscreenCanvas === 'undefined') { + if (typeof OffscreenCanvas === 'undefined') { + return blurSync(image, width, height, blurRadius) + } + + if (worker === undefined) { + loadWorker() + } + + if (!worker) { return blurSync(image, width, height, blurRadius) }