|
|
var LOADING_MSG = "<div class=\"post\">" + gettext('Loading...') + "</div>";
|
|
|
|
|
|
var CLS_PREVIEW = 'post_preview';
|
|
|
|
|
|
function $X(path, root) {
|
|
|
return document.evaluate(path, root || document, null, 6, null);
|
|
|
}
|
|
|
function $x(path, root) {
|
|
|
return document.evaluate(path, root || document, null, 8, null).singleNodeValue;
|
|
|
}
|
|
|
|
|
|
function $del(el) {
|
|
|
if(el) el.parentNode.removeChild(el);
|
|
|
}
|
|
|
|
|
|
function $each(list, fn) {
|
|
|
if(!list) return;
|
|
|
var i = list.snapshotLength;
|
|
|
if(i > 0) while(i--) fn(list.snapshotItem(i), i);
|
|
|
}
|
|
|
|
|
|
function mkPreview(cln, html) {
|
|
|
cln.innerHTML = html;
|
|
|
|
|
|
addScriptsToPost($(cln));
|
|
|
}
|
|
|
|
|
|
function isElementInViewport (el) {
|
|
|
//special bonus for those using jQuery
|
|
|
if (typeof jQuery === "function" && el instanceof jQuery) {
|
|
|
el = el[0];
|
|
|
}
|
|
|
|
|
|
var rect = el.getBoundingClientRect();
|
|
|
|
|
|
return (
|
|
|
rect.top >= 0 &&
|
|
|
rect.left >= 0 &&
|
|
|
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */
|
|
|
rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
|
|
|
);
|
|
|
}
|
|
|
|
|
|
function addRefLinkPreview(node) {
|
|
|
$each($X('.//a[starts-with(text(),">>")]', node || document), function(link) {
|
|
|
link.addEventListener('mouseover', showPostPreview, false);
|
|
|
link.addEventListener('mouseout', delPostPreview, false);
|
|
|
});
|
|
|
}
|
|
|
|
|
|
function showPostPreview(e) {
|
|
|
var doc = document;
|
|
|
|
|
|
var reflink = $(this);
|
|
|
var pNum = reflink.text().match(/\d+/);
|
|
|
|
|
|
if (pNum == null || pNum.length == 0) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
var post = $('#' + pNum);
|
|
|
if (post.length > 0 && isElementInViewport(post)) {
|
|
|
// If post is on the same page and visible, just highlight it
|
|
|
post.addClass('highlight');
|
|
|
} else {
|
|
|
var x = reflink.offset().left;
|
|
|
var y = reflink.offset().top;
|
|
|
|
|
|
var cln = doc.createElement('div');
|
|
|
cln.id = 'pstprev_' + pNum;
|
|
|
cln.className = CLS_PREVIEW;
|
|
|
|
|
|
cln.style.cssText = 'left:' + x + 'px; top:' + y + 'px';
|
|
|
|
|
|
cln.addEventListener('mouseout', delPostPreview, false);
|
|
|
|
|
|
cln.innerHTML = LOADING_MSG;
|
|
|
|
|
|
if (post.length > 0) {
|
|
|
// If post is on the same page but not visible, generate preview from it
|
|
|
var postClone = post.clone();
|
|
|
postClone.removeAttr('style');
|
|
|
var postdata = postClone.wrap("<div/>").parent().html();
|
|
|
|
|
|
mkPreview(cln, postdata);
|
|
|
} else {
|
|
|
// If post is from other page, load it
|
|
|
$.ajax({
|
|
|
url: '/api/post/' + pNum + '/?truncated'
|
|
|
})
|
|
|
.success(function(data) {
|
|
|
var postdata = $(data).wrap("<div/>").parent().html();
|
|
|
|
|
|
//make preview
|
|
|
mkPreview(cln, postdata);
|
|
|
})
|
|
|
.error(function() {
|
|
|
cln.innerHTML = "<div class=\"post\">"
|
|
|
+ gettext('Post not found') + "</div>";
|
|
|
});
|
|
|
}
|
|
|
|
|
|
$del(doc.getElementById(cln.id));
|
|
|
|
|
|
//add preview
|
|
|
$(cln).fadeIn(200);
|
|
|
$('body').append(cln);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
function delPostPreview(e) {
|
|
|
var el = $x('ancestor-or-self::*[starts-with(@id,"pstprev")]', e.relatedTarget);
|
|
|
if(!el) {
|
|
|
$each($X('.//div[starts-with(@id,"pstprev")]'), function(clone) {
|
|
|
$del(clone)
|
|
|
});
|
|
|
} else {
|
|
|
while (el.nextSibling) {
|
|
|
if (el.nextSibling.className == CLS_PREVIEW) {
|
|
|
$del(el.nextSibling);
|
|
|
} else {
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
$('.highlight').removeClass('highlight');
|
|
|
}
|
|
|
|
|
|
function addPreview() {
|
|
|
$('.post').find('a').each(function() {
|
|
|
showPostPreview($(this));
|
|
|
});
|
|
|
}
|
|
|
|