]> jaekl.net Git - quanweb.git/blob - js/ToolTip.js
Refactor JS into modules, and add basic MVC.
[quanweb.git] / js / ToolTip.js
1 // =======
2 // ToolTip
3
4 var ToolTip = (function () {
5     // =================
6     // Private variables
7     var my = {},
8         bookId = undefined,
9         milliSecs = 500,     // time to wait before displaying tooltip
10         mousePos = {
11             x: undefined,
12             y: undefined
13         },
14         threshold = 10,        // number of pixels that mouse can move before tip is dismissed
15         timer = undefined;
16
17     // ================
18     // Public variables
19     my.booksModel = undefined;
20
21     // ==============
22     // Public Methods
23     
24     // Set the book ID for the details pane, and then show it
25     my.displayDetails = function (newBookId) {
26         bookId = newBookId;
27         my.showDetails();
28     };
29
30     // Hide the details pane, if it is currently visible
31     my.hideDetails = function () {
32         mousePos.x = undefined;
33         mousePos.y = undefined;
34         
35         var elem = document.getElementById('details');
36         elem.innerHTML = '';
37         elem.style.display = 'none';
38     };
39     
40     my.mouseMoved = function (x, y) {
41         // Is there an active tooltip?
42         if (typeof mousePos.x === 'undefined') {
43             // No active tooltip, so nothing further to do
44             return;
45         }
46         
47         var deltaX = Math.abs(x - mousePos.x);
48         var deltaY = Math.abs(y - mousePos.y);
49         
50         if (  deltaX > threshold
51            || deltaY > threshold )
52         {
53             my.hideDetails();
54         }
55     };
56
57     // Show the details pane
58     my.showDetails = function () {
59         var id = bookId;
60         var elem = document.getElementById('details');
61         var index = BooksModel.map[id];
62         var book = BooksModel.cache[index];
63         var html = '<div><p><b>' + book.Title + '</b></p>'
64         + '<p><i>' + ce(book.AuthorReading) + '<br/>' + ce(book.Series) + ' ' + ce(book.Volume) + '</i></p></div><div>'
65         + ce(book.Description)
66         + '</div>';
67
68         // Remember the current mouse (x,y).
69         // If we move the mouse too far from this point, that will trigger hiding the tooltip.
70         mousePos.x = g_state.mousePos.x;
71         mousePos.y = g_state.mousePos.y;
72
73         elem.innerHTML = html;
74
75         elem.style.display = 'block';    // show, and calculate size, so that we can query it below
76         
77         var x = mousePos.x;
78         var y = mousePos.y;
79         
80         var bcr = elem.getBoundingClientRect();
81         
82         var width = bcr.width;
83         var height = bcr.height;
84         
85         x = Math.max(x - (width / 2), 0);
86         y = Math.max(y - (height / 2), 0);
87         
88         elem.style.left = x + 'px';
89         elem.style.top = y + 'px';
90     };
91
92     my.startTooltipTimer = function (newBookId) {
93         if (typeof timer !== 'undefined') {
94             clearTimeout(timer);
95         }
96         bookId = newBookId;
97         timer = setTimeout(my.showDetails, milliSecs);
98     };
99
100     my.stopTooltipTimer = function () {
101         if (typeof timer === 'undefined') {
102             return;
103         }
104         
105         clearTimeout(timer);
106         timer = undefined;
107         my.hideDetails();
108     };
109     
110     // ===============
111     // Private methods
112     
113     // ce(s):  "clear if empty()"
114     //         return s, unless it's undefined, in which case return an empty ("clear") string
115     function ce(s) {
116         if (typeof s !== 'undefined') {
117             return s;
118         }
119         return '';
120     }
121     
122     return my;
123 })();