two more free() -> g_free(); ok jrick
[xombrero.git] / autoscroll.js
blobbfe3bb90e1d9eda49ae2992015a225b26d0adf33
1 /* MIT/X Consortium License
2  *
3  * Copyright (c) 2011-2012 Stefan Bolte <portix@gmx.net>
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  */
24 MouseAutoScroll = (function() {
25   const SCROLL_ICON="transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAi5QTFRFAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEAAAEAAAAAAAAAAAAAAAAAAAAAAAAA////PMNlIQAAAKR0Uk5TAAAAD2p/JQqN+74iBn34sRkDbvT+ohIBX+78kwxQ5/mEB0Pf9XMEM9XwYgCLxhBc1tvc9f7Uu756BgQZHSXC/WIFCQMJu/1cCbv9XAm7/VwJu/1eB7f+YQa1/mEGtf5hBrX+YQgpLzTC/m4RFAhm5+vr+f/i0NOQCILHECPD6lUw0PBmAj3a9nUESuP6hQgAWOv8lA0CZ/H/pBIFdvWxGghQZRvM0CN6AAAAAWJLR0S5OrgWYAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAUJJREFUOMuV0FNzREEQhuET27ZtOxvbtm3btm10bOfnBV0bnJ3Zqv1u3+diphlGsImIionz6xKSUiAtQ++ycvIAJwqKtK6krAJweqaqpk7MQhqaWgBwfnGpraNLAsJ6+p8drq5vbg0MjQjA2AS+d3f/8GhqZs7TLSyBu6fnFytrGzaw/enw+vYOdvZs4ODo5OyCwNXN3cPTiw28fXz9/BFwAgKDgkn/CAlFEBZOOVREJIKoaAqIiUUQF08BCYkIkpIpICUVQVo6BWRkIsjKpoCcXAR5+RRQUIigqJhUS0rLyisQVFZV19TygLr6hsYmBM0trW3tHWzQCf/W1c0GPb1/e18/7yMGBn/70PAI4ZmjY9w+PjFJ/ObUNPaZ2TnyHeYXFr/60vIK5VDM6to6wMbmFkPd9s4u7O0zfHZweHTMCLYPkhas1aCqNgQAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTEtMDQtMDdUMTE6Mjk6MzcrMDI6MDB8AZWGAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDExLTA0LTA3VDExOjI5OjM3KzAyOjAwDVwtOgAAAABJRU5ErkJggg==) no-repeat scroll center";
26   const SIZE = 32;
27   const OFFSET = 5;
28   var doc;
29   Math.sign = function(x) { return x >=0 ? 1  : -1; };
30   var span = null;
31   var x = 0;
32   var y = 0;
33   var ev = null;
34   var timerId = 0;
35   var cursorStyle = null;
36   function startTimer() {
37     timerId = window.setInterval(timer, 40);
38   }
39   function stopTimer () {
40     window.clearInterval(timerId);
41     timerId = 0;
42   }
43   function timer () {
44     if (ev) {
45       var scrollY = (ev.y - y);
46       var scrollX = (ev.x - x);
47       var b = scrollY > 0
48         && doc.documentElement.scrollHeight == (window.innerHeight + window.pageYOffset);
49       var r = scrollX > 0
50         && doc.documentElement.scrollWidth == (window.innerWidth + window.pageXOffset);
51       var l = scrollX < 0 && window.pageXOffset == 0;
52       var t = scrollY < 0 && window.pageYOffset == 0;
53       var offX = Math.abs(scrollX) < OFFSET;
54       var offY = Math.abs(scrollY) < OFFSET;
55       if ( timerId != 0
56           && (( b && r ) || ( b && l) || ( b && offX )
57             || ( t && r ) || ( t && l) || ( t && offX )
58             || (offY && r) || (offY && l) )) {
59               stopTimer();
60               return;
61             }
62       window.scrollBy(scrollX - Math.sign(scrollX) * OFFSET,
63           scrollY - Math.sign(scrollY) * OFFSET);
64     }
65   }
66   function mouseMove (e) {
67     if (timerId == 0) {
68       startTimer();
69     }
70     ev = e;
71   }
72   function init (e) {
73     doc = e.target.ownerDocument;
74     if (window.innerHeight >= doc.documentElement.scrollHeight
75         && window.innerWidth >= doc.documentElement.scrollWidth) {
76           return;
77         }
78     span = doc.createElement("div");
79     span.style.width = SIZE + "px";
80     span.style.height = SIZE + "px";
81     span.style.background = SCROLL_ICON;
82     span.style.left = e.x - (SIZE / 2) + "px";
83     span.style.top  = e.y - (SIZE / 2) + "px";
84     span.style.position = "fixed";
85     span.style.fontSize = SIZE + "px";
86     span.style.opacity = 0.6;
87     cursorStyle = doc.defaultView.getComputedStyle(doc.body, null).cursor;
88     doc.body.style.cursor = "move";
89     doc.body.appendChild(span);
90     doc.addEventListener('mousemove', mouseMove, false);
91     span = span;
92   }
93   function clear (e) {
94     doc.body.style.cursor = cursorStyle;
95     span.parentNode.removeChild(span);
96     doc.removeEventListener('mousemove', mouseMove, false);
97     stopTimer();
98     if (span)
99       span =  null;
100     if (ev)
101       ev = null;
102   }
103   function mouseUp (e) { /* Simulate click, click event does not work during scrolling */
104     if (Math.abs(e.x - x) < 5 && Math.abs(e.y - y) < 5) {
105       init(e);
106       window.removeEventListener('mouseup', mouseUp, false);
107     }
108   }
109   function mouseDown (e) {
110     var t = e.target;
111     if (e.button == 0) {
112       if (span) {
113         clear();
114       }
115     } else if (e.button == 1) {
116       if (span) {
117         clear();
118       }
119       else if (!t.hasAttribute("href")
120           && !t.hasAttribute("onmousedown")
121           && !(t.hasAttribute("onclick"))) {
122         x = e.x;
123         y = e.y;
124         window.addEventListener('mouseup', mouseUp, false);
125       }
126     }
127   }
128   window.addEventListener('mousedown', mouseDown, false);
129 })();