2020-02-13 15:02:17 +00:00
|
|
|
const lzma = new LZMA('lzma.min.js');
|
2020-02-17 15:05:42 +00:00
|
|
|
let editor = null;
|
|
|
|
|
let select = null;
|
|
|
|
|
let clipboard = null;
|
2020-02-13 15:02:17 +00:00
|
|
|
|
2020-02-17 15:05:42 +00:00
|
|
|
const init = () => {
|
|
|
|
|
initCodeEditor();
|
2020-02-13 15:02:17 +00:00
|
|
|
initLangSelector();
|
|
|
|
|
initCode();
|
2020-02-17 15:05:42 +00:00
|
|
|
initClipboard();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const initCodeEditor = () => {
|
|
|
|
|
CodeMirror.modeURL = 'https://cdn.jsdelivr.net/npm/codemirror@5.51.0/mode/%N/%N.js';
|
|
|
|
|
editor = new CodeMirror(document.getElementById('editor'), {
|
|
|
|
|
lineNumbers: true,
|
|
|
|
|
theme: 'dracula'
|
2020-02-13 15:02:17 +00:00
|
|
|
});
|
2020-02-17 15:05:42 +00:00
|
|
|
};
|
2020-02-13 15:02:17 +00:00
|
|
|
|
2020-02-17 15:05:42 +00:00
|
|
|
const initLangSelector = () => {
|
2020-02-13 15:02:17 +00:00
|
|
|
select = new SlimSelect({
|
|
|
|
|
select: '#language',
|
2020-02-17 15:05:42 +00:00
|
|
|
data: CodeMirror.modeInfo.map(e => ({ text: e.name })),
|
2020-02-13 15:02:17 +00:00
|
|
|
showContent: 'up',
|
2020-02-14 09:46:37 +00:00
|
|
|
onChange: e => {
|
2020-02-17 15:05:42 +00:00
|
|
|
let mode = CodeMirror.findModeByName(e.text);
|
|
|
|
|
mode = mode ? mode.mode : null;
|
|
|
|
|
editor.setOption('mode', mode);
|
|
|
|
|
CodeMirror.autoLoadMode(editor, mode);
|
2020-02-13 15:02:17 +00:00
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const urlParams = new URLSearchParams(window.location.search);
|
2020-02-17 15:05:42 +00:00
|
|
|
select.set(decodeURIComponent(urlParams.get('lang') || 'Plain Text'));
|
|
|
|
|
};
|
2020-02-13 15:02:17 +00:00
|
|
|
|
2020-02-17 15:05:42 +00:00
|
|
|
const initCode = () => {
|
2020-02-13 15:02:17 +00:00
|
|
|
const base64 = location.hash.substr(1);
|
|
|
|
|
if (base64.length === 0) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2020-02-17 15:05:42 +00:00
|
|
|
decompress(base64, (code, err) => {
|
|
|
|
|
if (err) {
|
|
|
|
|
alert('Failed to decompress data: ' + err);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
editor.setValue(code);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const initClipboard = () => {
|
|
|
|
|
clipboard = new ClipboardJS('.clipboard');
|
|
|
|
|
clipboard.on('success', () => {
|
|
|
|
|
hideCopyBar(true);
|
|
|
|
|
});
|
|
|
|
|
};
|
2020-02-13 15:02:17 +00:00
|
|
|
|
2020-02-17 15:05:42 +00:00
|
|
|
const generateLink = () => {
|
|
|
|
|
compress(editor.getValue(), (base64, err) => {
|
|
|
|
|
if (err) {
|
|
|
|
|
alert('Failed to compress data: ' + err);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const url = buildUrl(base64);
|
|
|
|
|
showCopyBar(url);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Open the "Copy" bar and select the content
|
|
|
|
|
const showCopyBar = dataToCopy => {
|
|
|
|
|
const linkInput = document.getElementById('copy-link');
|
|
|
|
|
linkInput.value = dataToCopy;
|
|
|
|
|
linkInput.setSelectionRange(0, dataToCopy.length);
|
|
|
|
|
document.getElementById('copy').style.display = 'flex';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Close the "Copy" bar
|
|
|
|
|
const hideCopyBar = success => {
|
|
|
|
|
const copyButton = document.getElementById('copy-btn');
|
|
|
|
|
const copyBar = document.getElementById('copy');
|
|
|
|
|
if (!success) {
|
|
|
|
|
copyBar.style.display = 'none';
|
2020-02-13 15:02:17 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2020-02-17 15:05:42 +00:00
|
|
|
copyButton.innerText = 'Copied !';
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
copyBar.style.display = 'none';
|
|
|
|
|
copyButton.innerText = 'Copy';
|
|
|
|
|
}, 800);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Build a shareable URL
|
|
|
|
|
const buildUrl = rawData => {
|
|
|
|
|
return `${location.protocol}//${location.host}${location.pathname}?lang=${encodeURIComponent(
|
|
|
|
|
select.selected()
|
|
|
|
|
)}#${rawData}`;
|
|
|
|
|
};
|
2020-02-13 15:02:17 +00:00
|
|
|
|
2020-02-17 15:05:42 +00:00
|
|
|
// Transform a compressed base64 string into a plain text string
|
|
|
|
|
const decompress = (base64, cb) => {
|
2020-02-17 15:41:54 +00:00
|
|
|
const progressBar = document.getElementById('progress');
|
|
|
|
|
|
2020-02-17 15:05:42 +00:00
|
|
|
const req = new XMLHttpRequest();
|
|
|
|
|
req.open('GET', 'data:application/octet;base64,' + base64);
|
|
|
|
|
req.responseType = 'arraybuffer';
|
|
|
|
|
req.onload = e => {
|
2020-02-17 15:41:54 +00:00
|
|
|
lzma.decompress(
|
|
|
|
|
new Uint8Array(e.target.response),
|
|
|
|
|
(result, err) => {
|
|
|
|
|
progressBar.style.width = '0';
|
|
|
|
|
cb(result, err);
|
|
|
|
|
},
|
|
|
|
|
progress => {
|
|
|
|
|
progressBar.style.width = 100 * progress + '%';
|
|
|
|
|
}
|
|
|
|
|
);
|
2020-02-17 15:05:42 +00:00
|
|
|
};
|
|
|
|
|
req.send();
|
|
|
|
|
};
|
2020-02-13 15:02:17 +00:00
|
|
|
|
2020-02-17 15:05:42 +00:00
|
|
|
// Transform a plain text string into a compressed base64 string
|
|
|
|
|
const compress = (str, cb) => {
|
2020-02-17 15:41:54 +00:00
|
|
|
const progressBar = document.getElementById('progress');
|
|
|
|
|
|
|
|
|
|
lzma.compress(
|
|
|
|
|
str,
|
|
|
|
|
1,
|
|
|
|
|
(compressed, err) => {
|
|
|
|
|
if (err) {
|
|
|
|
|
progressBar.style.width = '0';
|
|
|
|
|
cb(compressed, err);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const reader = new FileReader();
|
|
|
|
|
reader.onload = () => {
|
|
|
|
|
progressBar.style.width = '0';
|
|
|
|
|
cb(reader.result.substr(reader.result.indexOf(',') + 1));
|
|
|
|
|
};
|
|
|
|
|
reader.readAsDataURL(new Blob([new Uint8Array(compressed)]));
|
|
|
|
|
},
|
|
|
|
|
progress => {
|
|
|
|
|
progressBar.style.width = 100 * progress + '%';
|
2020-02-13 15:02:17 +00:00
|
|
|
}
|
2020-02-17 15:41:54 +00:00
|
|
|
);
|
2020-02-17 15:05:42 +00:00
|
|
|
};
|
2020-02-13 15:02:17 +00:00
|
|
|
|
|
|
|
|
init();
|