Convert pic to url when you paste a pic in clipboard to editor by Ctrl+V or drag some pics into editor
// ==UserScript== // @name StackEdit PicToUrl // @namespace http://www.a23187.cn/ // @version 1.0.1 // @description Convert pic to url when you paste a pic in clipboard to editor by Ctrl+V or drag some pics into editor // @author A23187 // @match https://stackedit.io // @match https://stackedit.io/app // @grant none // ==/UserScript== const notifier = { __notify: (type, msg) => { const d = [ /* err */ 'M 13 14 L 11 14 L 11 9.99998 L 13 9.99998 M 13 18 L 11 18 L 11 16 L 13 16 M 1 21 L 23 21 L 12 1.99998 L 1 21 Z', /* info */ 'M 12.9994 8.99805 L 10.9994 8.99805 L 10.9994 6.99805 L 12.9994 6.99805 M 12.9994 16.998 L 10.9994 16.998 L 10.9994 10.998 L 12.9994 10.998 M 11.9994 1.99805 C 6.47642 1.99805 1.99943 6.47504 1.99943 11.998 C 1.99943 17.5211 6.47642 21.998 11.9994 21.998 C 17.5224 21.998 21.9994 17.5211 21.9994 11.998 C 21.9994 6.47504 17.5224 1.99805 11.9994 1.99805 Z', /* ok */ 'M 12,2C 17.5228,2 22,6.47716 22,12C 22,17.5228 17.5228,22 12,22C 6.47715,22 2,17.5228 2,12C 2,6.47716 6.47715,2 12,2 Z M 10.9999,16.5019L 17.9999,9.50193L 16.5859,8.08794L 10.9999,13.6739L 7.91391,10.5879L 6.49991,12.0019L 10.9999,16.5019 Z' ]; var parent = document.getElementsByClassName('notification')[0]; var element = document.createElement('div'); const id = Date.now(); parent.appendChild(element); element.outerHTML = ` <div id="${id}" class="notification__item flex flex--row flex--align-center"> <div class="notification__icon flex flex--column flex--center"> <svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24"><path d="${d[type]}" /></svg> </div> <div class="notification__content">${msg}</div> </div>`; setTimeout(() => { parent.removeChild(document.getElementById(id)); }, 2000); }, err: msg => notifier.__notify(0, msg), info: msg => notifier.__notify(1, msg), ok: msg => notifier.__notify(2, msg) } async function uploadPic(pic) { notifier.info('Upload Pic ...'); var body = new FormData(); body.append('smfile', pic); // only support sm.ms api currently TODO const {code, msg, data} = await fetch('https://sm.ms/api/upload', { method: 'POST', body: body }).then(response => { return response.json(); }); if(code === 'success') { return data.url; } else { notifier.err('Fail to upload picture.'); } } function insertUrlToEditor(url) { if(!url) return; var text = ``; const selection = window.getSelection(); if(!selection.rangeCount) return; // delete the original text chosen, if has. selection.deleteFromDocument(); // create text node and insert it into current cursor position const node = document.createTextNode(text); selection.getRangeAt(0).insertNode(node); // select the sub text 'image', which will be modified const range = document.createRange(); range.setStart(node, 2); // 2 - length of '![' range.setEnd(node, 7); // 7 - length of '![image' selection.removeAllRanges(); selection.addRange(range); } function isPic(info) { return info.type && info.type.match(/^image\/.+$/i); } function onPaste(event) { const items = (event.clipboardData || event.originalEvent.clipboardData).items; for(let i in items) { var item = items[i]; if(isPic(item)) { uploadPic(item.getAsFile()).then(url => insertUrlToEditor(url)); break; } } } function onDrop() { // prevent the browser's default behavior and stop the propagation of all events ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(name => { window.addEventListener(name, event => { event.preventDefault(); event.stopPropagation(); }); }); return event => { var files = event.dataTransfer.files; ([...files]).forEach(file => { if(isPic(file)) { uploadPic(file).then(url => insertUrlToEditor(url)); } else { // TODO if the file is a md or other plain text, to import it into editor notifier.err('Only pictures are allowed.'); } }); }; } (function() { 'use strict'; if(document.location.pathname == '/') { document.location = document.location.origin + '/app'; return; } window.addEventListener('paste', onPaste); window.addEventListener('drop', onDrop()); })();