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();