Misuzu.Forum.Editor = {}; Misuzu.Forum.Editor.allowWindowClose = false; Misuzu.Forum.Editor.init = function() { const postingForm = $q('.js-forum-posting'); if(!postingForm) return; const postingButtons = postingForm.querySelector('.js-forum-posting-buttons'), postingText = postingForm.querySelector('.js-forum-posting-text'), postingParser = postingForm.querySelector('.js-forum-posting-parser'), postingPreview = postingForm.querySelector('.js-forum-posting-preview'), postingMode = postingForm.querySelector('.js-forum-posting-mode'), previewButton = document.createElement('button'), bbcodeButtons = $q('.forum__post__actions--bbcode'), markdownButtons = $q('.forum__post__actions--markdown'), markupButtons = $qa('.forum__post__action--tag'); // Initialise EEPROM, code sucks ass but it's getting nuked soon again anyway if(typeof peepPath === 'string') document.body.appendChild($e({ tag: 'script', attrs: { src: peepPath + '/eeprom.js', charset: 'utf-8', type: 'text/javascript', onload: function() { const eepromClient = new EEPROM(peepApp, peepPath + '/uploads', ''); const eepromHistory = $e({ attrs: { className: 'eeprom-widget-history-items', }, }); const eepromHandleFileUpload = function(file) { const uploadElemNameValue = $e({ attrs: { className: 'eeprom-widget-file-name-value', title: file.name, }, child: file.name, }); const uploadElemName = $e({ tag: 'a', attrs: { className: 'eeprom-widget-file-name', target: '_blank', }, child: uploadElemNameValue, }); const uploadElemProgressText = $e({ attrs: { className: 'eeprom-widget-file-progress', }, child: 'Please wait...', }); const uploadElemProgressBarValue = $e({ attrs: { className: 'eeprom-widget-file-bar-fill', style: { width: '0%', }, }, }); const uploadElem = $e({ attrs: { className: 'eeprom-widget-file', }, child: [ { attrs: { className: 'eeprom-widget-file-info', }, child: [ uploadElemName, uploadElemProgressText, ], }, { attrs: { className: 'eeprom-widget-file-bar', }, child: uploadElemProgressBarValue, }, ], }); if(eepromHistory.children.length > 0) $ib(eepromHistory.firstChild, uploadElem); else eepromHistory.appendChild(uploadElem); const explodeUploadElem = function() { $r(uploadElem); }; const uploadTask = eepromClient.createUpload(file); uploadTask.onProgress = function(progressInfo) { const progressValue = progressInfo.progress.toString() + '%'; uploadElemProgressBarValue.style.width = progressValue; uploadElemProgressText.textContent = progressValue + ' (' + (progressInfo.total - progressInfo.loaded).toString() + ' 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 _t = ['bytes', 'KB', 'MB', 'GB', 'TB'], _i = parseInt(Math.floor(Math.log(errorInfo.maxSize) / Math.log(1024))), _s = Math.round(errorInfo.maxSize / Math.pow(1024, _i), 2); errorText = 'Upload may not be larger than %1 %2.'.replace('%1', _s).replace('%2', _t[_i]); } break; } uploadElem.classList.add('eeprom-widget-file-fail'); uploadElemProgressText.textContent = errorText; Misuzu.showMessageBox(errorText, 'Upload Error'); } }; uploadTask.onComplete = function(fileInfo) { const parserMode = parseInt(postingParser.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 + ')'; } uploadElem.classList.add('eeprom-widget-file-done'); uploadElemName.href = fileInfo.url; uploadElemProgressText.textContent = ''; const insertTheLinkIntoTheBoxEx2 = function() { $insertTags(postingText, insertText, ''); postingText.value = postingText.value.trim(); }; uploadElemProgressText.appendChild($e({ tag: 'a', attrs: { href: 'javascript:void(0);', onclick: function() { insertTheLinkIntoTheBoxEx2(); }, }, child: 'Insert', })); uploadElemProgressText.appendChild($t(' ')); uploadElemProgressText.appendChild($e({ tag: 'a', attrs: { href: 'javascript:void(0);', onclick: function() { eepromClient.deleteUpload(fileInfo).start(); explodeUploadElem(); }, }, child: 'Delete', })); insertTheLinkIntoTheBoxEx2(); }; uploadTask.start(); }; const eepromFormInput = $e({ tag: 'input', attrs: { type: 'file', multiple: 'multiple', className: 'eeprom-widget-form-input', onchange: function(ev) { const files = this.files; for(const file of files) eepromHandleFileUpload(file); this.value = ''; }, }, }); const eepromForm = $e({ tag: 'label', attrs: { className: 'eeprom-widget-form', }, child: [ eepromFormInput, { attrs: { className: 'eeprom-widget-form-text', }, child: 'Select Files...', } ], }); const eepromWidget = $e({ attrs: { className: 'eeprom-widget', }, child: [ eepromForm, { attrs: { className: 'eeprom-widget-history', }, child: eepromHistory, }, ], }); postingForm.appendChild(eepromWidget); postingText.addEventListener('paste', function(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', function(ev) { ev.preventDefault(); ev.stopPropagation(); }); document.body.addEventListener('dragover', function(ev) { ev.preventDefault(); ev.stopPropagation(); }); document.body.addEventListener('dragleave', function(ev) { ev.preventDefault(); ev.stopPropagation(); }); document.body.addEventListener('drop', function(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); } }); }, onerror: function(ev) { console.error('Failed to initialise EEPROM: ', ev); }, }, })); // hack: don't prompt user when hitting submit, really need to make this not stupid. postingButtons.firstElementChild.addEventListener('click', function() { Misuzu.Forum.Editor.allowWindowClose = true; }); window.addEventListener('beforeunload', function(ev) { if(!Misuzu.Forum.Editor.allowWindowClose && postingText.value.length > 0) { ev.preventDefault(); ev.returnValue = ''; } }); for(var i = 0; i < markupButtons.length; ++i) (function(currentBtn) { currentBtn.addEventListener('click', function(ev) { $insertTags(postingText, currentBtn.dataset.tagOpen, currentBtn.dataset.tagClose); }); })(markupButtons[i]); Misuzu.Forum.Editor.switchButtons(parseInt(postingParser.value)); var lastPostText = '', lastPostParser = null; postingParser.addEventListener('change', function() { var postParser = parseInt(postingParser.value); Misuzu.Forum.Editor.switchButtons(postParser); if(postingPreview.hasAttribute('hidden')) return; // dunno if this would even be possible, but ech if(postParser === lastPostParser) return; postingParser.setAttribute('disabled', 'disabled'); previewButton.setAttribute('disabled', 'disabled'); previewButton.classList.add('input__button--busy'); Misuzu.Forum.Editor.renderPreview(postParser, lastPostText, function(success, text) { if(!success) { Misuzu.showMessageBox(text); return; } postingPreview.classList[postParser == 2 ? 'add' : 'remove']('markdown'); lastPostParser = postParser; postingPreview.innerHTML = text; MszEmbed.handle($qa('.js-msz-embed-media')); previewButton.removeAttribute('disabled'); postingParser.removeAttribute('disabled'); previewButton.classList.remove('input__button--busy'); }); }); previewButton.className = 'input__button'; previewButton.textContent = 'Preview'; previewButton.type = 'button'; previewButton.value = 'preview'; previewButton.addEventListener('click', function() { if(previewButton.value === 'back') { postingPreview.setAttribute('hidden', 'hidden'); postingText.removeAttribute('hidden'); previewButton.value = 'preview'; previewButton.textContent = 'Preview'; postingMode.textContent = postingMode.dataset.original; postingMode.dataset.original = null; } else { var postText = postingText.value, postParser = parseInt(postingParser.value); if(lastPostText === postText && lastPostParser === postParser) { postingPreview.removeAttribute('hidden'); postingText.setAttribute('hidden', 'hidden'); previewButton.value = 'back'; previewButton.textContent = 'Edit'; postingMode.dataset.original = postingMode.textContent; postingMode.textContent = 'Previewing'; return; } postingParser.setAttribute('disabled', 'disabled'); previewButton.setAttribute('disabled', 'disabled'); previewButton.classList.add('input__button--busy'); Misuzu.Forum.Editor.renderPreview(postParser, postText, function(success, text) { if(!success) { Misuzu.showMessageBox(text); return; } postingPreview.classList[postParser == 2 ? 'add' : 'remove']('markdown'); lastPostText = postText; lastPostParser = postParser; postingPreview.innerHTML = text; MszEmbed.handle($qa('.js-msz-embed-media')); postingPreview.removeAttribute('hidden'); postingText.setAttribute('hidden', 'hidden'); previewButton.value = 'back'; previewButton.textContent = 'Back'; previewButton.removeAttribute('disabled'); postingParser.removeAttribute('disabled'); previewButton.classList.remove('input__button--busy'); postingMode.dataset.original = postingMode.textContent; postingMode.textContent = 'Previewing'; }); } }); postingButtons.insertBefore(previewButton, postingButtons.firstChild); }; Misuzu.Forum.Editor.switchButtons = function(parser) { var bbcodeButtons = $q('.forum__post__actions--bbcode'), markdownButtons = $q('.forum__post__actions--markdown'); bbcodeButtons.hidden = parser != 1; markdownButtons.hidden = parser != 2; }; Misuzu.Forum.Editor.renderPreview = function(parser, text, callback) { if(!callback) return; parser = parseInt(parser); text = text || ''; var xhr = new XMLHttpRequest, formData = new FormData; formData.append('post[mode]', 'preview'); formData.append('post[text]', text); formData.append('post[parser]', parser.toString()); xhr.addEventListener('readystatechange', function() { if(xhr.readyState !== XMLHttpRequest.DONE) return; if(xhr.status === 200) callback(true, xhr.response); else callback(false, 'Failed to render preview.'); }); // need to figure out a url registry system again, current one is too much overhead so lets just do this for now xhr.open('POST', '/forum/posting.php'); xhr.withCredentials = true; xhr.send(formData); };