// ==UserScript== // @name zhihuPostCopy // @namespace http://tampermonkey.net/ // @version 2024-08-04 // @description zhihu Post Copy // @author You // @match https://zhuanlan.zhihu.com/write // @match https://zhuanlan.zhihu.com/p/* // @match https://baijiahao.baidu.com/builder/rc/edit* // @match https://creator.xiaohongshu.com/publish/publish // @match https://cp.11467.com/home/personal/news_add.html // @match https://cp.11467.com/home/personal/product_add.html // @match https://member.bilibili.com/platform/upload/text/edit // @match https://member.bilibili.com/article-text/home* // @match https://mp.sohu.com/mpfe/v4/contentManagement/news/addarticle* // @match http://mp.163.com/subscribe_v4/index.html#/article-publish // @icon https://www.google.com/s2/favicons?sz=64&domain=zhihu.com // @grant GM.setValue // @grant GM.getValue // @license MIT // @downloadURL none // ==/UserScript== (function() { 'use strict'; // article-copy.tsx var tips = function(msg) { document.querySelectorAll(".article-tips-span").forEach((span2) => { span2.remove(); }); const span = document.createElement("span"); span.textContent = msg; span.className = "article-tips-span"; span.style.cssText = `position: fixed;width: fit-content;padding: 0.5em 1em;background: #000;box-shadow: 0 6px 12px -6px #222;border-radius: 6px;left: 0;right: 0;top: 20vh;margin: auto;color: #fff;z-index: 99;font-size: 13px;`; setTimeout(() => { span.remove(); }, 3000); document.body.appendChild(span); }; var fetchArticle = function() { const url = /^https:\/\/zhuanlan.zhihu.com\/p\/\d+$/; const { href } = window.location; if (!url.test(href)) { return; } const title = document.title.split(/\s+/).filter((s) => s.trim())[0] || ""; const h1 = document.querySelector("h1")?.innerText.trim(); const realy_title = title || h1 || ""; const container = document.querySelector(".Post-RichTextContainer .RichText"); const content = container?.innerHTML || ""; const data = { title: realy_title, content }; document.querySelectorAll(".article-copy").forEach((e) => { e.remove(); }); const div = document.createElement("div"); div.className = "article-copy"; div.style.cssText = "position:fixed;top:3em;right:2em;border-radius:6px;z-index:999;background:#222;color:#fff;cursor:pointer;padding:0.5em 1em;box-shadow:0 6px 12px -6px #222;"; div.textContent = "\u590D\u5236\u6587\u7AE0"; div.addEventListener("click", () => { globalThis.GM.setValue("ARTICLE_CACHE", JSON.stringify(data)); tips("\u590D\u5236\u5B8C\u6210"); }); document.body.appendChild(div); }; var entry = function(data) { const url = /^https:\/\/zhuanlan.zhihu.com\/p\/\d+$/; const { href } = window.location; if (url.test(href)) { return; } if (!data) { return; } class WebComponentExt extends HTMLElement { constructor() { super(...arguments); } html_content(html) { const doc = new DOMParser().parseFromString(`${html}`, "text/html"); const text = doc.body.innerText; return text; } html_images(html) { const container = document.createElement("div"); container.innerHTML = html; const images = []; container.querySelectorAll("img").forEach((img) => { const src = img.getAttribute("src"); const original = img.getAttribute("data-original"); if (original && original.startsWith("http")) { images.push(original); } else if (src && src.startsWith("http")) { images.push(src); } }); return images; } copy_image(e) { const src = e.getAttribute("src"); if (src) { this.imgToBlob(src).then((blob) => { navigator.clipboard.writeText(src); const buff = new ClipboardItem({ "image/png": blob }); navigator.clipboard.write([buff]).then(() => { tips("\u590D\u5236\u6210\u529F"); }); }); } } copy(text, html) { this.async_copy(text, html).then(() => { tips("\u590D\u5236\u6210\u529F"); }); } insert(item) { this.insert_xiaohongshu(item); this.insert_baijiahao(item); } insert_xiaohongshu(item) { if (!/xiaohongshu\.com/.test(window.location.hostname)) { return; } if (!window.location.pathname.endsWith("/publish/publish")) { return; } const title = document.querySelector(".titleInput input"); if (!title) { return; } this.setNativeValue(title, item.title); this.fireInputEvent(title); const content = document.querySelector("#post-textarea"); const text = this.html_content(item.content); const html = text.replace(/\n{2}/g, "\n").replace(/\n{3,}/g, "\n\n").replace(/\n/g, "
"); if (content) { content.innerHTML = html; this.fireInputEvent(content); } } insert_baijiahao(item) { if (!/baidu\.com/.test(window.location.hostname)) { return; } if (!window.location.pathname.endsWith("/builder/rc/edit")) { return; } const title = document.querySelector(".client_pages_edit_components_titleInput textarea"); if (!title) { console.log("title input not found"); return; } this.setNativeValue(title, item.title); this.fireInputEvent(title); } insert_bilibili(item) { const url2 = "https://member.bilibili.com//article-text/home"; if (!window.location.href.startsWith(url2)) { return; } const title = document.querySelector(".bre-title-input textarea"); if (!title) { return; } this.setNativeValue(title, item.title); this.fireInputEvent(title); } render_style() { const style = document.createElement("style"); style.innerHTML = ` .hidden .item, .hidden .images{ display: none; } .item{ display: flex; flex-direction: row; font-size: 12px; cursor:pointer; } .item span:first-child{ flex: 1; } .item .copy{ padding-left: 1em; color:#2c2; } .item *{ pointer-events: none; } .images{ align-items: center; padding-top: 6px; } .images span{ padding-top: 100%; position: relative; background: #fff2; border-radius: 3px; } .images img{ position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: contain; transition: 0.3s all; cursor:pointer; width: 100%; } .images img:hover{ background: #fff2; } `; return style; } render_images_html(images) { const container = document.createElement("div"); container.className = "images"; let columns = ""; if (images.length === 1) { columns = "1fr"; } else if (images.length === 2) { columns = "1fr 1fr"; } else if (images.length === 3) { columns = "1fr 1fr 1fr"; } else { columns = "1fr 1fr 1fr 1fr"; } container.style.cssText = `display:grid;grid-template-columns:${columns};grid-gap:4px;`; images.forEach((url2) => { const span = document.createElement("span"); span.innerHTML = ``; container.appendChild(span); }); return container.outerHTML; } async imgToBlob(imgUrl) { const img = new Image; img.crossOrigin = "Anonymous"; return new Promise((resolve, reject) => { img.onload = () => { const canvas = document.createElement("canvas"); const ctx = canvas.getContext("2d"); canvas.width = img.width; canvas.height = img.height; ctx?.drawImage(img, 0, 0); canvas.toBlob((blob) => { if (blob) { resolve(blob); } else { reject("\u56FE\u7247\u8F6C\u6362\u5931\u8D25"); } }, "image/png"); }; img.onerror = function() { reject("\u56FE\u7247\u52A0\u8F7D\u5931\u8D25"); }; img.src = imgUrl; }); } async async_copy(text, html) { if (html) { const doc = new DOMParser().parseFromString(`${text}`, "text/html"); const html2 = doc.documentElement.outerHTML; const plain = doc.body.innerText; const buff2 = new ClipboardItem({ "text/plain": new Blob([plain], { type: "text/plain" }), "text/html": new Blob([html2], { type: "text/html" }) }); await navigator.clipboard.write([buff2]); return; } const buff = new ClipboardItem({ "text/plain": new Blob([text], { type: "text/plain" }) }); await navigator.clipboard.write([buff]); } async load() { const text = await globalThis.GM.getValue("ARTICLE_CACHE", ""); try { const data2 = JSON.parse(text); return Promise.resolve(data2); } catch (error) { return Promise.reject(error); } } async render(data2) { const { title, content } = data2; const images = this.html_images(content); const image_html = this.render_images_html(images); const intro = this.html_content(content).substring(0, 10); const container = document.createElement("div"); container.style.cssText = "position:fixed;top:2em;right:2em;z-index:999;padding:0.5em 1em;border-radius:6px;background:#000;color:#fff"; container.innerHTML = `
\u6807\u9898\uFF1A${title}\u590D\u5236
\u6B63\u6587\uFF1A${intro}\u590D\u5236
${image_html}`; container.className = "root"; container.addEventListener("click", (e) => { const target = e.target; if (target.classList.contains("root")) { if (target.classList.contains("hidden")) { target.classList.remove("hidden"); } else { target.classList.add("hidden"); } return; } if (target.tagName === "IMG") { this.copy_image(target); return; } if (target.classList.contains("item")) { if (target.classList.contains("title")) { this.copy(title); this.insert(data2); } else if (target.classList.contains("content")) { this.copy(content, true); } } }); container.appendChild(this.render_style()); const shadow = this.attachShadow({ mode: "open" }); shadow.appendChild(container); } setNativeValue(element2, value) { const { set: valueSetter } = Object.getOwnPropertyDescriptor(element2, "value") || {}; const prototype = Object.getPrototypeOf(element2); const { set: prototypeValueSetter } = Object.getOwnPropertyDescriptor(prototype, "value") || {}; if (prototypeValueSetter && valueSetter !== prototypeValueSetter) { prototypeValueSetter.call(element2, value); } else { if (valueSetter) { valueSetter.call(element2, value); } else { throw new Error("The given element does not have a value setter"); } } } fireInputEvent(element2) { element2.dispatchEvent(new InputEvent("input", { bubbles: true, cancelable: false, composed: true })); } fireChangeEvent(element2) { element2.dispatchEvent(new Event("change", { bubbles: true, cancelable: false })); } fireClickEvent(element2) { element2.dispatchEvent(new MouseEvent("click", { bubbles: true, cancelable: true, button: 0, composed: true })); } connectedCallback() { this.load().then((data2) => { this.render(data2); }); } disconnectedCallback() { } } const elements = document.querySelectorAll(".web-component-article,web-component-article"); if (elements.length > 0) { elements.forEach((element2) => { element2.remove(); }); } const nodeName = `web-component-article-${Date.now()}`; customElements.define(nodeName, WebComponentExt); const element = document.createElement(nodeName); element.className = "web-component-article"; if (window.top !== window) { setTimeout(() => { console.log("insert after 10s"); document.body.appendChild(element); }, 1e4); } else { document.body.appendChild(element); } }; window.addEventListener("load", () => { fetchArticle(); entry("highlight"); }); // Your code here... })();