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; highlightCode($(cln)); addRefLinkPreview(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; //ref id var pNum = $(this).text().match(/\d+/); if (pNum == null || pNum.length == 0) { return; } var post = $('#' + pNum); if (post.length > 0 && isElementInViewport(post)) { post.addClass('highlight'); } else { var x = e.clientX + (doc.documentElement.scrollLeft || doc.body.scrollLeft) + 2; var y = e.clientY + (doc.documentElement.scrollTop || doc.body.scrollTop); var cln = doc.createElement('div'); cln.id = 'pstprev_' + pNum; cln.className = 'post_preview'; cln.style.cssText = 'top:' + y + 'px;' + (x < doc.body.clientWidth/2 ? 'left:' + x + 'px' : 'right:' + parseInt(doc.body.clientWidth - x + 1) + 'px'); cln.addEventListener('mouseout', delPostPreview, false); cln.innerHTML = "
" + gettext('Loading...') + "
"; if(post.length > 0) { var postdata = post.clone().wrap("
").parent().html(); mkPreview(cln, postdata); } else { $.ajax({ url: '/api/post/' + pNum + '/?truncated' }) .success(function(data) { var postdata = $(data).wrap("
").parent().html(); //make preview mkPreview(cln, postdata); }) .error(function() { cln.innerHTML = "
" + gettext('Post not found') + "
"; }); } $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) $del(el.nextSibling); } $('.highlight').removeClass('highlight'); } function addPreview() { $('.post').find('a').each(function() { showPostPreview($(this)); }); }