]> AND Private Git Repository - these_gilles.git/blob - PRESENTATION-1/js/impressConsole.js
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
final
[these_gilles.git] / PRESENTATION-1 / js / impressConsole.js
1 /**
2  * impressConsole.js
3  *
4  * Adds a presenter console to impress.js
5  *
6  * MIT Licensed, see license.txt.
7  *
8  * Copyright 2012 impress-console contributors (see README.txt)
9  *
10  * version: 1.1
11  * 
12  */
13
14 (function ( document, window ) {
15     'use strict';
16
17     // This is the default template for the speaker console window
18     var consoleTemplate = '<!DOCTYPE html>' + 
19         '<html id="impressconsole"><head>' + 
20           '<link rel="stylesheet" type="text/css" media="screen" href="{{cssFile}}">' +
21         '</head><body>' + 
22         '<div id="console">' +
23           '<div id="views">' +
24             '<iframe id="slideView" scrolling="no"></iframe>' +
25             '<iframe id="preView" scrolling="no"></iframe>' +
26             '<div id="blocker"></div>' + 
27           '</div>' +
28           '<div id="notes"></div>' +
29         '</div>' +
30         '<div id="controls"> ' +
31           '<div id="prev"><a  href="#" onclick="impress().prev(); return false;" />Prev</a></div>' +
32           '<div id="next"><a  href="#" onclick="impress().next(); return false;" />Next</a></div>' +
33           '<div id="clock">00:00:00 AM</div>' +
34           '<div id="timer" onclick="timerReset()">00m 00s</div>' +
35           '<div id="status">Loading</div>' +
36         '</div>' +
37         '</body></html>';
38
39     // Default css location
40     var cssFile = "css/impressConsole.css";
41     
42     // All console windows, so that you can call console() repeatedly.
43     var allConsoles = {};
44     
45     var useAMPM = false;
46     
47     // Zero padding helper function:
48     var zeroPad = function(i) {
49         return (i < 10 ? '0' : '') + i;
50     };
51     
52     // The console object
53     var console = window.console = function (rootId) {
54
55         rootId = rootId || 'impress';
56         
57         if (allConsoles[rootId]) {
58             return allConsoles[rootId];
59         }
60         
61         // root presentation elements
62         var root = document.getElementById( rootId );
63
64         var consoleWindow = null;
65
66         var nextStep = function() {
67             var nextElement = document.querySelector('.active').nextElementSibling;
68             var classes = "";
69             while (nextElement) {
70                 classes = nextElement.attributes['class'];
71                 if (classes && classes.value.indexOf('step') !== -1) {
72                    return nextElement;
73                 }
74                 nextElement = nextElement.nextElementSibling;
75             }
76             // No next element. Pick the first
77             return document.querySelector('.step');
78         };
79         
80         // Sync the notes to the step
81         var onStepLeave = function(){
82             if(consoleWindow) {
83                 // Set notes to next steps notes.
84                 var newNotes = document.querySelector('.active').querySelector('.notes');
85                 if (newNotes) {
86                     newNotes = newNotes.innerHTML;
87                 } else {
88                     newNotes = 'No notes for this step';
89                 }
90                 consoleWindow.document.getElementById('notes').innerHTML = newNotes;
91
92                 // Set the views                
93                 var baseURL = document.URL.substring(0, document.URL.search('#/'));
94                 var slideSrc = baseURL + '#' + document.querySelector('.active').id;
95                 var preSrc = baseURL + '#' + nextStep().id;
96                 var slideView = consoleWindow.document.getElementById('slideView');
97                 // Setting them when they are already set causes glithes in firexof, so we check first:
98                 if (slideView.src !== slideSrc) {
99                     slideView.src = slideSrc;
100                 }
101                 var preView = consoleWindow.document.getElementById('preView');
102                 if (preView.src !== preSrc) {
103                     preView.src = preSrc;
104                 }
105                 
106                 consoleWindow.document.getElementById('status').innerHTML = '<span style="color: red">Moving</span>';
107             }
108         };
109     
110         // Sync the previews to the step
111         var onStepEnter = function(){
112             if(consoleWindow) {
113                 // We do everything here again, because if you stopped the previos step to
114                 // early, the onstepleave trigger is not called for that step, so
115                 // we need this to sync things.
116                 var newNotes = document.querySelector('.active').querySelector('.notes');
117                 if (newNotes) {
118                     newNotes = newNotes.innerHTML;
119                 } else {
120                     newNotes = 'No notes for this step';
121                 }
122                 var notes = consoleWindow.document.getElementById('notes');
123                 notes.innerHTML = newNotes;
124                 notes.scrollTop = 0;
125                 
126                 // Set the views
127                 var baseURL = document.URL.substring(0, document.URL.search('#/'));
128                 var slideSrc = baseURL + '#' + document.querySelector('.active').id;
129                 var preSrc = baseURL + '#' + nextStep().id;
130                 var slideView = consoleWindow.document.getElementById('slideView');
131                 // Setting them when they are already set causes glithes in firexof, so we check first:
132                 if (slideView.src !== slideSrc) {
133                     slideView.src = slideSrc;
134                 }
135                 var preView = consoleWindow.document.getElementById('preView');
136                 if (preView.src !== preSrc) {
137                     preView.src = preSrc;
138                 }
139                 
140                 consoleWindow.document.getElementById('status').innerHTML = '<span style="color: green">Ready</span>';
141             }
142         };
143
144         var spaceHandler = function () {
145             var notes = consoleWindow.document.getElementById('notes');
146             if (notes.scrollTopMax - notes.scrollTop > 20) {
147                notes.scrollTop = notes.scrollTop + notes.clientHeight * 0.8;
148             } else {
149                impress().next();
150             }
151         };
152         
153         var timerReset = function () {
154             consoleWindow.timerStart = new Date();
155         };
156         
157         // Show a clock
158         var clockTick = function () {
159             var now = new Date();
160             var hours = now.getHours();
161             var minutes = now.getMinutes();
162             var seconds = now.getSeconds();
163             var ampm = '';
164         
165             if (useAMPM) {
166                 ampm = ( hours < 12 ) ? 'AM' : 'PM';
167                 hours = ( hours > 12 ) ? hours - 12 : hours;
168                 hours = ( hours === 0 ) ? 12 : hours;
169             }
170           
171             // Clock
172             var clockStr = zeroPad(hours) + ':' + zeroPad(minutes) + ':' + zeroPad(seconds) + ' ' + ampm;
173             consoleWindow.document.getElementById('clock').firstChild.nodeValue = clockStr;
174             
175             // Timer
176             seconds = Math.floor((now - consoleWindow.timerStart) / 1000);
177             minutes = Math.floor(seconds / 60);
178             seconds = Math.floor(seconds % 60);
179             consoleWindow.document.getElementById('timer').firstChild.nodeValue = zeroPad(minutes) + 'm ' + zeroPad(seconds) + 's';
180             
181             if (!consoleWindow.initialized) {
182                 // Nudge the slide windows after load, or they will scrolled wrong on Firefox.
183                 consoleWindow.document.getElementById('slideView').contentWindow.scrollTo(0,0);
184                 consoleWindow.document.getElementById('preView').contentWindow.scrollTo(0,0);
185                 consoleWindow.initialized = true;
186             }
187         };
188
189         var registerKeyEvent = function(keyCodes, handler, window) {
190             if (window === undefined) {
191                 window = consoleWindow;
192             }
193             
194             // prevent default keydown action when one of supported key is pressed
195             window.document.addEventListener("keydown", function ( event ) {
196                 if ( !event.ctrlKey && !event.altKey && !event.shiftKey && !event.metaKey && keyCodes.indexOf(event.keyCode) !== -1) {
197                     event.preventDefault();
198                 }
199             }, false);
200                     
201             // trigger impress action on keyup
202             window.document.addEventListener("keyup", function ( event ) {
203                 if ( !event.ctrlKey && !event.altKey && !event.shiftKey && !event.metaKey && keyCodes.indexOf(event.keyCode) !== -1) {
204                         handler();
205                         event.preventDefault();
206                 }
207             }, false);
208         };
209     
210         var open = function() {
211             if(top.isconsoleWindow){ 
212                 return;
213             }
214             
215             if (consoleWindow && !consoleWindow.closed) {
216                 consoleWindow.focus();
217             } else {
218                 consoleWindow = window.open();
219                 // This sets the window location to the main window location, so css can be loaded:
220                 consoleWindow.document.open();
221                 // Write the template:
222                 consoleWindow.document.write(consoleTemplate.replace("{{cssFile}}", cssFile));
223                 consoleWindow.document.title = 'Speaker Console (' + document.title + ')';
224                 consoleWindow.impress = window.impress;
225                 // We set this flag so we can detect it later, to prevent infinite popups.
226                 consoleWindow.isconsoleWindow = true;
227                 // Add clock tick
228                 consoleWindow.timerStart = new Date();
229                 consoleWindow.timerReset = timerReset;
230                 consoleWindow.clockInterval = setInterval('console("' + rootId + '").clockTick()', 1000 );
231                 
232                 // keyboard navigation handlers
233                 // 33: pg up, 37: left, 38: up
234                 registerKeyEvent([33, 37, 38], impress().prev);
235                 // 34: pg down, 39: right, 40: down
236                 registerKeyEvent([34, 39, 40], impress().next);
237                 // 32: space
238                 registerKeyEvent([32], spaceHandler);
239                 
240                 // Cleanup
241                 consoleWindow.onbeforeunload = function() {
242                     // I don't know why onunload doesn't work here.
243                     clearInterval(consoleWindow.clockInterval);
244                 };
245                 
246                 // It will need a little nudge on Firefox, but only after loading:                
247                 onStepEnter();
248                 consoleWindow.initialized = false;
249                 consoleWindow.document.close();
250
251                 return consoleWindow;
252             }
253         };
254
255         var init = function(css) {
256             if (css !== undefined) {
257                 cssFile = css;
258             }
259
260             // Register the event
261             root.addEventListener('impress:stepleave', onStepLeave);
262             root.addEventListener('impress:stepenter', onStepEnter);
263             
264             //When the window closes, clean up after ourselves.
265             window.onunload = function(){
266                 if (consoleWindow && !consoleWindow.closed) {
267                     consoleWindow.close();
268                 }
269             };
270             
271             //Open speaker console when they press 'p'
272             registerKeyEvent([80], open, window);
273         };
274                 
275         // Return the object        
276         allConsoles[rootId] = {init: init, open: open, clockTick: clockTick, registerKeyEvent: registerKeyEvent};
277         return allConsoles[rootId];
278         
279     };
280     
281 })(document, window);