Add 1152x864 as a resolution; I browse enough fullscreen pictures on my
[pr0n] / files / pr0n-fullscreen.js
1 var req;
2
3 function init_ajax()
4 {
5         req = false;
6
7         if (window.XMLHttpRequest) {
8                 // Mozilla/Safari
9                 try {
10                         req = new XMLHttpRequest();
11                 } catch(e) {
12                         req = false;
13                 }
14         } else if (window.ActiveXObject) {
15                 // IE/Windows
16                 try {
17                         req = new ActiveXObject("Msxml2.XMLHTTP");
18                 } catch(e) {
19                         try {
20                                 req = new ActiveXObject("Microsoft.XMLHTTP");
21                         } catch(e) {
22                                 req = false;
23                         }
24                 }
25         }
26 }
27
28 function find_width()
29 {
30         if (typeof(window.innerWidth) == 'number') {
31                 // non-IE
32                 return [window.innerWidth, window.innerHeight];
33         } else if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) {
34                 // IE 6+ in 'standards compliant mode'
35                 return [document.documentElement.clientWidth, document.documentElement.clientHeight];
36         } else if (document.body && (document.body.clientWidth || document.body.clientHeight)) {
37                 // IE 4-compatible
38                 return [document.body.clientWidth, document.body.clientHeight];
39         }
40         return [null,null];
41 }
42
43 function parse_image_num(url, default_value) {
44         var url_array = (window.location.toString().split("#"));
45         if (url_array.length != 2) {
46                 return default_value;
47         }
48
49         var num = parseInt(url_array[1]);
50         if (num > 1 && num <= global_image_list.length) {  // and then num != NaN
51                 return (num - 1);
52         } else {
53                 return default_value;
54         }
55 }
56
57 /*
58  * pr0n can resize to any size we'd like, but we're much more likely
59  * to have this set of fixed-resolution screens cached, so to increase
60  * performance, we round down to the closest fit and use that. This 
61  * function is a pessimal estimate of what thumbnail size we can _always_
62  * fit on the screen -- it's right if and only if all images are 4:3
63  * (and landscape). If individual size information is available, use
64  * pick_image_size, below.
65  */
66 var fixed_sizes = [
67         [ 1600, 1200 ],
68         [ 1400, 1050 ],
69         [ 1280, 960 ],
70         [ 1152, 864 ],
71         [ 1024, 768 ],
72         [ 800, 600 ],
73         [ 640, 480 ],
74         [ 512, 384 ],
75         [ 320, 256 ],
76         [ 240, 192 ],
77         [ 120, 96 ],
78         [ 80, 64 ]
79 ];
80 function max_image_size(screen_size)
81 {
82         var i;
83         for (i = 0; i < fixed_sizes.length; ++i) {
84                 if (screen_size[0] >= fixed_sizes[i][0] && screen_size[1] >= fixed_sizes[i][1]) {
85                         return fixed_sizes[i];
86                 }
87         }
88         return [ 80, 64 ];
89 }
90
91 function pick_image_size(screen_size, image_size)
92 {
93         var i;
94         for (i = 0; i < fixed_sizes.length; ++i) {
95                 // this is a duplicate of pr0n's resizing code, hope for no floating-point
96                 // inaccuracies :-)
97                 var thumbxres = fixed_sizes[i][0];
98                 var thumbyres = fixed_sizes[i][1];
99                 var width = image_size[0];
100                 var height = image_size[1];
101
102                 if (!(thumbxres >= width && thumbyres >= height)) {
103                         var sfh = width / thumbxres;
104                         var sfv = height / thumbyres;
105                         if (sfh > sfv) {
106                                 width  /= sfh;
107                                 height /= sfh;
108                         } else {
109                                 width  /= sfv;
110                                 height /= sfv;
111                         }
112                         width = Math.floor(width);
113                         height = Math.floor(height);
114                 }
115
116                 if (screen_size[0] >= width && screen_size[1] >= height) {
117                         // be sure _not_ to return a reference
118                         return [ fixed_sizes[i][0], fixed_sizes[i][1], width, height ];
119                 }
120         }
121         return [ 80, 64 ];
122 }
123
124 function display_image(width, height, evt, filename, element_id)
125 {
126         var url = "http://" + global_vhost + "/" + evt + "/" + width + "x" + height + "/" + global_infobox + filename;
127         var img = document.getElementById(element_id);
128         if (img !== null) {
129                 img.src = "data:";
130                 img.parentNode.removeChild(img);
131         }
132
133         img = document.createElement("img");
134         img.id = element_id;
135         img.alt = "";
136
137         if (img.src != url) {
138                 img.src = url;
139         }
140         
141         var main = document.getElementById("iehack");
142         main.appendChild(img);
143
144         return img;
145 }
146
147 function display_image_num(num, element_id)
148 {
149         var screen_size = find_width();
150         var adjusted_size;
151
152         if (global_image_list[num][2] == -1) {
153                 // no size information, use our pessimal guess
154                 adjusted_size = max_image_size(screen_size);
155         } else {
156                 adjusted_size = pick_image_size(screen_size, [ global_image_list[num][2], global_image_list[num][3] ]);
157         }
158
159         var img = display_image(adjusted_size[0], adjusted_size[1], global_image_list[num][0], global_image_list[num][1], element_id);
160         
161         if (element_id == "image") {
162                 // we want to shrink the box as much as possible if we know the true
163                 // size of the image
164                 center_image(num);
165                 
166                 // replace the anchor part (if any) with the image number
167                 var baseurl = (window.location.toString().split("#"))[0];
168                 window.location = baseurl + "#" + (num+1);
169         }
170
171         return img;
172 }
173
174 function prepare_preload(img, num)
175 {
176         // cancel any pending preload
177         var preload = document.getElementById("preload");
178         if (preload !== null) {
179                 preload.src = "data:";
180                 preload.parentNode.removeChild(preload);
181         }
182
183         // grmf -- IE doesn't fire onload if the image was loaded from cache, so check for
184         // completeness first; should at least be _somewhat_ better
185         if (img.complete) {
186                 display_image_num(num, "preload");
187         } else {
188                 img.onload = function() { display_image_num(num, "preload"); };
189         }       
190 }
191
192 function can_go_next()
193 {
194         return (global_image_num < global_image_list.length - 1);
195 }
196
197 function can_go_previous()
198 {
199         return (global_image_num > 0);
200 }
201
202 function set_opacity(id, amount)
203 {
204         var elem = document.getElementById(id);
205         if (typeof(elem.style.opacity) != 'undefined') {            // W3C
206                 elem.style.opacity = amount;
207         } else if (typeof(elem.style.mozOpacity) != 'undefined') {  // older Mozilla
208                 elem.style.mozOpacity = amount;
209         } else if (typeof(elem.style.filter) != 'undefined') {      // IE
210                 if (elem.style.filter.indexOf("alpha") == -1) {
211                         // add an alpha filter if there isn't one already
212                         if (elem.style.filter) {
213                                 elem.style.filter += " ";
214                         } else {
215                                 elem.style.filter = "";
216                         }
217                         elem.style.filter += "alpha(opacity=" + (amount*100.0) + ")";
218                 } else {        
219                         // ugh? this seems to break in color index mode...
220                         if (typeof(elem.filters) == 'unknown') {
221                                 elem.style.filter = "alpha(opacity=" + (amount*100.0) + ")";
222                         } else {
223                                 elem.filters.alpha.opacity = (amount * 100.0);
224                         }
225                 }
226         } else {                             // no alpha support
227                 if (amount > 0.5) {
228                         elem.style.visibility = "visible";
229                         elem.style.zorder = 1;
230                 } else {
231                         elem.style.visibility = "hidden";
232                 }
233         }
234 }
235
236 function center_image(num)
237 {
238         var screen_size = find_width();
239         var width, height;
240         
241         if (global_image_list[num][2] == -1) {
242                 // no size information, use our pessimal guess
243                 var adjusted_size = max_image_size(screen_size);
244                 width = adjusted_size[0];
245                 height = adjusted_size[1];
246         } else {
247                 // use the exact information
248                 var adjusted_size = pick_image_size(screen_size, [ global_image_list[num][2], global_image_list[num][3] ]);
249                 width = adjusted_size[2];
250                 height = adjusted_size[3];
251         }
252
253         // center the image on-screen
254         var main = document.getElementById("main");
255         main.style.position = "absolute";
256         main.style.left = (screen_size[0] - width) / 2 + "px";
257         main.style.top = (screen_size[1] - height) / 2 + "px"; 
258         main.style.width = width + "px";
259         main.style.height = height + "px";
260         main.style.lineHeight = height + "px";
261 }
262
263 function relayout()
264 {
265         var img = display_image_num(global_image_num, "image");
266         if (can_go_next()) {
267                 prepare_preload(img, global_image_num + 1);
268         }
269
270         set_opacity("previous", can_go_previous() ? 0.7 : 0.1);
271         set_opacity("next", can_go_next() ? 0.7 : 0.1);
272         set_opacity("close", 0.7);
273 }
274
275 function go_previous()
276 {
277         if (!can_go_previous()) {
278                 return;
279         }
280
281         var img = display_image_num(--global_image_num, "image");
282         if (can_go_previous()) {
283                 set_opacity("previous", 0.7);
284                 prepare_preload(img, global_image_num - 1);
285         } else {
286                 set_opacity("previous", 0.1);
287         }
288         set_opacity("next", can_go_next() ? 0.7 : 0.1);
289 }
290
291 function go_next()
292 {
293         if (!can_go_next()) {
294                 return;
295         }
296
297         var img = display_image_num(++global_image_num, "image");
298         if (can_go_next()) {
299                 set_opacity("next", 0.7);
300                 prepare_preload(img, global_image_num + 1);
301         } else {
302                 set_opacity("next", 0.1);
303         }
304         set_opacity("previous", can_go_previous() ? 0.7 : 0.1);
305 }
306
307 function do_close()
308 {
309         window.location = global_return_url;
310 }
311
312 function draw_text(msg)
313 {
314         // remove any text we might have left
315         var text = document.getElementById("text");
316         if (text !== null) {
317                 text.parentNode.removeChild(text);
318         }
319
320         text = document.createElement("p");
321         text.id = "text";
322         text.style.position = "absolute";
323         text.style.color = "white";
324         text.style.lineHeight = "24px";
325         text.style.font = "24px verdana, arial, sans-serif";
326         text.innerHTML = msg;
327
328         var main = document.getElementById("main");
329         main.appendChild(text);
330
331         text.style.left = (main.clientWidth - text.clientWidth) / 2 + "px";
332         text.style.top = (main.clientHeight - text.clientHeight) / 2 + "px";
333 }
334
335 function fade_text(opacity)
336 {
337         set_opacity("text", opacity);
338         if (opacity > 0.0) {
339                 opacity -= 0.03;
340                 if (opacity < 0.0) {
341                         opacity = 0.0;
342                 }
343                 setTimeout("fade_text(" + opacity + ")", 30);
344         } else {
345                 var text = document.getElementById("text");
346                 if (text !== null) {
347                         text.parentNode.removeChild(text);
348                 }
349         }
350 }
351
352 function select_image(evt, filename)
353 {
354         if (!req) {
355                 return;
356         }
357
358         draw_text("Selecting " + filename + "...");
359         
360         req.open("POST", "http://" + global_vhost + "/select", false);
361         req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
362         req.send("mode=single&event=" + evt + "&filename=" + filename);
363
364         setTimeout("fade_text(0.99)", 30);
365 }
366
367 function key_down(which)
368 {
369         if (which == 39) {   // right
370                 if (can_go_next()) {
371                         set_opacity("next", 0.99);
372                 }
373         } else if (which == 37) {   // left
374                 if (can_go_previous()) {
375                         set_opacity("previous", 0.99);
376                 }
377         } else if (which == 27) {   // escape
378                 set_opacity("close", 0.99);
379         }
380 }
381
382 function key_up(which) {
383         if (which == 39) {   // right
384                 if (can_go_next()) {
385                         set_opacity("next", 0.7);
386                         go_next();
387                 }
388         } else if (which == 37) {   // left
389                 if (can_go_previous()) {
390                         set_opacity("previous", 0.7);
391                         go_previous();
392                 }
393         } else if (which == 27) {   // escape
394                 set_opacity("close", 0.7);
395                 do_close();
396         } else if (which == 32 && global_select) {   // space
397                 select_image(global_image_list[global_image_num][0], global_image_list[global_image_num][1]);
398         }
399 }
400
401 // enable the horrible horrible IE PNG hack
402 function ie_png_hack()
403 {
404         var vstr = navigator.appVersion.split("MSIE");
405         var v = parseFloat(vstr[1]);
406         if (v >= 5.5 && v < 7.0 && document.body.filters) {
407                 var next = document.getElementById("next");
408                 next.outerHTML = "<span id=\"next\" style=\"display: inline-block; position: absolute; bottom: 0px; right: 0px; width: 50px; height: 50px; filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + next.src + "')\" onmousedown=\"if (can_go_next()) set_opacity('next', 1.0)\" onmouseup=\"if (can_go_next()) { set_opacity('next', 0.7); go_next(); }\" onmouseout=\"if (can_go_next()) { set_opacity('next', 0.7); }\" />";
409                 
410                 var previous = document.getElementById("previous");
411                 previous.outerHTML = "<span id=\"previous\" style=\"display: inline-block; position: absolute; bottom: 0px; right: 0px; width: 50px; height: 50px; filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + previous.src + "')\" onmousedown=\"if (can_go_previous()) set_opacity('previous', 1.0)\" onmouseup=\"if (can_go_previous()) { set_opacity('previous', 0.7); go_previous(); }\" onmouseout=\"if (can_go_previous()) { set_opacity('previous', 0.7); }\" />";
412                 
413                 var close = document.getElementById("close");
414                 close.outerHTML = "<span id=\"close\" style=\"display: inline-block; position: absolute; top: 0px; right: 0px; width: 50px; height: 50px; filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + close.src + "')\" onmousedown=\"set_opacity('close', 1.0)\" onmouseup=\"set_opacity('close', 0.7); do_close();\" onmouseout=\"set_opacity('close', 0.7);\" />";
415         }
416 }