Greasy Fork is available in English.
处理图片资源加载失败时自动重新加载
当前为
// ==UserScript==
// @name 修复copymanga图片错误
// @namespace https://github.com/IronKinoko/copymanga
// @version 1.0.6
// @license MIT
// @description 处理图片资源加载失败时自动重新加载
// @author IronKinoko
// @match https://*.copymanga.com/*
// @icon https://www.google.com/s2/favicons?domain=copymanga.com
// @grant none
// ==/UserScript==
(function () {
'use strict';
/**
* @return {Promise<HTMLImageElement[]>}
*/
async function waitHasComicContent() {
return new Promise((resolve, reject) => {
const now = Date.now();
function getComic() {
if (Date.now() - now > 5000) reject();
const imgs = document.querySelectorAll('ul li img');
if (imgs.length) {
resolve(imgs);
} else {
requestAnimationFrame(getComic);
}
}
getComic();
})
}
async function injectFixImg() {
const imgs = await waitHasComicContent();
console.log('注入成功');
imgs.forEach((img) => {
img.addEventListener('error', () => {
console.log('error');
const url = new URL(img.src);
url.searchParams.set('t', Date.now());
img.src = url.toString();
});
});
}
function $(string) {
return new DOMParser().parseFromString(string, 'text/html').body.firstChild
}
function main() {
if (window.__copymanga_autofix) return console.log('已经插入过了')
window.__copymanga_autofix = true;
if (/comic\/.*\/chapter/.test(location.href)) injectFixImg();
if (location.pathname.startsWith('/h5')) {
addH5HistoryListener();
}
replaceHeader();
}
const _historyWrap = function (type) {
const orig = history[type];
const e = new Event(type);
return function () {
const rv = orig.apply(this, arguments);
e.arguments = arguments;
window.dispatchEvent(e);
return rv
}
};
async function addH5HistoryListener() {
history.pushState = _historyWrap('pushState');
history.replaceState = _historyWrap('replaceState');
window.addEventListener('pushState', runH5main);
window.addEventListener('replaceState', runH5main);
window.addEventListener('popstate', runH5main);
window.addEventListener('scroll', currentPage);
runH5main();
}
/**
* @param {Event} e
*/
async function currentPage() {
try {
if (!/h5\/comicContent\/.*/.test(location.href)) return
const scrollHeight = document.scrollingElement.scrollTop;
const list = await waitHasComicContent();
let height = 0;
for (let i = 0; i < list.length; i++) {
const item = list[i];
height += item.getBoundingClientRect().height;
if (height > scrollHeight) {
const dom = document.querySelector('.comicContentPopup .comicFixed');
dom.textContent = dom.textContent.replace(/(.*)\//, `${i + 1}/`);
break
}
}
} catch (error) {}
}
async function runH5main() {
try {
if (!/h5\/comicContent\/.*/.test(location.href)) return
const ulDom = await searchImgListDom();
const uuid = getComicId();
const domUUID = ulDom.dataset.uuid;
if (domUUID !== uuid) {
ulDom.dataset.uuid = uuid;
const list = await waitHasComicContent();
list.forEach((dom) => (dom.dataset.uuid = uuid));
injectFixImg();
}
const main = ulDom.parentElement;
main.style.position = 'unset';
main.style.overflowY = 'unset';
let nextPartDom = document.querySelector('#comicContentMain #nextpart');
let nextButton = document.querySelector(
'.comicControlBottomTop > div:nth-child(3) > span'
);
if (!nextPartDom) {
if (!nextButton) {
await openControl();
nextButton = document.querySelector(
'.comicControlBottomTop > div:nth-child(3) > span'
);
}
nextPartDom = document.createElement('div');
nextPartDom.style.textAlign = 'center';
nextPartDom.style.lineHeight = '50px';
nextPartDom.style.fontSize = '16px';
nextPartDom.textContent = '下一话';
nextPartDom.id = 'nextpart';
nextPartDom.onclick = async (e) => {
e.stopPropagation();
nextButton && nextButton.click();
};
document.getElementById('comicContentMain').appendChild(nextPartDom);
}
nextPartDom.style.display = nextButton.parentElement.classList.contains(
'noneUuid'
)
? 'none'
: 'block';
} catch (error) {}
}
function getComicId() {
const [_, uuid] = location.href.match(/h5\/comicContent\/.*\/(.*)/);
return uuid
}
/**
* @return {Promise<HTMLDivElement>}
*/
async function searchImgListDom() {
return new Promise((resolve, reject) => {
const now = Date.now();
function _searchImgListDom() {
if (Date.now() - now > 5000) reject();
const dom = document.querySelector('.comicContentPopupImageList');
if (dom) resolve(dom);
else requestAnimationFrame(_searchImgListDom);
}
_searchImgListDom();
})
}
function replaceHeader() {
const header = document.querySelector('.container.header-log .row');
if (header) {
header.style.flexWrap = 'nowrap';
header.querySelector('div:nth-child(6)').replaceWith(
$(
`<div class="col-1">
<div class="log-txt">
<a href="/web/person/shujia">我的书架</a>
<div class="log-unboder"></div>
</div>
</div>`
)
);
header.querySelector('div:nth-child(7)').replaceWith(
$(
`<div class="col-1">
<div class="log-txt">
<a href="/web/person/liulan">我的浏览</a>
<div class="log-unboder"></div>
</div>
</div>`
)
);
header.querySelector('div:nth-child(8)').className = 'col';
header.querySelector('div.col > div > div').style.justifyContent =
'flex-end';
}
}
main();
function fakeClickEvent() {
const { width, height } = document.body.getBoundingClientRect();
return new MouseEvent('click', { clientX: width / 2, clientY: height / 2 })
}
function sleep(time) {
return new Promise((resolve, reject) => {
setTimeout(resolve, time);
})
}
async function openControl() {
const li = document.querySelector('li.comicContentPopupImageItem');
li.dispatchEvent(fakeClickEvent());
await sleep(0);
li.dispatchEvent(fakeClickEvent());
}
}());