/[takahashi]/takahashi.xul
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /takahashi.xul

Parent Directory Parent Directory | Revision Log Revision Log


Revision 14 - (show annotations)
Sat Apr 14 12:32:36 2007 UTC (16 years, 11 months ago) by dpavlin
File size: 81371 byte(s)
update to latest upstream version and migrate my wiki changes and rand= reload
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!--
3 高橋メソッドなプレゼンツール in XUL リターンズ
4 made by Piro
5 http://piro.sakura.ne.jp/
6
7 based on
8 高橋メソッドなプレゼン作成ツール ver.2 made by mala
9 http://la.ma.la/blog/diary_200504080545.htm
10 もんたメソッドなプレゼン作成ツール made by mala
11 http://la.ma.la/blog/diary_200505310749.htm
12 -->
13
14 <!-- ***** BEGIN LICENSE BLOCK *****
15 - Version: MPL 1.1
16 -
17 - The contents of this file are subject to the Mozilla Public License Version
18 - 1.1 (the "License"); you may not use this file except in compliance with
19 - the License. You may obtain a copy of the License at
20 - http://www.mozilla.org/MPL/
21 -
22 - Software distributed under the License is distributed on an "AS IS" basis,
23 - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
24 - for the specific language governing rights and limitations under the
25 - License.
26 -
27 - The Original Code is the Takahashi-Method-based Presentation Tool
28 - in XUL/Returns.
29 -
30 - The Initial Developer of the Original Code is SHIMODA Hiroshi.
31 - Portions created by the Initial Developer are Copyright (C) 2005-2006
32 - the Initial Developer. All Rights Reserved.
33 -
34 - Contributor(s): SHIMODA Hiroshi <piro@p.club.ne.jp>
35 - dynamis <dynamis@mozilla-japan.org>
36 - matobaa <matobaa@lily.freemail.ne.jp>
37 -
38 - ***** END LICENSE BLOCK ***** -->
39
40
41 <?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
42 <?xml-stylesheet href="takahashi.css" type="text/css"?>
43
44 <page xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
45 id="presentation"
46 xmlns:html="http://www.w3.org/1999/xhtml"
47 orient="vertical"
48 onkeypress="Presentation.onKeyPress(event);">
49
50
51 <html:textarea id="builtinCode" style="visibility: collapse">
52 TITLE::高橋メソッドなプレゼンツール in XUL リターンズ
53 高橋メソッド
54 in XUL
55 [[EM:RETURNS]]
56 ----
57 HEADER::高橋メソッドなプレゼンツール in XUL リターンズ
58 CHAPTER::操作説明
59 操作
60 ----
61 HEADER::操作
62 ALIGN::left
63 基本的な操作
64 |次のページ|→,↓,Enter,Page Down,左クリック
65 |前のページ|←,↑,Back Space,Page Up,右クリック
66 |最初のページ|Home
67 |最後のページ|End
68 |リロード|Ctrl-R
69 |編集モード|Ctrl-E
70 ----
71 ALIGN::center
72 キーボード操作時は
73 次のページへ進む操作で
74 [ラベル]をめくれます
75 (めくっていない
76 [ラベル]がなければ
77 そのまま次のページへ)
78 ----
79 一度めくったラベルは
80 状態を保持するので
81 ----
82 ALIGN::right
83 前のページに戻して
84 「奥さん、いいですか!
85 ここですよここ!」
86 ができる
87 ----
88 HEADER::
89 CHAPTER::編集機能
90 編集
91 ----
92 HEADER::編集
93 編集モード時の基本操作
94 |新しいページの追加|Ctrl-N
95 ----
96 HEADER::機能
97 部分
98 強調
99 ----
100 テキストを部分的に
101 [[EM:強調]]できる
102 [[PRE:
103 [[EM:強調テキスト]&#173;]
104 [[EM:強調テキスト:EM]&#173;]
105 ]]
106 ----
107 整形済み
108 テキスト
109 [[PRE:
110 [[PRE:整形済み]&#173;]
111 [[PRE:整形済み:PRE]&#173;]
112 ]]
113 ----
114 行内に[[PRE:preformatted text]]を
115 書ける(けどあんまり意味ない)
116 ----
117 複数行にまたがる整形済みテキスト
118 [[PRE:&lt;html&gt;
119 &lt;head&gt;
120 &lt;title&gt;サンプル&lt;/title&gt;
121 &lt;/head&gt;
122 &lt;body&gt;
123 &lt;p&gt;サンプル&lt;/p&gt;
124 &lt;/body&gt;
125 &lt;/html&gt;:PRE]]
126 ソースコードの例示などに使える
127 ----
128
129 |~見出し&lt;br/&gt;セル|セル1|セル2
130 |~見出し&lt;br/&gt;セル|セル3|セル4
131 データの例示などにどうぞ。
132 [[PRE:
133 |~見出し&lt;br/&gt;セル|セル1|セル2
134 |~見出し&lt;br/&gt;セル|セル3|セル4
135 ]]
136 ----
137 XUL
138 [[RAW:
139 &lt;vbox align="center"&gt;
140 &lt;button label="ボタン"/&gt;
141
142 &lt;hbox&gt;
143
144 &lt;menulist label="既定の値" style="width: 10em;"&gt;
145 &lt;menupopup&gt;
146 &lt;menuitem label="既定の値"/&gt;
147 &lt;menuseparator/&gt;
148 &lt;menuitem label="項目1"/&gt;
149 &lt;menuitem label="項目2"/&gt;
150 &lt;menuitem label="項目3"/&gt;
151 &lt;/menupopup&gt;
152 &lt;/menulist&gt;
153
154 &lt;menulist label="既定の値" style="width: 10em;" editable="true"&gt;
155 &lt;menupopup&gt;
156 &lt;menuitem label="既定の値"/&gt;
157 &lt;menuseparator/&gt;
158 &lt;menuitem label="項目1"/&gt;
159 &lt;menuitem label="項目2"/&gt;
160 &lt;menuitem label="項目3"/&gt;
161 &lt;/menupopup&gt;
162 &lt;/menulist&gt;
163
164 &lt;/hbox&gt;
165
166 &lt;toolbar style="background: ThreeDFace; border: 1px -moz-bg-outset;"&gt;
167
168 &lt;toolbarbutton label="ボタン"/&gt;
169
170 &lt;toolbarbutton label="ボタン" type="menu"&gt;
171 &lt;menupopup&gt;
172 &lt;menuitem label="項目1"/&gt;
173 &lt;menuitem label="項目2"/&gt;
174 &lt;menuitem label="項目3"/&gt;
175 &lt;menu label="サブメニュー"&gt;
176 &lt;menupopup&gt;
177 &lt;menuitem label="項目1"/&gt;
178 &lt;menuitem label="項目2"/&gt;
179 &lt;menuitem label="項目3"/&gt;
180 &lt;/menupopup&gt;
181 &lt;/menu&gt;
182 &lt;/menupopup&gt;
183 &lt;/toolbarbutton&gt;
184
185 &lt;toolbarbutton label="ボタン" type="menu-button"&gt;
186 &lt;menupopup&gt;
187 &lt;menuitem label="項目1"/&gt;
188 &lt;menuitem label="項目2"/&gt;
189 &lt;menuitem label="項目3"/&gt;
190 &lt;/menupopup&gt;
191 &lt;/toolbarbutton&gt;
192
193 &lt;/toolbar&gt;
194
195 &lt;/vbox&gt;
196 ]]
197 ----
198 SVG
199 [[RAW:
200 &lt;svg xmlns="http://www.w3.org/2000/svg" xml:space="default" width="220" height="200"&gt;
201 &lt;rect x="60" y="60" width="100" height="80" fill="lime" stroke="red"
202 stroke-width="5"/&gt;
203 &lt;rect x="30" y="20" width="80" opacity="0.6" height="100" fill="aqua" stroke="blue"
204 stroke-width="5"/&gt;
205 &lt;/svg&gt;
206 ]]
207 ----
208 XHTML
209 [[RAW:
210 &lt;table xmlns="http://www.w3.org/1999/xhtml" border="1"&gt;
211 &lt;tbody&gt;
212 &lt;tr&gt;&lt;th&gt;10進数&lt;/th&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;51&lt;/td&gt;&lt;td&gt;102&lt;/td&gt;&lt;td&gt;153&lt;/td&gt;&lt;td&gt;204&lt;/td&gt;&lt;td&gt;255&lt;/td&gt;&lt;/tr&gt;
213 &lt;tr&gt;&lt;th&gt;16進数&lt;/th&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;33&lt;/td&gt;&lt;td&gt;66&lt;/td&gt;&lt;td&gt;99&lt;/td&gt;&lt;td&gt;CC&lt;/td&gt;&lt;td&gt;FF&lt;/td&gt;&lt;/tr&gt;
214 &lt;/tbody&gt;
215 &lt;/table&gt;
216 ]]
217 ----
218 HIDDEN::true
219 MathML
220 [[RAW:
221 &lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;
222 &lt;mrow&gt;
223 &lt;mrow&gt;
224 &lt;munder&gt;
225 &lt;mo form="prefix" movablelimits="false"&gt;lim&lt;/mo&gt;
226 &lt;mrow&gt;
227 &lt;mi&gt;n&lt;/mi&gt;
228 &lt;mo&gt;&lt;/mo&gt;
229
230 &lt;mi&gt;N&lt;/mi&gt;
231 &lt;/mrow&gt;
232 &lt;/munder&gt;
233 &lt;msup&gt;
234 &lt;mrow&gt;
235 &lt;mo&gt;(&lt;/mo&gt;
236 &lt;mrow&gt;
237 &lt;mn&gt;1&lt;/mn&gt;
238
239 &lt;mo&gt;+&lt;/mo&gt;
240 &lt;mfrac&gt;
241 &lt;mn&gt;1&lt;/mn&gt;
242 &lt;mi&gt;n&lt;/mi&gt;
243 &lt;/mfrac&gt;
244 &lt;/mrow&gt;
245 &lt;mo&gt;)&lt;/mo&gt;
246
247 &lt;/mrow&gt;
248 &lt;mi&gt;n&lt;/mi&gt;
249 &lt;/msup&gt;
250 &lt;/mrow&gt;
251 &lt;mo&gt;?&lt;/mo&gt;
252 &lt;msup&gt;
253 &lt;mi&gt;e&lt;/mi&gt;
254
255 &lt;mi&gt;N&lt;/mi&gt;
256 &lt;/msup&gt;
257 &lt;/mrow&gt;
258 &lt;/math&gt;
259 ]]
260
261 ----
262 XMLの埋め込み
263 なんかもできる
264 [[PRE:
265 [[raw:
266 &lt;toolbar xmlns="http://www.mozilla.org/keymaster
267 /gatekeeper/there.is.only.xul"&gt;
268 &lt;toolbarbutton type="menu" label="メニュー1"/&gt;
269 &lt;menupopup&gt;
270 &lt;menuitem label="項目1"/&gt;
271 &lt;menuitem label="項目2"/&gt;
272 &lt;menuitem label="項目3"/&gt;
273 &lt;/menupopup&gt;
274 &lt;/toolbarbutton&gt;
275 &lt;/toolbar&gt;
276 ]&#173;]
277 ]]
278 (でもちょっとバギー)
279 ----
280 リンク
281 [[PRE:
282 [[URI]&#173;]
283 [[ラベル|URI]&#173;]
284 ]]
285 ----
286 [[リンクも埋め込める|http://piro.sakura.ne.jp/]]
287 ラベル無しリンクも可能↓
288 [[http://piro.sakura.ne.jp/]]
289 ----
290 [[image src="takahashi.png" width="300" height="168"]]
291 ----
292 画像
293 ----
294 [[PRE:
295 [[IMAGE src="*" width="*" height="*"]&#173;]
296 [[IMG src="*" width="*" height="*"]&#173;]
297 ]]
298 ----
299 インライン[[image src="takahashi.png" width="300" height="168"]]で
300 [[image src="takahashi.png" width="300" height="168"]]
301 いくつでも
302 埋め込める
303 ----
304 リンクや
305 画像のパスの
306 相対指定は
307 ----
308 データファイルの
309 あるディレクトリ
310 もしくは
311 本体のある
312 ディレクトリを
313 基準として解釈
314 ----
315 カスタム
316 スタイル
317 ----
318 自分だけのカスタム
319 指定も可能
320 [[PRE:
321 [[#クラス名:文字列]&#173;]
322 ]]
323 このように↓解釈
324 [[PRE:
325 &lt;description
326 class="クラス名"
327 value="文字列"/&gt;
328 ]]
329 ----
330 複数行にまたがる
331 指定も可能
332 [[PRE:
333 [[#クラス名:
334 1行目
335 2行目
336 ]&#173;]
337 ]]
338 このように↓解釈
339 [[PRE:
340 &lt;vbox class="クラス名 block"&gt;
341 &lt;description value="1行目"/&gt;
342 &lt;description value="2行目"/&gt;
343 &lt;/vbox&gt;
344 ]]
345 ----
346 takahashi.css
347 に自分で好きな
348 スタイル指定を
349 追加しよう!
350 ----
351 [[装飾記号|http://homepage2.nifty.com/k_maeda/code/uni/uni44.html]]などの
352 [[Unicodeの記号文字|http://homepage2.nifty.com/k_maeda/code/unicode.html]]
353 と組み合わせると
354 色々できるかも?
355 ----
356 HEADER::ヘッダ
357 FOOTER::フッタ
358 ヘッダとフッタも
359 自由に指定できる
360 [[PRE:
361 &#173;HEADER::ヘッダ
362 &#173;FOOTER::フッタ
363 ]]
364 ----
365 HEADER::
366 FOOTER::
367 テキストの水平配置
368 (ページ単位)
369 [[PRE:
370 &#173;ALIGN::left
371 &#173;ALIGN::right
372 &#173;ALIGN::center
373 ]]
374 ----
375 テキストの水平配置
376 (以後のページすべて)
377 [[PRE:
378 &#173;GLOBAL-ALIGN::left
379 &#173;GLOBAL-ALIGN::right
380 &#173;GLOBAL-ALIGN::center
381 ]]
382 ----
383 HEADER::機能
384 FOOTER::
385 CHAPTER::起動パラメータ
386 起動
387 パラ
388 メータ
389 ----
390 |表示ページを指定して起動|?page=[数値]
391 |外部データファイルを使用|?data=[パス]
392 |編集モードで起動|?edit=true
393 ----
394 HEADER::
395 CHAPTER::このアプリケーションについて
396 ファイ
397 ル構成
398 ----
399 HEADER::ファイル構成
400 [[takahashi.xul]]
401 [[takahashi.css]]
402 [[monta-label.png]]
403 ----
404 HEADER::
405 ライセンスは
406 [MPL1.1]
407 ってことで
408 ----
409 ご自由に
410 お使い
411 下さい
412 ----
413 説明
414 おわり
415 ----
416 Let's Enjoy
417 Takahashi
418 Method
419 Life !!
420 </html:textarea>
421
422
423 <deck flex="1" id="deck">
424
425 <vbox flex="1"
426 onmouseup="Presentation.handleEvent(event);"
427 onmousedown="Presentation.handleEvent(event);"
428 onmousemove="Presentation.handleEvent(event);">
429 <toolbox id="canvasToolbar">
430 <toolbar>
431 <toolbarbutton oncommand="Presentation.home()" label="|&lt;&lt;"
432 observes="canBack"/>
433 <toolbarbutton oncommand="Presentation.back()" label="&lt;"
434 observes="canBack"/>
435 <toolbarbutton oncommand="Presentation.forward()" label="&gt;"
436 observes="canForward"/>
437 <toolbarbutton oncommand="Presentation.end()" label="&gt;&gt;|"
438 observes="canForward"/>
439 <toolbarseparator/>
440 <hbox align="center">
441 <textbox id="current_page" size="4"
442 oninput="if (this.value) Presentation.showPage(parseInt(this.value)-1);"/>
443 <toolbarbutton id="pages-list-button"
444 type="menu"
445 label="Select Page"
446 tooltiptext="Select Page"
447 class="dropmarker-button">
448 <menupopup id="pages-list"
449 onpopupshowing="if (event.target == this) Presentation.preventToShowHideToolbar = true;"
450 onpopuphiding="if (event.target == this) Presentation.preventToShowHideToolbar = false;"
451 oncommand="Presentation.showPage(parseInt(event.target.value));"/>
452 </toolbarbutton>
453 <description value="/"/>
454 <description id="max_page"/>
455 </hbox>
456 <toolbarseparator/>
457 <vbox flex="2">
458 <spacer flex="1"/>
459 <scrollbar id="scroller"
460 align="center" orient="horizontal"
461 oncommand="Presentation.showPage(parseInt(event.target.getAttribute('curpos')));"
462 onclick="Presentation.showPage(parseInt(event.target.getAttribute('curpos')));"
463 onmousedown="Presentation.onScrollerDragStart();"
464 onmousemove="Presentation.onScrollerDragMove();"
465 onmouseup="Presentation.onScrollerDragDrop();"/>
466 <spacer flex="1"/>
467 </vbox>
468 <toolbarseparator/>
469 <toolbarbutton label="Pen"
470 id="penButton"
471 type="checkbox"
472 autoCheck="false"
473 oncommand="StrokablePresentationService.toggleCheck();"/>
474 <spacer flex="1"/>
475 <toolbarbutton id="func-menu-button"
476 type="menu"
477 label="Function">
478 <menupopup
479 onpopupshowing="Presentation.preventToShowHideToolbar = true;"
480 onpopuphiding="Presentation.preventToShowHideToolbar = false;">
481 <menuitem label="Set Timer"
482 oncommand="Presentation.setTimer();" />
483 <menuseparator/>
484 <menuitem label="Start Auto-Cruise"
485 id="autoButton"
486 type="checkbox"
487 autoCheck="false"
488 oncommand="Presentation.toggleAutoCruiseMode();" />
489 <menu id="auto-interval-button"
490 label="Change Interval">
491 <menupopup id="auto-interval-list"
492 onpopupshowing="(this.getElementsByAttribute('value', Presentation.autoCruiseInterval)[0] || this.lastChild).setAttribute('checked', true);"
493 oncommand="Presentation.changeAutoCruiseInterval(parseInt(event.target.value));">
494 <menuitem type="radio" radiogroup="autocruise-interval"
495 label="1 sec" value="1000"/>
496 <menuitem type="radio" radiogroup="autocruise-interval"
497 label="2 sec" value="2000"/>
498 <menuitem type="radio" radiogroup="autocruise-interval"
499 label="3 sec" value="3000"/>
500 <menuitem type="radio" radiogroup="autocruise-interval"
501 label="4 sec" value="4000"/>
502 <menuitem type="radio" radiogroup="autocruise-interval"
503 label="5 sec" value="5000"/>
504 <menuseparator/>
505 <menuitem type="radio" radiogroup="autocruise-interval"
506 label="1 min" value="60000"/>
507 <menuitem type="radio" radiogroup="autocruise-interval"
508 label="2 min" value="120000"/>
509 <menuitem type="radio" radiogroup="autocruise-interval"
510 label="3 min" value="180000"/>
511 <menuitem type="radio" radiogroup="autocruise-interval"
512 label="4 min" value="240000"/>
513 <menuitem type="radio" radiogroup="autocruise-interval"
514 label="5 min" value="300000"/>
515 <menuseparator/>
516 <menuitem type="radio" radiogroup="autocruise-interval"
517 label="Custom"
518 oncommand="
519 var current = Presentation.autoCruiseInterval;
520 var val = parseInt(prompt('input interval (sec)', parseInt(current/1000)));
521 if (isNaN(val)) {
522 event.preventBubble();
523 return;
524 }
525 else
526 val = val * 1000;
527 this.value = val;
528 "/>
529 </menupopup>
530 </menu>
531 <menuseparator/>
532 <menuitem oncommand="Presentation.print();" label="Print"/>
533 <menu id="auto-interval-button"
534 label="Thumbnail Format">
535 <menupopup
536 onpopupshowing="(this.getElementsByAttribute('value', Presentation.imageType)[0] || this.firstChild).setAttribute('checked', true);"
537 oncommand="Presentation.imageType = event.target.value;">
538 <menuitem type="radio" radiogroup="print-image-type"
539 label="PNG" value="png"/>
540 <menuitem type="radio" radiogroup="print-image-type"
541 label="JPEG (50%)" value="jpeg"/>
542 </menupopup>
543 </menu>
544 <menuseparator/>
545 <menuitem id="toggleEva" label="Eva Mode"
546 type="checkbox"
547 autoCheck="false"
548 oncommand="Presentation.toggleEvaMode();"/>
549 </menupopup>
550 </toolbarbutton>
551 <toolbarseparator/>
552 <toolbarbutton label="Edit"
553 oncommand="Presentation.toggleEditMode();"/>
554 <toolbarbutton oncommand="Presentation.reload();" label="Reload"/>
555 </toolbar>
556 </toolbox>
557 <vbox flex="1" id="canvas">
558 <stack flex="1">
559 <vbox flex="1">
560 <hbox id="headerBox" flex="1">
561 <label id="header"/>
562 <spacer flex="1"/>
563 <vbox>
564 <image id="logo"/>
565 <spacer flex="1"/>
566 </vbox>
567 </hbox>
568 <spacer flex="19"/>
569 <hbox id="footerBox" flex="1">
570 <spacer flex="1"/>
571 <label id="footer"/>
572 </hbox>
573 </vbox>
574 <vbox flex="1"
575 onclick="Presentation.onPresentationClick(event);">
576 <spacer flex="1"/>
577 <hbox flex="1" id="contentBox">
578 <spacer flex="1"/>
579 <vbox id="content"/>
580 <spacer flex="1"/>
581 </hbox>
582 <spacer flex="1"/>
583 </vbox>
584 </stack>
585 </vbox>
586 <hbox id="indicatorBar"
587 onclick="Presentation.onIndicatorBarClick(event);">
588 <stack flex="1">
589 <vbox>
590 <progressmeter id="remainingPageIndicator"
591 type="determined" value="0"
592 flex="1"/>
593 <progressmeter id="remainingTimeIndicator"
594 type="determined" value="0"
595 flex="1"
596 collapsed="true"/>
597 </vbox>
598 <hbox flex="1">
599 <label value="Next:"/>
600 <description id="nextPage" flex="1" crop="end"/>
601 </hbox>
602 </stack>
603 </hbox>
604 </vbox>
605
606
607 <vbox flex="1" id="edit">
608 <toolbox>
609 <toolbar>
610 <menubar flex="1">
611 <menu label="File">
612 <menupopup>
613 <menuitem label="Save"
614 key="key_save"
615 oncommand="Presentation.output()"/>
616 <menuitem label="Reload"
617 key="key_reload"
618 oncommand="Presentation.reload()"/>
619 </menupopup>
620 </menu>
621 <menu label="Insert">
622 <menupopup>
623 <menuitem label="New Page"
624 key="key_insert_newpage"
625 oncommand="Presentation.insert('page')"/>
626 <menuseparator/>
627 <menuitem label="Header"
628 oncommand="Presentation.insert('header')"/>
629 <menuitem label="Footer"
630 oncommand="Presentation.insert('footer')"/>
631 <menuseparator/>
632 <menuitem label="Link"
633 oncommand="Presentation.insert('link')"/>
634 <menuitem label="Emphasis"
635 oncommand="Presentation.insert('em')"/>
636 <menuitem label="Preformatted"
637 oncommand="Presentation.insert('pre')"/>
638 <menuitem label="Monta"
639 oncommand="Presentation.insert('monta')"/>
640 <menuitem label="Image"
641 oncommand="Presentation.insert('img')"/>
642 </menupopup>
643 </menu>
644 </menubar>
645 <toolbarseparator/>
646 <toolbarbutton label="View"
647 oncommand="Presentation.toggleEditMode();"/>
648 <toolbarbutton oncommand="Presentation.reload();" label="Reload"/>
649 </toolbar>
650 </toolbox>
651 <textbox id="textField" flex="1" multiline="true"
652 oninput="Presentation.onEdit()"/>
653 </vbox>
654
655 </deck>
656
657
658 <broadcasterset>
659 <broadcaster id="canBack"/>
660 <broadcaster id="canForward"/>
661 </broadcasterset>
662
663 <commandset>
664 <command id="cmd_forward"
665 oncommand="if (Presentation.isPresentationMode) Presentation.forward();"/>
666 <command id="cmd_forwardStep"
667 oncommand="if (Presentation.isPresentationMode) Presentation.forwardStep();"/>
668 <command id="cmd_back"
669 oncommand="if (Presentation.isPresentationMode) Presentation.back();"/>
670 <command id="cmd_home"
671 oncommand="if (Presentation.isPresentationMode) Presentation.home();"/>
672 <command id="cmd_end"
673 oncommand="if (Presentation.isPresentationMode) Presentation.end();"/>
674 </commandset>
675 <keyset>
676 <key keycode="VK_ENTER" command="cmd_forwardStep"/>
677 <key keycode="VK_RETURN" command="cmd_forwardStep"/>
678 <key keycode="VK_PAGE_DOWN" command="cmd_forwardStep"/>
679 <key keycode="VK_RIGHT" command="cmd_forwardStep"/>
680 <key keycode="VK_DOWN" command="cmd_forwardStep"/>
681 <!--key keycode="VK_BACK_SPACE" command="cmd_back"/-->
682 <key keycode="VK_PAGE_UP" command="cmd_back"/>
683 <key keycode="VK_UP" command="cmd_back"/>
684 <key keycode="VK_LEFT" command="cmd_back"/>
685 <key keycode="VK_HOME" command="cmd_home"/>
686 <key keycode="VK_END" command="cmd_end"/>
687
688 <key id="key_insert_newpage"
689 key="n" modifiers="accel" oncommand="Presentation.insert('page');"/>
690
691 <key id="key_save"
692 key="s" modifiers="accel" oncommand="Presentation.output();"/>
693 <key id="key_reload"
694 key="r" modifiers="accel" oncommand="Presentation.reload();"/>
695 <key id="key_reload"
696 key="p" modifiers="accel" oncommand="Presentation.print();"/>
697
698 <key key="e" modifiers="accel" oncommand="Presentation.toggleEditMode();"/>
699 <key key="e" modifiers="accel,shift" oncommand="Presentation.toggleEvaMode();"/>
700 </keyset>
701
702
703 <script type="application/x-javascript; e4x=1"><![CDATA[
704
705 const XULNS = 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul';
706 const XHTMLNS = 'http://www.w3.org/1999/xhtml';
707
708 var Presentation = {
709
710 size : 9,
711 montaLabelImage : 'monta-label.png',
712
713 phraseOpenParen : '[',
714 phraseCloseParen : ']',
715 makePhraseRegExp : function(aPattern, aFlags)
716 {
717 return new RegExp(
718 aPattern.replace(/%o(pen)?/gi, '\\'+this.phraseOpenParen)
719 .replace(/%c(lose)?/gi, '\\'+this.phraseCloseParen),
720 aFlags
721 );
722 },
723
724 dragStartDelta : 8,
725
726 imageType : 'jpeg',
727
728
729 initialized : false,
730
731 preventToShowHideToolbar : false,
732
733 showMontaKeywordTimeout : 100,
734 autoCruiseInterval : 2000,
735 timerUpdatingInterval : 30000,
736
737 cachedContents : [],
738
739 init : function(option){
740 if (this.initialized) {
741 this.startPresentation();
742 return;
743 }
744 this.initialized = true;
745
746
747 this._offset = 0;
748 this.canvas = document.getElementById('canvas');
749 this.content = document.getElementById('content');
750 this.header = document.getElementById('header');
751 this.footer = document.getElementById('footer');
752 this.logo = document.getElementById('logo');
753 this.next = document.getElementById('nextPage');
754
755 this.indicatorBar = document.getElementById('indicatorBar');
756 this.remainder = document.getElementById('remainingPageIndicator');
757 this.timer = document.getElementById('remainingTimeIndicator');
758
759 this.list = document.getElementById('pages-list');
760 this.textbox = document.getElementById('textField');
761 this.deck = document.getElementById('deck');
762 this.scroller = document.getElementById('scroller');
763
764 this.toolbar = document.getElementById('canvasToolbar');
765 this.toolbarHeight = this.toolbar.boxObject.height;
766 this.isToolbarHidden = true;
767 this.toolbar.setAttribute('style', 'margin-top:'+(0-this.toolbarHeight)+'px;margin-bottom:0px;');
768
769 this.preloadImage(this.montaLabelImage);
770
771 window.addEventListener('resize', this, false);
772 window.addEventListener('contextmenu', this, false);
773 window.addEventListener('CanvasContentAdded', this, false);
774
775 this.canvas.addEventListener('DOMMouseScroll', this, false);
776 this.indicatorBar.addEventListener('DOMMouseScroll', this, false);
777
778 if(option){
779 for(var i in option){this[i] = option[i]}
780 }
781
782 this.cachedContents = [];
783
784 if (this.readParameter()) {
785 this.startPresentation();
786 }
787
788 document.documentElement.focus();
789 },
790
791 startPresentation : function()
792 {
793 if (this.data.length)
794 document.title = this.data[0].title || this.data[0].header || this.data[0].text.join(' ');
795
796 this.takahashi();
797 },
798
799 takahashi : function() {
800 this.isRendering = true;
801
802 if(!this.data[this.offset]){
803 this.offset = this.data.length-1;
804 }
805 document.getElementById("current_page").value = this.offset+1;
806 document.getElementById("max_page").value = this.data.length;
807
808 this.scroller.setAttribute('maxpos', this.data.length-1);
809 this.scroller.setAttribute('curpos', this.offset);
810
811 var broadcaster = document.getElementById('canBack');
812 if (!this.offset)
813 broadcaster.setAttribute('disabled', true);
814 else
815 broadcaster.removeAttribute('disabled');
816
817 var broadcaster = document.getElementById('canForward');
818 if (this.offset == this.data.length-1)
819 broadcaster.setAttribute('disabled', true);
820 else
821 broadcaster.removeAttribute('disabled');
822
823 this.canvas.setAttribute('rendering', true);
824
825
826 this.header.removeAttribute('style');
827 this.footer.removeAttribute('style');
828 this.content.removeAttribute('style');
829
830 this.clickableNodes = [];
831
832
833 if ('title' in this.data[this.offset])
834 document.title = this.data[this.offset].title;
835
836 this.header.setAttribute('style', 'font-size:10px;');
837 this.header.value = this.data[this.offset].header;
838 this.footer.setAttribute('style', 'font-size:10px;');
839 this.footer.value = this.data[this.offset].footer;
840
841 var page = this.content.getAttribute('page');
842 var range = document.createRange();
843 range.selectNodeContents(this.content);
844 this.cachedContents[page] = {
845 fragment : range.extractContents(),
846 offsetWidth : parseInt(this.content.getAttribute('offsetWidth')),
847 offsetHeight : parseInt(this.content.getAttribute('offsetHeight'))
848 };
849 range.detach();
850
851
852 if (this.data[this.offset].load) {
853 this.isRendering = false;
854 location.href = location.href.split('?')[0] + '?'+this.data[this.offset].load;
855 return;
856 }
857
858 var content = (this.offset in this.cachedContents) ?
859 this.cachedContents[this.offset] :
860 this.createContent();
861
862 this.content.setAttribute('style', 'font-size:10px;');
863 this.content.setAttribute('page', this.offset);
864 this.content.setAttribute('offsetWidth', content.offsetWidth);
865 this.content.setAttribute('offsetHeight', content.offsetHeight);
866
867 this.content.appendChild(content.fragment);
868
869 this.clickableNodes.push(this.content);
870
871
872 this.fitHeaderFooterToCanvas();
873 this.fitMainContentToCanvas();
874
875
876 try {
877 var checkedItems = this.list.getElementsByAttribute('checked', 'true');
878 max = checkedItems.length;
879 for (i = max-1; i > -1 ; i--)
880 checkedItems[i].removeAttribute('checked');
881 }
882 catch(e) {
883 }
884
885 this.list.getElementsByAttribute('value', this.offset)[0].setAttribute('checked', true);
886
887 this.canvas.removeAttribute('rendering');
888 this.isRendering = false;
889 this.setHash('page', 'page'+(this.offset+1));
890
891 this.next.value = (this.offset <= this.data.length-2) ? (this.data[this.offset+1].plain.join('') || this.data[this.offset+1].text.join('')).replace(/\s+/g, ' ') : '(no page)' ;
892 this.remainder.setAttribute('value', this.offset == 0 ? 0 : parseInt(((this.offset)/(this.data.length-1))*100));
893
894 var event = document.createEvent('Events');
895 event.initEvent('PresentationRedraw', false, true);
896 this.canvas.dispatchEvent(event);
897 },
898 createContent : function()
899 {
900 var retVal = {
901 offsetWidth : 0,
902 offsetHeight : 0
903 };
904 var text = this.data[this.offset].text;
905 var line;
906 var newLine;
907 var uri;
908 var image_width;
909 var image_height;
910 var image_src;
911
912 var labelId = 0;
913 var lineRegExp = this.makePhraseRegExp('^([^%O]+)?(%O%Oem:((.+?)(:em)?%C%C)?|%O%O(raw|encoded):((.+?)(:raw|:encoded)?%C%C)?|%O%Opre:((.+?)(:pre)?%C%C)?|%O%O\#[^:]+:((.+?)%C%C)?|%O%Oima?ge? +src="([^"]+)" +width="([0-9]+)" +height="([0-9]+)"[^%C]*%C%C|%O%O(([^\|]+)?\\||)([^%C]+)%C%C|%O([^%C]+)%C)(.+)?', 'i');
914
915 var emRegExp = this.makePhraseRegExp('^([^%O]+)?%O%Oem:(.+?)()?%C%C', 'i');
916 var emStartRegExp = this.makePhraseRegExp('^([^%O]+)?%O%Oem:(.*)', 'i');
917 var emEndRegExp = this.makePhraseRegExp('^(.*?)((:em)?%C%C)', 'i');
918
919 var preRegExp = this.makePhraseRegExp('^([^%O]+)?%O%Opre:(.+?)(:pre)?%C%C', 'i');
920 var preStartRegExp = this.makePhraseRegExp('^([^%O]+)?%O%Opre:(.*)', 'i');
921 var preEndRegExp = this.makePhraseRegExp('^(.*?)((:pre)?%C%C)', 'i');
922
923 var rawRegExp = this.makePhraseRegExp('^([^%O]+)?%O%O(raw|encoded):(.+?)(:raw|:encoded)?%C%C', 'i');
924 var rawStartRegExp = this.makePhraseRegExp('^([^%O]+)?%O%O(raw|encoded):(.*)', 'i');
925 var rawEndRegExp = this.makePhraseRegExp('^(.*?)((:raw|:encoded)?%C%C)', 'i');
926
927 var styleRegExp = this.makePhraseRegExp('^([^%O]+)?%O%O\\#([^:]+):(.+?)%C%C', '');
928 var styleStartRegExp = this.makePhraseRegExp('^([^%O]+)?%O%O\\#([^:]+):(.*)', '');
929 var styleEndRegExp = this.makePhraseRegExp('^(.*?)(%C%C)', '');
930
931 var imagesRegExp = this.makePhraseRegExp('^([^%O]+)?%O%Oima?ge? +src="([^"]+)" +width="([0-9]+)" +height="([0-9]+)"[^%C]*%C%C', 'i');
932
933 var linksRegExp = this.makePhraseRegExp('^([^%O]+)?%O%O(([^|]+)?\\||)([^%C]+)%C%C', '');
934
935 var wikiRegExp = this.makePhraseRegExp('^([^%O]+)?%O([0-9]*)([#!])?([:\/\*_-])([^%C]+)[:\/\*_-]%C', '');
936
937 var montaRegExp = this.makePhraseRegExp('^([^%O]+)?%O([^%C]+)%C', '');
938
939 var inBlock = false,
940 blockClass = '',
941 blockContents = [];
942
943 var inGrid = false,
944 gridContents = null;
945
946 var fragment = document.createDocumentFragment();
947
948 var lineBox;
949 for (var i = 0, max = text.length; i < max; i++)
950 {
951 lineBox = document.createElement('hbox');
952 lineBox.setAttribute('align', 'center');
953 lineBox.setAttribute('pack', this.data[this.offset].align);
954
955 line = text[i];
956 image_width = 0;
957 image_height = 0;
958 if (!line) line = ' ';
959
960 if (inBlock) {
961 if (blockClass == 'raw' &&
962 rawEndRegExp.test(line)) {
963 inBlock = false;
964 blockContents.push(RegExp.$1);
965 line = line.substring((RegExp.$1+RegExp.$2).length);
966
967 eval('var xml = <hbox class="raw" onclick="event.stopPropagation();" onkeypress="event.stopPropagation();">'+blockContents.join('\n')+'</hbox>;');
968 importNodeTreeWithDelay(importE4XNode(xml, document, XULNS), lineBox, XULNS);
969
970 blockClass = '';
971 blockContents = [];
972 }
973 else if (blockClass == 'preformatted-text' &&
974 preEndRegExp.test(line)) {
975 inBlock = false;
976 blockContents.push(RegExp.$1);
977 line = line.substring((RegExp.$1+RegExp.$2).length);
978
979 lineBox.appendChild(document.createElement('description'));
980 lineBox.lastChild.setAttribute('class', 'preformatted-text block');
981 lineBox.lastChild.appendChild(document.createTextNode(
982 blockContents.join('\n')
983 .replace(/^[\r\n\s]+/, '')
984 .replace(/[\r\n\s]+$/, '')
985 .replace(/&amp;/g, '&')
986 .replace(/&quot;/g, '"')
987 .replace(/&gt;/g, '>')
988 .replace(/&lt;/g, '<')
989 ));
990
991 blockClass = '';
992 blockContents = [];
993 }
994 else if (emEndRegExp.test(line) || styleEndRegExp.test(line)) {
995 inBlock = false;
996 blockContents.push(RegExp.$1);
997 line = line.substring((RegExp.$1+RegExp.$2).length);
998
999 lineBox.appendChild(document.createElement('vbox'));
1000 lineBox.lastChild.setAttribute('class', blockClass+' block');
1001 lineBox.lastChild.setAttribute('align', this.data[this.offset].align);
1002 blockContents = blockContents.join('\n')
1003 .replace(/^[\r\n\s]+/, '')
1004 .replace(/[\r\n\s]+$/, '')
1005 .split('\n');
1006 for (var j = 0, jmax = blockContents.length; j < jmax; j++)
1007 {
1008 lineBox.lastChild.appendChild(document.createElement('description'));
1009 lineBox.lastChild.lastChild.setAttribute('value', blockContents[j]);
1010 }
1011
1012 blockClass = '';
1013 blockContents = [];
1014 }
1015 else {
1016 blockContents.push(line);
1017 continue;
1018 }
1019 }
1020
1021 if (line.indexOf('|') == 0) {
1022 fragment.appendChild(lineBox);
1023
1024 if (fragment.childNodes.length == 1 ||
1025 !fragment.childNodes[fragment.childNodes.length-2] ||
1026 !fragment.childNodes[fragment.childNodes.length-2].lastChild ||
1027 fragment.childNodes[fragment.childNodes.length-2].lastChild.localName != 'grid') {
1028 fragment.lastChild.appendChild(document.createElement('grid'));
1029 fragment.lastChild.lastChild.appendChild(document.createElement('columns'));
1030 fragment.lastChild.lastChild.appendChild(document.createElement('rows'));
1031 }
1032 else {
1033 fragment.removeChild(fragment.lastChild);
1034 }
1035 fragment.lastChild.lastChild.lastChild.appendChild(document.createElement('row'));
1036 fragment.lastChild.lastChild.lastChild.lastChild.setAttribute('flex', 1);
1037
1038 line = line.split('|');
1039 for (var j = 1, jmax = line.length; j < jmax; j++)
1040 {
1041 fragment.lastChild.lastChild.lastChild.lastChild.appendChild(document.createElement('vbox'));
1042 fragment.lastChild.lastChild.lastChild.lastChild.lastChild.setAttribute('align', this.data[this.offset].align);
1043 fragment.lastChild.lastChild.lastChild.lastChild.lastChild.setAttribute('pack', 'center');
1044 if (line[j].charAt(0) == '~') {
1045 fragment.lastChild.lastChild.lastChild.lastChild.lastChild.setAttribute('class', 'special');
1046 line[j] = line[j].substring(1);
1047 }
1048 line[j] = line[j].split(/<br\s*\/>/g);
1049 for (var k = 0, kmax = line[j].length; k < kmax; k++)
1050 {
1051 fragment.lastChild.lastChild.lastChild.lastChild.lastChild.appendChild(document.createElement('description'));
1052 fragment.lastChild.lastChild.lastChild.lastChild.lastChild.lastChild.appendChild(document.createTextNode(line[j][k].replace(/^\s+|\s+$/g, '')));
1053 }
1054 if (fragment.lastChild.lastChild.firstChild.childNodes.length < j) {
1055 fragment.lastChild.lastChild.firstChild.appendChild(document.createElement('column'));
1056 fragment.lastChild.lastChild.firstChild.lastChild.setAttribute('flex', 1);
1057 }
1058 }
1059 continue;
1060 }
1061
1062
1063 while (line.match(lineRegExp))
1064 {
1065 if (RegExp.$1) {
1066 lineBox.appendChild(document.createElement('description'));
1067 lineBox.lastChild.setAttribute('value', RegExp.$1);
1068 }
1069 newLine = line.substring((RegExp.$1+RegExp.$2).length);
1070
1071 // Raw Codes: Parsed as XML
1072 if (rawRegExp.test(line)) {
1073 eval('var xml = <hbox class="raw" onclick="event.stopPropagation();" onkeypress="event.stopPropagation();">'+RegExp.$3+'</hbox>;');
1074 importNodeTreeWithDelay(importE4XNode(xml, document, XULNS), lineBox, XULNS);
1075 }
1076 else if (rawStartRegExp.test(line)) {
1077 inBlock = true;
1078 blockClass = 'raw';
1079 blockContents = [RegExp.$3];
1080 newLine = '';
1081 }
1082
1083 // Preformatted Text
1084 if (preRegExp.test(line)) {
1085 lineBox.appendChild(document.createElement('description'));
1086 lineBox.lastChild.setAttribute('value', RegExp.$2);
1087 lineBox.lastChild.setAttribute('class', 'preformatted-text');
1088 }
1089 else if (preStartRegExp.test(line)) {
1090 inBlock = true;
1091 blockClass = 'preformatted-text';
1092 blockContents = [RegExp.$2];
1093 newLine = '';
1094 }
1095
1096 // Emphasis
1097 else if (emRegExp.test(line)) {
1098 lineBox.appendChild(document.createElement('description'));
1099 lineBox.lastChild.setAttribute('value', RegExp.$2);
1100 lineBox.lastChild.setAttribute('class', 'em-text');
1101 }
1102 else if (emStartRegExp.test(line)) {
1103 inBlock = true;
1104 blockClass = 'em-text';
1105 blockContents = [RegExp.$2];
1106 newLine = '';
1107 }
1108
1109 // User-defined Styles
1110 else if (styleRegExp.test(line)) {
1111 lineBox.appendChild(document.createElement('description'));
1112 lineBox.lastChild.setAttribute('value', RegExp.$3);
1113 lineBox.lastChild.setAttribute('class', RegExp.$2);
1114 }
1115 else if (styleStartRegExp.test(line)) {
1116 inBlock = true;
1117 blockClass = RegExp.$2;
1118 blockContents = [RegExp.$3];
1119 newLine = '';
1120 }
1121
1122 // Images
1123 else if (imagesRegExp.test(line)) {
1124 lineBox.appendChild(document.createElement('image'));
1125 image_src = RegExp.$2;
1126 if (image_src.indexOf('http://') < 0 &&
1127 image_src.indexOf('https://') < 0)
1128 image_src = this.dataFolder+image_src;
1129 lineBox.lastChild.setAttribute('src', image_src);
1130 lineBox.lastChild.setAttribute('width', parseInt(RegExp.$3 || '0'));
1131 lineBox.lastChild.setAttribute('height', parseInt(RegExp.$4 || '0'));
1132 image_width += parseInt(RegExp.$3 || '0');
1133 image_height = Math.max(image_height, parseInt(RegExp.$4 || '0'));
1134 }
1135
1136 // Links
1137 else if (linksRegExp.test(line)) {
1138 uri = RegExp.$4;
1139 if (uri.indexOf('://') < 0)
1140 uri = this.dataFolder+uri;
1141 lineBox.appendChild(document.createElement('description'));
1142 lineBox.lastChild.setAttribute('value', RegExp.$3 || RegExp.$4);
1143 lineBox.lastChild.setAttribute('href', uri);
1144 lineBox.lastChild.setAttribute('tooltiptext', uri);
1145 lineBox.lastChild.setAttribute('statustext', uri);
1146 lineBox.lastChild.setAttribute('class', 'link-text');
1147
1148 this.clickableNodes.push(lineBox.lastChild);
1149 }
1150
1151 // modify font size and wiki-style
1152 else if (wikiRegExp.test(line)) {
1153 lineBox.appendChild(document.createElement('description'));
1154 lineBox.lastChild.setAttribute('value', RegExp.$5);
1155 var style = 'font-size:'+ ( RegExp.$2 || 100 ) +'%';
1156 if (RegExp.$4 == '*') {
1157 style += '; font-weight: bold;';
1158 } else if (RegExp.$4 == '/') {
1159 style += '; font-style: italic;';
1160 } else if (RegExp.$4 == '_') {
1161 style += '; text-decoration: underline;';
1162 } else if (RegExp.$4 == '-') {
1163 style += '; text-decoration: line-through;';
1164 }
1165 lineBox.lastChild.setAttribute('style', style);
1166 if (RegExp.$3 == '!') lineBox.lastChild.setAttribute('class', 'em-text');
1167 else if (RegExp.$3 == '#') lineBox.lastChild.setAttribute('class', 'preformatted-text');
1168 }
1169
1170 // Monta
1171 else if (montaRegExp.test(line)) {
1172 lineBox.appendChild(document.createElement('stack'));
1173
1174 lineBox.lastChild.appendChild(document.createElement('description'));
1175 lineBox.lastChild.lastChild.setAttribute('value', RegExp.$2);
1176 lineBox.lastChild.lastChild.setAttribute('class', 'monta-text');
1177
1178 lineBox.lastChild.appendChild(document.createElement('spacer'));
1179 lineBox.lastChild.lastChild.setAttribute('flex', 1);
1180 lineBox.lastChild.lastChild.setAttribute('class', 'monta-label');
1181
1182 lineBox.lastChild.lastChild.setAttribute('label-id', 'label-' + (++labelId));
1183
1184 lineBox.lastChild.lastChild.setAttribute('monta-hidden', 'true');
1185
1186 this.clickableNodes.push(lineBox.lastChild.lastChild);
1187 }
1188
1189 line = newLine;
1190 }
1191
1192 if (line) {
1193 lineBox.appendChild(document.createElement('description'));
1194 lineBox.lastChild.setAttribute('value', line);
1195 }
1196
1197 retVal.offsetWidth = Math.max(retVal.offsetWidth, image_width);
1198 retVal.offsetHeight += image_height;
1199
1200 if (lineBox.hasChildNodes())
1201 fragment.appendChild(lineBox);
1202 }
1203
1204 retVal.fragment = fragment;
1205 return retVal;
1206 },
1207
1208 fitToCanvas : function(aContent, aCanvas, aOffsetWidth, aOffsetHeight)
1209 {
1210 aContent.removeAttribute('style');
1211 aContent.setAttribute('style', 'font-size:10px;');
1212
1213 var grids = aContent.getElementsByTagName('grid');
1214 var gridsCount = grids.length;
1215
1216 if (!aContent.boxObject.width) return;
1217
1218 var canvas_w = aCanvas.boxObject.width;
1219 var canvas_h = aCanvas.boxObject.height-aOffsetHeight;
1220
1221 var content_w = aContent.boxObject.width;
1222 var new_fs = Math.round((canvas_w/content_w) * this.size);
1223 aContent.setAttribute('style', 'font-size:'+ new_fs + "px");
1224
1225 for (var i = 0; i < gridsCount; i++)
1226 {
1227 grids[i].firstChild.lastChild.removeAttribute('flex', 1);
1228 grids[i].firstChild.lastChild.setAttribute('flex', 1);
1229 }
1230
1231 if (aContent.boxObject.width < aOffsetWidth) {
1232 content_w = aOffsetWidth;
1233 new_fs = Math.round((canvas_w/content_w) * this.size);
1234 aContent.setAttribute('style', 'font-size:'+ new_fs + "px");
1235
1236 for (var i = 0; i < gridsCount; i++)
1237 {
1238 grids[i].firstChild.lastChild.removeAttribute('flex', 1);
1239 grids[i].firstChild.lastChild.setAttribute('flex', 1);
1240 }
1241 }
1242
1243 var content_h = aContent.boxObject.height;
1244 if(content_h >= canvas_h){
1245 state='height';
1246 content_h = aContent.boxObject.height;
1247 new_fs = Math.round((canvas_h/content_h) * new_fs);
1248 aContent.setAttribute('style', 'font-size:'+ new_fs + "px");
1249
1250 for (var i = 0; i < gridsCount; i++)
1251 {
1252 grids[i].firstChild.lastChild.removeAttribute('flex', 1);
1253 grids[i].firstChild.lastChild.setAttribute('flex', 1);
1254 }
1255 }
1256 },
1257 fitMainContentToCanvas : function()
1258 {
1259 this.fitToCanvas(
1260 this.content,
1261 this.canvas,
1262 parseInt(this.content.getAttribute('offsetWidth')),
1263 parseInt(this.content.getAttribute('offsetHeight'))
1264 +this.header.boxObject.height
1265 +this.footer.boxObject.height
1266 );
1267 },
1268 fitHeaderFooterToCanvas : function()
1269 {
1270 this.fitToCanvas(this.header, this.header.parentNode, 0, 0);
1271 this.fitToCanvas(this.footer, this.footer.parentNode, 0, 0);
1272 },
1273
1274 reload : function() {
1275 var file = String(location.href).replace(/#.+$/, '');
1276 if (this.dataPath != file) {
1277 var path = this.dataPath;
1278 var request = new XMLHttpRequest();
1279 request.open('GET', path + '?rand=' + Math.random() );
1280 request.onload = function() {
1281 Presentation.textbox.value = request.responseText;
1282 Presentation.data = Presentation.textbox.value;
1283 Presentation.init();
1284
1285 path = null;
1286 request = null;
1287 };
1288 request.send(null);
1289 }
1290 else
1291 window.location.reload();
1292 },
1293
1294 forward : function(){
1295 if (!this.canForward) return;
1296 this.offset++;
1297 this.takahashi();
1298 },
1299 forwardStep : function(){
1300 if (!this.canForward) return;
1301 var monta = document.getElementsByAttribute('monta-hidden', 'true');
1302 if (monta && monta.length) {
1303 this.showMontaKeyword(monta[0]);
1304 }
1305 else
1306 this.forward();
1307 },
1308 back : function(){
1309 if (!this.canBack) return;
1310 this.offset--;
1311 if(this.offset < 0){this.offset = 0}
1312 this.takahashi();
1313 },
1314 home : function(){
1315 if (!this.canMove) return;
1316 this.offset = 0;
1317 this.takahashi();
1318 },
1319 end : function(){
1320 if (!this.canMove) return;
1321 this.offset = this.data.length-1;
1322 this.takahashi();
1323 },
1324 showPage : function(aPageOffset){
1325 if (!this.canMove) return;
1326 this.offset = aPageOffset ? aPageOffset : 0 ;
1327 this.takahashi();
1328 },
1329
1330 get canMove()
1331 {
1332 return (
1333 this.isRendering ||
1334 importNodeTreeWithDelayTimers ||
1335 this.montaAnimating
1336 ) ? false : true ;
1337 },
1338 get canBack()
1339 {
1340 return this.canMove;
1341 },
1342 get canForward()
1343 {
1344 return this.canMove;
1345 },
1346
1347
1348 insert : function(aType) {
1349 switch (aType)
1350 {
1351 case 'page':
1352 this.insertTextFor('\n----\n', this.textbox, 6);
1353 break;
1354 case 'header':
1355 this.insertTextFor('\nHEADER::\n', this.textbox, 9);
1356 break;
1357 case 'footer':
1358 this.insertTextFor('\nFOOTER::\n', this.textbox, 9);
1359 break;
1360
1361 case 'em':
1362 case 'emphasis':
1363 this.insertTextFor(this.phraseOpenParen+this.phraseOpenParen+'EM:'+this.phraseCloseParen+this.phraseCloseParen, this.textbox, 5);
1364 break;
1365 case 'pre':
1366 case 'preformatted':
1367 this.insertTextFor(this.phraseOpenParen+this.phraseOpenParen+'PRE:'+this.phraseCloseParen+this.phraseCloseParen, this.textbox, 6);
1368 break;
1369 case 'monta':
1370 this.insertTextFor(this.phraseOpenParen+this.phraseCloseParen, this.textbox, 1);
1371 break;
1372 case 'link':
1373 this.insertTextFor(this.phraseOpenParen+this.phraseOpenParen+'|http://'+this.phraseCloseParen+this.phraseCloseParen, this.textbox, 2);
1374 break;
1375 case 'img':
1376 case 'image':
1377 this.insertTextFor(this.phraseOpenParen+this.phraseOpenParen+'image src="" width="" height=""'+this.phraseCloseParen+this.phraseCloseParen, this.textbox, 13);
1378 break;
1379
1380 default:
1381 return;
1382 }
1383 this.onEdit();
1384 },
1385 insertTextFor : function(aString, aNode, aPosOffset)
1386 {
1387 var pos = aNode.selectionStart;
1388 var value = aNode.value;
1389 aNode.value = [value.substring(0, pos), aString, value.substring(pos, value.length)].join('');
1390 aNode.selectionEnd = aNode.selectionStart = pos + (aPosOffset || 0);
1391 },
1392
1393
1394 output : function()
1395 {
1396 location.href = 'data:application/octet-stream,'+encodeURIComponent(this.textbox.value);
1397 },
1398
1399
1400 toggleEditMode : function(){
1401 this.deck.selectedIndex = this.deck.selectedIndex == 0 ? 1 : 0 ;
1402 this.setHash('edit', this.deck.selectedIndex == 0 ? '' : 'edit' );
1403 },
1404 toggleEvaMode : function(){
1405 var check = document.getElementById('toggleEva');
1406 if (this.canvas.getAttribute('eva') == 'true') {
1407 this.canvas.removeAttribute('eva');
1408 this.logo.removeAttribute('eva');
1409 check.checked = false;
1410 }
1411 else {
1412 this.canvas.setAttribute('eva', true);
1413 this.logo.setAttribute('eva',true);
1414 check.checked = true;
1415 }
1416 this.setHash('eva', check.checked ? 'eva' : '' );
1417 },
1418
1419
1420
1421 toggleAutoCruiseMode : function()
1422 {
1423 var autoCruise = document.getElementById('autoButton');
1424 if(!autoCruise.checked)
1425 this.startAutoCruise();
1426 else
1427 autoCruise.checked = false;
1428 },
1429 startAutoCruise : function()
1430 {
1431 var autoCruise = document.getElementById('autoButton');
1432 autoCruise.checked = true;
1433
1434 if (this.autoCruiseTimer) {
1435 window.clearTimeout(this.autoCruiseTimer);
1436 }
1437 this.autoCruiseTimer = window.setTimeout(this.autoCruise, this.autoCruiseInterval);
1438 },
1439
1440 changeAutoCruiseInterval : function(aInterval)
1441 {
1442 this.autoCruiseInterval = aInterval;
1443 this.startAutoCruise();
1444 },
1445
1446 autoCruise : function()
1447 {
1448 var autoCruise = document.getElementById('autoButton');
1449 if (!autoCruise.checked) return;
1450
1451 if (Presentation.offset == Presentation.data.length-1) {
1452 if (Presentation.canMove)
1453 Presentation.home();
1454 }
1455 else {
1456 if (Presentation.canForward)
1457 Presentation.forwardStep();
1458 }
1459 Presentation.autoCruiseTimer = window.setTimeout(arguments.callee, Presentation.autoCruiseInterval);
1460 },
1461 autoCruiseTimer : null,
1462
1463
1464
1465 setHash : function(aKey, aValue)
1466 {
1467 aKey = String(aKey).toLowerCase();
1468 var hashArray = String(location.hash).replace(/^#/, '').toLowerCase().split(',');
1469
1470 for (var i = hashArray.length-1; i > -1; i--)
1471 if (!hashArray[i] || hashArray[i].indexOf(aKey) == 0)
1472 hashArray.splice(i, 1);
1473
1474 if (aValue) hashArray.push(aValue);
1475 hashArray.sort();
1476
1477 location.hash = hashArray.length ? hashArray.join(',') : '' ;
1478 },
1479
1480
1481 showMontaKeyword : function(aNode, aWithoutAnimation) {
1482 if (aNode.getAttribute('monta-hidden') != 'true') return;
1483
1484 if (aWithoutAnimation) {
1485 aNode.setAttribute('monta-hidden', 'false');
1486 return;
1487 }
1488
1489 aNode.setAttribute('monta-hidden', 'progress');
1490
1491 this.montaAnimating = true;
1492
1493 window.setTimeout(this.showMontaKeywordCallback, 0, {
1494 position : -100,
1495 node : aNode,
1496 interval : this.showMontaKeywordTimeout/10
1497 });
1498 },
1499 showMontaKeywordCallback : function(aInfo) {
1500 if (aInfo.position >= aInfo.node.boxObject.width) {
1501 aInfo.node.setAttribute('monta-hidden', 'false');
1502 Presentation.montaAnimating = false;
1503 return;
1504 }
1505
1506 aInfo.position += (aInfo.node.boxObject.width/10);
1507 aInfo.node.setAttribute('style', 'background-position: '+aInfo.position+'px 0 !important;');
1508 window.setTimeout(arguments.callee, aInfo.interval, aInfo);
1509 },
1510 montaAnimating : false,
1511
1512
1513
1514 onPresentationClick : function(aEvent)
1515 {
1516 if (this.isPrinting) {
1517 if (confirm('Do you want printing operation to be stopped?')) {
1518 this.stopPrint();
1519 }
1520 return;
1521 }
1522
1523 if (!this.isToolbarHidden)
1524 this.showHideToolbar();
1525
1526 switch(aEvent.button)
1527 {
1528 case 0:
1529 switch (aEvent.target.getAttribute('class'))
1530 {
1531 case 'link-text':
1532 var uri = aEvent.target.getAttribute('href');
1533 if (uri) {
1534 window.open(uri);
1535 return;
1536 }
1537 break;
1538
1539 case 'monta-label':
1540 if (aEvent.target.getAttribute('monta-hidden') == 'true') {
1541 this.showMontaKeyword(aEvent.target);
1542 aEvent.preventBubble();
1543 return;
1544 }
1545
1546 default:
1547 break;
1548 }
1549 this.forward();
1550 document.documentElement.focus();
1551 break;
1552 case 2:
1553 this.back();
1554 document.documentElement.focus();
1555 break;
1556 default:
1557 break;
1558 }
1559 },
1560
1561 onScrollerDragStart : function(){
1562 if (this.isPrinting) return;
1563
1564 this.scroller.dragging = true;
1565 },
1566 onScrollerDragMove : function(){
1567 if (this.isPrinting) return;
1568
1569 if (this.scroller.dragging)
1570 this.showPage(parseInt(this.scroller.getAttribute('curpos')));
1571 },
1572 onScrollerDragDrop : function(){
1573 if (this.isPrinting) return;
1574
1575 this.onScrollerDragMove();
1576 this.scroller.dragging = false;
1577 },
1578
1579 onIndicatorBarClick : function(aEvent)
1580 {
1581 if (this.isPrinting) return;
1582
1583 var bar = this.indicatorBar;
1584 this.showPage(Math.round((aEvent.screenX - bar.boxObject.screenX) / bar.boxObject.width * this.data.length));
1585 },
1586 onIndicatorBarDragStart : function()
1587 {
1588 if (this.isPrinting) return;
1589
1590 this.indicatorBar.dragging = true;
1591 },
1592 onIndicatorBarDragMove : function(aEvent)
1593 {
1594 if (this.isPrinting) return;
1595
1596 var bar = this.indicatorBar;
1597 this.showPage(Math.round((aEvent.screenX - bar.boxObject.screenX) / bar.boxObject.width * this.data.length));
1598 },
1599 onIndicatorBarDragEnd : function(aEvent)
1600 {
1601 if (this.isPrinting) return;
1602
1603 this.onIndicatorBarDragMove(aEvent);
1604 this.indicatorBar.dragging = false;
1605 },
1606
1607 onEdit : function() {
1608 if (this.isPrinting) return;
1609
1610 this.data = this.textbox.value;
1611 this.init();
1612 },
1613
1614 onKeyPress : function(aEvent) {
1615 if (this.isPrinting) return;
1616
1617 switch(aEvent.keyCode)
1618 {
1619 case aEvent.DOM_VK_BACK_SPACE:
1620 if (this.isPresentationMode) {
1621 aEvent.preventBubble();
1622 aEvent.preventDefault();
1623 Presentation.back();
1624 }
1625 break;
1626 default:
1627 break;
1628 }
1629 },
1630
1631
1632
1633 handleEvent : function(aEvent)
1634 {
1635 if (this.isPrinting) return;
1636
1637 var node = aEvent.target;
1638 var inRawContents = false;
1639 do {
1640 if (node.nodeType == Node.ELEMENT_NODE &&
1641 /\braw\b/i.test(node.getAttribute('class'))) {
1642 inRawContents = true;
1643 break;
1644 }
1645
1646 node = node.parentNode;
1647 }
1648 while (node.parentNode)
1649
1650
1651 switch (aEvent.type)
1652 {
1653 default:
1654 break;
1655
1656 case 'resize':
1657 this.takahashi(); // redrwa
1658 break;
1659
1660 case 'contextmenu':
1661 aEvent.stopPropagation();
1662 aEvent.preventCapture();
1663 aEvent.preventDefault();
1664 aEvent.preventBubble();
1665 break;
1666
1667
1668 case 'mouseup':
1669 if (inRawContents) return;
1670 this.dragStartX = -1;
1671 this.dragStartY = -1;
1672 if (this.indicatorBar.dragging)
1673 this.onIndicatorBarDragEnd(aEvent);
1674 break;
1675
1676 case 'mousedown':
1677 if (inRawContents) return;
1678 if (this.dragStartX < 0) {
1679 this.dragStartX = aEvent.clientX;
1680 this.dragStartY = aEvent.clientY;
1681 }
1682 var box = this.indicatorBar.boxObject;
1683 if (!(aEvent.screenX < box.screenX ||
1684 aEvent.screenY < box.screenY ||
1685 aEvent.screenX > box.screenX+box.width ||
1686 aEvent.screenY > box.screenY+box.height))
1687 this.onIndicatorBarDragStart();
1688 break;
1689
1690 case 'mousemove':
1691 if (inRawContents) return;
1692 this.checkShowHideToolbar(aEvent);
1693 if (this.indicatorBar.dragging) {
1694 this.onIndicatorBarDragMove(aEvent);
1695 return;
1696 }
1697 if (this.dragStartX > -1) {
1698 if (Math.abs(this.dragStartX-aEvent.clientX) > Math.abs(this.dragStartDelta) ||
1699 Math.abs(this.dragStartY-aEvent.clientY) > Math.abs(this.dragStartDelta)) {
1700 var event = document.createEvent('Events');
1701 event.initEvent('StartDragOnCanvas', false, true);
1702 this.canvas.dispatchEvent(event);
1703 }
1704 }
1705 break;
1706
1707 case 'CanvasContentAdded':
1708 if (this.fitToCanvasTimer) {
1709 window.clearTimeout(this.fitToCanvasTimer);
1710 this.fitToCanvasTimer = null;
1711 }
1712 this.fitToCanvasTimer = window.setTimeout('Presentation.fitMainContentToCanvas()', 100);
1713 break;
1714
1715 case 'DOMMouseScroll':
1716 if (
1717 (aEvent.detail > 0 && this.scrollCounter < 0) ||
1718 (aEvent.detail < 0 && this.scrollCounter > 0)
1719 )
1720 this.scrollCounter = 0;
1721
1722 this.scrollCounter += aEvent.detail;
1723 if (Math.abs(this.scrollCounter) >= this.scrollThreshold) {
1724 if (aEvent.detail > 0)
1725 Presentation.forwardStep();
1726 else
1727 Presentation.back();
1728
1729 this.scrollCounter = 0;
1730 }
1731 break;
1732 }
1733 },
1734 dragStartX : -1,
1735 dragStartY : -1,
1736 scrollCounter : 0,
1737 scrollThreshold : 10,
1738
1739
1740
1741 onToolbarArea : false,
1742 toolbarHeight : 0,
1743 toolbarDelay : 300,
1744 toolbarTimer : null,
1745 isToolbarHidden : false,
1746 checkShowHideToolbar : function(aEvent) {
1747 if (!this.scroller || this.scroller.dragging || this.preventToShowHideToolbar) return;
1748
1749 this.onToolbarArea = (aEvent.clientY < this.toolbarHeight);
1750
1751 if (this.isToolbarHidden == this.onToolbarArea) {
1752 if (this.toolbarTimer) window.clearTimeout(this.toolbarTimer);
1753 this.toolbarTimer = window.setTimeout('Presentation.checkShowHideToolbarCallback()', this.toolbarDelay);
1754 }
1755 },
1756 checkShowHideToolbarCallback : function() {
1757 if (this.isToolbarHidden == this.onToolbarArea)
1758 this.showHideToolbar();
1759 },
1760
1761 toolbarAnimationDelay : 100,
1762 toolbarAnimationSteps : 5,
1763 toolbarAnimationInfo : null,
1764 toolbarAnimationTimer : null,
1765 showHideToolbar : function(aWithoutAnimation)
1766 {
1767 if (this.isPrinting) return;
1768
1769 if (this.toolbarAnimationTimer) window.clearTimeout(this.toolbarAnimationTimer);
1770
1771 this.toolbarAnimationInfo = { count : 0 };
1772 if (this.isToolbarHidden) {
1773 this.toolbarAnimationInfo.start = 0;
1774 this.toolbarAnimationInfo.end = this.toolbarHeight;
1775 }
1776 else {
1777 this.toolbarAnimationInfo.start = this.toolbarHeight;
1778 this.toolbarAnimationInfo.end = 0;
1779 }
1780 this.toolbarAnimationInfo.current = 0;
1781
1782 this.toolbar.setAttribute('style', 'margin-top:'+(0-(this.toolbarHeight-this.toolbarAnimationInfo.start))+'px; margin-bottom:'+(0-this.toolbarAnimationInfo.start)+'px;');
1783
1784 if (aWithoutAnimation) {
1785 this.toolbarAnimationInfo.current = this.toolbarHeight;
1786 Presentation.animateToolbar();
1787 }
1788 else {
1789 this.toolbarAnimationTimer = window.setTimeout('Presentation.animateToolbar()', this.toolbarAnimationDelay/this.toolbarAnimationSteps);
1790 }
1791 },
1792 animateToolbar : function()
1793 {
1794 this.toolbarAnimationInfo.current += parseInt(this.toolbarHeight/this.toolbarAnimationSteps);
1795
1796 var top, bottom;
1797 if (this.toolbarAnimationInfo.start < this.toolbarAnimationInfo.end) {
1798 top = this.toolbarHeight-this.toolbarAnimationInfo.current;
1799 bottom = this.toolbarAnimationInfo.current;
1800 }
1801 else {
1802 top = this.toolbarAnimationInfo.current;
1803 bottom = this.toolbarHeight-this.toolbarAnimationInfo.current;
1804 }
1805
1806 top = Math.min(Math.max(top, 0), this.toolbarHeight);
1807 bottom = Math.min(Math.max(bottom, 0), this.toolbarHeight);
1808
1809 this.toolbar.setAttribute('style', 'margin-top:'+(0-top)+'px; margin-bottom:'+(0-bottom)+'px');
1810
1811 if (this.toolbarAnimationInfo.count < this.toolbarAnimationSteps) {
1812 this.toolbarAnimationInfo.count++;
1813 this.toolbarAnimationTimer = window.setTimeout('Presentation.animateToolbar()', this.toolbarAnimationDelay/this.toolbarAnimationSteps);
1814 }
1815 else
1816 this.isToolbarHidden = !this.isToolbarHidden;
1817 },
1818
1819
1820
1821 get offset(){
1822 return this._offset;
1823 },
1824 set offset(aValue){
1825 this._offset = parseInt(aValue || 0);
1826 document.documentElement.setAttribute('lastoffset', this.offset);
1827 return this.offset;
1828 },
1829
1830 get data(){
1831 var codes = document.getElementById('builtinCode');
1832 if (!this._data) {
1833 // mozilla splits very long text node into multiple text nodes whose length is less than 4096 bytes.
1834 // so, we must concat all the text nodes.
1835 this.textbox.value = "";
1836 for (var i = 0; i < codes.childNodes.length; i++) {
1837 this.textbox.value += codes.childNodes[i].nodeValue;
1838 }
1839
1840 this._data = this.textbox.value.split(/----+/);
1841 this.initData();
1842 }
1843 if (codes)
1844 codes.parentNode.removeChild(codes);
1845
1846 return this._data;
1847 },
1848 set data(aValue){
1849 this._data = aValue.split(/----+/);
1850 this.initData();
1851 return aValue;
1852 },
1853 initData : function()
1854 {
1855 var range = document.createRange();
1856 range.selectNodeContents(this.list);
1857 range.deleteContents();
1858
1859
1860 var regexp = [
1861 /^[\r\n\s]+/g,
1862 /[\r\n\s]+$/g,
1863 /(\r\n|[\r\n])/g
1864 ];
1865
1866 var title;
1867 var titleRegExp = /^(TITLE::)([^\n]*)\n?/im;
1868 var header = '';
1869 var headerRegExp = /^(HEADER::)([^\n]*)\n?/im;
1870 var footer = '';
1871 var footerRegExp = /^(FOOTER::)([^\n]*)\n?/im;
1872 var chapter = '';
1873 var chapterRegExp = /^(CHAPTER::)([^\n]*)\n?/im;
1874 var lastChapter;
1875 var alignGlobal = 'center';
1876 var align;
1877 var alignRegExp = /^((GLOBAL-)?ALIGN::)(left|right|center|start|end)?\n?/im;
1878
1879 var imageMatchResults;
1880 var imagesRegExp = this.makePhraseRegExp('%O%Oima?ge? +src="[^"]+" +width="[0-9]+" +height="[0-9]+"[^%C]*%C%C', 'gi');
1881 var imagesRegExp2 = this.makePhraseRegExp('%O%Oima?ge? +src="([^"]+)"', 'i');
1882 var image_src;
1883
1884 var plainTextRegExp = this.makePhraseRegExp('(%O%O\#[^:]+:(.+)%C%C|%O%OEM:(.+)(:EM)?%C%C|%O%OPRE:(.+)(:PRE)?%C%C|%O%Oima?ge? +src="[^"]*"[^%C]+%C%C|%O%O([^\\|%C]+)(\\|[^%C]+)?%C%C|%O([^%O]+)%C)', 'gi');
1885
1886 var hiddenRegExp = /^(HIDDEN|IGNORE)::true\n?/im;
1887
1888 var loadRegExp = /^LOAD::(.+)\n?/im;
1889
1890 var dataObj;
1891 var i, j,
1892 max = this._data.length;
1893 var fragment = document.createDocumentFragment();
1894 var popup;
1895 var dataPath;
1896 for (i = 0; i < max; i++)
1897 {
1898 image_src = null;
1899 align = null;
1900 dataPath = '';
1901
1902 this._data[i] = this._data[i]
1903 .replace(regexp[0], '')
1904 .replace(regexp[1], '')
1905 .replace(regexp[2], '\n');
1906
1907 if (loadRegExp.test(this._data[i])) {
1908 this._data[i] = this._data[i].replace(loadRegExp, '');
1909 dataPath = RegExp.$1;
1910 }
1911
1912 if (hiddenRegExp.test(this._data[i])) {
1913 this._data.splice(i, 1);
1914 max--;
1915 i--;
1916 continue;
1917 }
1918
1919 while (titleRegExp.test(this._data[i])) {
1920 this._data[i] = this._data[i].replace(titleRegExp, '');
1921 if (String(RegExp.$1).toUpperCase() == 'TITLE::')
1922 title = RegExp.$2 || '' ;
1923 }
1924
1925 while (headerRegExp.test(this._data[i])) {
1926 this._data[i] = this._data[i].replace(headerRegExp, '');
1927 if (String(RegExp.$1).toUpperCase() == 'HEADER::')
1928 header = RegExp.$2 || '' ;
1929 }
1930
1931 while (footerRegExp.test(this._data[i])) {
1932 this._data[i] = this._data[i].replace(footerRegExp, '');
1933 if (String(RegExp.$1).toUpperCase() == 'FOOTER::')
1934 footer = RegExp.$2 || '' ;
1935 }
1936
1937 while (chapterRegExp.test(this._data[i])) {
1938 this._data[i] = this._data[i].replace(chapterRegExp, '');
1939 if (String(RegExp.$1).toUpperCase() == 'CHAPTER::')
1940 chapter = RegExp.$2 || '' ;
1941 }
1942
1943 while (alignRegExp.test(this._data[i])) {
1944 this._data[i] = this._data[i].replace(alignRegExp, '');
1945
1946 align = (RegExp.$3 || '').toLowerCase();
1947 if (align == 'left')
1948 align = 'start';
1949 else if (align == 'right')
1950 align = 'end';
1951
1952 if (String(RegExp.$1).toUpperCase() == 'GLOBAL-ALIGN::') {
1953 alignGlobal = align;
1954 align = null;
1955 }
1956 }
1957
1958 imageMatchResults = this._data[i].match(imagesRegExp);
1959 if (imageMatchResults) {
1960 for (j = imageMatchResults.length-1; j > -1; j--)
1961 image_src = this.preloadImage(imageMatchResults[j].match(imagesRegExp2)[1]);
1962 }
1963
1964 this._data[i] = {
1965 load : dataPath,
1966 header : header,
1967 footer : footer,
1968 text : this._data[i].split('\n'),
1969 image : image_src,
1970 align : align || alignGlobal
1971 };
1972 this._data[i].plain = this._data[i].text
1973 .join('\n')
1974 .replace(plainTextRegExp, '$2$3$5$7$9')
1975 .split('\n');
1976 if (title !== void(0))
1977 this._data[i].title = title;
1978
1979 this._data[i].chapter = chapter || title || '';
1980 if (lastChapter === void(0) ||
1981 lastChapter != this._data[i].chapter) {
1982 lastChapter = this._data[i].chapter;
1983
1984 if (popup && popup.childNodes.length == 1) {
1985 fragment.removeChild(fragment.lastChild);
1986 fragment.appendChild(popup.removeChild(popup.lastChild));
1987 }
1988
1989 popup = document.createElement('menupopup');
1990 fragment.appendChild(document.createElement('menu'));
1991 fragment.lastChild.setAttribute('label', this._data[i].chapter);
1992 fragment.lastChild.appendChild(popup);
1993 }
1994
1995 popup.appendChild(document.createElement('menuitem'));
1996 popup.lastChild.setAttribute('type', 'radio');
1997 popup.lastChild.setAttribute('radiogroup', 'pages');
1998 popup.lastChild.setAttribute('label', (i+1)+': '+(
1999 (this._data[i].plain.join('') || this._data[i].text.join(' ')).replace(/\s+/g, ' ')
2000 ));
2001 popup.lastChild.setAttribute('value', i);
2002
2003 // if (image_src) {
2004 // popup.lastChild.setAttribute('image', image_src);
2005 // popup.lastChild.setAttribute('class', 'menuitem-iconic');
2006 // }
2007 }
2008
2009 if (fragment.childNodes.length == 1) {
2010 range.selectNodeContents(fragment.firstChild.firstChild);
2011 fragment = range.extractContents();
2012 }
2013 this.list.appendChild(fragment);
2014
2015 range.detach();
2016
2017
2018 this.shownMontaLabels = [];
2019 },
2020
2021 preloadImage : function(aURI)
2022 {
2023 if (aURI in this.imageRequests) return;
2024
2025 if (aURI.indexOf('http://') < 0 &&
2026 aURI.indexOf('https://') < 0)
2027 aURI = this.dataFolder+aURI;
2028
2029 this.imageRequests[aURI] = new XMLHttpRequest();
2030 try {
2031 this.imageRequests[aURI].open('GET', aURI);
2032 this.imageRequests[aURI].onload = function() {
2033 Presentation.imageRequests[aURI] = null;
2034 };
2035 this.imageRequests[aURI].send(null);
2036 }
2037 catch(e) {
2038 this.imageRequests[aURI] = null;
2039 }
2040 return aURI;
2041 },
2042 imageRequests : {},
2043
2044
2045 get isPresentationMode(){
2046 return (this.deck.selectedIndex == 0);
2047 },
2048
2049
2050 get dataPath(){
2051 if (!this._dataPath)
2052 this.dataPath = String(location.href).replace(/#.+$/, '');
2053 return this._dataPath;
2054 },
2055 set dataPath(aValue){
2056 var oldDataPath = this._dataPath;
2057 this._dataPath = aValue;
2058 if (oldDataPath != aValue) {
2059 this._dataFolder = this._dataPath.split('?')[0].replace(/[^\/]+$/, '');
2060 }
2061 return this._dataPath;
2062 },
2063
2064 get dataFolder(){
2065 if (!this._dataFolder)
2066 this.dataPath = this.dataPath;
2067 return this._dataFolder;
2068 },
2069 set dataFolder(aValue){
2070 this._dataFolder = aValue;
2071 return this._dataFolder;
2072 },
2073
2074 readParameter : function() {
2075 if (location.search || location.hash) {
2076 var param = location.search.replace(/^\?/, '');
2077
2078 if (location.hash.match(/page([0-9]+)/i) ||
2079 param.match(/page=([0-9]+)/i))
2080 this.offset = parseInt(RegExp.$1)-1;
2081
2082 if (location.hash.match(/edit/i) ||
2083 param.match(/edit=(1|true|yes)/i))
2084 this.toggleEditMode();
2085
2086 if (location.hash.match(/eva/i) ||
2087 param.match(/eva=(1|true|yes)/i))
2088 this.toggleEvaMode();
2089
2090 if (location.hash.match(/timer(\d+)\-(\d+)/i))
2091 this.setTimer(RegExp.$1, RegExp.$2);
2092
2093 if (param.match(/(style|css)=([^&;]+)/i)) {
2094 var style = unescape(RegExp.$2);
2095 var pi = document.createProcessingInstruction('xml-stylesheet', 'href="'+style+'" type="text/css"');
2096 document.insertBefore(pi, document.documentElement);
2097 }
2098
2099 if (param.match(/data=([^&;]+)/i)) {
2100 this.loadData(RegExp.$1);
2101 return false;
2102 }
2103 }
2104 return true;
2105 },
2106 loadData : function(aPath)
2107 {
2108 this.dataPath = aPath;
2109 var request = new XMLHttpRequest();
2110 request.open('GET', aPath);
2111 request.onload = function() {
2112 Presentation.textbox.value = request.responseText;
2113 Presentation.data = Presentation.textbox.value;
2114 Presentation.init();
2115 };
2116 request.send(null);
2117 },
2118
2119
2120
2121 resetTimer : function()
2122 {
2123 if (this.timerTimer) {
2124 window.clearInterval(this.timerTimer);
2125 this.timerTimer = null;
2126 }
2127 this.timer.setAttribute('value', 0);
2128 this.timer.setAttribute('collapsed', true);
2129 this.setHash('timer', '');
2130 },
2131 setTimer : function(aStart, aEnd)
2132 {
2133 var now = (new Date()).getTime();
2134 if (aStart === void(0) || aEnd === void(0)) {
2135 var rest = prompt('Remaining Time (minits)');
2136 if (rest == '') {
2137 this.resetTimer();
2138 return;
2139 }
2140 else {
2141 rest = Number(rest);
2142 if (!rest || isNaN(rest)) return;
2143 }
2144
2145 rest = Math.abs(rest);
2146 this.timerStart = now;
2147 this.timerEnd = this.timerStart + (rest * 60000);
2148 }
2149 else {
2150 aStart = Number(aStart);
2151 aEnd = Number(aEnd);
2152 if (isNaN(aStart) || isNaN(aEnd)) return;
2153
2154 this.timerStart = Math.min(aStart, aEnd);
2155 this.timerEnd = Math.max(aStart, aEnd);
2156
2157 if (this.timerStart >= now || this.timerEnd <= now) return;
2158 }
2159
2160 this.resetTimer();
2161
2162 this.timer.removeAttribute('collapsed');
2163 this.setHash('timer', 'timer'+this.timerStart+'-'+this.timerEnd);
2164
2165 if (now != this.timerStart)
2166 this.updateTimer(this);
2167
2168 window.setInterval(this.updateTimer, Math.min(this.timerUpdatingInterval, (this.timerEnd-this.timerStart)/(this.data.length*2)), this);
2169 },
2170 updateTimer : function(aThis)
2171 {
2172 var now = (new Date()).getTime();
2173 if (now >= aThis.timerEnd) {
2174 aThis.resetTimer();
2175 aThis.timer.setAttribute('value', 100);
2176 aThis.timer.removeAttribute('collapsed');
2177 aThis.setHash('timer', '');
2178 }
2179 else {
2180 var value = parseInt(((now - aThis.timerStart) / (aThis.timerEnd - aThis.timerStart)) * 100);
2181 aThis.timer.setAttribute('value', value);
2182 }
2183 },
2184 timerStart : 0,
2185 timerEnd : 0,
2186 timerTimer : null,
2187
2188
2189
2190 print : function()
2191 {
2192 if (!this.canMove) {
2193 alert('Please wait for a while, and retry later.');
2194 return;
2195 }
2196
2197 this.stopPrint();
2198 if (this.printWindow) {
2199 this.printWindow.close();
2200 this.printWindow = null;
2201 }
2202
2203 if (!this.isToolbarHidden)
2204 this.showHideToolbar(true);
2205
2206 this.printWindow = window.open('output.htm', 'PresentationPrint', 'dependent=yes,hotkeys=yes,location=yes,menubar=yes,personalbar=yes,scrollbars=yes,status=yes,toolbar=yes');
2207 if (!this.printWindow) return;
2208
2209 this.isPrinting = true;
2210
2211 if (!this.printCanvas)
2212 this.printCanvas = document.createElementNS(XHTMLNS, 'canvas');
2213
2214 this.printWindow.document.write('<html><head><title>'+document.title+'</title></head><body></body></html>');
2215 this.home();
2216 this.printTimer = window.setInterval(this.printCallback, 0, this);
2217 },
2218 printCallback : function(aThis)
2219 {
2220 if (
2221 !aThis.canMove
2222 )
2223 return;
2224
2225 var monta = document.getElementsByAttribute('monta-hidden', 'true');
2226 if (monta && monta.length) {
2227 for (var i = monta.length-1; i > -1; i--)
2228 aThis.showMontaKeyword(monta[i], true);
2229 }
2230
2231 var doc = aThis.printWindow.document;
2232 var body = doc.getElementsByTagName('body')[0];
2233 var img = doc.createElement('img');
2234
2235 if ((aThis.offset+1) % 2 == 1) {
2236 body.appendChild(doc.createElement('div'));
2237 // body.lastChild.style.clear = 'both';
2238 }
2239 var box = doc.createElement('div');
2240 box.appendChild(doc.createElement('div'));
2241 box.lastChild.appendChild(document.createTextNode(aThis.offset+1));
2242 body.lastChild.appendChild(box);
2243
2244 var w = window.innerWidth;
2245 var h = window.innerHeight;
2246 var canvasW = parseInt(w * aThis.printSize);
2247 var canvasH = parseInt(h * aThis.printSize);
2248
2249 aThis.printCanvas.width = canvasW;
2250 aThis.printCanvas.height = canvasH;
2251 aThis.printCanvas.style.border = 'black solid medium';
2252
2253 img.style.border = 'black solid medium';
2254 img.style.width = canvasW+'px';
2255 img.style.height = canvasH+'px';
2256
2257 box.style.margin = '1em';
2258 box.style.width = parseInt(w * aThis.printSize)+'px';
2259 box.style.cssFloat = ((aThis.offset+1) % 2 == 1) ? 'left' : 'right' ;
2260
2261 try {
2262 netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead');
2263
2264 var ctx = aThis.printCanvas.getContext('2d');
2265 ctx.clearRect(0, 0, canvasW, canvasH);
2266 ctx.save();
2267 ctx.scale(aThis.printSize, aThis.printSize);
2268 ctx.drawWindow(window, 0, 0, w, h, 'rgb(255,255,255)');
2269 ctx.restore();
2270 try {
2271 if (aThis.imageType == 'jpeg')
2272 img.src = aThis.printCanvas.toDataURL('image/jpeg', 'quality=50');
2273 else
2274 img.src = aThis.printCanvas.toDataURL('image/png', 'transparency=none');
2275
2276 box.appendChild(img);
2277 }
2278 catch(e) {
2279 box.appendChild(aThis.printCanvas.cloneNode(true));
2280 ctx = box.lastChild.getContext('2d');
2281 ctx.clearRect(0, 0, canvasW, canvasH);
2282 ctx.save();
2283 ctx.scale(aThis.printSize, aThis.printSize);
2284 ctx.drawWindow(window, 0, 0, w, h, 'rgb(255,255,255)');
2285 ctx.restore();
2286 }
2287 }
2288 catch(e) {
2289 alert('Error: Failed to create a document for printing.\n\n------\n'+e);
2290 aThis.stopPrint();
2291 return;
2292 }
2293
2294 if (aThis.offset == aThis.data.length-1) {
2295 aThis.stopPrint();
2296 aThis.printWindow.focus();
2297 }
2298 else {
2299 aThis.forward();
2300 }
2301 },
2302 stopPrint : function()
2303 {
2304 window.clearInterval(this.printTimer);
2305 this.printTimer = null;
2306 this.isPrinting = false;
2307 },
2308 printSize : 0.4,
2309 printTimer : null,
2310 printWindow : null,
2311 printCanvas : null
2312
2313 };
2314
2315
2316
2317
2318
2319 var StrokeService = {
2320 className : 'stroke-dot',
2321 dragStartDelta : 8,
2322 lineColor : 'red',
2323 lineWidth : 3,
2324
2325 initialized : false,
2326
2327
2328 mode : null,
2329 canvas : null,
2330 canvasContext : null,
2331 startX : -1,
2332 startY : -1,
2333
2334 init : function(aCanvas)
2335 {
2336 this.initialized = true;
2337
2338 this.canvas = aCanvas;
2339
2340 var canvas = document.createElementNS('http://www.w3.org/1999/xhtml', 'canvas');
2341 this.canvas.appendChild(canvas);
2342 if (!('getContext' in canvas) || !canvas.getContext) {
2343 this.canvas.removeChild(canvas);
2344 this.mode = 'box';
2345 }
2346 else {
2347 this.canvas = canvas;
2348 this.canvasContext = this.canvas.getContext('2d');
2349 this.mode = 'canvas';
2350 }
2351
2352 document.documentElement.addEventListener('PresentationRedraw', this, false);
2353 window.addEventListener('resize', this, false);
2354 this.canvas.addEventListener('mouseup', this, false);
2355 this.canvas.addEventListener('mousedown', this, false);
2356 this.canvas.addEventListener('mousemove', this, false);
2357
2358 this.canvas.addEventListener('click', this, false);
2359 this.canvas.addEventListener('dblclick', this, false);
2360
2361 this.clear();
2362 },
2363
2364 destroy : function()
2365 {
2366 document.documentElement.removeEventListener('PresentationRedraw', this, false);
2367 window.removeEventListener('resize', this, false);
2368 this.canvas.removeEventListener('mouseup', this, false);
2369 this.canvas.removeEventListener('mousedown', this, false);
2370 this.canvas.removeEventListener('mousemove', this, false);
2371 this.canvas.removeEventListener('click', this, false);
2372
2373 this.cliclableNodesManager = null;
2374 this.canvas = null;
2375
2376 this.initialized = false;
2377 },
2378
2379
2380
2381 handleEvent : function(aEvent)
2382 {
2383 switch(aEvent.type)
2384 {
2385 default:
2386 break;
2387
2388 case 'mouseup':
2389 this.finish(aEvent);
2390 this.startX = -1;
2391 this.startY = -1;
2392 window.setTimeout('StrokeService.preventToSendClickEvent = false', 10);
2393 break;
2394
2395 case 'mousedown':
2396 if (this.startX < 0) {
2397 this.startX = aEvent.clientX;
2398 this.startY = aEvent.clientY;
2399 }
2400 break;
2401
2402 case 'mousemove':
2403 if (this.startX > -1 && !this.active) {
2404 if (Math.abs(this.startX-aEvent.clientX) > Math.abs(this.dragStartDelta) ||
2405 Math.abs(this.startY-aEvent.clientY) > Math.abs(this.dragStartDelta)) {
2406 this.start(aEvent, this.startX, this.startY);
2407 this.preventToSendClickEvent = true;
2408 }
2409 }
2410 else
2411 this.trace(aEvent);
2412
2413 break;
2414
2415 case 'PresentationRedraw':
2416 case 'resize':
2417 this.clear();
2418 break;
2419
2420 case 'click':
2421 if (this.preventToSendClickEvent) {
2422 aEvent.stopPropagation();
2423 aEvent.preventCapture();
2424 aEvent.preventDefault();
2425 aEvent.preventBubble();
2426 this.preventToSendClickEvent = false;
2427 }
2428 else if (this.cliclableNodesManager && this.cliclableNodesManager.clickableNodes) {
2429 var nodes = this.cliclableNodesManager.clickableNodes;
2430 var max = nodes.length;
2431 var x, y, width, height
2432 for (var i = 0; i < max; i++)
2433 {
2434 if (nodes[i].boxObject) {
2435 x = nodes[i].boxObject.x;
2436 y = nodes[i].boxObject.y;
2437 width = nodes[i].boxObject.width;
2438 height = nodes[i].boxObject.height;
2439 }
2440 else {
2441 x = nodes[i].offsetLeft;
2442 y = nodes[i].offsetTop;
2443 width = nodes[i].offsetWidth;
2444 height = nodes[i].offsetHeight;
2445 }
2446 if (aEvent.clientX < x ||
2447 aEvent.clientX > x+width ||
2448 aEvent.clientY < y ||
2449 aEvent.clientY > y+height)
2450 continue;
2451
2452 var event = document.createEvent('MouseEvents');
2453 event.initMouseEvent(
2454 aEvent.type, aEvent.canBubble, aEvent.cancelable, aEvent.view,
2455 aEvent.detail,
2456 aEvent.screenX, aEvent.screenY, aEvent.clientX, aEvent.clientY,
2457 aEvent.ctrlKey, aEvent.altKey, aEvent.shiftKey, aEvent.metaKey,
2458 aEvent.button,
2459 aEvent.relatedTarget
2460 );
2461 nodes[i].dispatchEvent(event);
2462 break;
2463 }
2464 }
2465 break;
2466 }
2467 },
2468 preventToSendClickEvent : false,
2469
2470
2471
2472 start : function(aEvent, aX, aY)
2473 {
2474 this.active = true;
2475 this.trace(aEvent, aX, aY);
2476 },
2477
2478 finish : function(aEvent)
2479 {
2480 if (!this.active) return;
2481 this.trace(aEvent);
2482 this.finishStroke();
2483 },
2484
2485 trace : function(aEvent, aX, aY)
2486 {
2487 if (!this.active) return;
2488 this.addPoint((aX === void(0) ? aEvent.clientX : aX ), (aY === void(0) ? aEvent.clientY : aY ));
2489 },
2490
2491
2492 finishStroke : function()
2493 {
2494 this.active = false;
2495 this.lastX = -1;
2496 this.lastY = -1;
2497 },
2498
2499
2500 addPoint : function(aX, aY)
2501 {
2502 if (this.lastX != -1)
2503 this.drawLine(this.lastX, this.lastY, aX, aY);
2504 else
2505 this.drawDot(aX, aY);
2506
2507 this.lastX = aX;
2508 this.lastY = aY;
2509 },
2510
2511
2512
2513 clear : function()
2514 {
2515 this.active = false;
2516 this.lastX = -1;
2517 this.lastY = -1;
2518
2519 if (this.mode == 'canvas') {
2520 if (this.canvas.lastWindowWidth != window.innerWidth ||
2521 this.canvas.lastWindowHeight != window.innerHeight) {
2522 this.canvas.width = this.canvas.parentNode.boxObject.width-2;
2523 this.canvas.height = this.canvas.parentNode.boxObject.height-2;
2524
2525 this.canvas.lastWindowWidth = window.innerWidth;
2526 this.canvas.lastWindowHeight = window.innerHeight;
2527 }
2528 this.canvasContext.clearRect(0, 0, this.canvas.width, this.canvas.height);
2529 this.canvasContext.strokeStyle = this.lineColor;
2530 this.canvasContext.lineWidth = this.lineWidth;
2531 }
2532 else {
2533 var dotes = this.canvas.getElementsByAttribute('class', this.className);
2534 if (!dotes.length) return;
2535
2536 var range = document.createRange();
2537 range.selectNodeContents(this.canvas);
2538 range.setStartBefore(dotes[0]);
2539 range.setEndAfter(dotes[dotes.length-1]);
2540 range.deleteContents();
2541 range.detach();
2542 }
2543 },
2544
2545 drawDot : function(aX, aY, aParent)
2546 {
2547 if (this.mode == 'canvas') {
2548 this.canvasContext.strokeRect(aX, aY, 0, 0);
2549 this.canvasContext.stroke();
2550 }
2551 else {
2552 var dot = document.createElement('spacer');
2553 dot.setAttribute('style', 'left:'+aX+'px; top:'+aY+'px');
2554 dot.setAttribute('class', this.className);
2555 (aParent || this.canvas).appendChild(dot);
2556 }
2557 },
2558 drawLine : function(aX1, aY1, aX2, aY2)
2559 {
2560 if (aX1 == aX2 && aY1 == aY2) return;
2561
2562
2563 if (this.mode == 'canvas') {
2564 this.canvasContext.beginPath();
2565 this.canvasContext.moveTo(aX1, aY1);
2566 this.canvasContext.lineTo(aX2, aY2);
2567 /*
2568 this.canvasContext.bezierCurveTo(
2569 parseInt(aX1+((aX2-this.lastX)*0.3)), parseInt(aY1+((aY2-this.lastY)*0.3)),
2570 parseInt(aX1+((aX2-this.lastX)*0.6)), parseInt(aY1+((aY2-this.lastY)*0.6)),
2571 aX2, aY2
2572 );
2573 */
2574 this.canvasContext.closePath();
2575 this.canvasContext.stroke();
2576 }
2577 else {
2578 var x_move = aX2 - aX1;
2579 var y_move = aY2 - aY1;
2580 var x_diff = x_move < 0 ? 1 : -1;
2581 var y_diff = y_move < 0 ? 1 : -1;
2582
2583 var fragment = document.createDocumentFragment();
2584 if (Math.abs(x_move) >= Math.abs(y_move)) {
2585 for (var i = x_move; i != 0; i += x_diff)
2586 this.drawDot(aX2 - i, aY2 - Math.round(y_move * i / x_move), fragment);
2587 }
2588 else {
2589 for (var i = y_move; i != 0; i += y_diff)
2590 this.drawDot(aX2 - Math.round(x_move * i / y_move), aY2 - i, fragment);
2591 }
2592 this.canvas.appendChild(fragment);
2593 }
2594 }
2595 };
2596
2597
2598
2599
2600
2601 var StrokablePresentationService = {
2602
2603 id : 'stroke-canvas-box',
2604
2605 strokeService : null,
2606 cliclableNodesManager : null,
2607 canvasContainer : null,
2608 canvas : null,
2609
2610 autoStart : false,
2611
2612 init : function(aPresentation, aStrokeService)
2613 {
2614 this.cliclableNodesManager = aPresentation;
2615 this.strokeService = aStrokeService;
2616 this.canvasContainer = document.getElementById('canvas').firstChild;
2617 this.check = document.getElementById('penButton');
2618
2619 document.documentElement.addEventListener('StartDragOnCanvas', this, false);
2620 document.documentElement.addEventListener('PresentationRedraw', this, false);
2621 },
2622
2623 toggle : function(aEnable)
2624 {
2625 if (aEnable)
2626 this.start();
2627 else
2628 this.end();
2629 },
2630
2631 start : function()
2632 {
2633 if (!this.strokeService || !this.canvasContainer) return;
2634
2635 this.strokeService.cliclableNodesManager = this.cliclableNodesManager;
2636 var box = document.createElement('vbox');
2637 box.setAttribute('flex', 1);
2638 box.setAttribute('id', this.id);
2639 this.canvas = this.canvasContainer.appendChild(box);
2640 this.strokeService.init(this.canvas);
2641
2642 this.canvas.addEventListener('dblclick', this, false);
2643 },
2644
2645 end : function()
2646 {
2647 this.canvas.removeEventListener('dblclick', this, false);
2648
2649 this.strokeService.destroy();
2650 this.canvasContainer.removeChild(this.canvas);
2651 this.canvas = null;
2652 },
2653
2654 handleEvent : function(aEvent)
2655 {
2656 switch (aEvent.type)
2657 {
2658 default:
2659 break;
2660
2661 case 'StartDragOnCanvas':
2662 if (!this.check.checked) {
2663 this.toggleCheck();
2664 this.strokeService.startX = Presentation.dragStartX;
2665 this.strokeService.startY = Presentation.dragStartY;
2666
2667 this.autoStart = true;
2668 }
2669 break;
2670
2671 case 'PresentationRedraw':
2672 if (this.autoStart && this.check.checked) {
2673 this.autoStart = false;
2674 this.toggleCheck();
2675 }
2676 break;
2677
2678 case 'dblclick':
2679 if (this.canvas)
2680 this.end();
2681 break;
2682 }
2683 },
2684
2685 toggleCheck : function()
2686 {
2687 var enable = !this.check.checked;
2688 this.toggle(enable);
2689 this.check.checked = enable;
2690
2691 this.autoStart = false;
2692 }
2693
2694 };
2695
2696
2697
2698
2699 function init()
2700 {
2701 window.removeEventListener('load', init, false);
2702
2703 Presentation.init();
2704 StrokablePresentationService.init(Presentation, StrokeService);
2705 }
2706 window.addEventListener('load', init, false);
2707
2708
2709
2710
2711 // http://ecmanaut.blogspot.com/2006/03/e4x-and-dom.html
2712
2713
2714 function importE4XNode( e4x, doc, aDefaultNS )
2715 {
2716 aDefaultNS = aDefaultNS || XHTMLNS;
2717 var root, domTree, importMe;
2718 this.Const = this.Const || { mimeType: 'text/xml' };
2719 this.Static = this.Static || {};
2720 this.Static.parser = this.Static.parser || new DOMParser;
2721 eval('root = <testing xmlns="'+aDefaultNS+'" />;');
2722 root.test = e4x;
2723 domTree = this.Static.parser.parseFromString( root.toXMLString(),
2724 this.Const.mimeType );
2725 importMe = domTree.documentElement.firstChild;
2726 while( importMe && importMe.nodeType != 1 )
2727 importMe = importMe.nextSibling;
2728 if( !doc ) doc = document;
2729 return importMe ? doc.importNode( importMe, true ) : null;
2730 }
2731
2732 function appendE4XTo( e4x, node, doc, aDefaultNS )
2733 {
2734 return node.appendChild( importE4XNode( e4x, (doc || node.ownerDocument), aDefaultNS ) );
2735 }
2736
2737 function setE4XContent( e4x, node, aDefaultNS )
2738 {
2739 while( node.firstChild )
2740 node.removeChild( node.firstChild );
2741 appendE4XTo( e4x, node, aDefaultNS );
2742 }
2743
2744 // importE4XNodeで得たノードツリーを埋め込むと、XULでバインディングが適用されないことがある。
2745 // 遅延処理でこの問題を一部避けることができる(が、これでもまだダメな場合がある。menuとか。)
2746 // とりあえずXULとSVGとXHTMLはいけた。MathMLはダメだった。
2747 function importNodeTreeWithDelay(aNode, aParent, aDefaultNS, aFromTimeout)
2748 {
2749 if (aFromTimeout) {
2750 importNodeTreeWithDelayTimers--;
2751 }
2752
2753 var node;
2754 var delay = 1;
2755 switch (aNode.nodeType)
2756 {
2757 case Node.ELEMENT_NODE:
2758 var ns = (aNode.namespaceURI || aDefaultNS);
2759 node = document.createElementNS(ns, aNode.localName);
2760 aParent.appendChild(node);
2761
2762 var attr = aNode.attributes;
2763 for (var i = 0, maxi = attr.length; i < maxi; i++)
2764 node.setAttribute(attr[i].name, attr[i].value);
2765
2766 if (ns == XULNS) delay = 1; else delay = 0;
2767
2768 var children = aNode.childNodes;
2769 for (var i = 0, maxi = children.length; i < maxi; i++)
2770 if (delay) {
2771 importNodeTreeWithDelayTimers++;
2772 window.setTimeout(importNodeTreeWithDelay, delay, children[i], node, aDefaultNS, true);
2773 }
2774 else
2775 importNodeTreeWithDelay(children[i], node, aDefaultNS);
2776 break;
2777
2778 default:
2779 if (
2780 aNode.nodeType == Node.TEXT_NODE &&
2781 /^\s*$/.test(aNode.nodeValue) &&
2782 (aNode.parentNode.namespaceURI || aDefaultNS) != XHTMLNS
2783 )
2784 return;
2785 node = aParent.appendChild(aNode.cloneNode(true));
2786 break;
2787 }
2788
2789 var event = document.createEvent('Events');
2790 event.initEvent('CanvasContentAdded', true, true);
2791 node.dispatchEvent(event);
2792
2793 return node;
2794 }
2795 var importNodeTreeWithDelayTimers = 0;
2796
2797 ]]></script>
2798
2799 </page>

Properties

Name Value
svn:eol-style CRLF

  ViewVC Help
Powered by ViewVC 1.1.26