🏠 Home 

刺猬猫章节自动下载

打开刺猬猫章节页面时自动保存文章到本地, 支持##章节。

// ==UserScript==
// @name     刺猬猫章节自动下载
// @namespace https://github.com/NateScarlet/Scripts/tree/master/user-script
// @description 打开刺猬猫章节页面时自动保存文章到本地, 支持##章节。
// @grant    none
// @include	 https://www.ciweimao.com/chapter/*
// @run-at   document-idle
// @version   2023.12.05+fbf1a78c
// ==/UserScript==
"use strict";
(() => {
var __async = (__this, __arguments, generator) => {
return new Promise((resolve, reject) => {
var fulfilled = (value) => {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
};
var rejected = (value) => {
try {
step(generator.throw(value));
} catch (e) {
reject(e);
}
};
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
step((generator = generator.apply(__this, __arguments)).next());
});
};
// src/utils/elementRootText.ts
function elementRootText(element) {
let ret = "";
for (const i of element.childNodes) {
if (i.nodeType === i.TEXT_NODE) {
ret += i.nodeValue;
}
}
return ret.trim();
}
// src/utils/canvasToMarkdown.ts
function canvasToMarkdown(canvas, alt = "", title = "") {
return `![${alt}](${canvas.toDataURL()} "${title}")`;
}
// src/utils/isCanvasTainted.ts
function isCanvasTainted(canvas) {
try {
canvas.getContext("2d").getImageData(0, 0, 1, 1);
return false;
} catch (err) {
return err instanceof DOMException && err.name === "SecurityError";
}
}
// src/utils/imageToCanvas.ts
function imageToCanvas(_0) {
return __async(this, arguments, function* (img, {
background
} = {}) {
const canvas = document.createElement("canvas");
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;
const ctx = canvas.getContext("2d");
if (background) {
ctx.fillStyle = background;
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
ctx.drawImage(img, 0, 0);
if (img.src && img.crossOrigin !== "anonymous" && isCanvasTainted(canvas)) {
const corsImage = new Image();
corsImage.crossOrigin = "anonymous";
corsImage.src = img.src;
yield corsImage.decode();
return imageToCanvas(corsImage, { background });
}
return canvas;
});
}
// src/utils/imageToMarkdown.ts
function imageToMarkdown(_0) {
return __async(this, arguments, function* (img, {
background
} = {}) {
return canvasToMarkdown(
yield imageToCanvas(img, { background }),
img.alt,
img.title
);
});
}
// src/utils/loadImage.ts
function loadImage(url) {
return __async(this, null, function* () {
const img = new Image();
img.src = url;
img.alt = url;
yield img.decode();
return img;
});
}
// src/utils/sleep.ts
function sleep(duration) {
return __async(this, null, function* () {
return new Promise((resolve) => {
setTimeout(resolve, duration);
});
});
}
// src/ciweimao.com/download.user.ts
var __name__ = "刺猬猫章节自动下载";
(function() {
return __async(this, null, function* () {
const chapter = document.querySelector("#J_BookCnt .chapter").firstChild.textContent;
let lines = [];
let startTime = Date.now();
while (lines.length === 0 && Date.now() - startTime < 6e4) {
yield sleep(1e3);
for (const i of document.querySelectorAll("#J_BookImage")) {
const url = i.style["background-image"].match(
/(?:url\(")?(.+)(?:"\))?/
)[1];
const line = yield imageToMarkdown(yield loadImage(url));
lines.push(line);
}
for (const i of document.querySelectorAll("#J_BookRead p.chapter")) {
const line = elementRootText(i);
lines.push(line);
for (const img of i.querySelectorAll("img")) {
yield img.decode();
lines.push(yield imageToMarkdown(img));
}
}
for (const i of document.querySelectorAll("p.author_say")) {
const line = elementRootText(i);
lines.push(`    ${line}`);
for (const img of i.querySelectorAll("img")) {
yield img.decode();
lines.push(yield imageToMarkdown(img));
}
}
lines = lines.filter((i) => i.length > 0);
}
console.log(`${__name__}: 获取到 ${lines.length} 行`);
const file = new Blob([`# ${chapter}
`, lines.join("\n\n") + "\n"], {
type: "text/markdown"
});
const anchor = document.createElement("a");
anchor.href = URL.createObjectURL(file);
anchor.download = `${location.pathname.split("/").slice(-1)[0]} ${document.title}.md`;
anchor.style["display"] = "none";
document.body.append(anchor);
anchor.click();
setTimeout(() => {
document.body.removeChild(anchor);
URL.revokeObjectURL(anchor.href);
}, 0);
});
})();
})();