// ==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 // @downloadURL none // ==/UserScript== (function () { 'use strict'; /** * @return {Promise} */ 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} */ 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( $( `` ) ); header.querySelector('div:nth-child(7)').replaceWith( $( `` ) ); 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()); } }());