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