Release commit for 0.008
[catagits/Web-Simple.git] / docs / takahashi.js
CommitLineData
879d8965 1var 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
497function init()
498{
499 window.removeEventListener('load', init, false);
500
501 Presentation.init();
502}
503window.addEventListener('load', init, false);