Commit | Line | Data |
879d8965 |
1 | var Presentation = { |
2 | init : function(option){ |
3 | this.size = 9; |
4 | |
5 | this._offset = 0; |
6 | this.canvas = document.getElementById('canvas'); |
7 | this.content = document.getElementById('content'); |
8 | this.textbox = document.getElementById('textField'); |
9 | this.deck = document.getElementById('deck'); |
10 | this.scroller = document.getElementById('scroller'); |
11 | |
12 | this.toolbar = document.getElementById('canvasToolbar'); |
13 | this.toolbarHeight = this.toolbar.boxObject.height; |
14 | this.isToolbarHidden = true; |
15 | this.toolbar.setAttribute('style', 'margin-top:'+(0-this.toolbarHeight)+'px;margin-bottom:0px;'); |
16 | |
17 | if(option){ |
18 | for(var i in option){this[i] = option[i]} |
19 | } |
20 | |
21 | if (this.readParameter()) { |
22 | this.takahashi(); |
23 | } |
24 | |
25 | document.documentElement.focus(); |
26 | }, |
27 | |
28 | takahashi : function(){ |
29 | if (!document.title) |
30 | document.title = this.data[0].replace(/[\r\n]/g, ' '); |
31 | |
32 | if(!this.data[this.offset]){ |
33 | this.offset = this.data.length-1; |
34 | } |
35 | document.getElementById("current_page").value = this.offset+1; |
36 | document.getElementById("max_page").value = this.data.length; |
37 | |
38 | this.scroller.setAttribute('maxpos', this.data.length-1); |
39 | this.scroller.setAttribute('curpos', this.offset); |
40 | |
41 | var broadcaster = document.getElementById('canBack'); |
42 | if (!this.offset) |
43 | broadcaster.setAttribute('disabled', true); |
44 | else |
45 | broadcaster.removeAttribute('disabled'); |
46 | |
47 | var broadcaster = document.getElementById('canForward'); |
48 | if (this.offset == this.data.length-1) |
49 | broadcaster.setAttribute('disabled', true); |
50 | else |
51 | broadcaster.removeAttribute('disabled'); |
52 | |
53 | this.canvas.setAttribute('rendering', true); |
54 | |
55 | var text = this.data[this.offset]. |
56 | replace(/^[\r\n]+/g,"").replace(/[\r\n]+$/g,"").replace(/(\r\n|[\r\n])/g,"\n") |
57 | .split('\n'); |
58 | var range = document.createRange(); |
59 | range.selectNodeContents(this.content); |
60 | range.deleteContents(); |
61 | range.detach(); |
62 | |
63 | var line; |
64 | var newLine; |
65 | var uri; |
66 | var image_width; |
67 | var image_total_width = 0; |
68 | var image_height; |
69 | var image_total_height = 0; |
70 | var image_src; |
71 | var code_listing = 0; |
72 | |
73 | |
74 | var labelId = 0; |
75 | |
76 | for (var i = 0; i < text.length; i++) |
77 | { |
78 | this.content.appendChild(document.createElement('hbox')); |
79 | this.content.lastChild.setAttribute('align', 'center'); |
80 | this.content.lastChild.setAttribute('pack', 'center'); |
81 | |
82 | line = text[i]; |
83 | image_width = 0; |
84 | image_height = 0; |
85 | |
86 | if (line.match(/^ /)) { |
87 | code_listing = 1; |
88 | this.content.lastChild.setAttribute('align', 'left'); |
89 | this.content.lastChild.setAttribute('class', 'pre'); |
90 | line = line.substring(1) |
91 | } |
92 | |
93 | while (line.match(/^([^\{]+)?(\{\{ima?ge? +src="([^"]+)" +width="([0-9]+)" +height="([0-9]+)"[^\}]*\}\}|\{\{(([^\|]+)?\||)([^\}]+)\}\})(.+)?/)) |
94 | { |
95 | if (RegExp.$1) { |
96 | this.content.lastChild.appendChild(document.createElement('description')); |
97 | this.content.lastChild.lastChild.setAttribute('value', RegExp.$1); |
98 | } |
99 | newLine = line.substring((RegExp.$1+RegExp.$2).length); |
100 | |
101 | // Images |
102 | if (/^([^\{]+)?\{\{ima?ge? +src="([^"]+)" +width="([0-9]+)" +height="([0-9]+)"[^\}]*\}\}/.test(line)) { |
103 | this.content.lastChild.appendChild(document.createElement('image')); |
104 | image_src = RegExp.$2; |
105 | if (image_src.indexOf('http://') < 0 && |
106 | image_src.indexOf('https://') < 0) |
107 | image_src = this.dataFolder+image_src; |
108 | this.content.lastChild.lastChild.setAttribute('src', image_src); |
109 | this.content.lastChild.lastChild.setAttribute('width', parseInt(RegExp.$3 || '0')); |
110 | this.content.lastChild.lastChild.setAttribute('height', parseInt(RegExp.$4 || '0')); |
111 | image_width += parseInt(RegExp.$3 || '0'); |
112 | image_height = Math.max(image_height, parseInt(RegExp.$4 || '0')); |
113 | } |
114 | |
115 | // Styles |
116 | // else if (/^([^\{]+)?\{\{#([^\|]+)\|([^\}]+)\}\}/.test(line)) { |
117 | else if (/^([^\{]+)?\{\{(#([^\|]+)?\|)([^\}]+)\}\}/.test(line)) { |
118 | uri = RegExp.$4; |
119 | this.content.lastChild.appendChild(document.createElement('description')); |
120 | this.content.lastChild.lastChild.setAttribute('value', uri); |
121 | this.content.lastChild.lastChild.setAttribute('class', RegExp.$3); |
122 | } |
123 | |
124 | // Links |
125 | else if (/^([^\{]+)?\{\{(([^\|]+)?\||)([^\}]+)\}\}/.test(line)) { |
126 | uri = RegExp.$4; |
127 | if (uri.indexOf('://') < 0) |
128 | uri = this.dataFolder+uri; |
129 | this.content.lastChild.appendChild(document.createElement('description')); |
130 | this.content.lastChild.lastChild.setAttribute('value', RegExp.$3 || RegExp.$4); |
131 | this.content.lastChild.lastChild.setAttribute('href', uri); |
132 | this.content.lastChild.lastChild.setAttribute('tooltiptext', uri); |
133 | this.content.lastChild.lastChild.setAttribute('statustext', uri); |
134 | this.content.lastChild.lastChild.setAttribute('class', 'link-text'); |
135 | } |
136 | |
137 | line = newLine; |
138 | } |
139 | |
140 | if (line) { |
141 | this.content.lastChild.appendChild(document.createElement('description')); |
142 | this.content.lastChild.lastChild.setAttribute('value', line); |
143 | } |
144 | |
145 | image_total_width = Math.max(image_total_width, image_width); |
146 | image_total_height += image_height; |
147 | } |
148 | |
149 | this.content.setAttribute('style', 'font-size:10px;'); |
150 | |
151 | if (this.content.boxObject.width) { |
152 | var canvas_w = this.canvas.boxObject.width; |
153 | var canvas_h = this.canvas.boxObject.height-image_total_height; |
154 | |
155 | var content_w = this.content.boxObject.width; |
156 | var new_fs = Math.round((canvas_w/content_w) * this.size); |
157 | |
158 | new_fs = new_fs - (new_fs % 32); |
159 | if (code_listing) { new_fs = 48;} |
160 | |
161 | this.content.setAttribute('style', 'top: 0'); |
162 | this.content.setAttribute('style', 'font-size:'+ new_fs + "px"); |
163 | |
164 | if (this.content.boxObject.width < image_total_width) { |
165 | content_w = image_total_width; |
166 | new_fs = Math.round((canvas_w/content_w) * this.size); |
167 | this.content.setAttribute('style', 'font-size:'+ new_fs + "px"); |
168 | } |
169 | |
170 | var content_h = this.content.boxObject.height; |
171 | if(content_h >= canvas_h){ |
172 | content_h = this.content.boxObject.height; |
173 | new_fs = Math.round((canvas_h/content_h) * new_fs); |
174 | this.content.setAttribute('style', 'font-size:'+ new_fs + "px"); |
175 | } |
176 | } |
177 | |
178 | |
179 | |
180 | this.canvas.removeAttribute('rendering'); |
181 | }, |
182 | |
183 | reload : function() { |
184 | if (this.dataPath != location.href) { |
185 | var path = this.dataPath; |
186 | if (location.href.match(/^https?:/)) { |
187 | var request = new XMLHttpRequest(); |
188 | request.open('GET', path); |
189 | request.onload = function() { |
190 | Presentation.textbox.value = request.responseText; |
191 | Presentation.data = Presentation.textbox.value.split('----'); |
192 | |
193 | Presentation.takahashi(); |
194 | |
195 | path = null; |
196 | request = null; |
197 | }; |
198 | request.send(null); |
199 | } |
200 | else { |
201 | document.getElementById('dataLoader').setAttribute('src', 'about:blank'); |
202 | window.setTimeout(function() { |
203 | document.getElementById('dataLoader').setAttribute('src', path); |
204 | path = null; |
205 | }, 10); |
206 | } |
207 | } |
208 | else |
209 | window.location.reload(); |
210 | }, |
211 | |
212 | forward : function(){ |
213 | this.offset++; |
214 | this.takahashi(); |
215 | }, |
216 | back : function(){ |
217 | this.offset--; |
218 | if(this.offset < 0){this.offset = 0} |
219 | this.takahashi(); |
220 | }, |
221 | home : function(){ |
222 | this.offset = 0; |
223 | this.takahashi(); |
224 | }, |
225 | end : function(){ |
226 | this.offset = this.data.length-1; |
227 | this.takahashi(); |
228 | }, |
229 | showPage : function(aPageOffset){ |
230 | this.offset = aPageOffset ? aPageOffset : 0 ; |
231 | this.takahashi(); |
232 | }, |
233 | |
234 | addPage : function() { |
235 | if (this.textbox.value && |
236 | !this.textbox.value.match(/(\r\n|[\r\n])$/)) |
237 | this.textbox.value += '\n'; |
238 | this.textbox.value += '----\n'; |
239 | this.onEdit(); |
240 | }, |
241 | |
242 | toggleEditMode : function(){ |
243 | this.deck.selectedIndex = (this.deck.selectedIndex == 0) ? 1 : 0 ; |
244 | }, |
245 | toggleEvaMode : function(){ |
246 | var check = document.getElementById('toggleEva'); |
247 | if (this.canvas.getAttribute('eva') == 'true') { |
248 | this.canvas.removeAttribute('eva'); |
249 | check.checked = false; |
250 | } |
251 | else { |
252 | this.canvas.setAttribute('eva', true); |
253 | check.checked = true; |
254 | } |
255 | }, |
256 | |
257 | onPresentationClick : function(aEvent){ |
258 | if (!this.isToolbarHidden) |
259 | this.showHideToolbar(); |
260 | |
261 | switch(aEvent.button) |
262 | { |
263 | case 0: |
264 | var uri = aEvent.target.getAttribute('href'); |
265 | if (uri) |
266 | window.open(uri); |
267 | else { |
268 | this.forward(); |
269 | document.documentElement.focus(); |
270 | } |
271 | break; |
272 | case 2: |
273 | this.back(); |
274 | document.documentElement.focus(); |
275 | break; |
276 | default: |
277 | break; |
278 | } |
279 | }, |
280 | onScrollerDragStart : function(){ |
281 | this.scroller.dragging = true; |
282 | }, |
283 | onScrollerDragMove : function(){ |
284 | if (this.scroller.dragging) |
285 | this.showPage(parseInt(this.scroller.getAttribute('curpos'))); |
286 | }, |
287 | onScrollerDragDrop : function(){ |
288 | if (this.scroller.dragging) { |
289 | this.showPage(parseInt(this.scroller.getAttribute('curpos'))); |
290 | } |
291 | this.scroller.dragging = false; |
292 | }, |
293 | onEdit : function() { |
294 | this.data = this.textbox.value.split('----'); |
295 | this.takahashi(); |
296 | }, |
297 | |
298 | onKeyPress : function(aEvent) { |
299 | switch(aEvent.keyCode) |
300 | { |
301 | case aEvent.DOM_VK_BACK_SPACE: |
302 | if (this.isPresentationMode) { |
303 | aEvent.preventBubble(); |
304 | aEvent.preventDefault(); |
305 | Presentation.back(); |
306 | } |
307 | break; |
308 | default: |
309 | break; |
310 | } |
311 | }, |
312 | |
313 | |
314 | onToolbarArea : false, |
315 | toolbarHeight : 0, |
316 | toolbarDelay : 300, |
317 | toolbarTimer : null, |
318 | isToolbarHidden : false, |
319 | onMouseMoveOnCanvas : function(aEvent) { |
320 | if (this.scroller.dragging) return; |
321 | |
322 | this.onToolbarArea = (aEvent.clientY < this.toolbarHeight); |
323 | |
324 | if (this.isToolbarHidden == this.onToolbarArea) { |
325 | if (this.toolbarTimer) window.clearTimeout(this.toolbarTimer); |
326 | this.toolbarTimer = window.setTimeout('Presentation.onMouseMoveOnCanvasCallback()', this.toolbarDelay); |
327 | } |
328 | }, |
329 | onMouseMoveOnCanvasCallback : function() { |
330 | if (this.isToolbarHidden == this.onToolbarArea) |
331 | this.showHideToolbar(); |
332 | }, |
333 | |
334 | toolbarAnimationDelay : 100, |
335 | toolbarAnimationSteps : 5, |
336 | toolbarAnimationInfo : null, |
337 | toolbarAnimationTimer : null, |
338 | showHideToolbar : function() |
339 | { |
340 | if (this.toolbarAnimationTimer) window.clearTimeout(this.toolbarAnimationTimer); |
341 | |
342 | this.toolbarAnimationInfo = { count : 0 }; |
343 | if (this.isToolbarHidden) { |
344 | this.toolbarAnimationInfo.start = 0; |
345 | this.toolbarAnimationInfo.end = this.toolbarHeight; |
346 | } |
347 | else { |
348 | this.toolbarAnimationInfo.start = this.toolbarHeight; |
349 | this.toolbarAnimationInfo.end = 0; |
350 | } |
351 | this.toolbarAnimationInfo.current = 0; |
352 | |
353 | this.toolbar.setAttribute('style', 'margin-top:'+(0-(this.toolbarHeight-this.toolbarAnimationInfo.start))+'px; margin-bottom:'+(0-this.toolbarAnimationInfo.start)+'px;'); |
354 | |
355 | this.toolbarAnimationTimer = window.setTimeout('Presentation.animateToolbar()', this.toolbarAnimationDelay/this.toolbarAnimationSteps); |
356 | }, |
357 | animateToolbar : function() |
358 | { |
359 | this.toolbarAnimationInfo.current += parseInt(this.toolbarHeight/this.toolbarAnimationSteps); |
360 | |
361 | var top, bottom; |
362 | if (this.toolbarAnimationInfo.start < this.toolbarAnimationInfo.end) { |
363 | top = this.toolbarHeight-this.toolbarAnimationInfo.current; |
364 | bottom = this.toolbarAnimationInfo.current; |
365 | } |
366 | else { |
367 | top = this.toolbarAnimationInfo.current; |
368 | bottom = this.toolbarHeight-this.toolbarAnimationInfo.current; |
369 | } |
370 | |
371 | top = Math.min(Math.max(top, 0), this.toolbarHeight); |
372 | bottom = Math.min(Math.max(bottom, 0), this.toolbarHeight); |
373 | |
374 | this.toolbar.setAttribute('style', 'margin-top:'+(0-top)+'px; margin-bottom:'+(0-bottom)+'px'); |
375 | |
376 | if (this.toolbarAnimationInfo.count < this.toolbarAnimationSteps) { |
377 | this.toolbarAnimationInfo.count++; |
378 | this.toolbarAnimationTimer = window.setTimeout('Presentation.animateToolbar()', this.toolbarAnimationDelay/this.toolbarAnimationSteps); |
379 | } |
380 | else |
381 | this.isToolbarHidden = !this.isToolbarHidden; |
382 | }, |
383 | |
384 | |
385 | |
386 | get offset(){ |
387 | return this._offset; |
388 | }, |
389 | set offset(aValue){ |
390 | this._offset = parseInt(aValue || 0); |
391 | document.documentElement.setAttribute('lastoffset', this.offset); |
392 | return this.offset; |
393 | }, |
394 | |
395 | get data(){ |
396 | if (!this._data) { |
397 | // Make sure you break the text into parts smaller than 4096 |
398 | // characters, and name them as indicated. Tweak as required. |
399 | // (What a hack. A JS programmer should find a better way.) |
400 | // Luc St-Louis, and email is lucs@pobox.com. |
401 | |
402 | nodes = document.getElementById('builtinCode').childNodes; |
403 | content = ''; |
404 | for (i in nodes) { |
405 | if (nodes[i].nodeValue) { |
406 | content = content + nodes[i].nodeValue; |
407 | } |
408 | } |
409 | |
410 | this._data = content.split("----"); |
411 | } |
412 | |
413 | return this._data; |
414 | }, |
415 | set data(aValue){ |
416 | this._data = aValue; |
417 | return aValue; |
418 | }, |
419 | |
420 | |
421 | get isPresentationMode(){ |
422 | return (this.deck.selectedIndex == 0); |
423 | }, |
424 | |
425 | |
426 | get dataPath(){ |
427 | if (!this._dataPath) |
428 | this.dataPath = location.href; |
429 | return this._dataPath; |
430 | }, |
431 | set dataPath(aValue){ |
432 | var oldDataPath = this._dataPath; |
433 | this._dataPath = aValue; |
434 | if (oldDataPath != aValue) { |
435 | this._dataFolder = this._dataPath.split('?')[0].replace(/[^\/]+$/, ''); |
436 | } |
437 | return this._dataPath; |
438 | }, |
439 | |
440 | get dataFolder(){ |
441 | if (!this._dataFolder) |
442 | this.dataPath = this.dataPath; |
443 | return this._dataFolder; |
444 | }, |
445 | set dataFolder(aValue){ |
446 | this._dataFolder = aValue; |
447 | return this._dataFolder; |
448 | }, |
449 | |
450 | readParameter : function() { |
451 | if (location.search) { |
452 | var param = location.search.replace(/^\?/, ''); |
453 | |
454 | if (param.match(/page=([0-9]+)/i)) |
455 | this.offset = parseInt(RegExp.$1)-1; |
456 | |
457 | if (param.match(/edit=(1|true|yes)/i)) |
458 | this.toggleEditMode(); |
459 | |
460 | if (param.match(/eva=(1|true|yes)/i)) |
461 | this.toggleEvaMode(); |
462 | |
463 | if (param.match(/data=([^&;]+)/i)) { |
464 | var path = unescape(RegExp.$1); |
465 | this.dataPath = path; |
466 | if (location.href.match(/^https?:/)) { |
467 | var request = new XMLHttpRequest(); |
468 | request.open('GET', path); |
469 | request.onload = function() { |
470 | Presentation.textbox.value = request.responseText; |
471 | Presentation.data = Presentation.textbox.value.split('----'); |
472 | |
473 | Presentation.takahashi(); |
474 | }; |
475 | request.send(null); |
476 | } |
477 | else { |
478 | document.getElementById('dataLoader').setAttribute('src', path); |
479 | } |
480 | return false; |
481 | } |
482 | } |
483 | return true; |
484 | }, |
485 | onDataLoad : function() { |
486 | if (!window.frames[0].document.body.hasChildNodes()) return; |
487 | var data = window.frames[0].document.body.firstChild.innerHTML; |
488 | if (!data) return; |
489 | |
490 | this.textbox.value = data; |
491 | this.data = this.textbox.value.split('----'); |
492 | |
493 | this.takahashi(); |
494 | } |
495 | }; |
496 | |
497 | function init() |
498 | { |
499 | window.removeEventListener('load', init, false); |
500 | |
501 | Presentation.init(); |
502 | } |
503 | window.addEventListener('load', init, false); |