##// END OF EJS Templates
Fixed mouseout on cascade previews
neko259 -
r1476:fdce35a2 default
parent child Browse files
Show More
@@ -1,132 +1,134 b''
1 var LOADING_MSG = "<div class=\"post\">" + gettext('Loading...') + "</div>";
1 var LOADING_MSG = "<div class=\"post\">" + gettext('Loading...') + "</div>";
2
2
3 var CLS_PREVIEW = 'post_preview';
4
3 function $X(path, root) {
5 function $X(path, root) {
4 return document.evaluate(path, root || document, null, 6, null);
6 return document.evaluate(path, root || document, null, 6, null);
5 }
7 }
6 function $x(path, root) {
8 function $x(path, root) {
7 return document.evaluate(path, root || document, null, 8, null).singleNodeValue;
9 return document.evaluate(path, root || document, null, 8, null).singleNodeValue;
8 }
10 }
9
11
10 function $del(el) {
12 function $del(el) {
11 if(el) el.parentNode.removeChild(el);
13 if(el) el.parentNode.removeChild(el);
12 }
14 }
13
15
14 function $each(list, fn) {
16 function $each(list, fn) {
15 if(!list) return;
17 if(!list) return;
16 var i = list.snapshotLength;
18 var i = list.snapshotLength;
17 if(i > 0) while(i--) fn(list.snapshotItem(i), i);
19 if(i > 0) while(i--) fn(list.snapshotItem(i), i);
18 }
20 }
19
21
20 function mkPreview(cln, html) {
22 function mkPreview(cln, html) {
21 cln.innerHTML = html;
23 cln.innerHTML = html;
22
24
23 addScriptsToPost($(cln));
25 addScriptsToPost($(cln));
24 }
26 }
25
27
26 function isElementInViewport (el) {
28 function isElementInViewport (el) {
27 //special bonus for those using jQuery
29 //special bonus for those using jQuery
28 if (typeof jQuery === "function" && el instanceof jQuery) {
30 if (typeof jQuery === "function" && el instanceof jQuery) {
29 el = el[0];
31 el = el[0];
30 }
32 }
31
33
32 var rect = el.getBoundingClientRect();
34 var rect = el.getBoundingClientRect();
33
35
34 return (
36 return (
35 rect.top >= 0 &&
37 rect.top >= 0 &&
36 rect.left >= 0 &&
38 rect.left >= 0 &&
37 rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */
39 rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */
38 rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
40 rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
39 );
41 );
40 }
42 }
41
43
42 function addRefLinkPreview(node) {
44 function addRefLinkPreview(node) {
43 $each($X('.//a[starts-with(text(),">>")]', node || document), function(link) {
45 $each($X('.//a[starts-with(text(),">>")]', node || document), function(link) {
44 link.addEventListener('mouseover', showPostPreview, false);
46 link.addEventListener('mouseover', showPostPreview, false);
45 link.addEventListener('mouseout', delPostPreview, false);
47 link.addEventListener('mouseout', delPostPreview, false);
46 });
48 });
47 }
49 }
48
50
49 function showPostPreview(e) {
51 function showPostPreview(e) {
50 var doc = document;
52 var doc = document;
51
53
52 var reflink = $(this);
54 var reflink = $(this);
53 var pNum = reflink.text().match(/\d+/);
55 var pNum = reflink.text().match(/\d+/);
54
56
55 if (pNum == null || pNum.length == 0) {
57 if (pNum == null || pNum.length == 0) {
56 return;
58 return;
57 }
59 }
58
60
59 var post = $('#' + pNum);
61 var post = $('#' + pNum);
60 if (post.length > 0 && isElementInViewport(post)) {
62 if (post.length > 0 && isElementInViewport(post)) {
61 // If post is on the same page and visible, just highlight it
63 // If post is on the same page and visible, just highlight it
62 post.addClass('highlight');
64 post.addClass('highlight');
63 } else {
65 } else {
64 var x = reflink.offset().left;
66 var x = reflink.offset().left;
65 var y = reflink.offset().top;
67 var y = reflink.offset().top;
66
68
67 var cln = doc.createElement('div');
69 var cln = doc.createElement('div');
68 cln.id = 'pstprev_' + pNum;
70 cln.id = 'pstprev_' + pNum;
69 cln.className = 'post_preview';
71 cln.className = CLS_PREVIEW;
70
72
71 cln.style.cssText = 'left:' + x + 'px; top:' + y + 'px';
73 cln.style.cssText = 'left:' + x + 'px; top:' + y + 'px';
72
74
73 cln.addEventListener('mouseout', delPostPreview, false);
75 cln.addEventListener('mouseout', delPostPreview, false);
74
76
75 cln.innerHTML = LOADING_MSG;
77 cln.innerHTML = LOADING_MSG;
76
78
77 if (post.length > 0) {
79 if (post.length > 0) {
78 // If post is on the same page but not visible, generate preview from it
80 // If post is on the same page but not visible, generate preview from it
79 var postClone = post.clone();
81 var postClone = post.clone();
80 postClone.removeAttr('style');
82 postClone.removeAttr('style');
81 var postdata = postClone.wrap("<div/>").parent().html();
83 var postdata = postClone.wrap("<div/>").parent().html();
82
84
83 mkPreview(cln, postdata);
85 mkPreview(cln, postdata);
84 } else {
86 } else {
85 // If post is from other page, load it
87 // If post is from other page, load it
86 $.ajax({
88 $.ajax({
87 url: '/api/post/' + pNum + '/?truncated'
89 url: '/api/post/' + pNum + '/?truncated'
88 })
90 })
89 .success(function(data) {
91 .success(function(data) {
90 var postdata = $(data).wrap("<div/>").parent().html();
92 var postdata = $(data).wrap("<div/>").parent().html();
91
93
92 //make preview
94 //make preview
93 mkPreview(cln, postdata);
95 mkPreview(cln, postdata);
94 })
96 })
95 .error(function() {
97 .error(function() {
96 cln.innerHTML = "<div class=\"post\">"
98 cln.innerHTML = "<div class=\"post\">"
97 + gettext('Post not found') + "</div>";
99 + gettext('Post not found') + "</div>";
98 });
100 });
99 }
101 }
100
102
101 $del(doc.getElementById(cln.id));
103 $del(doc.getElementById(cln.id));
102
104
103 //add preview
105 //add preview
104 $(cln).fadeIn(200);
106 $(cln).fadeIn(200);
105 $('body').append(cln);
107 $('body').append(cln);
106 }
108 }
107 }
109 }
108
110
109 function delPostPreview(e) {
111 function delPostPreview(e) {
110 var el = $x('ancestor-or-self::*[starts-with(@id,"pstprev")]', e.relatedTarget);
112 var el = $x('ancestor-or-self::*[starts-with(@id,"pstprev")]', e.relatedTarget);
111 if(!el) {
113 if(!el) {
112 $each($X('.//div[starts-with(@id,"pstprev")]'), function(clone) {
114 $each($X('.//div[starts-with(@id,"pstprev")]'), function(clone) {
113 $del(clone)
115 $del(clone)
114 });
116 });
115 } else {
117 } else {
116 while (el.nextSibling) {
118 while (el.nextSibling) {
117 if (el.nextSibling.className.startsWith('pstprev')) {
119 if (el.nextSibling.className == CLS_PREVIEW) {
118 $del(el.nextSibling);
120 $del(el.nextSibling);
119 } else {
121 } else {
120 break;
122 break;
121 }
123 }
122 }
124 }
123 }
125 }
124
126
125 $('.highlight').removeClass('highlight');
127 $('.highlight').removeClass('highlight');
126 }
128 }
127
129
128 function addPreview() {
130 function addPreview() {
129 $('.post').find('a').each(function() {
131 $('.post').find('a').each(function() {
130 showPostPreview($(this));
132 showPostPreview($(this));
131 });
133 });
132 }
134 }
General Comments 0
You need to be logged in to leave comments. Login now