diff --git a/src/platform/web/dom/ImageHandle.js b/src/platform/web/dom/ImageHandle.js index ae05e868..fae3799e 100644 --- a/src/platform/web/dom/ImageHandle.js +++ b/src/platform/web/dom/ImageHandle.js @@ -15,6 +15,7 @@ limitations under the License. */ import {BlobHandle} from "./BlobHandle.js"; +import {domEventAsPromise} from "./utils.js"; export class ImageHandle { static async fromBlob(blob) { @@ -106,15 +107,7 @@ export function hasReadPixelPermission() { async function loadImgFromBlob(blob) { const img = document.createElement("img"); let detach; - const loadPromise = new Promise((resolve, _reject) => { - const reject = evt => _reject(evt.target.error); - detach = () => { - img.removeEventListener("load", resolve); - img.removeEventListener("error", reject); - }; - img.addEventListener("load", resolve); - img.addEventListener("error", reject); - }); + const loadPromise = domEventAsPromise(img, "load"); img.src = blob.url; await loadPromise; detach(); @@ -124,32 +117,14 @@ async function loadImgFromBlob(blob) { async function loadVideoFromBlob(blob) { const video = document.createElement("video"); video.muted = true; - let detach; - const loadPromise = new Promise((resolve, _reject) => { - const reject = evt => _reject(evt.target.error); - detach = () => { - video.removeEventListener("loadedmetadata", resolve); - video.removeEventListener("error", reject); - }; - video.addEventListener("loadedmetadata", resolve); - video.addEventListener("error", reject); - }); + const loadPromise = domEventAsPromise(video, "loadedmetadata"); video.src = blob.url; video.load(); await loadPromise; // seek to the first 1/10s to make sure that drawing the video // on a canvas won't give a blank image - const seekPromise = new Promise((resolve, _reject) => { - const reject = evt => _reject(evt.target.error); - detach = () => { - video.removeEventListener("seeked", resolve); - video.removeEventListener("error", reject); - }; - video.addEventListener("seeked", resolve); - video.addEventListener("error", reject); - }); + const seekPromise = domEventAsPromise(video, "seeked"); video.currentTime = 0.1; await seekPromise; - detach(); return video; } diff --git a/src/platform/web/dom/utils.js b/src/platform/web/dom/utils.js new file mode 100644 index 00000000..43a26640 --- /dev/null +++ b/src/platform/web/dom/utils.js @@ -0,0 +1,35 @@ +/* +Copyright 2020 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +export function domEventAsPromise(element, successEvent) { + return new Promise((resolve, reject) => { + let detach; + const handleError = evt => { + detach(); + reject(evt.target.error); + }; + const handleSuccess = () => { + detach(); + resolve(); + }; + detach = () => { + element.removeEventListener(successEvent, handleSuccess); + element.removeEventListener("error", handleError); + }; + element.addEventListener(successEvent, handleSuccess); + element.addEventListener("error", handleError); + }); +}