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 => ({ text: e.name })),
25 showContent: 'up',
26 onChange: e => {
27 let mode = CodeMirror.findModeByName(e.text);
28 mode = mode ? mode.mode : null;
29 editor.setOption('mode', mode);
30 CodeMirror.autoLoadMode(editor, mode);
31 }
32 });
33
34 const urlParams = new URLSearchParams(window.location.search);
35 select.set(decodeURIComponent(urlParams.get('lang') || 'Plain Text'));
36};
37
38const initCode = () => {
39 const base64 = location.hash.substr(1);
40 if (base64.length === 0) {
41 return;
42 }
43 decompress(base64, (code, err) => {
44 if (err) {
45 alert('Failed to decompress data: ' + err);
46 return;
47 }
48 editor.setValue(code);
49 });
50};
51
52const initClipboard = () => {
53 clipboard = new ClipboardJS('.clipboard');
54 clipboard.on('success', () => {
55 hideCopyBar(true);
56 });
57};
58
59const generateLink = () => {
60 compress(editor.getValue(), (base64, err) => {
61 if (err) {
62 alert('Failed to compress data: ' + err);
63 return;
64 }
65 const url = buildUrl(base64);
66 showCopyBar(url);
67 });
68};
69
70// Open the "Copy" bar and select the content
71const showCopyBar = dataToCopy => {
72 const linkInput = document.getElementById('copy-link');
73 linkInput.value = dataToCopy;
74 linkInput.setSelectionRange(0, dataToCopy.length);
75 document.getElementById('copy').style.display = 'flex';
76};
77
78// Close the "Copy" bar
79const hideCopyBar = success => {
80 const copyButton = document.getElementById('copy-btn');
81 const copyBar = document.getElementById('copy');
82 if (!success) {
83 copyBar.style.display = 'none';
84 return;
85 }
86 copyButton.innerText = 'Copied !';
87 setTimeout(() => {
88 copyBar.style.display = 'none';
89 copyButton.innerText = 'Copy';
90 }, 800);
91};
92
93// Build a shareable URL
94const buildUrl = rawData => {
95 return `${location.protocol}//${location.host}${location.pathname}?lang=${encodeURIComponent(
96 select.selected()
97 )}#${rawData}`;
98};
99
100// Transform a compressed base64 string into a plain text string
101const decompress = (base64, cb) => {
102 const progressBar = document.getElementById('progress');
103
104 const req = new XMLHttpRequest();
105 req.open('GET', 'data:application/octet;base64,' + base64);
106 req.responseType = 'arraybuffer';
107 req.onload = e => {
108 lzma.decompress(
109 new Uint8Array(e.target.response),
110 (result, err) => {
111 progressBar.style.width = '0';
112 cb(result, err);
113 },
114 progress => {
115 progressBar.style.width = 100 * progress + '%';
116 }
117 );
118 };
119 req.send();
120};
121
122// Transform a plain text string into a compressed base64 string
123const compress = (str, cb) => {
124 const progressBar = document.getElementById('progress');
125
126 lzma.compress(
127 str,
128 1,
129 (compressed, err) => {
130 if (err) {
131 progressBar.style.width = '0';
132 cb(compressed, err);
133 return;
134 }
135 const reader = new FileReader();
136 reader.onload = () => {
137 progressBar.style.width = '0';
138 cb(reader.result.substr(reader.result.indexOf(',') + 1));
139 };
140 reader.readAsDataURL(new Blob([new Uint8Array(compressed)]));
141 },
142 progress => {
143 progressBar.style.width = 100 * progress + '%';
144 }
145 );
146};
147
148init();