var each = (a,c)=> Array.prototype.forEach.call(a, c);
var node = elem => elem instanceof window.$ ? elem[0] : elem;
var smrm = elem => getComputedStyle(node(elem)).animationName!=="none"?node(elem).addEventListener('animationend',node(elem).remove):node(elem).remove();
function beyond(node) {
var rect = node.getBoundingClientRect();
return (
(rect.x + rect.width) < 0 ||
(rect.y + rect.height) < 0 ||
(rect.x > window.innerWidth || rect.y > window.innerHeight)
);
}
var
popup = 'popup',
popupA = 'popupA',
popupF = 'popupF',
hilite = 'highlighted'
;
var nav = {
setHighlight: (/*HTMLElement | JQuery*/ post, /*boolean*/ status) => {
switch (status) {
case true:
node(post).classList.add(hilite);
break;
case false:
node(post).classList.remove(hilite);
break;
case undefined:
node(post).classList.contains(hilite)
? node(post).classList.add(hilite)
: node(post).classList.add(hilite)
;
break;
default:
break;
}
},
clonePost: (clonedPost, parent, rm) => {
switch (rm) {
case true:
case undefined:
clonedPost.attr('id', clonedPost.attr('id')+'_copy');
clonedPost.addClass(popup);
clonedPost.addClass(popupA);
getComputedStyle(node(clonedPost)).animationName != 'none'
? clonedPost.on( 'animationend', e => e.target.classList.remove(popupA) )
: clonedPost.removeClass(popupA)
;
parent.append(clonedPost);
break;
case false:
clonedPost.addClass(popupF);
smrm(clonedPost);
break;
default:
break;
}
return clonedPost;
},
}
function enableFastNavigation() { // Highlights and popups
function highlightOnLinkEnter(/*JQuery*/ post, /*JQuery*/ link) {
nav.setHighlight(post, true);
link.on('mouseleave', function mouseLeave() {
nav.setHighlight(post, false);
link.off('mouseleave', mouseLeave);
});
}
function popup(/*JQuery*/ clonedPost, /*JQuery*/ link) {
var popupDeletionTimer = null;
var parentPost = link.parent().parent();
/* Callbacks
* W: Each one assumes that clonedPost and link are valid JQuery objects.*/
const cbs = {
_initiateCountdown: () => {
popupDeletionTimer = setTimeout( () => {
nav.clonePost(clonedPost, parentPost, false);
link.removeAttr('locked');
}, 1000 );
},
/* Postlink mouseleave callback. */
linkLeave: function linkLeave(e) {
cbs._initiateCountdown();
clonedPost.on('mouseenter', cbs.popupEnter);
link.off('mouseleave');
},
/* Fires when cursor leaves a popup. */
popupLeave: function postLeave() {
cbs._initiateCountdown();
clonedPost.on('mouseenter', cbs.popupEnter);
},
/* Fires if cursor returns onto a popup before postDeletionTimer's time is up.
Otherwise popup will be removed from document. */
popupEnter: function postEnter() {
clearTimeout(popupDeletionTimer);
postDeletionTimer = null;
clonedPost.off('mouseenter', popupEnter);
}
};
if (link.attr('locked')) return;
link.attr('locked', true);
nav.clonePost(clonedPost, parentPost);
let _l = node(link), _ld = _l.getBoundingClientRect();
clonedPost
.css('position', 'absolute')
.css('left', _l.offsetLeft + 'px')
.css('top', _l.offsetTop + _ld.height + 'px')
;
link.on('mouseleave', cbs.linkLeave);
clonedPost.on('mouseleave', cbs.popupLeave);
}
function show(e) {
let link = $(e.target),
numb = link.text().substr(2),
post = $(`#reply${numb}`) || null;
if (node(post)) {
if( beyond(node(post)) ) {
let _embed = node(post).cloneNode(true);
each(_embed.children, item => {
if (item.classList.contains(popup)) item.remove();
});
popup($(_embed), link);
} else {
highlightOnLinkEnter(post, link);
}
}
}
$(document).on('mouseenter', '.message a[href*="res"]', show);
}
document.addEventListener('DOMContentLoaded', enableFastNavigation);