#include msgbox.jsx #include parsing.js #include utility.js #include ext/eeprom.js let MszForumEditorAllowClose = false; const MszForumEditor = function(form) { if(!(form instanceof Element)) throw 'form must be an instance of element'; const buttonsElem = form.querySelector('.js-forum-posting-buttons'), textElem = form.querySelector('.js-forum-posting-text'), parserElem = form.querySelector('.js-forum-posting-parser'), previewElem = form.querySelector('.js-forum-posting-preview'), modeElem = form.querySelector('.js-forum-posting-mode'), markupActs = form.querySelector('.js-forum-posting-actions'); let lastPostText = '', lastPostParser; MszEEPROM.init() .catch(() => console.error('Failed to initialise EEPROM')) .then(() => { const eepromClient = new EEPROM(peepApp, peepPath); const eepromHistory =
; const eepromHandleFileUpload = async file => { const uploadElemNameValue = ; const uploadElemName = {uploadElemNameValue}; const uploadElemProgressText = ; const uploadElemProgressBarValue = ; const uploadElem = ; if(eepromHistory.children.length > 0) $ib(eepromHistory.firstChild, uploadElem); else eepromHistory.appendChild(uploadElem); const explodeUploadElem = () => $r(uploadElem); const uploadTask = eepromClient.create(file); uploadTask.onProgress(prog => { const progress = `}%`; uploadElemProgressBarValue.style.width = `${Math.ceil(prog.progress * 100)}%`; uploadElemProgressText.textContent = `${prog.progress.toLocaleString(undefined, { style: 'percent' })} (${prog.total - prog.loaded} bytes remaining)`; }); try { const fileInfo = await uploadTask.start(); uploadElem.classList.add('eeprom-widget-file-done'); uploadElemName.href = fileInfo.url; uploadElemProgressText.textContent = ''; const insertTheLinkIntoTheBoxEx2 = () => { const parserMode = parseInt(parserElem.value); let insertText = location.protocol + fileInfo.url; if(parserMode == 1) { // bbcode if(fileInfo.isImage()) insertText = `[img]${fileInfo.url}[/img]`; else if(fileInfo.isAudio()) insertText = `[audio]${fileInfo.url}[/audio]`; else if(fileInfo.isVideo()) insertText = `[video]${fileInfo.url}[/video]`; } else if(parserMode == 2) { // markdown if(fileInfo.isMedia()) insertText = `![](${fileInfo.url})`; } $insertTags(textElem, insertText, ''); textElem.value = textElem.value.trim(); }; uploadElemProgressText.appendChild( insertTheLinkIntoTheBoxEx2()}>Insert); uploadElemProgressText.appendChild($t(' ')); uploadElemProgressText.appendChild( { eepromClient.delete(fileInfo) .then(() => explodeUploadElem()) .catch(ex => { console.error(ex); MszShowMessageBox(ex, 'Upload Error'); }); }}>Delete); insertTheLinkIntoTheBoxEx2(); } catch(ex) { let errorText = 'Upload aborted.'; if(!ex.aborted) { console.error(ex); errorText = ex.toString(); } uploadElem.classList.add('eeprom-widget-file-fail'); uploadElemProgressText.textContent = errorText; await MszShowMessageBox(errorText, 'Upload Error'); } }; const eepromFormInput = { const files = eepromFormInput.files; for(const file of files) eepromHandleFileUpload(file); eepromFormInput.value = ''; }}/>; const eepromForm = ; const eepromWidget = ; form.appendChild(eepromWidget); textElem.addEventListener('paste', ev => { if(ev.clipboardData && ev.clipboardData.files.length > 0) { ev.preventDefault(); const files = ev.clipboardData.files; for(const file of files) eepromHandleFileUpload(file); } }); document.body.addEventListener('dragenter', ev => { ev.preventDefault(); ev.stopPropagation(); }); document.body.addEventListener('dragover', ev => { ev.preventDefault(); ev.stopPropagation(); }); document.body.addEventListener('dragleave', ev => { ev.preventDefault(); ev.stopPropagation(); }); document.body.addEventListener('drop', ev => { ev.preventDefault(); ev.stopPropagation(); if(ev.dataTransfer && ev.dataTransfer.files.length > 0) { const files = ev.dataTransfer.files; for(const file of files) eepromHandleFileUpload(file); } }); }); // hack: don't prompt user when hitting submit, really need to make this not stupid. buttonsElem.firstChild.addEventListener('click', () => MszForumEditorAllowClose = true); window.addEventListener('beforeunload', function(ev) { if(!MszForumEditorAllowClose && textElem.value.length > 0) { ev.preventDefault(); ev.returnValue = ''; } }); const switchButtons = parser => { $rc(markupActs); const tags = MszParsing.getTagsFor(parser); for(const tag of tags) markupActs.appendChild(); }; const renderPreview = async (parser, text) => { if(typeof text !== 'string') return ''; const formData = new FormData; formData.append('post[mode]', 'preview'); formData.append('post[text]', text); formData.append('post[parser]', parseInt(parser)); const result = await $x.post('/forum/posting.php', { authed: true }, formData); return result.body(); }; const previewBtn = ; previewBtn.addEventListener('click', function() { if(previewBtn.value === 'back') { previewElem.setAttribute('hidden', 'hidden'); textElem.removeAttribute('hidden'); previewBtn.value = 'preview'; previewBtn.textContent = 'Preview'; modeElem.textContent = modeElem.dataset.original; modeElem.dataset.original = null; } else { const postText = textElem.value, postParser = parseInt(parserElem.value); if(lastPostText === postText && lastPostParser === postParser) { previewElem.removeAttribute('hidden'); textElem.setAttribute('hidden', 'hidden'); previewBtn.value = 'back'; previewBtn.textContent = 'Edit'; modeElem.dataset.original = modeElem.textContent; modeElem.textContent = 'Previewing'; return; } parserElem.setAttribute('disabled', 'disabled'); previewBtn.setAttribute('disabled', 'disabled'); previewBtn.classList.add('input__button--busy'); renderPreview(postParser, postText) .catch(() => { previewElem.innerHTML = ''; MszShowMessageBox('Failed to render preview.'); }) .then(body => { previewElem.classList.toggle('markdown', postParser === 2); lastPostText = postText; lastPostParser = postParser; previewElem.innerHTML = body; MszEmbed.handle($qa('.js-msz-embed-media')); previewElem.removeAttribute('hidden'); textElem.setAttribute('hidden', 'hidden'); previewBtn.value = 'back'; previewBtn.textContent = 'Back'; previewBtn.removeAttribute('disabled'); parserElem.removeAttribute('disabled'); previewBtn.classList.remove('input__button--busy'); modeElem.dataset.original = modeElem.textContent; modeElem.textContent = 'Previewing'; }); } }); buttonsElem.insertBefore(previewBtn, buttonsElem.firstChild); switchButtons(parserElem.value); parserElem.addEventListener('change', () => { const postParser = parseInt(parserElem.value); switchButtons(postParser); if(previewElem.hasAttribute('hidden')) return; // dunno if this would even be possible, but ech if(postParser === lastPostParser) return; parserElem.setAttribute('disabled', 'disabled'); previewBtn.setAttribute('disabled', 'disabled'); previewBtn.classList.add('input__button--busy'); renderPreview(postParser, lastPostText) .catch(() => { previewElem.innerHTML = ''; MszShowMessageBox('Failed to render preview.'); }) .then(body => { previewElem.classList.add('markdown', postParser === 2); lastPostParser = postParser; previewElem.innerHTML = body; MszEmbed.handle($qa('.js-msz-embed-media')); previewBtn.removeAttribute('disabled'); parserElem.removeAttribute('disabled'); previewBtn.classList.remove('input__button--busy'); }); }); };