##// END OF EJS Templates
Do not close images from refpopups when the popup is removed
neko259 -
r1474:378f92ac default
parent child Browse files
Show More
@@ -1,202 +1,201 b''
1 1 /*
2 2 @licstart The following is the entire license notice for the
3 3 JavaScript code in this page.
4 4
5 5
6 6 Copyright (C) 2013 neko259
7 7
8 8 The JavaScript code in this page is free software: you can
9 9 redistribute it and/or modify it under the terms of the GNU
10 10 General Public License (GNU GPL) as published by the Free Software
11 11 Foundation, either version 3 of the License, or (at your option)
12 12 any later version. The code is distributed WITHOUT ANY WARRANTY;
13 13 without even the implied warranty of MERCHANTABILITY or FITNESS
14 14 FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
15 15
16 16 As additional permission under GNU GPL version 3 section 7, you
17 17 may distribute non-source (e.g., minimized or compacted) forms of
18 18 that code without the copy of the GNU GPL normally required by
19 19 section 4, provided you include this license notice and a URL
20 20 through which recipients can access the Corresponding Source.
21 21
22 22 @licend The above is the entire license notice
23 23 for the JavaScript code in this page.
24 24 */
25 25
26 26 var IMAGE_POPUP_MARGIN = 10;
27 27
28 28
29 29 var IMAGE_VIEWERS = [
30 30 ['simple', new SimpleImageViewer()],
31 31 ['popup', new PopupImageViewer()]
32 32 ];
33 33
34 34 var FULL_IMG_CLASS = 'post-image-full';
35 35
36 36 var ATTR_SCALE = 'scale';
37 37
38 38
39 39 // Init image viewer
40 40 var viewerName = $('body').attr('data-image-viewer');
41 41 var viewer = ImageViewer();
42 42 for (var i = 0; i < IMAGE_VIEWERS.length; i++) {
43 43 var item = IMAGE_VIEWERS[i];
44 44 if (item[0] === viewerName) {
45 45 viewer = item[1];
46 46 break;
47 47 }
48 48 }
49 49
50 50
51 51 function getFullImageWidth(previewImage) {
52 52 var full_img_w = previewImage.attr('data-width');
53 53 if (full_img_w == null) {
54 54 full_img_w = previewImage[0].naturalWidth;
55 55 }
56 56
57 57 return full_img_w;
58 58 }
59 59
60 60 function getFullImageHeight(previewImage) {
61 61 var full_img_h = previewImage.attr('data-height');
62 62 if (full_img_h == null) {
63 63 full_img_h = previewImage[0].naturalHeight;
64 64 }
65 65
66 66 return full_img_h;
67 67 }
68 68
69 69
70 70 function ImageViewer() {}
71 71 ImageViewer.prototype.view = function (post) {};
72 72
73 73 function SimpleImageViewer() {}
74 74 SimpleImageViewer.prototype.view = function (post) {
75 75 var images = post.find('img');
76 76 images.toggle();
77 77
78 78 // When we first enlarge an image, a full image needs to be created
79 79 if (images.length == 1) {
80 80 var thumb = images.first();
81 81
82 82 var width = getFullImageWidth(thumb);
83 83 var height = getFullImageHeight(thumb);
84 84
85 85 if (width == null || height == null) {
86 86 width = '100%';
87 87 height = '100%';
88 88 }
89 89
90 90 var parent = images.first().parent();
91 91 var link = parent.attr('href');
92 92
93 93 var fullImg = $('<img />')
94 94 .addClass(FULL_IMG_CLASS)
95 95 .attr('src', link)
96 96 .attr('width', width)
97 97 .attr('height', height);
98 98
99 99 parent.append(fullImg);
100 100 }
101 101 };
102 102
103 103 function PopupImageViewer() {}
104 104 PopupImageViewer.prototype.view = function (post) {
105 105 var el = post;
106 106 var thumb_id = 'full' + el.find('img').attr('alt');
107 107
108 108 var existingPopups = $('#' + thumb_id);
109 109 if (!existingPopups.length) {
110 110 var imgElement = el.find('img');
111 111
112 112 var full_img_w = getFullImageWidth(imgElement);
113 113 var full_img_h = getFullImageHeight(imgElement);
114 114
115 115 var win = $(window);
116 116
117 117 var win_w = win.width();
118 118 var win_h = win.height();
119 119
120 120 // New image size
121 121 var w_scale = 1;
122 122 var h_scale = 1;
123 123
124 124 var freeWidth = win_w - 2 * IMAGE_POPUP_MARGIN;
125 125 var freeHeight = win_h - 2 * IMAGE_POPUP_MARGIN;
126 126
127 127 if (full_img_w > freeWidth) {
128 128 w_scale = full_img_w / freeWidth;
129 129 }
130 130 if (full_img_h > freeHeight) {
131 131 h_scale = full_img_h / freeHeight;
132 132 }
133 133
134 134 var scale = Math.max(w_scale, h_scale)
135 135 var img_w = full_img_w / scale;
136 136 var img_h = full_img_h / scale;
137 137
138 138 var postNode = $(el);
139 139
140 140 var img_pv = new Image();
141 141 var newImage = $(img_pv);
142 142 newImage.addClass('img-full')
143 143 .attr('id', thumb_id)
144 144 .attr('src', postNode.attr('href'))
145 145 .attr(ATTR_SCALE, scale)
146 146 .css({
147 147 'width': img_w,
148 148 'height': img_h,
149 149 'left': (win_w - img_w) / 2,
150 150 'top': ((win_h - img_h) / 2)
151 151 })
152 .appendTo(postNode)
153 //scaling preview
154 .mousewheel(function(event, delta) {
155 var cx = event.originalEvent.clientX;
156 var cy = event.originalEvent.clientY;
152 //scaling preview
153 .mousewheel(function(event, delta) {
154 var cx = event.originalEvent.clientX;
155 var cy = event.originalEvent.clientY;
157 156
158 var scale = newImage.attr(ATTR_SCALE) / (delta > 0 ? 1.25 : 0.8);
157 var scale = newImage.attr(ATTR_SCALE) / (delta > 0 ? 1.25 : 0.8);
159 158
160 var oldWidth = newImage.width();
161 var oldHeight = newImage.height();
159 var oldWidth = newImage.width();
160 var oldHeight = newImage.height();
162 161
163 var newIW = full_img_w / scale;
164 var newIH = full_img_h / scale;
162 var newIW = full_img_w / scale;
163 var newIH = full_img_h / scale;
165 164
166 newImage.width(newIW);
167 newImage.height(newIH);
168 newImage.attr(ATTR_SCALE, scale);
165 newImage.width(newIW);
166 newImage.height(newIH);
167 newImage.attr(ATTR_SCALE, scale);
169 168
170 // Set position
171 var oldPosition = newImage.position();
172 newImage.css({
173 left: parseInt(cx - (newIW/oldWidth) * (cx - parseInt(oldPosition.left, 10)), 10),
174 top: parseInt(cy - (newIH/oldHeight) * (cy - parseInt(oldPosition.top, 10)), 10)
175 });
169 // Set position
170 var oldPosition = newImage.position();
171 newImage.css({
172 left: parseInt(cx - (newIW/oldWidth) * (cx - parseInt(oldPosition.left, 10)), 10),
173 top: parseInt(cy - (newIH/oldHeight) * (cy - parseInt(oldPosition.top, 10)), 10)
174 });
176 175
177 return false;
178 }
179 )
176 return false;
177 })
180 178 .draggable({
181 179 addClasses: false,
182 180 stack: '.img-full'
183 });
181 })
182 .appendTo($('body'));
184 183 } else {
185 184 existingPopups.remove();
186 185 }
187 186 };
188 187
189 188 function addImgPreview() {
190 189 //keybind
191 190 $(document).on('keyup.removepic', function(e) {
192 191 if(e.which === 27) {
193 192 $('.img-full').remove();
194 193 }
195 194 });
196 195
197 196 $('body').on('click', '.thumb', function() {
198 197 viewer.view($(this));
199 198
200 199 return false;
201 200 });
202 201 }
@@ -1,122 +1,132 b''
1 var LOADING_MSG = "<div class=\"post\">" + gettext('Loading...') + "</div>";
2
1 3 function $X(path, root) {
2 4 return document.evaluate(path, root || document, null, 6, null);
3 5 }
4 6 function $x(path, root) {
5 7 return document.evaluate(path, root || document, null, 8, null).singleNodeValue;
6 8 }
7 9
8 10 function $del(el) {
9 11 if(el) el.parentNode.removeChild(el);
10 12 }
11 13
12 14 function $each(list, fn) {
13 15 if(!list) return;
14 16 var i = list.snapshotLength;
15 17 if(i > 0) while(i--) fn(list.snapshotItem(i), i);
16 18 }
17 19
18 20 function mkPreview(cln, html) {
19 21 cln.innerHTML = html;
20 22
21 23 addScriptsToPost($(cln));
22 24 }
23 25
24 26 function isElementInViewport (el) {
25 27 //special bonus for those using jQuery
26 28 if (typeof jQuery === "function" && el instanceof jQuery) {
27 29 el = el[0];
28 30 }
29 31
30 32 var rect = el.getBoundingClientRect();
31 33
32 34 return (
33 35 rect.top >= 0 &&
34 36 rect.left >= 0 &&
35 37 rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */
36 38 rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
37 39 );
38 40 }
39 41
40 42 function addRefLinkPreview(node) {
41 43 $each($X('.//a[starts-with(text(),">>")]', node || document), function(link) {
42 44 link.addEventListener('mouseover', showPostPreview, false);
43 45 link.addEventListener('mouseout', delPostPreview, false);
44 46 });
45 47 }
46 48
47 49 function showPostPreview(e) {
48 50 var doc = document;
49 51
50 52 var reflink = $(this);
51 53 var pNum = reflink.text().match(/\d+/);
52 54
53 55 if (pNum == null || pNum.length == 0) {
54 56 return;
55 57 }
56 58
57 59 var post = $('#' + pNum);
58 60 if (post.length > 0 && isElementInViewport(post)) {
61 // If post is on the same page and visible, just highlight it
59 62 post.addClass('highlight');
60 63 } else {
61 64 var x = reflink.offset().left;
62 65 var y = reflink.offset().top;
63 66
64 67 var cln = doc.createElement('div');
65 68 cln.id = 'pstprev_' + pNum;
66 69 cln.className = 'post_preview';
67 70
68 // var newX = x < doc.body.clientWidth/2 ? 'left:' + x : 'right:' + parseInt(doc.body.clientWidth - x - reflink.width());
69 // var newY = y < doc.body.clientHeight/2 ? 'top:' + y : 'bottom:' + parseInt(doc.body.clientHeight - y - reflink.height());
70 71 cln.style.cssText = 'left:' + x + 'px; top:' + y + 'px';
71 72
72 73 cln.addEventListener('mouseout', delPostPreview, false);
73 74
74 cln.innerHTML = "<div class=\"post\">" + gettext('Loading...') + "</div>";
75 cln.innerHTML = LOADING_MSG;
75 76
76 if(post.length > 0) {
77 var postdata = post.clone().wrap("<div/>").parent().html();
77 if (post.length > 0) {
78 // If post is on the same page but not visible, generate preview from it
79 var postClone = post.clone();
80 postClone.removeAttr('style');
81 var postdata = postClone.wrap("<div/>").parent().html();
78 82
79 83 mkPreview(cln, postdata);
80 84 } else {
85 // If post is from other page, load it
81 86 $.ajax({
82 87 url: '/api/post/' + pNum + '/?truncated'
83 88 })
84 .success(function(data) {
85 var postdata = $(data).wrap("<div/>").parent().html();
86
87 //make preview
88 mkPreview(cln, postdata);
89 .success(function(data) {
90 var postdata = $(data).wrap("<div/>").parent().html();
89 91
90 })
91 .error(function() {
92 cln.innerHTML = "<div class=\"post\">"
93 + gettext('Post not found') + "</div>";
94 });
92 //make preview
93 mkPreview(cln, postdata);
94 })
95 .error(function() {
96 cln.innerHTML = "<div class=\"post\">"
97 + gettext('Post not found') + "</div>";
98 });
95 99 }
96 100
97 101 $del(doc.getElementById(cln.id));
98 102
99 103 //add preview
100 104 $(cln).fadeIn(200);
101 105 $('body').append(cln);
102 106 }
103 107 }
104 108
105 109 function delPostPreview(e) {
106 110 var el = $x('ancestor-or-self::*[starts-with(@id,"pstprev")]', e.relatedTarget);
107 111 if(!el) {
108 112 $each($X('.//div[starts-with(@id,"pstprev")]'), function(clone) {
109 113 $del(clone)
110 114 });
111 115 } else {
112 while(el.nextSibling) $del(el.nextSibling);
116 while (el.nextSibling) {
117 if (el.nextSibling.className.startsWith('pstprev')) {
118 $del(el.nextSibling);
119 } else {
120 break;
121 }
122 }
113 123 }
114 124
115 125 $('.highlight').removeClass('highlight');
116 126 }
117 127
118 128 function addPreview() {
119 129 $('.post').find('a').each(function() {
120 130 showPostPreview($(this));
121 131 });
122 132 }
General Comments 0
You need to be logged in to leave comments. Login now