diff --git a/assets/js/misuzu/__extensions.js b/assets/js/misuzu/__extensions.js index 7eff7e2..20d761e 100644 --- a/assets/js/misuzu/__extensions.js +++ b/assets/js/misuzu/__extensions.js @@ -1,176 +1,183 @@ -Array.prototype.removeIndex = function(index) { - this.splice(index, 1); - return this; -}; -Array.prototype.removeItem = function(item) { - var index; - while(this.length > 0 && (index = this.indexOf(item)) >= 0) - this.removeIndex(index); - return this; -}; -Array.prototype.removeFind = function(predicate) { - var index; - while(this.length > 0 && (index = this.findIndex(predicate)) >= 0) - this.removeIndex(index); - return this; +const $i = document.getElementById.bind(document); +const $c = document.getElementsByClassName.bind(document); +const $q = document.querySelector.bind(document); +const $qa = document.querySelectorAll.bind(document); +const $t = document.createTextNode.bind(document); + +const $r = function(element) { + if(element && element.parentNode) + element.parentNode.removeChild(element); }; -HTMLCollection.prototype.toArray = function() { - return Array.prototype.slice.call(this); +const $ri = function(name) { + $r($i(name)); }; -HTMLTextAreaElement.prototype.insertTags = function(tagOpen, tagClose) { - tagOpen = tagOpen || ''; - tagClose = tagClose || ''; +const $ib = function(ref, elem) { + ref.parentNode.insertBefore(elem, ref); +}; - if(document.selection) { - this.focus(); - var selected = document.selection.createRange(); - selected.text = tagOpen + selected.text + tagClose; - this.focus(); - } else if(this.selectionStart || this.selectionStart === 0) { - var startPos = this.selectionStart, - endPos = this.selectionEnd, - scrollTop = this.scrollTop; +const $rc = function(element) { + while(element.lastChild) + element.removeChild(element.lastChild); +}; - this.value = this.value.substring(0, startPos) - + tagOpen - + this.value.substring(startPos, endPos) - + tagClose - + this.value.substring(endPos, this.value.length); +const $e = function(info, attrs, child, created) { + info = info || {}; - this.focus(); - this.selectionStart = startPos + tagOpen.length; - this.selectionEnd = endPos + tagOpen.length; - this.scrollTop + scrollTop; - } else { - this.value += tagOpen + tagClose; - this.focus(); + if(typeof info === 'string') { + info = {tag: info}; + if(attrs) + info.attrs = attrs; + if(child) + info.child = child; + if(created) + info.created = created; } -}; -var CreateElement = function(elemInfo) { - elemInfo = elemInfo || {}; - var elem = document.createElement(elemInfo.tag || 'div'); + const elem = document.createElement(info.tag || 'div'); - if(elemInfo.props) { - var propKeys = Object.keys(elemInfo.props); + if(info.attrs) { + const attrs = info.attrs; - for(var i = 0; i < propKeys.length; i++) { - var propKey = propKeys[i]; - - if(elemInfo.props[propKey] === undefined - || elemInfo.props[propKey] === null) + for(let key in attrs) { + const attr = attrs[key]; + if(attr === undefined || attr === null) continue; - switch(typeof elemInfo.props[propKey]) { + switch(typeof attr) { case 'function': - elem.addEventListener( - propKey.substring(0, 2) === 'on' - ? propKey.substring(2).toLowerCase() - : propKey, - elemInfo.props[propKey] - ); + if(key.substring(0, 2) === 'on') + key = key.substring(2).toLowerCase(); + elem.addEventListener(key, attr); + break; + + case 'object': + if(attr instanceof Array) { + if(key === 'class') + key = 'classList'; + + const prop = elem[key]; + let addFunc = null; + + if(prop instanceof Array) + addFunc = prop.push.bind(prop); + else if(prop instanceof DOMTokenList) + addFunc = prop.add.bind(prop); + + if(addFunc !== null) { + for(let j = 0; j < attr.length; ++j) + addFunc(attr[j]); + } else { + if(key === 'classList') + key = 'class'; + elem.setAttribute(key, attr.toString()); + } + } else { + for(const attrKey in attr) + elem[key][attrKey] = attr[attrKey]; + } break; default: - elem.setAttribute(propKey === 'className' ? 'class' : propKey, elemInfo.props[propKey]); + if(key === 'className') + key = 'class'; + elem.setAttribute(key, attr.toString()); break; } } } - if(elemInfo.children) { - var children = elemInfo.children; + if(info.child) { + let children = info.child; if(!Array.isArray(children)) children = [children]; - for(var i = 0; i < children.length; i++) { - var child = children[i]; - + for(const child of children) { switch(typeof child) { case 'string': - elem.appendChild(document.createTextNode(child)); + elem.appendChild($t(child)); break; case 'object': if(child instanceof Element) elem.appendChild(child); - else if(child.getElement) - elem.appendChild(child.getElement()); - else - elem.appendChild(CreateElement(child)); + else if(child.getElement) { + const childElem = child.getElement(); + if(childElem instanceof Element) + elem.appendChild(childElem); + else + elem.appendChild($e(child)); + } else + elem.appendChild($e(child)); break; default: - elem.appendChild(document.createTextNode(child.toString())); + elem.appendChild($t(child.toString())); break; } } } - if(elemInfo.created) - elemInfo.created(elem); + if(info.created) + info.created(elem); return elem; }; -var CreateBasicElement = function(className, children, tagName) { - return CreateElement({ - tag: tagName || null, - props: { - 'class': className || null, - }, - 'children': children || null, - }); +const $ar = function(array, index) { + array.splice(index, 1); +}; +const $ari = function(array, item) { + let index; + while(array.length > 0 && (index = array.indexOf(item)) >= 0) + $ar(array, index); +}; +const $arf = function(array, predicate) { + let index; + while(array.length > 0 && (index = array.findIndex(predicate)) >= 0) + $ar(array, index); }; -var LoadScript = function(url, loaded, error) { - if(document.querySelector('script[src="' + encodeURI(url) + '"]')) { - if(loaded) - loaded(); +const $as = function(array) { + if(array.length < 2) return; + + for(let i = array.length - 1; i > 0; --i) { + let j = Math.floor(Math.random() * (i + 1)), + tmp = array[i]; + array[i] = array[j]; + array[j] = tmp; } - - var script = document.createElement('script'); - script.type = 'text/javascript'; - if(loaded) - script.addEventListener('load', function() { loaded(); }); - script.addEventListener('error', function() { - document.body.removeChild(script); - if(error) - error(); - }); - script.src = url; - document.body.appendChild(script); }; -var MakeEventTarget = function(object) { - object.eventListeners = {}; - object.addEventListener = function(type, callback) { - if(!(type in this.eventListeners)) - this.eventListeners[type] = []; - this.eventListeners[type].push(callback); - }; - object.removeEventListener = function(type, callback) { - if(!(type in this.eventListeners)) - return; - this.eventListeners[type].removeItem(callback); - }; - object.dispatchEvent = function(event) { - if(!(event.type in this.eventListeners)) - return true; - var stack = this.eventListeners[event.type].slice(); - for(var i = 0; i < stack.length; ++i) - stack[i].call(this, event); - return !event.defaultPrevented; - }; -}; +var $insertTags = function(target, tagOpen, tagClose) { + tagOpen = tagOpen || ''; + tagClose = tagClose || ''; -var DefineEnum = function(values) { - var keys = Object.keys(values); - for(var i = 0; i < keys.length; ++i) - values[values[keys[i]]] = keys[i]; - return values; + if(document.selection) { + target.focus(); + var selected = document.selection.createRange(); + selected.text = tagOpen + selected.text + tagClose; + target.focus(); + } else if(target.selectionStart || target.selectionStart === 0) { + var startPos = target.selectionStart, + endPos = target.selectionEnd, + scrollTop = target.scrollTop; + + target.value = target.value.substring(0, startPos) + + tagOpen + + target.value.substring(startPos, endPos) + + tagClose + + target.value.substring(endPos, target.value.length); + + target.focus(); + target.selectionStart = startPos + tagOpen.length; + target.selectionEnd = endPos + tagOpen.length; + target.scrollTop + scrollTop; + } else { + target.value += tagOpen + tagClose; + target.focus(); + } }; diff --git a/assets/js/misuzu/_main.js b/assets/js/misuzu/_main.js index 257453d..1489c47 100644 --- a/assets/js/misuzu/_main.js +++ b/assets/js/misuzu/_main.js @@ -1,47 +1,14 @@ var Misuzu = function() { - if(Misuzu.initialised) - throw 'Misuzu script has already initialised.'; - Misuzu.started = true; - - console.log( - "%cMisuzu%c\nhttps://git.flash.moe/flashii/misuzu", - 'font-size: 48px; color: #8559a5; background: #111;' - + 'border-radius: 5px; padding: 0 10px; text-shadow: 0 0 1em #fff;', - ); - - timeago.render(document.querySelectorAll('time')); + timeago.render($qa('time')); hljs.initHighlighting(); - Misuzu.CSRF.init(); - Misuzu.Urls.loadFromDocument(); - Misuzu.User.refreshLocalUser(); - Misuzu.FormUtils.initDataRequestMethod(); - Misuzu.initQuickSubmit(); - Misuzu.Comments.init(); + Misuzu.initQuickSubmit(); // only used by the forum posting form Misuzu.Forum.Editor.init(); - - if(Misuzu.User.isLoggedIn()) - console.log( - 'You are %s with user id %d and colour %s.', - Misuzu.User.localUser.getUsername(), - Misuzu.User.localUser.getId(), - Misuzu.User.localUser.getColour().getCSS() - ); - else - console.log('You aren\'t logged in.'); - Misuzu.Events.dispatch(); - Misuzu.initLoginPage(); }; -Misuzu.Parser = DefineEnum({ - plain: 0, - bbcode: 1, - markdown: 2, -}); -Misuzu.supportsSidewaysText = function() { return CSS.supports('writing-mode', 'sideways-lr'); }; Misuzu.showMessageBox = function(text, title, buttons) { - if(document.querySelector('.messagebox')) + if($q('.messagebox')) return false; text = text || ''; @@ -111,11 +78,12 @@ Misuzu.initLoginPage = function() { usernameElem.value = json.name; avatarElem.src = json.avatar; }); - xhr.open('GET', Misuzu.Urls.format('auth-resolve-user', [{name: 'username', value: encodeURIComponent(usernameElem.value)}])); + // need to figure out a url registry system again, current one is too much overhead so lets just do this for now + xhr.open('GET', '/auth/login.php?resolve=1&name=' + encodeURIComponent(usernameElem.value)); xhr.send(); }; - var loginForms = document.getElementsByClassName('js-login-form'); + var loginForms = $c('js-login-form'); for(var i = 0; i < loginForms.length; ++i) (function(form) { @@ -136,7 +104,7 @@ Misuzu.initLoginPage = function() { })(loginForms[i]); }; Misuzu.initQuickSubmit = function() { - var ctrlSubmit = document.getElementsByClassName('js-quick-submit').toArray().concat(document.getElementsByClassName('js-ctrl-enter-submit').toArray()); + var ctrlSubmit = Array.from($qa('.js-quick-submit, .js-ctrl-enter-submit')); if(!ctrlSubmit) return; diff --git a/assets/js/misuzu/colour.js b/assets/js/misuzu/colour.js deleted file mode 100644 index 1b8e1bb..0000000 --- a/assets/js/misuzu/colour.js +++ /dev/null @@ -1,93 +0,0 @@ -Misuzu.Colour = function(raw) { - this.setRaw(raw || 0); -}; -Misuzu.Colour.prototype.raw = 0; -Misuzu.Colour.FLAG_INHERIT = 0x40000000; -Misuzu.Colour.READABILITY_THRESHOLD = 186; -Misuzu.Colour.LUMINANCE_WEIGHT_RED = .299; -Misuzu.Colour.LUMINANCE_WEIGHT_GREEN = .587; -Misuzu.Colour.LUMINANCE_WEIGHT_BLUE = .114; -Misuzu.Colour.none = function() { return new Misuzu.Colour(Misuzu.Colour.FLAG_INHERIT); }; -Misuzu.Colour.fromRGB = function(red, green, blue) { - var colour = new Misuzu.Colour; - colour.setRed(red); - colour.setGreen(green); - colour.setBlue(blue); - return colour; -}; -Misuzu.Colour.fromHex = function(hex) { - var colour = new Misuzu.Colour; - colour.setHex(hex); - return colour; -}; -Misuzu.Colour.prototype.getRaw = function() { return this.raw; }; -Misuzu.Colour.prototype.setRaw = function(raw) { - this.raw = parseInt(raw) & 0x7FFFFFFF; -}; -Misuzu.Colour.prototype.getInherit = function() { return (this.getRaw() & Misuzu.Colour.FLAG_INHERIT) > 0; }; -Misuzu.Colour.prototype.setInherit = function(inherit) { - var raw = this.getRaw(); - if(inherit) - raw |= Misuzu.Colour.FLAG_INHERIT; - else - raw &= ~Misuzu.Colour.FLAG_INHERIT; - this.setRaw(raw); -}; -Misuzu.Colour.prototype.getRed = function() { return (this.getRaw() >> 16) & 0xFF }; -Misuzu.Colour.prototype.setRed = function(red) { - var raw = this.getRaw(); - raw &= ~0xFF0000; - raw |= (parseInt(red) & 0xFF) << 16; - this.setRaw(raw); -}; -Misuzu.Colour.prototype.getGreen = function() { return (this.getRaw() >> 8) & 0xFF }; -Misuzu.Colour.prototype.setGreen = function(green) { - var raw = this.getRaw(); - raw &= ~0xFF0000; - raw |= (parseInt(green) & 0xFF) << 8; - this.setRaw(raw); -}; -Misuzu.Colour.prototype.getBlue = function() { return this.getRaw() & 0xFF }; -Misuzu.Colour.prototype.setBlue = function(blue) { - var raw = this.getRaw(); - raw &= ~0xFF0000; - raw |= parseInt(blue) & 0xFF; - this.setRaw(raw); -}; -Misuzu.Colour.prototype.getLuminance = function() { - return Misuzu.Colour.LUMINANCE_WEIGHT_RED * this.getRed() - + Misuzu.Colour.LUMINANCE_WEIGHT_GREEN * this.getGreen() - + Misuzu.Colour.LUMINANCE_WEIGHT_BLUE * this.getBlue(); -}; -Misuzu.Colour.prototype.getHex = function() { - var hex = (this.getRaw() & 0xFFFFFF).toString(16); - if(hex.length < 6) - hex = '000000'.substring(0, 6 - hex.length) + hex; - return hex; -}; -Misuzu.Colour.prototype.setHex = function(hex) { - hex = (hex || '').toString(); - if(hex[0] === '#') - hex = hex.substring(1); - if(/[^A-Fa-f0-9]/g.test(hex)) - throw 'Argument contains invalid characters.'; - if(hex.length === 3) - hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2]; - else if(hex.length !== 6) - throw 'Argument is not a hex string.'; - return this.setRaw(parseInt(hex, 16)); -}; -Misuzu.Colour.prototype.getCSS = function() { - if(this.getInherit()) - return 'inherit'; - return '#' + this.getHex(); -}; -Misuzu.Colour.prototype.getCSSConstrast = function(dark, light, inheritIsDark) { - dark = dark || 'dark'; - light = light || 'light'; - - if(this.getInherit()) - return inheritIsDark ? dark : light; - - return this.getLuminance() > Misuzu.Colour.READABILITY_THRESHOLD ? dark : light; -}; diff --git a/assets/js/misuzu/comments.js b/assets/js/misuzu/comments.js deleted file mode 100644 index 8ba3a8f..0000000 --- a/assets/js/misuzu/comments.js +++ /dev/null @@ -1,491 +0,0 @@ -Misuzu.Comments = {}; -Misuzu.Comments.Vote = DefineEnum({ - none: 0, - like: 1, - dislike: -1, -}); -Misuzu.Comments.init = function() { - var commentDeletes = document.getElementsByClassName('comment__action--delete'); - for(var i = 0; i < commentDeletes.length; ++i) { - commentDeletes[i].addEventListener('click', Misuzu.Comments.deleteCommentHandler); - commentDeletes[i].dataset.href = commentDeletes[i].href; - commentDeletes[i].href = 'javascript:;'; - } - - var commentInputs = document.getElementsByClassName('comment__text--input'); - for(var i = 0; i < commentInputs.length; ++i) { - commentInputs[i].form.action = 'javascript:void(0);'; - commentInputs[i].form.addEventListener('submit', Misuzu.Comments.postCommentHandler); - commentInputs[i].addEventListener('keydown', Misuzu.Comments.inputCommentHandler); - } - - var voteButtons = document.getElementsByClassName('comment__action--vote'); - for(var i = 0; i < voteButtons.length; ++i) { - voteButtons[i].href = 'javascript:;'; - voteButtons[i].addEventListener('click', Misuzu.Comments.voteCommentHandler); - } - - var pinButtons = document.getElementsByClassName('comment__action--pin'); - for(var i = 0; i < pinButtons.length; ++i) { - pinButtons[i].href = 'javascript:;'; - pinButtons[i].addEventListener('click', Misuzu.Comments.pinCommentHandler); - } -}; -Misuzu.Comments.postComment = function(formData, onSuccess, onFailure) { - if(!Misuzu.User.isLoggedIn() - || !Misuzu.User.localUser.perms.canCreateComment()) { - if(onFailure) - onFailure("You aren't allowed to post comments."); - return; - } - - var xhr = new XMLHttpRequest; - xhr.addEventListener('readystatechange', function() { - if(xhr.readyState !== 4) - return; - - Misuzu.CSRF.setToken(xhr.getResponseHeader('X-Misuzu-CSRF')); - - var json = JSON.parse(xhr.responseText), - message = json.error || json.message; - - if(message && onFailure) - onFailure(message); - else if(!message && onSuccess) - onSuccess(json); - }); - xhr.open('POST', Misuzu.Urls.format('comment-create')); - xhr.setRequestHeader('X-Misuzu-XHR', 'comments'); - xhr.send(formData); -}; -Misuzu.Comments.postCommentHandler = function() { - if(this.dataset.disabled) - return; - this.dataset.disabled = '1'; - this.style.opacity = '0.5'; - - Misuzu.Comments.postComment( - Misuzu.FormUtils.extractFormData(this, true), - Misuzu.Comments.postCommentSuccess.bind(this), - Misuzu.Comments.postCommentFailed.bind(this) - ); -}; -Misuzu.Comments.inputCommentHandler = function(ev) { - if(ev.code === 'Enter' && ev.ctrlKey && !ev.altKey && !ev.shiftKey && !ev.metaKey) { - Misuzu.Comments.postComment( - Misuzu.FormUtils.extractFormData(this.form, true), - Misuzu.Comments.postCommentSuccess.bind(this.form), - Misuzu.Comments.postCommentFailed.bind(this.form) - ); - } -}; -Misuzu.Comments.postCommentSuccess = function(comment) { - if(this.classList.contains('comment--reply')) - this.parentNode.parentNode.querySelector('label.comment__action').click(); - - Misuzu.Comments.insertComment(comment, this); - this.style.opacity = '1'; - this.dataset.disabled = ''; -}; -Misuzu.Comments.postCommentFailed = function(message) { - Misuzu.showMessageBox(message); - this.style.opacity = '1'; - this.dataset.disabled = ''; -}; -Misuzu.Comments.deleteComment = function(commentId, onSuccess, onFailure) { - if(!Misuzu.User.isLoggedIn() - || !Misuzu.User.localUser.perms.canDeleteOwnComment()) { - if(onFailure) - onFailure('You aren\'t allowed to delete comments.'); - return; - } - - var xhr = new XMLHttpRequest; - xhr.addEventListener('readystatechange', function() { - if(xhr.readyState !== 4) - return; - - Misuzu.CSRF.setToken(xhr.getResponseHeader('X-Misuzu-CSRF')); - - var json = JSON.parse(xhr.responseText), - message = json.error || json.message; - - if(message && onFailure) - onFailure(message); - else if(!message && onSuccess) - onSuccess(json); - }); - xhr.open('GET', Misuzu.Urls.format('comment-delete', [Misuzu.Urls.v('comment', commentId)])); - xhr.setRequestHeader('X-Misuzu-XHR', 'comments'); - xhr.send(); -}; -Misuzu.Comments.deleteCommentHandler = function() { - var commentId = parseInt(this.dataset.commentId); - if(commentId < 1) - return; - - Misuzu.Comments.deleteComment( - commentId, - function(info) { - var elem = document.getElementById('comment-' + info.id); - - if(elem) - elem.parentNode.removeChild(elem); - }, - function(message) { Misuzu.showMessageBox(message); } - ); -}; -Misuzu.Comments.pinComment = function(commentId, pin, onSuccess, onFailure) { - if(!Misuzu.User.isLoggedIn() - || !Misuzu.User.localUser.perms.canPinComment()) { - if(onFailure) - onFailure("You aren't allowed to pin comments."); - return; - } - - var xhr = new XMLHttpRequest; - xhr.onreadystatechange = function() { - if(xhr.readyState !== 4) - return; - - Misuzu.CSRF.setToken(xhr.getResponseHeader('X-Misuzu-CSRF')); - - var json = JSON.parse(xhr.responseText), - message = json.error || json.message; - - if(message && onFailure) - onFailure(message); - else if(!message && onSuccess) - onSuccess(json); - }; - xhr.open('GET', Misuzu.Urls.format('comment-' + (pin ? 'pin' : 'unpin'), [Misuzu.Urls.v('comment', commentId)])); - xhr.setRequestHeader('X-Misuzu-XHR', 'comments'); - xhr.send(); -}; -Misuzu.Comments.pinCommentHandler = function() { - var target = this, - commentId = parseInt(target.dataset.commentId), - isPinned = target.dataset.commentPinned !== '0'; - - target.textContent = '...'; - - Misuzu.Comments.pinComment( - commentId, - !isPinned, - function(info) { - if(info.comment_pinned === null) { - target.textContent = 'Pin'; - target.dataset.commentPinned = '0'; - var pinElement = document.querySelector('#comment-' + info.comment_id + ' .comment__pin'); - pinElement.parentElement.removeChild(pinElement); - } else { - target.textContent = 'Unpin'; - target.dataset.commentPinned = '1'; - - var pinInfo = document.querySelector('#comment-' + info.comment_id + ' .comment__info'), - pinElement = document.createElement('div'), - pinTime = document.createElement('time'), - pinDateTime = new Date(info.comment_pinned + 'Z'); - - pinTime.title = pinDateTime.toLocaleString(); - pinTime.dateTime = pinDateTime.toISOString(); - pinTime.textContent = timeago.format(pinDateTime); - timeago.render(pinTime); - - pinElement.className = 'comment__pin'; - pinElement.appendChild(document.createTextNode('Pinned ')); - pinElement.appendChild(pinTime); - pinInfo.appendChild(pinElement); - } - }, - function(message) { - target.textContent = isPinned ? 'Unpin' : 'Pin'; - Misuzu.showMessageBox(message); - } - ); -}; -Misuzu.Comments.voteComment = function(commentId, vote, onSuccess, onFailure) { - if(!Misuzu.User.isLoggedIn() - || !Misuzu.User.localUser.perms.canVoteOnComment()) { - if(onFailure) - onFailure("You aren't allowed to vote on comments."); - return; - } - - var xhr = new XMLHttpRequest; - xhr.onreadystatechange = function() { - if(xhr.readyState !== 4) - return; - - Misuzu.CSRF.setToken(xhr.getResponseHeader('X-Misuzu-CSRF')); - - var json = JSON.parse(xhr.responseText), - message = json.error || json.message; - - if(message && onFailure) - onFailure(message); - else if(!message && onSuccess) - onSuccess(json); - }; - xhr.open('GET', Misuzu.Urls.format('comment-vote', [Misuzu.Urls.v('comment', commentId), Misuzu.Urls.v('vote', vote)])); - xhr.setRequestHeader('X-Misuzu-XHR', 'comments'); - xhr.send(); -}; -Misuzu.Comments.voteCommentHandler = function() { - var commentId = parseInt(this.dataset.commentId), - voteType = parseInt(this.dataset.commentVote), - buttons = document.querySelectorAll('.comment__action--vote[data-comment-id="' + commentId + '"]'), - likeButton = document.querySelector('.comment__action--like[data-comment-id="' + commentId + '"]'), - dislikeButton = document.querySelector('.comment__action--dislike[data-comment-id="' + commentId + '"]'), - classVoted = 'comment__action--voted'; - - for(var i = 0; i < buttons.length; ++i) { - buttons[i].textContent = buttons[i] === this ? '...' : ''; - buttons[i].classList.remove(classVoted); - buttons[i].dataset.commentVote = buttons[i] === likeButton - ? (voteType === Misuzu.Comments.Vote.like ? Misuzu.Comments.Vote.none : Misuzu.Comments.Vote.like ).toString() - : (voteType === Misuzu.Comments.Vote.dislike ? Misuzu.Comments.Vote.none : Misuzu.Comments.Vote.dislike).toString(); - } - - Misuzu.Comments.voteComment( - commentId, - voteType, - function(info) { - switch(voteType) { - case Misuzu.Comments.Vote.like: - likeButton.classList.add(classVoted); - break; - case Misuzu.Comments.Vote.dislike: - dislikeButton.classList.add(classVoted); - break; - } - - likeButton.textContent = info.likes > 0 ? ('Like (' + info.likes.toLocaleString() + ')') : 'Like'; - dislikeButton.textContent = info.dislikes > 0 ? ('Dislike (' + info.dislikes.toLocaleString() + ')') : 'Dislike'; - }, - function(message) { - likeButton.textContent = 'Like'; - dislikeButton.textContent = 'Dislike'; - Misuzu.showMessageBox(message); - } - ); -}; -Misuzu.Comments.insertComment = function(comment, form) { - var isReply = form.classList.contains('comment--reply'), - parent = isReply - ? form.parentElement - : form.parentElement.parentElement.getElementsByClassName('comments__listing')[0], - repliesIndent = isReply - ? (parseInt(parent.classList[1].substr(25)) + 1) - : 1, - commentElement = Misuzu.Comments.buildComment(comment, repliesIndent); - - if(isReply) - parent.appendChild(commentElement); - else - parent.insertBefore(commentElement, parent.firstElementChild); - - var placeholder = document.getElementById('_no_comments_notice_' + comment.category_id); - if(placeholder) - placeholder.parentNode.removeChild(placeholder); -}; -Misuzu.Comments.buildComment = function(comment, layer) { - comment = comment || {}; - layer = parseInt(layer || 0); - - var date = new Date(comment.comment_created + 'Z'), - colour = new Misuzu.Colour(comment.user_colour), - actions = [], - commentTime = CreateElement({ - tag: 'time', - props: { - className: 'comment__date', - title: date.toLocaleString(), - datetime: date.toISOString(), - }, - children: timeago.format(date), - }); - - if(Misuzu.User.isLoggedIn() && Misuzu.User.localUser.perms.canVoteOnComment()) { - actions.push(CreateElement({ - tag: 'a', - props: { - className: 'comment__action comment__action--link comment__action--vote comment__action--like', - 'data-comment-id': comment.comment_id, - 'data-comment-vote': Misuzu.Comments.Vote.like, - href: 'javascript:;', - onclick: Misuzu.Comments.voteCommentHandler, - }, - children: 'Like', - })); - actions.push(CreateElement({ - tag: 'a', - props: { - className: 'comment__action comment__action--link comment__action--vote comment__action--dislike', - 'data-comment-id': comment.comment_id, - 'data-comment-vote': Misuzu.Comments.Vote.dislike, - href: 'javascript:;', - onclick: Misuzu.Comments.voteCommentHandler, - }, - children: 'Dislike', - })); - } - - actions.push(CreateElement({ - tag: 'label', - props: { - className: 'comment__action comment__action--link', - 'for': 'comment-reply-toggle-' + comment.comment_id.toString() - }, - children: 'Reply', - })); - - var commentText = CreateBasicElement('comment__text'); - if(comment.comment_html) - commentText.innerHTML = comment.comment_html; - else - commentText.textContent = comment.comment_text; - - var commentElem = CreateElement({ - props: { - className: 'comment', - id: 'comment-' + comment.comment_id.toString(), - }, - children: [ - { - props: { className: 'comment__container', }, - children: [ - { - tag: 'a', - props: { - className: 'comment__avatar', - href: Misuzu.Urls.format('user-profile', [{name:'user',value:comment.user_id}]), - }, - children: { - tag: 'img', - props: { - className: 'avatar', - alt: comment.username, - width: (layer <= 1 ? 50 : 40), - height: (layer <= 1 ? 50 : 40), - src: Misuzu.Urls.format('user-avatar', [ - { name: 'user', value: comment.user_id }, - { name: 'res', value: layer <= 1 ? 100 : 80 } - ]), - }, - }, - }, - { - props: { className: 'comment__content', }, - children: [ - { - props: { className: 'comment__info', }, - children: [ - { - tag: 'a', - props: { - className: 'comment__user comment__user--link', - href: Misuzu.Urls.format('user-profile', [{name:'user',value:comment.user_id}]), - style: '--user-colour: ' + colour.getCSS(), - }, - children: comment.username, - }, - { - tag: 'a', - props: { - className: 'comment__link', - href: '#comment-' + comment.comment_id.toString(), - }, - children: commentTime, - }, - ], - }, - commentText, - { - props: { className: 'comment__actions', }, - children: actions, - }, - ], - }, - ], - }, - { - props: { - className: 'comment__replies comment__replies--indent-' + layer.toString(), - id: 'comment-' + comment.comment_id.toString() + '-replies', - }, - children: [ - { - tag: 'input', - props: { - className: 'comment__reply-toggle', - type: 'checkbox', - id: ('comment-reply-toggle-' + comment.comment_id.toString()), - }, - }, - { - tag: 'form', - props: { - className: 'comment comment--input comment--reply', - id: 'comment-reply-' + comment.comment_id.toString(), - method: 'post', - action: 'javascript:;', - onsubmit: Misuzu.Comments.postCommentHandler, - }, - children: [ - { tag: 'input', props: { type: 'hidden', name: 'csrf', value: Misuzu.CSRF.getToken() } }, - { tag: 'input', props: { type: 'hidden', name: 'comment[category]', value: comment.category_id } }, - { tag: 'input', props: { type: 'hidden', name: 'comment[reply]', value: comment.comment_id } }, - { - props: { className: 'comment__container' }, - children: [ - { - props: { className: 'avatar comment__avatar' }, - children: { - tag: 'img', - props: { - className: 'avatar', - width: 40, - height: 40, - src: Misuzu.Urls.format('user-avatar', [{name: 'user', value: comment.user_id}, {name: 'res', value: 80}]), - }, - }, - }, - { - props: { className: 'comment__content' }, - children: [ - { props: { className: 'comment__info' } }, - { - tag: 'textarea', - props: { - className: 'comment__text input__textarea comment__text--input', - name: 'comment[text]', - placeholder: 'Share your extensive insights...', - onkeydown: Misuzu.Comments.inputCommentHandler, - }, - }, - { - props: { className: 'comment__actions' }, - children: { - tag: 'button', - props: { - className: 'input__button comment__action comment__action--button comment__action--post', - }, - children: 'Reply', - }, - }, - ], - }, - ], - }, - ], - }, - ], - }, - ], - }); - - timeago.render(commentTime); - - return commentElem; -}; \ No newline at end of file diff --git a/assets/js/misuzu/csrf.js b/assets/js/misuzu/csrf.js deleted file mode 100644 index e022059..0000000 --- a/assets/js/misuzu/csrf.js +++ /dev/null @@ -1,17 +0,0 @@ -Misuzu.CSRF = {}; -Misuzu.CSRF.tokenValue = undefined; -Misuzu.CSRF.tokenElement = undefined; -Misuzu.CSRF.init = function() { - Misuzu.CSRF.tokenElement = document.querySelector('[name="csrf-token"]'); - Misuzu.CSRF.tokenValue = Misuzu.CSRF.tokenElement.getAttribute('value'); -}; -Misuzu.CSRF.getToken = function() { return Misuzu.CSRF.tokenValue || ''; }; -Misuzu.CSRF.setToken = function(token) { - if(!token) - return; - Misuzu.CSRF.tokenElement.setAttribute('value', Misuzu.CSRF.tokenValue = token); - - var elems = document.getElementsByName('csrf'); - for(var i = 0; i < elems.length; ++i) - elems[i].value = token; -}; diff --git a/assets/js/misuzu/events/christmas2019.js b/assets/js/misuzu/events/christmas2019.js index 92e9658..2bfa3c8 100644 --- a/assets/js/misuzu/events/christmas2019.js +++ b/assets/js/misuzu/events/christmas2019.js @@ -11,8 +11,8 @@ Misuzu.Events.Christmas2019.prototype.isActive = function() { return d.getMonth() === 11 && d.getDate() > 5 && d.getDate() < 27; }; Misuzu.Events.Christmas2019.prototype.dispatch = function() { - var headerBg = document.querySelector('.header__background'), - menuBgs = document.querySelectorAll('.header__desktop__submenu__background'); + var headerBg = $q('.header__background'), + menuBgs = $qa('.header__desktop__submenu__background'); if(!localStorage.getItem(this.propName)) localStorage.setItem(this.propName, '0'); diff --git a/assets/js/misuzu/formutils.js b/assets/js/misuzu/formutils.js deleted file mode 100644 index 27e7f20..0000000 --- a/assets/js/misuzu/formutils.js +++ /dev/null @@ -1,81 +0,0 @@ -Misuzu.FormUtils = {}; -Misuzu.FormUtils.extractFormData = function(form, resetSource) { - var formData = new FormData; - - for(var i = 0; i < form.length; ++i) { - if(form[i].type.toLowerCase() === 'checkbox' && !form[i].checked) - continue; - formData.append(form[i].name, form[i].value || ''); - } - - if(resetSource) - Misuzu.FormUtils.resetFormData(form); - - return formData; -}; -Misuzu.FormUtils.resetFormData = function(form, defaults) { - defaults = defaults || []; - - for(var i = 0; i < form.length; ++i) { - var input = form[i]; - - switch(input.type.toLowerCase()) { - case 'checkbox': - input.checked = false; - break; - - case 'hidden': - var hiddenDefault = defaults.find(function(fhd) { return fhd.Name.toLowerCase() === input.name.toLowerCase(); }); - if(hiddenDefault) - input.value = hiddenDefault.Value; - break; - - default: - input.value = ''; - } - } -}; -Misuzu.FormUtils.initDataRequestMethod = function() { - var links = document.links; - - for(var i = 0; i < links.length; ++i) { - if(!links[i].href || !links[i].dataset || !links[i].dataset.mszMethod) - continue; - - links[i].addEventListener('click', function(ev) { - Misuzu.FormUtils.handleDataRequestMethod(this, this.dataset.mszMethod, this.href); - ev.preventDefault(); - }); - } -}; -Misuzu.FormUtils.handleDataRequestMethod = function(elem, method, url) { - var split = url.split('?', 2), - target = split[0], - query = split[1] || null; - - if(elem.getAttribute('disabled')) - return; - elem.setAttribute('disabled', 'disabled'); - - var xhr = new XMLHttpRequest; - xhr.onreadystatechange = function(ev) { - if(xhr.readyState !== 4) - return; - elem.removeAttribute('disabled'); - - if(xhr.status === 301 || xhr.status === 302 || xhr.status === 307 || xhr.status === 308) { - location.assign(xhr.getResponseHeader('X-Misuzu-Location')); - return; - } - - if(xhr.status >= 400 && xhr.status <= 599) { - alert(xhr.responseText); - return; - } - }; - xhr.open(method, target); - xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); - xhr.setRequestHeader('X-Misuzu-CSRF', Misuzu.CSRF.getToken()); - xhr.setRequestHeader('X-Misuzu-XHR', '1'); - xhr.send(query); -}; diff --git a/assets/js/misuzu/forum/editor.js b/assets/js/misuzu/forum/editor.js index ff1f333..c43e9ec 100644 --- a/assets/js/misuzu/forum/editor.js +++ b/assets/js/misuzu/forum/editor.js @@ -1,7 +1,7 @@ Misuzu.Forum.Editor = {}; Misuzu.Forum.Editor.allowWindowClose = false; Misuzu.Forum.Editor.init = function() { - var postingForm = document.querySelector('.js-forum-posting'); + var postingForm = $q('.js-forum-posting'); if(!postingForm) return; @@ -11,9 +11,9 @@ Misuzu.Forum.Editor.init = function() { postingPreview = postingForm.querySelector('.js-forum-posting-preview'), postingMode = postingForm.querySelector('.js-forum-posting-mode'), previewButton = document.createElement('button'), - bbcodeButtons = document.querySelector('.forum__post__actions--bbcode'), - markdownButtons = document.querySelector('.forum__post__actions--markdown'), - markupButtons = document.querySelectorAll('.forum__post__action--tag'); + bbcodeButtons = $q('.forum__post__actions--bbcode'), + markdownButtons = $q('.forum__post__actions--markdown'), + markupButtons = $qa('.forum__post__action--tag'); // hack: don't prompt user when hitting submit, really need to make this not stupid. postingButtons.firstElementChild.addEventListener('click', function() { @@ -30,7 +30,7 @@ Misuzu.Forum.Editor.init = function() { for(var i = 0; i < markupButtons.length; ++i) (function(currentBtn) { currentBtn.addEventListener('click', function(ev) { - postingText.insertTags(currentBtn.dataset.tagOpen, currentBtn.dataset.tagClose); + $insertTags(postingText, currentBtn.dataset.tagOpen, currentBtn.dataset.tagClose); }); })(markupButtons[i]); @@ -60,10 +60,7 @@ Misuzu.Forum.Editor.init = function() { return; } - if(postParser === Misuzu.Parser.markdown) - postingPreview.classList.add('markdown'); - else - postingPreview.classList.remove('markdown'); + postingPreview.classList[postParser == 2 ? 'add' : 'remove']('markdown'); lastPostParser = postParser; postingPreview.innerHTML = text; @@ -109,10 +106,7 @@ Misuzu.Forum.Editor.init = function() { return; } - if(postParser === Misuzu.Parser.markdown) - postingPreview.classList.add('markdown'); - else - postingPreview.classList.remove('markdown'); + postingPreview.classList[postParser == 2 ? 'add' : 'remove']('markdown'); lastPostText = postText; lastPostParser = postParser; @@ -133,23 +127,11 @@ Misuzu.Forum.Editor.init = function() { postingButtons.insertBefore(previewButton, postingButtons.firstChild); }; Misuzu.Forum.Editor.switchButtons = function(parser) { - var bbcodeButtons = document.querySelector('.forum__post__actions--bbcode'), - markdownButtons = document.querySelector('.forum__post__actions--markdown'); + var bbcodeButtons = $q('.forum__post__actions--bbcode'), + markdownButtons = $q('.forum__post__actions--markdown'); - switch(parser) { - default: - case Misuzu.Parser.plain: - bbcodeButtons.hidden = markdownButtons.hidden = true; - break; - case Misuzu.Parser.bbcode: - bbcodeButtons.hidden = false; - markdownButtons.hidden = true; - break; - case Misuzu.Parser.markdown: - bbcodeButtons.hidden = true; - markdownButtons.hidden = false; - break; - } + bbcodeButtons.hidden = parser != 1; + markdownButtons.hidden = parser != 2; }; Misuzu.Forum.Editor.renderPreview = function(parser, text, callback) { if(!callback) @@ -172,7 +154,8 @@ Misuzu.Forum.Editor.renderPreview = function(parser, text, callback) { else callback(false, 'Failed to render preview.'); }); - xhr.open('POST', Misuzu.Urls.format('forum-topic-new')); + // 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); }; diff --git a/assets/js/misuzu/perms.js b/assets/js/misuzu/perms.js deleted file mode 100644 index b4a106b..0000000 --- a/assets/js/misuzu/perms.js +++ /dev/null @@ -1,15 +0,0 @@ -Misuzu.Perms = function(perms) { - this.perms = perms || {}; -}; -Misuzu.Perms.prototype.perms = undefined; -Misuzu.Perms.check = function(section, value) { - return function() { return this.perms[section] && (this.perms[section] & value) > 0; }; -}; - -// Comment permissions -Misuzu.Perms.prototype.canCreateComment = Misuzu.Perms.check('comments', 0x01); -Misuzu.Perms.prototype.canDeleteOwnComment = Misuzu.Perms.check('comments', 0x08 | 0x10); -Misuzu.Perms.prototype.canDeleteAnyComment = Misuzu.Perms.check('comments', 0x10); -Misuzu.Perms.prototype.canLockCommentSection = Misuzu.Perms.check('comments', 0x20); -Misuzu.Perms.prototype.canPinComment = Misuzu.Perms.check('comments', 0x40); -Misuzu.Perms.prototype.canVoteOnComment = Misuzu.Perms.check('comments', 0x80); diff --git a/assets/js/misuzu/urls.js b/assets/js/misuzu/urls.js deleted file mode 100644 index d911bb6..0000000 --- a/assets/js/misuzu/urls.js +++ /dev/null @@ -1,66 +0,0 @@ -Misuzu.Urls = {}; -Misuzu.Urls.registry = []; -Misuzu.Urls.loadFromDocument = function() { - var elem = document.getElementById('js-urls-list'); - if(!elem) - return; - Misuzu.Urls.registry = JSON.parse(elem.textContent); -}; -Misuzu.Urls.handleVariable = function(value, vars) { - if(value[0] === '<' && value.slice(-1) === '>') - return (vars.find(function(x) { return x.name == value.slice(1, -1); }) || {}).value || ''; - if(value[0] === '[' && value.slice(-1) === ']') - return ''; // not sure if there's a proper substitute for this, should probably resolve these in url_list - if(value[0] === '{' && value.slice(-1) === '}') - return Misuzu.CSRF.getToken(); - - // Allow file extensions - var split = value.split('.'), - extension = split[split.length - 1], - fileName = split.slice(0, -1).join('.'); - if(value !== fileName) { - var fallback = Misuzu.Urls.handleVariable(fileName, vars); - if(fallback !== fileName) - return fallback + '.' + extension; - } - - return value; -}; -Misuzu.Urls.v = function(name, value) { - if(typeof value === 'undefined' || value === null) - value = ''; - return { name: name.toString(), value: value.toString() }; -}; -Misuzu.Urls.format = function(name, vars) { - vars = vars || []; - var entry = Misuzu.Urls.registry.find(function(x) { return x.name == name; }); - if(!entry || !entry.path) - return ''; - - var split = entry.path.split('/'); - for(var i = 0; i < split.length; ++i) - split[i] = Misuzu.Urls.handleVariable(split[i], vars); - - var url = split.join('/'); - - if(entry.query) { - url += '?'; - - for(var i = 0; i < entry.query.length; ++i) { - var query = entry.query[i], - value = Misuzu.Urls.handleVariable(query.value, vars); - - if(!value || (query.name === 'page' && parseInt(value) < 2)) - continue; - - url += query.name + '=' + value.toString() + '&'; - } - - url = url.replace(/^[\?\&]+|[\?\&]+$/g, ''); - } - - if(entry.fragment) - url += ('#' + Misuzu.Urls.handleVariable(entry.fragment, vars)).replace(/[\#]+$/g, ''); - - return url; -}; \ No newline at end of file diff --git a/assets/js/misuzu/user.js b/assets/js/misuzu/user.js deleted file mode 100644 index 07247bb..0000000 --- a/assets/js/misuzu/user.js +++ /dev/null @@ -1,19 +0,0 @@ -Misuzu.User = function(userInfo) { - this.id = parseInt(userInfo.user_id || 0); - this.name = (userInfo.username || '').toString(); - this.colour = new Misuzu.Colour(userInfo.user_colour || Misuzu.Colour.FLAG_INHERIT); - this.perms = new Misuzu.Perms(userInfo.perms || {}); -}; -Misuzu.User.localUser = undefined; -Misuzu.User.refreshLocalUser = function() { - var userInfo = document.getElementById('js-user-info'); - - if(!userInfo) - Misuzu.User.localUser = undefined; - else - Misuzu.User.localUser = new Misuzu.User(JSON.parse(userInfo.textContent)); -}; -Misuzu.User.isLoggedIn = function() { return Misuzu.User.localUser !== undefined; }; -Misuzu.User.prototype.getId = function() { return this.id || 0; }; -Misuzu.User.prototype.getUsername = function() { return this.name || ''; }; -Misuzu.User.prototype.getColour = function() { return this.colour || null; }; diff --git a/src/TwigMisuzu.php b/src/TwigMisuzu.php index 61b3267..71b189f 100644 --- a/src/TwigMisuzu.php +++ b/src/TwigMisuzu.php @@ -32,7 +32,6 @@ final class TwigMisuzu extends AbstractExtension { return [ new TwigFunction('url_construct', 'url_construct'), new TwigFunction('url', 'url'), - new TwigFunction('url_list', 'url_list'), new TwigFunction('html_avatar', 'html_avatar'), new TwigFunction('forum_may_have_children', 'forum_may_have_children'), new TwigFunction('forum_may_have_topics', 'forum_may_have_topics'), diff --git a/src/Users/User.php b/src/Users/User.php index 13db1cb..7348f8d 100644 --- a/src/Users/User.php +++ b/src/Users/User.php @@ -594,15 +594,6 @@ class User implements HasRankInterface, JsonSerializable { return self::$localUser !== null; } - public function getClientJson(): string { - return json_encode([ - 'user_id' => $this->getId(), - 'username' => $this->getUsername(), - 'user_colour' => $this->getColour()->getRaw(), - 'perms' => $this->getLegacyPerms(), - ]); - } - /************** * VALIDATION * **************/ diff --git a/src/url.php b/src/url.php index 8804db7..51d00e5 100644 --- a/src/url.php +++ b/src/url.php @@ -196,37 +196,6 @@ function url_variable(string $value, array $variables): string { return $value; } -function url_list(): array { - global $hasManageAccess; - - $collection = []; - - foreach(MSZ_URLS as $name => $urlInfo) { - if(empty($hasManageAccess) && str_starts_with($name, 'manage-')) - continue; - - $item = [ - 'name' => $name, - 'path' => $urlInfo[0], - 'query' => [], - 'fragment' => $urlInfo[2] ?? '', - ]; - - if(!empty($urlInfo[1]) && is_array($urlInfo[1])) { - foreach($urlInfo[1] as $name => $value) { - $item['query'][] = [ - 'name' => $name, - 'value' => $value, - ]; - } - } - - $collection[] = $item; - } - - return $collection; -} - function url_construct(string $url, array $query = [], ?string $fragment = null): string { if(count($query)) { $url .= mb_strpos($url, '?') !== false ? '&' : '?'; diff --git a/templates/_layout/comments.twig b/templates/_layout/comments.twig index 97f5b13..89c05e1 100644 --- a/templates/_layout/comments.twig +++ b/templates/_layout/comments.twig @@ -173,11 +173,11 @@ {% endif %} - #}
{% if category.posts|length > 0 %} diff --git a/templates/forum/macros.twig b/templates/forum/macros.twig index a8275dc..4f85af7 100644 --- a/templates/forum/macros.twig +++ b/templates/forum/macros.twig @@ -55,7 +55,7 @@
{% for action in actions %} {% if action.display is not defined or action.display %} - + {{ action.html|raw }} {% endif %} diff --git a/templates/master.twig b/templates/master.twig index 2be4018..e0be252 100644 --- a/templates/master.twig +++ b/templates/master.twig @@ -4,7 +4,6 @@ {% include '_layout/meta.twig' %} - @@ -149,14 +148,6 @@ {% include '_layout/footer.twig' %} {% endblock %} -{% if current_user is defined %} - -{% endif %} -