- // ==UserScript==
- // @name CopyMaster
- // @namespace http://tampermonkey.net/
- // @version 8.0
- // @description Tool for copying raw text and formated text
- // Advanced tools : formats PDF, DOCX, LibreOffice (ODT), Excel/CSV/ODS, audio, vidéo, images, tabs, etc.
- // @author yglsan
- // @match *://*/*
- // @grant GM_setClipboard
- // @grant GM_xmlhttpRequest
- // @grant GM_notification
- // @grant GM_download
- // @license Gpl-3.0-or-later
- // ==/UserScript==
-
- /*
- Copyright (C) 2025 Benjamin Moine (yglsan)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-
- (function() {
- 'use strict';
-
- // Création du bouton flottant moderne
- const button = document.createElement('button');
- button.innerText = '📋 Copier Formaté';
- button.style.position = 'fixed';
- button.style.bottom = '20px';
- button.style.right = '20px';
- button.style.padding = '10px 20px';
- button.style.background = '#007bff';
- button.style.color = 'white';
- button.style.border = 'none';
- button.style.borderRadius = '10px';
- button.style.boxShadow = '0 4px 6px rgba(0,0,0,0.1)';
- button.style.cursor = 'pointer';
- button.style.fontSize = '16px';
- button.style.zIndex = '1000';
- button.style.transition = 'background 0.3s';
- button.addEventListener('mouseover', () => button.style.background = '#0056b3');
- button.addEventListener('mouseout', () => button.style.background = '#007bff');
- button.addEventListener('click', copyWithStyles);
- document.body.appendChild(button);
-
- // Fonction pour copier le contenu formaté avec styles et médias
- async function copyWithStyles() {
- const selection = window.getSelection();
- if (!selection.rangeCount) return;
- const range = selection.getRangeAt(0);
- const clonedSelection = range.cloneContents();
-
- // Ajout des styles inline
- clonedSelection.querySelectorAll('*').forEach(el => {
- const computedStyle = window.getComputedStyle(el);
- el.style.cssText = computedStyle.cssText;
- });
-
- // Gestion des images
- await Promise.all(
- Array.from(clonedSelection.querySelectorAll('img')).map(async (img) => {
- if (img.src.startsWith('data:')) return;
- try {
- const response = await fetch(img.src);
- const blob = await response.blob();
- const reader = new FileReader();
- reader.onloadend = () => {
- img.src = reader.result;
- };
- reader.readAsDataURL(blob);
- } catch (e) {
- console.error('Erreur de téléchargement de l\'image', img.src, e);
- }
- })
- );
-
- // Gestion des éléments audio et vidéo
- clonedSelection.querySelectorAll('audio, video').forEach(media => {
- if (media.src && !media.src.startsWith('data:')) {
- fetch(media.src)
- .then(res => res.blob())
- .then(blob => {
- const reader = new FileReader();
- reader.onloadend = () => {
- media.src = reader.result;
- };
- reader.readAsDataURL(blob);
- })
- .catch(err => console.error('Erreur lors du téléchargement du média', media.src, err));
- }
- });
-
- // Gestion des liens
- clonedSelection.querySelectorAll('a').forEach(link => {
- link.setAttribute('target', '_blank');
- });
-
- // Reconnaissance avancée de la mise en forme
- clonedSelection.querySelectorAll('code, pre').forEach(block => {
- block.innerText = '```' + block.innerText + '```'; // Format Markdown
- });
-
- // Gestion des tableaux
- clonedSelection.querySelectorAll('table').forEach(table => {
- table.style.borderCollapse = 'collapse';
- table.querySelectorAll('td, th').forEach(cell => {
- cell.style.border = '1px solid black';
- cell.style.padding = '4px';
- });
- });
-
- // Formatage des éléments textuels
- clonedSelection.querySelectorAll('b, strong').forEach(el => {
- el.innerText = '**' + el.innerText + '**';
- });
- clonedSelection.querySelectorAll('i, em').forEach(el => {
- el.innerText = '*' + el.innerText + '*';
- });
- clonedSelection.querySelectorAll('u').forEach(el => {
- el.innerText = '__' + el.innerText + '__';
- });
-
- // Conversion en HTML complet
- const div = document.createElement('div');
- div.appendChild(clonedSelection);
- GM_setClipboard(div.innerHTML, 'text/html');
-
- // Notification de réussite
- GM_notification({
- text: 'Contenu copié avec succès dans le presse-papiers !',
- title: 'CopyMasterX',
- timeout: 3000
- });
- }
-
- // Fonction pour exporter en PDF
- function exportToPDF(content) {
- const jsPDF = window.jsPDF;
- const doc = new jsPDF();
- doc.html(content, {
- callback: function (doc) {
- doc.save('export.pdf');
- },
- margin: [10, 10, 10, 10],
- autoPaging: true
- });
- }
-
- // Fonction pour exporter en DOCX
- function exportToDOCX(content) {
- const PizZip = window.PizZip;
- const Docxtemplater = window.Docxtemplater;
-
- const zip = new PizZip();
- const doc = new Docxtemplater(zip);
- doc.setData({ content });
- doc.render();
- const out = doc.getZip().generate({ type: 'blob' });
- GM_download(out, 'export.docx');
- }
-
- // Fonction pour exporter en ODT (LibreOffice)
- function exportToODT(content) {
- const odf = window.odf; // Assurez-vous d'avoir la bibliothèque js-odf importée dans votre projet
- const odtDoc = new odf.OdtDocument();
- odtDoc.addText(content);
- const blob = odtDoc.save();
- GM_download(blob, 'export.odt');
- }
-
- // Fonction pour exporter en CSV
- function exportToCSV(table) {
- let csv = '';
- const rows = table.querySelectorAll('tr');
- rows.forEach(row => {
- const cells = row.querySelectorAll('th, td');
- const rowData = [];
- cells.forEach(cell => {
- rowData.push('"' + cell.textContent.replace(/"/g, '""') + '"');
- });
- csv += rowData.join(',') + '\n';
- });
-
- const blob = new Blob([csv], { type: 'text/csv' });
- GM_download(blob, 'export.csv');
- }
-
- // Fonction pour exporter en Excel
- function exportToExcel(table) {
- const XLSX = window.XLSX; // Assurez-vous d'avoir la bibliothèque xlsx importée dans votre projet
- const wb = XLSX.utils.table_to_book(table);
- const wbout = XLSX.write(wb, { bookType: 'xlsx', type: 'binary' });
-
- const blob = new Blob([s2ab(wbout)], { type: 'application/octet-stream' });
- GM_download(blob, 'export.xlsx');
- }
-
- // Fonction pour exporter en ODS (LibreOffice)
- function exportToODS(table) {
- const ODS = window.ODS; // Assurez-vous d'avoir la bibliothèque js-ods importée dans votre projet
- const odsDoc = new ODS.Document();
- const sheet = odsDoc.addSheet('Sheet1');
-
- const rows = table.querySelectorAll('tr');
- rows.forEach((row, rowIndex) => {
- const cells = row.querySelectorAll('th, td');
- cells.forEach((cell, cellIndex) => {
- sheet.write(cellIndex, rowIndex, cell.textContent);
- });
- });
-
- const blob = odsDoc.save();
- GM_download(blob, 'export.ods');
- }
-
- // Fonction utilitaire pour convertir le binaire en tableau
- function s2ab(s) {
- const buf = new ArrayBuffer(s.length);
- const view = new Uint8Array(buf);
- for (let i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
- return buf;
- }
-
- // Ajout de la gestion de la touche de raccourci
- document.addEventListener('keydown', (e) => {
- if (e.ctrlKey && e.shiftKey && e.key === 'C') copyWithStyles();
- });
- })();