var autosize = require('autosize');
require('whatwg-fetch');
require('element-closest');
require('classlist.js');
if (!('remove' in Element.prototype)) { // Firefox <23
Element.prototype.remove = function() {
if (this.parentNode) {
this.parentNode.removeChild(this);
}
};
}
NodeList.prototype.forEach = Array.prototype.forEach;
HTMLCollection.prototype.forEach = Array.prototype.forEach;
var ws,
pageTitle;
function initWS() {
var content = document.getElementById('content');
if (!content) { return }
var pageMID = content.getAttribute('data-mid');
if (!pageMID) { return }
var url = (window.location.protocol === 'https:' ? 'wss' : 'ws') + ':'
+ (typeof juickDebug !== 'undefined' ?
'//ws.juick.com/_replies' : ('//ws.juick.com/' + pageMID)),
hash = document.getElementById('body').getAttribute('data-hash');
if (hash) {
url += '?hash=' + hash;
}
ws = new WebSocket(url);
ws.onopen = function () {
console.log('online');
if (!document.querySelector('#wsthread')) {
var d = document.createElement('div');
d.id = 'wsthread';
d.addEventListener('click', nextReply);
document.querySelector('body').appendChild(d);
pageTitle = document.title;
}
};
ws.onclose = function () {
console.log('offline');
ws = false;
setTimeout(function () {
initWS();
}, 2000);
};
ws.onmessage = function (msg) {
if (msg.data == ' ') {
ws.send(' ');
} else {
try {
var jsonMsg = JSON.parse(msg.data);
console.log('data: ' + msg.data);
wsIncomingReply(jsonMsg);
} catch (err) {
console.log(err);
}
}
};
setInterval(wsSendKeepAlive, 90000);
}
function wsSendKeepAlive() {
if (ws) {
ws.send(' ');
}
}
function wsShutdown() {
if (ws) {
ws.onclose = function () { };
ws.close();
}
}
function isTreeMode() {
// relies on UserThread.printReplies implementation TODO keep this in cookie or something
return document.querySelector('.title2-right > a').href.match(/\?view=(\w+)/)[1] == 'list';
}
function wsIncomingReply(msg) {
var li = document.createElement('li');
li.setAttribute('class', 'msg reply-new');
li.setAttribute('id', msg.rid);
li.addEventListener('click', newReply);
li.addEventListener('mouseover', newReply);
var msgAvatar = document.createElement('div');
msgAvatar.setAttribute('class', 'msg-avatar');
var msgAvatarLink = document.createElement('a');
msgAvatarLink.setAttribute('href', '/' + msg.user.uname + '/');
var msgAvatarImg = document.createElement('img');
msgAvatarImg.setAttribute('src', '//i.juick.com/a/' + msg.user.uid + '.png');
msgAvatarLink.appendChild(msgAvatarImg);
msgAvatar.appendChild(msgAvatarLink);
var msgCont = document.createElement('div');
msgCont.setAttribute('class', 'msg-cont');
var msgMenu = document.createElement('div');
msgMenu.setAttribute('class', 'msg-menu');
msgCont.appendChild(msgMenu);
var msgMenuLink = document.createElement('a');
msgMenuLink.setAttribute('href', '#');
msgMenuLink.addEventListener('click', function (e) {
showMessageLinksDialog(msg.mid, msg.rid);
e.preventDefault();
});
msgMenu.appendChild(msgMenuLink);
var msgHeader = document.createElement('div');
msgHeader.setAttribute('class', 'msg-header');
var msgHeaderLink = document.createElement('a');
msgHeaderLink.setAttribute('href', '/' + msg.user.uname + '/');
msgHeaderLink.textContent = '@' + msg.user.uname + ':';
msgHeader.appendChild(msgHeaderLink);
var msgTimestamp = document.createElement('div');
msgTimestamp.setAttribute('class', 'msg-ts');
var msgTimestampLink = document.createElement('a');
msgTimestampLink.setAttribute('href', '/' + msg.mid + '#' + msg.rid);
msgTimestampLink.setAttribute('title', msg.timestamp + ' GMT');
msgTimestampLink.textContent = msg.timestamp;
msgTimestamp.appendChild(msgTimestampLink);
var msgTxt = document.createElement('div');
msgTxt.setAttribute('class', 'msg-txt');
var msgLinks = document.createElement('div');
msgLinks.setAttribute('class', 'msg-links');
var msgNum = '/' + msg.rid;
if (msg.replyto > 0) {
msgNum += ' в ответ на <a href="#' + msg.replyto + '">/' + msg.replyto + '</a>';
}
msgLinks.innerHTML = msgNum + ' · ';
var msgLinksLink = document.createElement('a');
msgLinksLink.setAttribute('href', '#');
msgLinksLink.textContent = 'Ответить';
msgLinksLink.addEventListener('click', function (e) {
showCommentForm(msg.mid, msg.rid);
e.preventDefault();
});
msgLinks.appendChild(msgLinksLink);
var msgComment = document.createElement('div');
msgComment.setAttribute('class', 'msg-comment');
msgComment.style.display = 'none';
msgHeader.appendChild(msgAvatar);
msgHeader.appendChild(msgMenu);
msgHeader.appendChild(msgTimestamp);
msgCont.appendChild(msgHeader);
msgCont.appendChild(msgTxt);
msgCont.appendChild(msgLinks);
msgCont.appendChild(msgComment);
li.appendChild(msgCont);
li.querySelector('.msg-txt').textContent = msg.body;
if (isTreeMode() && (msg.replyto > 0)) {
var p = document.getElementById(msg.replyto);
var m = parseInt(p.style.marginLeft) + 20;
while (p.nextElementSibling && (parseInt(p.nextElementSibling.style.marginLeft) >= m)) p = p.nextElementSibling;
li.style.marginLeft = m + 'px';
p.parentNode.insertBefore(li, p.nextSibling);
} else {
document.getElementById('replies').appendChild(li);
}
updateRepliesCounter();
}
function newReply(e) {
var li = e.target;
li.classList.remove('reply-new');
li.removeEventListener('click', e);
li.removeEventListener('mouseover', e);
updateRepliesCounter();
}
function nextReply() {
var li = document.querySelector('#replies>li.reply-new');
if (li) {
li.classList.remove('reply-new');
li.removeEventListener('click', this);
li.childNodes[0].scrollIntoView();
updateRepliesCounter();
}
}
function updateRepliesCounter() {
var replies = document.querySelectorAll('#replies>li.reply-new').length;
var wsthread = document.getElementById('wsthread');
if (replies) {
wsthread.textContent = replies;
wsthread.style.display = 'block';
document.title = '[' + replies + '] ' + pageTitle;
} else {
wsthread.style.display = 'none';
document.title = pageTitle;
}
}
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/
function postformListener(formEl, ev) {
var form = formEl.closest('form');
if (ev.ctrlKey && (ev.keyCode == 10 || ev.keyCode == 13)) {
if (!form.onsubmit || form.onsubmit()) {
form.submit();
}
}
}
function unfoldPostForm() {
if (window.location.pathname === '/' && window.location.hash === '#post') {
document.querySelector('#newmessage>div').style.display = 'block';
var ta = document.querySelector('#newmessage textarea');
ta.style.minHeight = '70px';
ta.focus();
}
}
function newMessage() {
if (document.querySelector('#newmessage textarea').value.length == 0) {
openDialog('<p class="dialogtxt">Пожалуйста, введите текст сообщения</p>');
return false;
}
return true;
}
function showMoreReplies(el, id) {
var foldedReplies = el.closest('li').querySelector('.msg-comments');
if (!foldedReplies) { return }
foldedReplies.style.display = 'none';
var replies = document.querySelectorAll('#replies>li'),
flagshow = 0,
i = 0;
for (; i < replies.length; i += 1) {
if (flagshow == 1) {
if (replies[i].style.display == 'none') {
replies[i].style.display = 'block';
} else {
break;
}
}
if (replies[i].id == id) {
flagshow = 1;
}
}
return false;
}
function replyForm(mid, rid) {
var form = document.createElement('form');
form.setAttribute('action', '/comment');
form.setAttribute('method', 'POST');
form.setAttribute('enctype', 'multipart/form-data');
var input = document.createElement('input');
input.setAttribute('type', 'hidden');
input.setAttribute('name', 'mid');
input.setAttribute('value', mid);
form.appendChild(input);
if (rid) {
var inputRid = document.createElement('input');
inputRid.setAttribute('type', 'hidden');
inputRid.setAttribute('name', 'rid');
inputRid.setAttribute('value', rid);
form.appendChild(inputRid);
}
return form;
}
function taWrapper() {
var txtarea = document.createElement('textarea');
txtarea.setAttribute('name', 'body');
txtarea.setAttribute('rows', 1);
txtarea.setAttribute('class', 'reply narrow');
txtarea.setAttribute('placeholder', 'Написать комментарий...');
var txtKeypress = function (e) {
postformListener(e.target, e);
};
txtarea.addEventListener('keypress', txtKeypress);
var wrapper = document.createElement('div');
wrapper.setAttribute('class', 'ta-wrapper');
wrapper.appendChild(txtarea);
var att = document.createElement('div');
att.setAttribute('class', 'attach-photo');
att.addEventListener('click', function () {
attachCommentPhoto(this);
});
wrapper.appendChild(att);
return wrapper;
}
function showCommentForm(mid, rid) {
var reply = document.getElementById(rid);
if (reply && !reply.querySelector('textarea')) {
var c = reply.querySelector('div.msg-cont > .msg-comment'),
newNode = c.cloneNode(true),
form = replyForm(mid, rid);
form.appendChild(newNode);
newNode.appendChild(taWrapper());
var subm = document.createElement('input');
subm.setAttribute('type', 'submit');
subm.setAttribute('value', 'OK');
newNode.appendChild(subm);
c.parentNode.insertBefore(form, c);
c.remove();
}
var commentBlock = reply.querySelector('div.msg-cont > form > div.msg-comment');
commentBlock.style.display = 'block';
var commentText = commentBlock.querySelector('textarea');
if (commentText) {
autosize(commentText);
commentText.focus();
}
}
function showCommentFooter(e, mid, rid) {
var a = e.closest('article');
if (!a.querySelector('footer.comm')) {
var form = replyForm(mid, rid),
footer = document.createElement('footer');
footer.setAttribute('class', 'comm');
footer.appendChild(taWrapper());
var subm = document.createElement('input');
subm.setAttribute('type', 'submit');
subm.setAttribute('value', 'OK');
footer.appendChild(subm);
form.appendChild(footer);
a.appendChild(form);
autosize(a.querySelector('textarea'));
}
a.querySelector('textarea').focus();
}
function attachInput() {
var inp = document.createElement('input');
inp.setAttribute('type', 'file');
inp.setAttribute('name', 'attach');
inp.setAttribute('accept', 'image/jpeg,image/png');
inp.style.visibility = 'hidden';
return inp;
}
function attachCommentPhoto(div) {
if (div.children.length === 0) {
var inp = attachInput();
inp.addEventListener('change', function () {
inp.parentNode.classList.add('attach-photo-active');
});
inp.click();
div.appendChild(inp);
} else {
div.innerHTML = null;
div.classList.add('attach-photo');
}
}
function attachMessagePhoto(div) {
var f = div.closest('form'),
finput = f.querySelector('input[type="file"]');
if (!finput) {
var inp = attachInput();
inp.style.float = 'left';
inp.style.width = 0;
inp.style.height = 0;
inp.addEventListener('change', function () {
div.textContent = 'загрузить (✓)';
});
f.appendChild(inp);
inp.click();
} else {
finput.remove();
div.textContent = 'загрузить';
}
}
function unfoldReply() {
var anchor = window.location.hash.substring(1);
if ((0 + anchor) > 0) {
var el = document.getElementById(anchor);
if (!el) { return }
while (el.style.display === 'none') {
el = el.previousElementSibling;
}
showMoreReplies(el, el.getAttribute('id'));
window.location.replace(window.location.hash);
}
}
function showMessageLinksDialog(mid, rid) {
var hlink = window.location.protocol + '//juick.com/' + mid,
mlink = '#' + mid;
if (rid > 0) {
hlink += '#' + rid;
mlink += '/' + rid;
}
var hlinkenc = encodeURIComponent(hlink),
html = '<div class="dialogshare">Ссылка на сообщение:'
+ '<div onclick="this.selectText()" class="dialogl">' + hlink + '</div>'
+ 'Номер сообщения:'
+ '<div onclick="this.selectText()" class="dialogl">' + mlink + '</div>'
+ 'Поделиться:<ul>'
+ '<li><a href="https://www.facebook.com/sharer/sharer.php?u=' + hlinkenc + '" onclick="return openSocialWindow(this)"></a></li>'
+ '<li><a href="https://twitter.com/intent/tweet?url=' + hlinkenc + '" onclick="return openSocialWindow(this)" style="background-position: -32px 0;"></a></li>'
+ '<li><a href="https://vk.com/share.php?url=' + hlinkenc + '" onclick="return openSocialWindow(this)" style="background-position: -64px 0;"></a></li>'
+ '<li><a href="https://plus.google.com/share?url=' + hlinkenc + '" onclick="return openSocialWindow(this)" style="background-position: -96px 0;"></a></li>'
+ '</ul></div>';
openDialog(html);
}
function showPhotoDialog(fname) {
var width = window.innerWidth,
height = window.innerHeight * 0.9;
if (width < 640) {
return true;
} else if (width < 1280) {
openDialog('<a href="//i.juick.com/photos-1024/' + fname + '"><img src="//i.juick.com/photos-512/' + fname + '"/></a>');
document.querySelector('#dialogw img').style.maxHeight = height + 'px';
return false;
} else {
openDialog('<a href="//i.juick.com/p/' + fname + '"><img src="//i.juick.com/photos-1024/' + fname + '"/></a>');
document.querySelector('#dialogw img').style.maxHeight = height + 'px';
return false;
}
}
function openDialog(html) {
var dhtml = '<table id="dialogt"><tr><td><div id="dialogb"></div><div id="dialogw"><div id="dialogc"></div>' + html + '</div></td></tr></table>';
document.querySelector('body').insertAdjacentHTML('afterbegin', dhtml);
document.querySelector('#dialogb').addEventListener('click', closeDialog);
document.querySelector('#dialogc').addEventListener('click', closeDialog);
}
function closeDialog() {
document.querySelector('#dialogb').remove();
document.querySelector('#dialogt').remove();
}
function openSocialWindow(a) {
var w = window.open(a.href, 'juickshare', 'width=640,height=400');
if (window.focus) w.focus();
return false;
}
function checkUsername() {
var uname = document.querySelector('#username').textContent,
style = document.querySelector('#username').style;
fetch('//api.juick.com/users?uname=' + uname)
.then(function () {
style.background = '#FFCCCC';
})
.catch(function () {
style.background = '#CCFFCC';
});
}
/******************************************************************************/
function openDialogLogin() {
var html = '<div class="dialoglogin"><p>Пожалуйста, представьтесь:'
+ '<a href="/_fblogin" id="signfb">Facebook</a> '
+ '<a href="/_vklogin" id="signvk">ВКонтакте</a></p>'
+ '<p>Уже зарегистрированы?</p>'
+ '<form action="/login" method="POST">'
+ '<input class="signinput" type="text" name="username" placeholder="Имя пользователя"/><br/>'
+ '<input class="signinput" type="password" name="password" placeholder="Пароль"/><br/>'
+ '<input class="signsubmit" type="submit" value="OK"/>'
+ '</form></div>';
openDialog(html);
return false;
}
/******************************************************************************/
function resultMessage(str) {
var result = document.createElement('p');
result.textContent = str;
return result;
}
function likeMessage(e, mid) {
if (confirm('Are you sure?')) {
fetch('//juick.com/like?mid=' + mid, {
method: 'POST',
credentials: 'same-origin'
})
.then(function (response) {
if (response.ok) {
e.closest('article').appendChild(resultMessage('OK!'));
}
})
.catch(function () {
e.closest('article').appendChild(resultMessage('Ошибка'));
});
}
return false;
}
/******************************************************************************/
function setPopular(e, mid, popular) {
fetch('//api.juick.com/messages/set_popular?mid=' + mid
+ '&popular=' + popular
+ '&hash=' + document.getElementById('body').getAttribute('data-hash'), {
credentials: 'same-origin'
})
.then(function () {
e.closest('article').append(resultMessage('OK!'));
});
return false;
}
function setPrivacy(e, mid) {
fetch('//api.juick.com/messages/set_privacy?mid=' + mid
+ '&hash=' + document.getElementById('body').getAttribute('data-hash'), {
credentials: 'same-origin'
})
.then(function () {
e.closest('article').append(resultMessage('OK!'));
});
return false;
}
/******************************************************************************/
Element.prototype.selectText = function () {
var d = document;
if (d.body.createTextRange) {
var range = d.body.createTextRange();
range.moveToElementText(this);
range.select();
} else if (window.getSelection) {
var selection = window.getSelection();
var rangeSel = d.createRange();
rangeSel.selectNodeContents(this);
selection.removeAllRanges();
selection.addRange(rangeSel);
}
};
function ready(fn) {
if (document.readyState != 'loading') {
fn();
} else {
document.addEventListener('DOMContentLoaded', fn);
}
}
ready(function () {
autosize(document.querySelectorAll('textarea'));
var insertButtons = function (e) {
var textarea = e.target;
textarea.classList.add('narrow');
var att = document.createElement('div');
att.classList.add('attach-photo');
att.addEventListener('click', function(e) {
attachCommentPhoto(e.target);
});
textarea.parentNode.insertBefore(att, textarea.nextSibling);
textarea.parentNode.insertAdjacentHTML('afterend', '<input type="submit" value="OK"/>');
textarea.removeEventListener('click', insertButtons);
e.preventDefault();
};
document.querySelectorAll('textarea.reply').forEach(function(e) {
e.addEventListener('click', insertButtons);
e.addEventListener('keypress', function(e) {
postformListener(e.target, e);
});
});
var insertPMButtons = function (e) {
e.target.classList.add('narrowpm');
e.target.parentNode.insertAdjacentHTML('afterend', '<input type="submit" value="OK"/>');
e.target.removeEventListener('click', insertPMButtons);
e.preventDefault();
};
document.querySelectorAll('textarea.replypm').forEach(function(e) {
e.addEventListener('click', insertPMButtons);
});
var content = document.getElementById('content');
if (content) {
var pageMID = content.getAttribute('data-mid');
if (pageMID > 0) {
document.querySelectorAll('.msg-comments').forEach(function(e) {
e.addEventListener('click', function (e) {
var rid = e.target.closest('li').id;
showMoreReplies(e.target, rid);
e.preventDefault();
});
});
document.querySelectorAll('.a-thread-comment').forEach(function(e) {
e.addEventListener('click', function (e) {
var rid = e.target.closest('li').id;
showCommentForm(pageMID, rid);
e.preventDefault();
});
});
}
}
document.querySelectorAll('.msg-menu a').forEach(function(el) {
el.addEventListener('click', function(e) {
showMessageLinksDialog(
e.target.closest('section').getAttribute('data-mid'),
parseInt(e.target.closest('li').id)); // rid
e.preventDefault();
});
});
document.querySelectorAll('.l .a-comment').forEach(function(e) {
e.addEventListener('click', function (e) {
showCommentFooter(
e.target,
e.target.closest('article').getAttribute('data-mid'));
e.preventDefault();
});
});
document.querySelectorAll('.l .a-privacy').forEach(function(e) {
e.addEventListener('click', function (e) {
setPrivacy(
e.target,
e.target.closest('article').getAttribute('data-mid'));
e.preventDefault();
});
});
document.querySelectorAll('.l .a-popular-plus').forEach(function(e) {
e.addEventListener('click', function (e) {
setPopular(
e.target,
e.target.closest('article').getAttribute('data-mid'),
2);
e.preventDefault();
});
});
document.querySelectorAll('.l .a-popular-minus').forEach(function(e) {
e.addEventListener('click', function (e) {
setPopular(
e.target,
e.target.closest('article').getAttribute('data-mid'),
-1);
e.preventDefault();
});
});
document.querySelectorAll('.l .a-popular-delete').forEach(function(e) {
e.addEventListener('click', function (e) {
setPopular(
e.target,
e.target.closest('article').getAttribute('data-mid'),
-2);
e.preventDefault();
});
});
document.querySelectorAll('.ir a').forEach(function(e) {
e.addEventListener('click', function (e) {
var fname = e.target.closest('[data-fname]').getAttribute('data-fname');
if (!showPhotoDialog(fname)) {
e.preventDefault();
}
});
});
document.querySelectorAll('.social a').forEach(function(e) {
e.addEventListener('click', function (e) {
openSocialWindow(e.target);
e.preventDefault();
});
});
var username = document.getElementById('username');
if (username) {
username.addEventListener('blur', function () {
checkUsername();
});
}
document.querySelectorAll('.l .a-like').forEach(function(e) {
e.addEventListener('click', function (e) {
likeMessage(
e.target,
e.target.closest('article').getAttribute('data-mid'));
e.preventDefault();
});
});
document.querySelectorAll('.a-login').forEach(function(el) {
el.addEventListener('click', function(e) {
openDialogLogin();
e.preventDefault();
});
});
document.querySelectorAll('.attach-photo').forEach(function(el) {
el.addEventListener('click', function(e) {
attachCommentPhoto(e.target);
});
});
var unfoldall = document.getElementById('unfoldall');
if (unfoldall) {
unfoldall.addEventListener('click', function(e) {
document.querySelectorAll('#replies>li').forEach(function(e) {
e.style.display = 'block';
});
document.querySelectorAll('#replies .msg-comments').forEach(function(e) {
e.style.display = 'none';
});
e.preventDefault();
});
}
var newMessageBlock = document.getElementById('newmessage');
if (newMessageBlock) {
var form = newMessageBlock.parentNode;
form.addEventListener('submit', newMessage);
newMessageBlock.querySelector('textarea').addEventListener('click', function(e) {
var parent = e.target.parentNode;
parent.querySelector('div').style.display = 'block';
e.target.style.minHeight = '70px';
e.target.addEventListener('keypress', function(e) {
postformListener(e.target, e);
});
});
newMessageBlock.querySelector('a').addEventListener('click', function(e) {
attachMessagePhoto(e.target);
});
}
document.querySelectorAll('article').forEach(function(article) {
if (Array.prototype.some.call(
article.querySelectorAll('.u a'),
function (a) {
return a.textContent === 'NSFW';
}
)) {
var img = article.querySelector('.ir img');
if (img) {
img.style.opacity = 0.05;
img.addEventListener('mouseover', function(e) {
e.target.style.opacity = 1;
});
img.addEventListener('mouseout', function(e) {
e.target.style.opacity = 0.05;
});
}
}
});
unfoldPostForm();
unfoldReply();
initWS();
window.addEventListener('hashchange', unfoldPostForm);
window.addEventListener('hashchange', unfoldReply);
window.addEventListener('pagehide', wsShutdown);
});