var autosize = require('autosize'); require('whatwg-fetch'); require('element-closest'); require('classlist.js'); var killy = require('killy'); 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 += ' в ответ на /' + msg.replyto + ''; } 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('
Пожалуйста, введите текст сообщения
'); 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 = '' + html + ' |