Pruned a lot of existing Javascript, comments will receive and overhaul later.
This commit is contained in:
parent
5a495ec472
commit
ed2201090c
17 changed files with 155 additions and 1029 deletions
|
@ -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();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
|
@ -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;
|
||||
};
|
|
@ -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;
|
||||
};
|
|
@ -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');
|
||||
|
|
|
@ -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);
|
||||
};
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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);
|
|
@ -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;
|
||||
};
|
|
@ -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; };
|
|
@ -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'),
|
||||
|
|
|
@ -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 *
|
||||
**************/
|
||||
|
|
31
src/url.php
31
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 ? '&' : '?';
|
||||
|
|
|
@ -173,11 +173,11 @@
|
|||
</div>
|
||||
{% endif %}
|
||||
|
||||
<noscript>
|
||||
{#<noscript>
|
||||
<div class="comments__javascript">
|
||||
While the comments work fine without Javascript, it is recommended you enable it as it has a lower bandwidth overhead.
|
||||
</div>
|
||||
</noscript>
|
||||
</noscript>#}
|
||||
|
||||
<div class="comments__listing">
|
||||
{% if category.posts|length > 0 %}
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
<div class="forum__header__actions">
|
||||
{% for action in actions %}
|
||||
{% if action.display is not defined or action.display %}
|
||||
<a class="forum__header__action{% if action.class is defined %}{{ action.class }}{% endif %}" href="{{ action.url }}"{% if action.method is defined %} data-msz-method="{{ action.method }}"{% endif %}>
|
||||
<a class="forum__header__action{% if action.class is defined %}{{ action.class }}{% endif %}" href="{{ action.url }}">
|
||||
{{ action.html|raw }}
|
||||
</a>
|
||||
{% endif %}
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
<meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
{% include '_layout/meta.twig' %}
|
||||
<meta name="csrf-token" value="{{ csrf_token() }}"/>
|
||||
<link href="/vendor/fontawesome/css/all.min.css" type="text/css" rel="stylesheet"/>
|
||||
<link href="/vendor/highlightjs/styles/tomorrow-night.css" type="text/css" rel="stylesheet"/>
|
||||
<link href="/assets/misuzu.css" type="text/css" rel="stylesheet"/>
|
||||
|
@ -149,14 +148,6 @@
|
|||
{% include '_layout/footer.twig' %}
|
||||
{% endblock %}
|
||||
|
||||
{% if current_user is defined %}
|
||||
<script type="application/json" id="js-user-info">
|
||||
{{ current_user.clientJson|raw }}
|
||||
</script>
|
||||
{% endif %}
|
||||
<script type="application/json" id="js-urls-list">
|
||||
{{ url_list()|json_encode|raw }}
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
window.addEventListener('DOMContentLoaded', function() { Misuzu(); });
|
||||
</script>
|
||||
|
|
Loading…
Reference in a new issue