You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

281 lines
11 KiB

/*
| Snicker The first native FlatFile Comment Plugin 4 Bludit
| @file ./system/themes/default/snicker.js
| @author SamBrishes <sam@pytes.net>
| @version 0.1.2 [0.1.0] - Alpha
|
| @website https://github.com/pytesNET/snicker
| @license X11 / MIT License
| @copyright Copyright © 2019 SamBrishes, pytesNET <info@pytes.net>
*/
;(function(root){
"use strict";
var w = root, d = root.document;
/*
| AJAX HELPER
*/
function ajax(url, type, data, callback, self){
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function(){
if(this.readyState == 4){
callback.call((self? self: this), this.responseText, this);
}
};
xhttp.open(type, url, true);
xhttp.setRequestHeader("Cache-Control", "no-cache");
xhttp.setRequestHeader("X-Requested-With", "XMLHttpRequest");
if(type == "POST"){
if(!(data instanceof FormData)){
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
}
xhttp.send(data);
} else {
xhttp.send();
}
}
/*
| ALERT HELPER
*/
function showAlert(type, message, parent){
var alert = d.createElement("DIV");
alert.className = "comment-alert alert-" + type;
alert.innerText = message;
// Remove Existing Status
var alerts = parent.querySelectorAll(".comment-alert");
if(alerts.length > 0){
Array.prototype.forEach.call(alerts, function(item){
item.parentElement.removeChild(item);
});
}
// Add Status
if(parent.children.length > 0){
parent.insertBefore(alert, parent.children[0]);
} else {
parent.appendChild(alert);
}
}
// Ready?
d.addEventListener("DOMContentLoaded", function(){
"use strict";
// Main Elements
var form = d.querySelector("form.comment-form"),
list = d.querySelector(".snicker-comments-list"),
captcha = d.querySelector("a[data-captcha='reload']");
/*
| HANDLE COMMENT FORM
*/
if(form){
form.addEventListener("submit", function(event){
event.preventDefault();
if(typeof(FormData) !== "function" || !SNICKER_AJAX){
return true;
}
var data = new FormData(this), self = this;
// Check Button
var btn = this.querySelector("[name='snicker']");
if(btn.disabled){
return true;
}
event.preventDefault();
// AJAX Call
btn.disabled = true;
btn.classList.add("loading");
data.append("snicker", btn.value);
ajax(SNICKER_PATH, "POST", data, function(json){
var data = JSON.parse(json);
// Add Comment
if(list && data.status == "success" && "comment" in data){
if(list.querySelector(".comment")){
list.querySelector(".comment").insertAdjacentHTML("beforebegin", data.comment);
} else {
list.insertAdjacentHTML("afterbegin", data.comment);
}
list.querySelector(".comment").classList.add("new-comment");
list.querySelector(".comment").scrollIntoView({ behavior: "smooth", block: "center" });
// Empty Form
var field = self.querySelectorAll("#comment-title,#comment-text");
for(var i = 0, l = field.length; i < l; i++){
if(field[i].tagName == "SELECT"){
field[i].options[0].selected = true;
} else if(field[i].getAttribute("type") === "checkbox"){
field[i].checked = false;
} else {
field[i].value = "";
}
}
showAlert("success", data.success, form.querySelector(".comment-article"));
} else if(data.status === "error"){
showAlert("error", data.error, form.querySelector(".comment-article"));
if(captcha && "captcha" in data){
d.querySelector("input[name='comment[captcha]']").value = "";
captcha.querySelector("img").src = data.captcha;
}
}
// Re-Enable Button
btn.disabled = false;
btn.classList.remove("loading");
});
});
}
/*
| HANDLE CAPTCHA RELOAD
*/
if(captcha){
captcha.addEventListener("click", function(event){
if(!SNICKER_AJAX){
return false;
}
event.preventDefault();
captcha.classList.add("reload");
var data = "action=snicker&snicker=captcha&tokenCSRF=";
var token = d.querySelector("input[name='tokenCSRF']").value;
ajax(SNICKER_PATH, "POST", data + token, function(json){
var data = JSON.parse(json);
if(data.status !== "success"){
window.location.replace(captcha.getAttribute("href"));
}
captcha.querySelector("img").src = data.captcha;
captcha.classList.remove("reload");
});
})
}
/*
| HANDLE COMMENT REPLY
*/
if(list){
list.addEventListener("click", function(event){
if(event.target.tagName != "A" || !form){
return true;
}
// Check Link
var href = event.target.getAttribute("href");
if(href.indexOf("snicker=reply") < 0){
return true;
}
// Handle Reply
event.preventDefault();
var comment = (function getComment(element){
var parent = element.parentElement;
return (parent.classList.contains("comment"))? parent: getComment(parent);
})(event.target);
// Create Elements
var reply = d.createElement("DIV");
reply.className = "comment-reply";
reply.innerHTML = '<a href="' + window.location.href + '" class="reply-cancel"></a>'
+ '<div class="reply-title">' + comment.querySelector(".author-username").innerText + ' wrotes:</div>'
+ '<div class="reply-content">' + comment.querySelector(".comment-comment").innerHTML + '</div>';
var parent = d.createElement("INPUT");
parent.type = "hidden";
parent.name = "comment[parent_uid]";
parent.value = comment.id.replace("comment-", "");
// Append Cancel
reply.querySelector(".reply-cancel").addEventListener("click", function(event){
event.preventDefault();
// Remove Elements
reply.parentElement.removeChild(reply);
parent.parentElement.removeChild(parent);
// Switch Button Text
var old = form.querySelector("button").innerText;
form.querySelector("button").value = "comment";
form.querySelector("button").innerText = form.querySelector("button").getAttribute("data-string");
form.querySelector("button").setAttribute("data-string", old);
});
// Inject Elements
var art = form.querySelector(".comment-article");
if(art.querySelector(".comment-reply")){
art.replaceChild(reply, art.querySelector(".comment-reply"));
} else {
art.insertBefore(reply, form.querySelector("textarea").parentElement);
}
var foo = form.querySelector(".comment-footer");
if(foo.querySelector("input[name='comment[parent_uid]']")){
foo.replaceChild(parent, foo.querySelector("input[name='comment[parent_uid]']"));
} else {
foo.appendChild(parent);
}
// Switch Button Text
var old = form.querySelector("button").innerText;
form.querySelector("button").value = "reply";
form.querySelector("button").innerText = form.querySelector("button").getAttribute("data-string");
form.querySelector("button").setAttribute("data-string", old);
});
}
/*
| HANDLE COMMENT RATING
*/
if(list){
list.addEventListener("click", function(event){
if(event.target.tagName != "A" || !SNICKER_AJAX){
return true;
}
if(event.target.classList.contains("disabled")){
return true;
}
// Check Link
var href = event.target.getAttribute("href");
if(href.indexOf("&type=like") < 0 && href.indexOf("&type=dislike") < 0){
return true;
}
// Event Handler
event.preventDefault();
event.target.classList.add("disabled");
var comment = (function getComment(element){
var parent = element.parentElement;
return (parent.classList.contains("comment"))? parent: getComment(parent);
})(event.target), self = event.target;
href = href.split("?");
// AJAX REQUEST
ajax(SNICKER_PATH, "POST", href[1], function(json){
var data = JSON.parse(json);
if(data.status === "success" && "rating" in data){
var like = comment.querySelector("[data-snicker='like']");
if(like){
like.innerText = String(data.rating[0]);
}
like.parentElement.classList[(like.parentElement == self? "add": "remove")]("active");
var dislike = comment.querySelector("[data-snicker='dislike']");
if(dislike){
dislike.innerText = String(data.rating[1]);
}
dislike.parentElement.classList[(dislike.parentElement == self? "add": "remove")]("active");
}
// Re-Enable Button
self.classList.remove("disabled");
});
});
}
});
})(window);