mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-08-16 01:13:08 +09:00
111 lines
2.8 KiB
JavaScript
111 lines
2.8 KiB
JavaScript
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
// ==UserScript==
|
|
// @name HTMLImageElement.decode Polyfill (best-effort)
|
|
// @namespace internal-userscripts
|
|
// @description Adds a Promise-based decode() that resolves on load and rejects on error.
|
|
// @match *://*/*
|
|
// @grant none
|
|
// @run-at document-start
|
|
// ==/UserScript==
|
|
(function () {
|
|
"use strict";
|
|
|
|
var global = typeof window !== "undefined" ? window : null;
|
|
if (!global || !global.HTMLImageElement) {
|
|
return;
|
|
}
|
|
|
|
var proto = global.HTMLImageElement.prototype;
|
|
if (typeof proto.decode === "function") {
|
|
return;
|
|
}
|
|
|
|
var PromiseCtor = global.Promise;
|
|
if (typeof PromiseCtor !== "function") {
|
|
return;
|
|
}
|
|
|
|
function rejectPromise(error) {
|
|
return new PromiseCtor(function (resolve, reject) {
|
|
reject(error);
|
|
});
|
|
}
|
|
|
|
function hasLoadedImage(img) {
|
|
return img.complete && (img.naturalWidth > 0 || img.naturalHeight > 0);
|
|
}
|
|
|
|
function isBrokenImage(img) {
|
|
return img.complete && img.naturalWidth === 0 && img.naturalHeight === 0;
|
|
}
|
|
|
|
function decode() {
|
|
var img = this;
|
|
if (!(img instanceof global.HTMLImageElement)) {
|
|
return rejectPromise(new TypeError("decode can only be used on an HTMLImageElement"));
|
|
}
|
|
|
|
if (hasLoadedImage(img)) {
|
|
return PromiseCtor.resolve();
|
|
}
|
|
if (isBrokenImage(img)) {
|
|
return rejectPromise(new Error("Image decode failed"));
|
|
}
|
|
|
|
var src = "";
|
|
try {
|
|
src = img.currentSrc || img.src || "";
|
|
} catch (e) {}
|
|
if (!src) {
|
|
return rejectPromise(new Error("Image has no src"));
|
|
}
|
|
|
|
return new PromiseCtor(function (resolve, reject) {
|
|
var settled = false;
|
|
|
|
function cleanup() {
|
|
if (settled) {
|
|
return;
|
|
}
|
|
settled = true;
|
|
img.removeEventListener("load", onLoad, false);
|
|
img.removeEventListener("error", onError, false);
|
|
}
|
|
|
|
function onLoad() {
|
|
cleanup();
|
|
resolve();
|
|
}
|
|
|
|
function onError() {
|
|
cleanup();
|
|
reject(new Error("Image decode failed"));
|
|
}
|
|
|
|
img.addEventListener("load", onLoad, false);
|
|
img.addEventListener("error", onError, false);
|
|
|
|
if (hasLoadedImage(img)) {
|
|
cleanup();
|
|
resolve();
|
|
} else if (isBrokenImage(img)) {
|
|
cleanup();
|
|
reject(new Error("Image decode failed"));
|
|
}
|
|
});
|
|
}
|
|
|
|
try {
|
|
Object.defineProperty(proto, "decode", {
|
|
value: decode,
|
|
writable: true,
|
|
configurable: true
|
|
});
|
|
} catch (e) {
|
|
proto.decode = decode;
|
|
}
|
|
|
|
try { global.__internalUserscriptsImageDecodePolyfill = true; } catch (e) {}
|
|
})();
|