///
(() => {
/**
* @template {any[]} A
* @template R
* @param {(...args: A) => Promise} func
* @returns {(...args: A) => Promise}
*/
function wrapErr(func) {
return async (...args) => {
try {
return await func(...args);
} catch (e) {
console.error(e);
}
};
}
/**
* @param {string} url
*/
async function makeObjUrlFromUrl(url) {
const res = await fetch(url);
const blob = await res.blob();
return URL.createObjectURL(blob);
}
/** @typedef {(elem: HTMLElement, objUrl: string) => Promise} PropSetterType */
/** @type {Record} */
const propSetterMap = {
'data-background-image': async (elem, objUrl) => {
elem.style.backgroundImage = `url(${objUrl})`;
},
'data-src': async (elem, objUrl) => {
if (elem instanceof HTMLImageElement) elem.src = objUrl;
},
};
/**
* @param {HTMLElement} elem
* @param {string} attr
* @param {PropSetterType} setter
*/
async function lazyLoadOne(elem, attr, setter) {
const url = elem.getAttribute(attr);
if (!url) return;
const objUrl = await makeObjUrlFromUrl(url);
await setter(elem, objUrl);
elem.removeAttribute(attr);
}
/**
* @param {string} attr
*/
async function lazyLoad(attr) {
/** @type {HTMLElement[]} */
// @ts-ignore
const elements = [...document.body.querySelectorAll(`[${attr}]`)].filter(
(v) => v instanceof HTMLElement
);
const tasks = elements.map((v) =>
wrapErr(lazyLoadOne)(v, attr, propSetterMap[attr])
);
await Promise.all(tasks);
}
async function lazyLoadAll() {
await Promise.all(Object.keys(propSetterMap).map(lazyLoad));
}
// 使用 globalThis.plugins.push 注册插件
// 只有这样才能保证你的插件运行完成之后才会网页截图
globalThis.plugins.push(async () => {
await lazyLoadAll();
});
})();