|
|
一般来说复制一段内容,里面的图片不会复制过去 本脚本可以同时复制文字和图片 其中的图片会转化为插入图片的格式
类似的: @Name @Match
- // ==UserScript==
- // @name GM一键复制图片
- // @version 1.0
- // @description 复制时自动将图片转换为插入图片的格式
- // @author M
- // @match https://www.gamemale.com/*
- // @run-at document-start
- // @grant none
- // ==/UserScript==
- (function() {
- 'use strict';
- function getImageRealUrl(img) {
- let imgUrl = img.src;
- const lazyAttrs = ['data-original', 'data-src', 'file', 'data-url', 'src'];
- for (let attr of lazyAttrs) {
- const url = img.getAttribute(attr);
- if (url && url.trim() !== '' && !url.startsWith('data:image')) {
- imgUrl = url;
- break;
- }
- }
- try {
- if (imgUrl && !imgUrl.startsWith('http')) {
- imgUrl = new URL(imgUrl, window.location.origin).href;
- }
- } catch (e) {}
- return imgUrl || null;
- }
- function hasImagesInSelection(selection) {
- if (!selection || selection.rangeCount === 0) return false;
- try {
- const range = selection.getRangeAt(0);
- const container = document.createElement('div');
- container.appendChild(range.cloneContents());
- return container.getElementsByTagName('img').length > 0;
- } catch (e) {
- return false;
- }
- }
- function isUnwantedText(text) {
- if (!text) return false;
- const unwantedPatterns = [
- /下载附件/,
- /保存到相册/,
- /图片尺寸/,
- /\d+\.\d{2}\s*KB/,
- /\d+\s*x\s*\d+\s*像素/,
- /下载次数:?\s*\d+/,
- /本帖最后由.*编辑/,
- /发表于\s*\d{4}-\d{1,2}-\d{1,2}/,
- /来自:/
- ];
- return unwantedPatterns.some(pattern => pattern.test(text));
- }
- function cleanUnwantedNodes(container) {
- const nodesToRemove = [];
- const walker = document.createTreeWalker(
- container,
- NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT,
- {
- acceptNode: function(node) {
- if (node.nodeType === Node.ELEMENT_NODE) {
- if (node.tagName === 'IMG') {
- return NodeFilter.FILTER_SKIP;
- }
- if (node.className && typeof node.className === 'string') {
- if (node.className.includes('attinfo') ||
- node.className.includes('tip') ||
- node.className.includes('attnm') ||
- node.className.includes('xg1') ||
- node.className.includes('patt') ||
- node.className.includes('authi')) {
- return NodeFilter.FILTER_ACCEPT;
- }
- }
- if (node.tagName === 'SPAN' || node.tagName === 'DIV' || node.tagName === 'EM') {
- const text = node.textContent || '';
- if (isUnwantedText(text) && !node.querySelector('img')) {
- return NodeFilter.FILTER_ACCEPT;
- }
- }
- }
- if (node.nodeType === Node.TEXT_NODE) {
- const text = node.textContent || '';
- if (isUnwantedText(text)) {
- return NodeFilter.FILTER_ACCEPT;
- }
- }
- return NodeFilter.FILTER_SKIP;
- }
- }
- );
- let node;
- while (node = walker.nextNode()) {
- nodesToRemove.push(node);
- }
- nodesToRemove.forEach(node => {
- if (node.parentNode) {
- if (node.nodeType === Node.TEXT_NODE) {
- node.parentNode.removeChild(node);
- } else {
- if (!node.querySelector('img')) {
- node.parentNode.removeChild(node);
- }
- }
- }
- });
- return container;
- }
- function removeEmptyNodes(container) {
- let changed;
- do {
- changed = false;
- const emptyNodes = [];
- const walker = document.createTreeWalker(
- container,
- NodeFilter.SHOW_ELEMENT,
- {
- acceptNode: function(node) {
- if (node.tagName !== 'IMG' &&
- node.tagName !== 'BR' &&
- node.children.length === 0 &&
- (!node.textContent || node.textContent.trim() === '')) {
- return NodeFilter.FILTER_ACCEPT;
- }
- return NodeFilter.FILTER_SKIP;
- }
- }
- );
- let node;
- while (node = walker.nextNode()) {
- emptyNodes.push(node);
- }
- emptyNodes.forEach(node => {
- if (node.parentNode) {
- node.parentNode.removeChild(node);
- changed = true;
- }
- });
- } while (changed);
- return container;
- }
- function processCopyEvent(e) {
- const selection = window.getSelection();
- if (!selection || selection.rangeCount === 0) return;
- const hasImages = hasImagesInSelection(selection);
- if (!hasImages && (!selection.toString() || selection.toString().trim() === '')) return;
- try {
- const range = selection.getRangeAt(0);
- const container = document.createElement('div');
- container.appendChild(range.cloneContents());
- const images = container.getElementsByTagName('img');
- const imageCount = images.length;
- if (imageCount === 0 && !hasImages) {
- if (container.textContent.trim()) {
- e.clipboardData.setData('text/plain', selection.toString());
- e.clipboardData.setData('text/html', container.innerHTML);
- e.preventDefault();
- }
- return;
- }
- for (let i = images.length - 1; i >= 0; i--) {
- const img = images[i];
- const imgUrl = getImageRealUrl(img);
- if (imgUrl) {
- const imgText = `[img]${imgUrl}[/img]`;
- const textNode = document.createTextNode(imgText);
- if (img.parentNode) {
- img.parentNode.replaceChild(textNode, img);
- }
- } else {
- const imgText = `[img]${img.src}[/img]`;
- const textNode = document.createTextNode(imgText);
- if (img.parentNode) {
- img.parentNode.replaceChild(textNode, img);
- }
- }
- }
- cleanUnwantedNodes(container);
- removeEmptyNodes(container);
- let processedText = container.textContent || container.innerText || '';
- processedText = processedText
- .split('\n')
- .map(line => line.trim())
- .filter(line => line.length > 0)
- .join('\n')
- .replace(/\n{3,}/g, '\n\n');
- if (imageCount > 0 && processedText.trim() === '') {
- const imgTexts = [];
- for (let i = 0; i < imageCount; i++) {
- const img = images[i];
- const imgUrl = getImageRealUrl(img) || img.src;
- imgTexts.push(`[img]${imgUrl}[/img]`);
- }
- processedText = imgTexts.join('\n');
- }
- const processedHtml = container.innerHTML;
- if (processedText) {
- e.clipboardData.setData('text/plain', processedText);
- e.clipboardData.setData('text/html', processedHtml);
- e.preventDefault();
- }
- } catch (error) {
- console.error('复制处理错误:', error);
- }
- }
- function addCopyListener() {
- document.removeEventListener('copy', processCopyEvent, true);
- document.addEventListener('copy', processCopyEvent, true);
- }
- if (document.readyState === 'loading') {
- document.addEventListener('DOMContentLoaded', addCopyListener);
- } else {
- addCopyListener();
- }
- })();
复制代码
|
评分
-
查看全部评分
|