all repos — NoPaste @ eb3e5fa5f0f1e3aa2aeb236c3932dcc163342d40

Resurrected - The PussTheCat.org fork of NoPaste

index.js (view raw)

  1const lzma = new LZMA('lzma.min.js');
  2let editor = null;
  3let select = null;
  4let clipboard = null;
  5
  6const init = () => {
  7    initCodeEditor();
  8    initLangSelector();
  9    initCode();
 10    initClipboard();
 11};
 12
 13const initCodeEditor = () => {
 14    CodeMirror.modeURL = 'https://cdn.jsdelivr.net/npm/codemirror@5.51.0/mode/%N/%N.js';
 15    editor = new CodeMirror(document.getElementById('editor'), {
 16        lineNumbers: true,
 17        theme: 'dracula'
 18    });
 19};
 20
 21const initLangSelector = () => {
 22    select = new SlimSelect({
 23        select: '#language',
 24        data: CodeMirror.modeInfo.map(e => ({
 25            text: e.name,
 26            value: slugify(e.name),
 27            data: { mime: e.mime, mode: e.mode }
 28        })),
 29        showContent: 'up',
 30        onChange: e => {
 31            const language = e.data || { mime: null, mode: null };
 32            editor.setOption('mode', language.mime);
 33            CodeMirror.autoLoadMode(editor, language.mode);
 34        }
 35    });
 36
 37    const urlParams = new URLSearchParams(window.location.search);
 38    select.set(decodeURIComponent(urlParams.get('lang') || 'plain-text'));
 39};
 40
 41const initCode = () => {
 42    const base64 = location.hash.substr(1);
 43    if (base64.length === 0) {
 44        return;
 45    }
 46    decompress(base64, (code, err) => {
 47        if (err) {
 48            alert('Failed to decompress data: ' + err);
 49            return;
 50        }
 51        editor.setValue(code);
 52    });
 53};
 54
 55const initClipboard = () => {
 56    clipboard = new ClipboardJS('.clipboard');
 57    clipboard.on('success', () => {
 58        hideCopyBar(true);
 59    });
 60};
 61
 62const generateLink = mode => {
 63    compress(editor.getValue(), (base64, err) => {
 64        if (err) {
 65            alert('Failed to compress data: ' + err);
 66            return;
 67        }
 68        const url = buildUrl(base64, mode);
 69        showCopyBar(url);
 70    });
 71};
 72
 73// Open the "Copy" bar and select the content
 74const showCopyBar = dataToCopy => {
 75    const linkInput = document.getElementById('copy-link');
 76    linkInput.value = dataToCopy;
 77    linkInput.setSelectionRange(0, dataToCopy.length);
 78    document.getElementById('copy').style.display = 'flex';
 79};
 80
 81// Close the "Copy" bar
 82const hideCopyBar = success => {
 83    const copyButton = document.getElementById('copy-btn');
 84    const copyBar = document.getElementById('copy');
 85    if (!success) {
 86        copyBar.style.display = 'none';
 87        return;
 88    }
 89    copyButton.innerText = 'Copied !';
 90    setTimeout(() => {
 91        copyBar.style.display = 'none';
 92        copyButton.innerText = 'Copy';
 93    }, 800);
 94};
 95
 96// Build a shareable URL
 97const buildUrl = (rawData, mode) => {
 98    const url = `${location.protocol}//${location.host}${location.pathname}?lang=${encodeURIComponent(
 99        select.selected()
100    )}#${rawData}`;
101    return mode === 'markdown' ? `[paste](${url})` : url;
102};
103
104// Transform a compressed base64 string into a plain text string
105const decompress = (base64, cb) => {
106    const progressBar = document.getElementById('progress');
107
108    const req = new XMLHttpRequest();
109    req.open('GET', 'data:application/octet;base64,' + base64);
110    req.responseType = 'arraybuffer';
111    req.onload = e => {
112        lzma.decompress(
113            new Uint8Array(e.target.response),
114            (result, err) => {
115                progressBar.style.width = '0';
116                cb(result, err);
117            },
118            progress => {
119                progressBar.style.width = 100 * progress + '%';
120            }
121        );
122    };
123    req.send();
124};
125
126// Transform a plain text string into a compressed base64 string
127const compress = (str, cb) => {
128    const progressBar = document.getElementById('progress');
129
130    lzma.compress(
131        str,
132        1,
133        (compressed, err) => {
134            if (err) {
135                progressBar.style.width = '0';
136                cb(compressed, err);
137                return;
138            }
139            const reader = new FileReader();
140            reader.onload = () => {
141                progressBar.style.width = '0';
142                cb(reader.result.substr(reader.result.indexOf(',') + 1));
143            };
144            reader.readAsDataURL(new Blob([new Uint8Array(compressed)]));
145        },
146        progress => {
147            progressBar.style.width = 100 * progress + '%';
148        }
149    );
150};
151
152const slugify = str =>
153    str
154        .toString()
155        .toLowerCase()
156        .replace(/\s+/g, '-')
157        .replace(/\+/g, '-p')
158        .replace(/#/g, '-sharp')
159        .replace(/[^\w\-]+/g, '');
160
161init();