aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.browserslistrc1
-rw-r--r--src/main/assets/embed.js4
-rw-r--r--src/main/assets/scripts.js250
3 files changed, 68 insertions, 187 deletions
diff --git a/.browserslistrc b/.browserslistrc
index 5d6dd745..dd6bc33d 100644
--- a/.browserslistrc
+++ b/.browserslistrc
@@ -4,4 +4,3 @@ ie_mob >= 7
ios_saf >= 9.3
android >= 4.1
firefox >= 48
-opera >= 12.1
diff --git a/src/main/assets/embed.js b/src/main/assets/embed.js
index 739b95f3..0022ae82 100644
--- a/src/main/assets/embed.js
+++ b/src/main/assets/embed.js
@@ -255,10 +255,10 @@ function getEmbeddableLinkTypes() {
div.innerHTML = `<blockquote class="twitter-tweet" data-lang="en"><a href="${url}"></a></blockquote>`;
- if (window.twttr) {
+ if (window['twttr']) {
// this will only happen if you embed another set of twitter posts after the twitter script loads (likely never)
// https://developer.twitter.com/en/docs/twitter-for-websites/javascript-api/guides/scripting-loading-and-initialization
- window.twttr.widgets.load(div);
+ window['twttr'].widgets.load(div);
} else if (!document.head.querySelector ('[src="https://platform.twitter.com/widgets.js\"]')) {
// innerHTML cannot insert scripts, so...
let script = document.createElement('script');
diff --git a/src/main/assets/scripts.js b/src/main/assets/scripts.js
index e801c9be..d053748e 100644
--- a/src/main/assets/scripts.js
+++ b/src/main/assets/scripts.js
@@ -1,50 +1,24 @@
-require('element-closest/browser');
-require('classlist.js');
-require('formdata-polyfill');
-require('whatwg-fetch');
+import elementClosest from 'element-closest';
+import 'formdata-polyfill';
+import 'classlist.js';
+import 'whatwg-fetch';
import 'core-js/stable';
import { embedLinksToX, embedAll, format } from './embed';
import renderIcons from './icon';
import svg4everybody from 'svg4everybody';
-if (!('remove' in Element.prototype)) { // Firefox <23
- Element.prototype.remove = function() {
- if (this.parentNode) {
- this.parentNode.removeChild(this);
- }
- };
-}
-
-Element.prototype.selectText = function() {
- let d = document;
- if (d.body.createTextRange) {
- let range = d.body.createTextRange();
- range.moveToElementText(this);
- range.select();
- } else if (window.getSelection) {
- let selection = window.getSelection();
- let rangeSel = d.createRange();
- rangeSel.selectNodeContents(this);
- selection.removeAllRanges();
- selection.addRange(rangeSel);
- }
-};
-
+/**
+ * Autosize textarea
+ * @param {HTMLTextAreaElement} el textarea element
+ */
function autosize(el) {
- let offset = (!window.opera)
- ? (el.offsetHeight - el.clientHeight)
- : (el.offsetHeight + parseInt(window.getComputedStyle(el, null).getPropertyValue('border-top-width')));
+ let offset = el.offsetHeight - el.clientHeight;
- let resize = function(el) {
- el.style.height = 'auto';
- el.style.height = (el.scrollHeight + offset) + 'px';
- };
-
- if (el.addEventListener) {
- el.addEventListener('input', () => resize(el));
- } else if (el.attachEvent) {
- el.attachEvent('onkeyup', () => resize(el));
- }
+ el.addEventListener('input', (ev) => {
+ const textarea = /** @type HTMLTextAreaElement */ (ev.target);
+ textarea.style.height = 'auto';
+ textarea.style.height = (textarea.scrollHeight + offset) + 'px';
+ });
}
function evilIcon(name) {
@@ -108,7 +82,7 @@ const translations = {
function getLang() {
return (window.navigator.languages && window.navigator.languages[0])
- || window.navigator.userLanguage
+ || window.navigator['userLanguage']
|| window.navigator.language;
}
function i18n(key, lang = undefined) {
@@ -225,7 +199,7 @@ function updateRepliesCounter() {
var replies = Array.from(document.querySelectorAll('#replies>li.reply-new')).length;
var wsthread = document.getElementById('wsthread');
if (replies) {
- wsthread.textContent = replies;
+ wsthread.textContent = `${replies}`;
wsthread.style.display = 'block';
document.title = '[' + replies + '] ' + pageTitle;
} else {
@@ -238,33 +212,31 @@ function updateRepliesCounter() {
/******************************************************************************/
/******************************************************************************/
+/**
+ * Submit form on Ctrl+Enter
+ * @param {HTMLElement} formEl Target form element
+ * @param {KeyboardEvent} ev Keyboard event
+ */
function postformListener(formEl, ev) {
if (ev.ctrlKey && (ev.keyCode == 10 || ev.keyCode == 13)) {
let form = formEl.closest('form');
- if (!form.onsubmit || form.onsubmit()) {
- form.querySelector('input[type="submit"]').click();
+ if (!form.onsubmit || form.submit()) {
+ /** @type HTMLInputElement */ (form.querySelector('input[type="submit"]')).click();
}
}
}
+
+/**
+ * Close dialog on Esc
+ * @param {KeyboardEvent} ev Keyboard event
+ */
function closeDialogListener(ev) {
- ev = ev || window.event;
+ ev = ev || /** @type KeyboardEvent */ (window.event);
if (ev.keyCode == 27) {
closeDialog();
}
}
-function newMessage(evt) {
- Array.from(document.querySelectorAll('#newmessage .dialogtxt')).forEach(t => {
- t.remove();
- });
- if (document.querySelector('#newmessage textarea').value.length == 0
- && document.querySelector('#newmessage .img').value.length == 0
- && !document.querySelector('#newmessage input[type="file"]')) {
- document.querySelector('#newmessage').insertAdjacentHTML('afterbegin', `<p class="dialogtxt">${i18n('postForm.pleaseInputMessageText')}</p>`);
- evt.preventDefault();
- }
-}
-
function handleErrors(response) {
if (!response.ok) {
throw Error(response.statusText);
@@ -292,13 +264,13 @@ function showCommentForm(mid, rid) {
formTarget.remove();
let form = reply.querySelector('form');
- let submitButton = form.querySelector('input[type="submit"]');
+ let submitButton = /** @type HTMLInputElement */ (form.querySelector('input[type="submit"]'));
let attachButton = form.querySelector('.msg-comment .attach-photo');
- attachButton.addEventListener('click', e => attachCommentPhoto(e.target));
+ attachButton.addEventListener('click', e => attachCommentPhoto(/** @type HTMLDivElement */ (e.target)));
- let textarea = form.querySelector('.msg-comment textarea');
- textarea.addEventListener('keypress', e => postformListener(e.target, e));
+ let textarea = /** @type HTMLTextAreaElement */ (form.querySelector('.msg-comment textarea'));
+ textarea.addEventListener('keypress', e => postformListener(/** @type HTMLElement */ (e.target), e));
autosize(textarea);
let validateMessage = () => {
@@ -324,11 +296,11 @@ function showCommentForm(mid, rid) {
if (response.ok) {
response.json().then(result => {
if (result.newMessage) {
- window.location.href = new URL(`${mid}#${result.newMessage.rid}`, window.location.href);
+ window.location.hash = `#${result.newMessage.rid}`;
} else {
alert(result.text);
}
- window.location.reload(true);
+ window.location.reload();
});
}
}).catch(error => {
@@ -337,7 +309,7 @@ function showCommentForm(mid, rid) {
e.preventDefault();
});
}
- reply.querySelector('.msg-comment textarea').focus();
+ /** @type HTMLTextAreaElement */ (reply.querySelector('.msg-comment textarea')).focus();
}
function attachInput() {
@@ -349,6 +321,10 @@ function attachInput() {
return inp;
}
+/**
+ * "Attach" button
+ * @param {HTMLDivElement} div
+ */
function attachCommentPhoto(div) {
let input = div.querySelector('input');
if (input) {
@@ -364,48 +340,6 @@ function attachCommentPhoto(div) {
}
}
-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 = i18n('postForm.upload') + ' (✓)';
- });
- f.appendChild(inp);
- inp.click();
- } else {
- finput.remove();
- div.textContent = i18n('postForm.upload');
- }
-}
-
-function showMessageLinksDialog(mid, rid) {
- let hlink = window.location.protocol + '//juick.com/' + mid;
- let mlink = '#' + mid;
- if (rid > 0) {
- hlink += '#' + rid;
- mlink += '/' + rid;
- }
- let hlinkenc = encodeURIComponent(hlink);
- let html = `
- <div class="dialogshare">
- ${i18n('shareDialog.linkToMessage')}: <div onclick="this.selectText()" class="dialogl">${hlink}</div>
- ${i18n('shareDialog.messageNumber')}: <div onclick="this.selectText()" class="dialogl">${mlink}</div>
- ${i18n('shareDialog.share')}:
- <ul>
- <li><a href="https://www.facebook.com/sharer/sharer.php?u=${hlinkenc}" onclick="return openSocialWindow(this)">${evilIcon('ei-sc-facebook')}</a></li>
- <li><a href="https://twitter.com/intent/tweet?url=${hlinkenc}" onclick="return openSocialWindow(this)">${evilIcon('ei-sc-twitter')}</a></li>
- <li><a href="https://vk.com/share.php?url=${hlinkenc}" onclick="return openSocialWindow(this)">${evilIcon('ei-sc-vk')}</a></li>
- </ul>
- </div>`;
-
- openDialog(html);
-}
-
function showPhotoDialog(fname) {
let width = window.innerWidth;
let height = window.innerHeight;
@@ -421,21 +355,6 @@ function showPhotoDialog(fname) {
}
}
-function openPostDialog() {
- let newmessageTemplate = `
- <form id="newmessage" action="/post" method="post" enctype="multipart/form-data">
- <textarea name="body" placeholder="${i18n('postForm.newMessage')}"></textarea>
- <div>
- <input class="img" name="img" placeholder="${i18n('postForm.imageLink')} (${i18n('postForm.imageFormats')})"/>
- ${i18n('postForm.or')} <a href="#">${i18n('postForm.upload')}</a><br/>
- <input id="tags_input" class="tags" name="tags" placeholder="${i18n('postForm.tags')}"/><br/>
- <input type="submit" class="subm Button" value="${i18n('postForm.submit')}"/>
- </div>
- </form>
- `;
- return openDialog(newmessageTemplate);
-}
-
function openDialog(html, image) {
var dialogHtml = `
<div id="dialogt">
@@ -460,24 +379,14 @@ function openDialog(html, image) {
}
function closeDialog() {
- let draft = document.querySelector('#newmessage textarea');
- if (draft) {
- window.draft = draft.value;
- }
document.querySelector('body').classList.remove('dialog-opened');
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;
+ style = /** @type HTMLElement */ (document.querySelector('#username')).style;
fetch('/api/users?uname=' + uname)
.then(handleErrors)
.then(function() {
@@ -546,7 +455,7 @@ function subscribeMessage(e, mid) {
.then(handleErrors)
.then(function(response) {
if (response.ok) {
- window.location.reload(true);
+ window.location.reload();
} else {
alert('Something went wrong :(');
}
@@ -559,19 +468,6 @@ function subscribeMessage(e, mid) {
/******************************************************************************/
-function setPopular(e, mid, popular) {
- fetch('/api/messages/set_popular?mid=' + mid
- + '&popular=' + popular
- + '&hash=' + document.getElementById('body').getAttribute('data-hash'), {
- credentials: 'same-origin'
- })
- .then(handleErrors)
- .then(function() {
- e.closest('article').append(resultMessage('OK!'));
- });
- return false;
-}
-
function setPrivacy(e, mid) {
fetch('/api/messages/set_privacy?mid=' + mid
+ '&hash=' + document.getElementById('body').getAttribute('data-hash'), {
@@ -636,7 +532,8 @@ function ready(fn) {
}
}
-ready(function() {
+ready(() => {
+ elementClosest(window);
Array.from(document.querySelectorAll('textarea')).forEach((ta) => {
autosize(ta);
});
@@ -648,21 +545,21 @@ ready(function() {
e.target.removeEventListener('click', insertPMButtons);
e.preventDefault();
};
- Array.from(document.querySelectorAll('textarea.replypm')).forEach(function(e) {
+ /** @type HTMLTextAreaElement[] */ (Array.from(document.querySelectorAll('textarea.replypm'))).forEach(function(e) {
e.addEventListener('click', insertPMButtons);
e.addEventListener('keypress', function(e) {
- postformListener(e.target, e);
+ postformListener(/** @type HTMLElement */ (e.target), e);
});
});
- Array.from(document.querySelectorAll('#postmsg textarea')).forEach(function(e) {
+ /** @type HTMLTextAreaElement[] */ (Array.from(document.querySelectorAll('#postmsg textarea'))).forEach(function(e) {
e.addEventListener('keypress', function(e) {
- postformListener(e.target, e);
+ postformListener(/** @type HTMLElement */ (e.target), e);
});
});
var content = document.getElementById('content');
if (content) {
- var pageMID = content.getAttribute('data-mid');
+ var pageMID = +content.getAttribute('data-mid');
if (pageMID > 0) {
Array.from(document.querySelectorAll('li.msg')).forEach(li => {
let showReplyFormBtn = li.querySelector('.a-thread-comment');
@@ -675,10 +572,10 @@ ready(function() {
});
let opMessage = document.querySelector('.msgthread');
if (opMessage) {
- let replyTextarea = opMessage.querySelector('textarea.reply');
+ let replyTextarea = /** @type HTMLTextAreaElement */ (opMessage.querySelector('textarea.reply'));
if (replyTextarea) {
replyTextarea.addEventListener('focus', e => showCommentForm(pageMID, 0));
- replyTextarea.addEventListener('keypress', e => postformListener(e.target, e));
+ replyTextarea.addEventListener('keypress', e => postformListener(/** @type HTMLElement */ (e.target), e));
if (!window.location.hash) {
replyTextarea.focus();
}
@@ -687,7 +584,7 @@ ready(function() {
}
}
- var postmsg = document.getElementById('postmsg');
+ var postmsg = /** @type HTMLFormElement */(document.getElementById('postmsg'));
if (postmsg) {
Array.from(document.querySelectorAll('a')).filter(t => t.href.indexOf('?') >= 0).forEach(t => {
t.addEventListener('click', e => {
@@ -709,7 +606,7 @@ ready(function() {
if (response.ok) {
response.json().then(result => {
if (result.newMessage) {
- window.location = new URL(`/m/${result.newMessage.mid}`, window.location.href);
+ window.location.href = new URL(`/m/${result.newMessage.mid}`, window.location.href).href;
} else {
alert(result.text);
}
@@ -723,7 +620,7 @@ ready(function() {
e.preventDefault();
});
}
- Array.from(document.querySelectorAll('.pmmsg')).forEach(pmmsg => {
+ /** @type HTMLFormElement[] */ (Array.from(document.querySelectorAll('.pmmsg'))).forEach(pmmsg => {
pmmsg.addEventListener('submit', e => {
let formData = new FormData(pmmsg);
fetch('/api/pm' + '?hash=' + document.getElementById('body').getAttribute('data-hash'), {
@@ -735,7 +632,7 @@ ready(function() {
if (response.ok) {
response.json().then(result => {
if (result.to) {
- window.location = new URL('/pm/sent', window.location.href);
+ window.location.href = new URL('/pm/sent', window.location.href).href;
} else {
alert('Something went wrong :(');
}
@@ -750,38 +647,23 @@ ready(function() {
});
});
- Array.from(document.querySelectorAll('.msg-menu')).forEach(function(el) {
- el.addEventListener('click', function(e) {
- var reply = e.target.closest('li');
- var rid = reply ? parseInt(reply.id) : 0;
- var message = e.target.closest('section');
- var mid = message.getAttribute('data-mid') || e.target.closest('article').getAttribute('data-mid');
- showMessageLinksDialog(mid, rid);
- e.preventDefault();
- });
- });
Array.from(document.querySelectorAll('.l .a-privacy')).forEach(function(e) {
e.addEventListener('click', function(e) {
setPrivacy(
e.target,
- e.target.closest('article').getAttribute('data-mid'));
+ /** @type HTMLElement */(e.target).closest('article').getAttribute('data-mid'));
e.preventDefault();
});
});
Array.from(document.querySelectorAll('.ir a[data-fname], .msg-media a[data-fname]')).forEach(function(el) {
el.addEventListener('click', function(e) {
- let fname = e.target.closest('[data-fname]').getAttribute('data-fname');
+ let fname = /** @type HTMLElement */ (e.target).closest('[data-fname]').getAttribute('data-fname');
if (!showPhotoDialog(fname)) {
e.preventDefault();
}
});
});
- Array.from(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() {
@@ -793,7 +675,7 @@ ready(function() {
e.addEventListener('click', function(e) {
likeMessage(
e.target,
- e.target.closest('article').getAttribute('data-mid'));
+ /** @type HTMLElement */(e.target).closest('article').getAttribute('data-mid'));
e.preventDefault();
});
});
@@ -814,12 +696,12 @@ ready(function() {
var unfoldall = document.getElementById('unfoldall');
if (unfoldall) {
unfoldall.addEventListener('click', function(e) {
- Array.from(document.querySelectorAll('#replies>li')).forEach(function(e) {
- e.style.display = 'block';
- });
- Array.from(document.querySelectorAll('#replies .msg-comments')).forEach(function(e) {
- e.style.display = 'none';
- });
+ /** @type HTMLElement[] */ (Array.from(document.querySelectorAll('#replies>li'))).forEach(function(e) {
+ e.style.display = 'block';
+ });
+ /** @type HTMLElement[] */ (Array.from(document.querySelectorAll('#replies .msg-comments'))).forEach(function(e) {
+ e.style.display = 'none';
+ });
e.preventDefault();
});
}
@@ -867,7 +749,7 @@ ready(function() {
}
});
let location = window.location.href;
- Array.from(document.querySelectorAll('#header_wrapper a')).forEach(el => {
+ /** @type HTMLLinkElement[] */ (Array.from(document.querySelectorAll('#header_wrapper a'))).forEach(el => {
if (el.href === location) {
el.classList.add('active');
el.setAttribute('disabled', 'disabled');