#include msgbox.jsx #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'), markupBtns = form.querySelectorAll('.js-forum-posting-markup'); const bbBtns = $q('.forum__post__actions--bbcode'), mdBtns = $q('.forum__post__actions--markdown'); let lastPostText = '', lastPostParser; MszEEPROM.init() .catch(() => console.error('Failed to initialise EEPROM')) .then(() => { const eepromClient = new EEPROM(peepApp, `${peepPath}/uploads`, ''); const eepromHistory =
; const eepromHandleFileUpload = file => { const uploadElemNameValue =
{file.name}
; const uploadElemName = {uploadElemNameValue}; const uploadElemProgressText =
Please wait...
; const uploadElemProgressBarValue =
; const uploadElem =
{uploadElemName} {uploadElemProgressText}
{uploadElemProgressBarValue}
; if(eepromHistory.children.length > 0) $ib(eepromHistory.firstChild, uploadElem); else eepromHistory.appendChild(uploadElem); const explodeUploadElem = () => $r(uploadElem); const uploadTask = eepromClient.createUpload(file); uploadTask.onProgress = function(progressInfo) { const progressValue = `${progressInfo.progress}%`; uploadElemProgressBarValue.style.width = progressValue; uploadElemProgressText.textContent = `${progressValue} (${progressInfo.total - progressInfo.loaded} bytes remaining)`; }; uploadTask.onFailure = function(errorInfo) { if(!errorInfo.userAborted) { let errorText = 'Was unable to upload file.'; switch(errorInfo.error) { case EEPROM.ERR_INVALID: errorText = 'Upload request was invalid.'; break; case EEPROM.ERR_AUTH: errorText = 'Upload authentication failed, refresh and try again.'; break; case EEPROM.ERR_ACCESS: errorText = "You're not allowed to upload files."; break; case EEPROM.ERR_GONE: errorText = 'Upload client has a configuration error or the server is gone.'; break; case EEPROM.ERR_DMCA: errorText = 'This file has been uploaded before and was removed for copyright reasons, you cannot upload this file.'; break; case EEPROM.ERR_SERVER: errorText = 'Upload server returned a critical error, try again later.'; break; case EEPROM.ERR_SIZE: if(errorInfo.maxSize < 1) errorText = 'Selected file is too large.'; else { const types = ['bytes', 'KB', 'MB', 'GB', 'TB'], typeIndex = parseInt(Math.floor(Math.log(errorInfo.maxSize) / Math.log(1024))), number = Math.round(errorInfo.maxSize / Math.pow(1024, _i), 2); errorText = `Upload may not be larger than ${number} ${types[typeIndex]}.`; } break; } uploadElem.classList.add('eeprom-widget-file-fail'); uploadElemProgressText.textContent = errorText; MszShowMessageBox(errorText, 'Upload Error'); } }; uploadTask.onComplete = function(fileInfo) { uploadElem.classList.add('eeprom-widget-file-done'); uploadElemName.href = fileInfo.url; uploadElemProgressText.textContent = ''; const insertTheLinkIntoTheBoxEx2 = function() { 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.deleteUpload(fileInfo).start(); explodeUploadElem(); }}>Delete); insertTheLinkIntoTheBoxEx2(); }; uploadTask.start(); }; const eepromFormInput = { const files = eepromFormInput.files; for(const file of files) eepromHandleFileUpload(file); eepromFormInput.value = ''; }}/>; const eepromForm = ; const eepromWidget =
{eepromForm}
{eepromHistory}
; 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 = ''; } }); for(const button of markupBtns) button.addEventListener('click', () => $insertTags(textElem, button.dataset.tagOpen, button.dataset.tagClose)); const switchButtons = parser => { parser = parseInt(parser); bbBtns.hidden = parser !== 1; mdBtns.hidden = parser !== 2; }; 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'); }); }); };