/[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

Annotation of /takahashi.xul

Parent Directory Parent Directory | Revision Log Revision Log


Revision 14 - (hide annotations)
Sat Apr 14 12:32:36 2007 UTC (17 years ago) by dpavlin
File size: 81371 byte(s)
update to latest upstream version and migrate my wiki changes and rand= reload
1 dpavlin 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 dpavlin 14 xmlns:html="http://www.w3.org/1999/xhtml"
47 dpavlin 1 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 dpavlin 14 基本的な操作
64     |次のページ|→,↓,Enter,Page Down,左クリック
65     |前のページ|←,↑,Back Space,Page Up,右クリック
66     |最初のページ|Home
67     |最後のページ|End
68     |リロード|Ctrl-R
69     |編集モード|Ctrl-E
70 dpavlin 1 ----
71     ALIGN::center
72     キーボード操作時は
73     次のページへ進む操作で
74 dpavlin 14 [ラベル]をめくれます
75 dpavlin 1 (めくっていない
76 dpavlin 14 [ラベル]がなければ
77 dpavlin 1 そのまま次のページへ)
78     ----
79     一度めくったラベルは
80     状態を保持するので
81     ----
82     ALIGN::right
83     前のページに戻して
84     「奥さん、いいですか!
85     ここですよここ!」
86     ができる
87     ----
88     HEADER::
89     CHAPTER::編集機能
90     編集
91     ----
92     HEADER::編集
93 dpavlin 14 編集モード時の基本操作
94     |新しいページの追加|Ctrl-N
95 dpavlin 1 ----
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 dpavlin 14
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 dpavlin 1 リンク
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 dpavlin 14 |表示ページを指定して起動|?page=[数値]
391     |外部データファイルを使用|?data=[パス]
392     |編集モードで起動|?edit=true
393 dpavlin 1 ----
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 dpavlin 14 <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 dpavlin 1 <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 dpavlin 14 <vbox>
564     <image id="logo"/>
565     <spacer flex="1"/>
566     </vbox>
567 dpavlin 1 </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 dpavlin 14 <key id="key_reload"
696     key="p" modifiers="accel" oncommand="Presentation.print();"/>
697 dpavlin 1
698     <key key="e" modifiers="accel" oncommand="Presentation.toggleEditMode();"/>
699     <key key="e" modifiers="accel,shift" oncommand="Presentation.toggleEvaMode();"/>
700     </keyset>
701    
702    
703 dpavlin 14 <script type="application/x-javascript; e4x=1"><![CDATA[
704 dpavlin 1
705 dpavlin 14 const XULNS = 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul';
706     const XHTMLNS = 'http://www.w3.org/1999/xhtml';
707    
708 dpavlin 1 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 dpavlin 14 imageType : 'jpeg',
727 dpavlin 1
728 dpavlin 14
729 dpavlin 1 initialized : false,
730    
731     preventToShowHideToolbar : false,
732    
733     showMontaKeywordTimeout : 100,
734     autoCruiseInterval : 2000,
735     timerUpdatingInterval : 30000,
736    
737 dpavlin 14 cachedContents : [],
738    
739 dpavlin 1 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 dpavlin 14 this.logo = document.getElementById('logo');
753 dpavlin 1 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 dpavlin 14 window.addEventListener('CanvasContentAdded', this, false);
774 dpavlin 1
775 dpavlin 14 this.canvas.addEventListener('DOMMouseScroll', this, false);
776     this.indicatorBar.addEventListener('DOMMouseScroll', this, false);
777    
778 dpavlin 1 if(option){
779     for(var i in option){this[i] = option[i]}
780     }
781    
782 dpavlin 14 this.cachedContents = [];
783    
784 dpavlin 1 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 dpavlin 14 this.isRendering = true;
801    
802 dpavlin 1 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 dpavlin 14 var page = this.content.getAttribute('page');
842 dpavlin 1 var range = document.createRange();
843     range.selectNodeContents(this.content);
844 dpavlin 14 this.cachedContents[page] = {
845     fragment : range.extractContents(),
846     offsetWidth : parseInt(this.content.getAttribute('offsetWidth')),
847     offsetHeight : parseInt(this.content.getAttribute('offsetHeight'))
848     };
849 dpavlin 1 range.detach();
850    
851 dpavlin 14
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 dpavlin 1 var line;
906     var newLine;
907     var uri;
908     var image_width;
909     var image_height;
910     var image_src;
911    
912 dpavlin 2 var labelId = 0;
913 dpavlin 14 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 dpavlin 1
915 dpavlin 14 var emRegExp = this.makePhraseRegExp('^([^%O]+)?%O%Oem:(.+?)()?%C%C', 'i');
916 dpavlin 1 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 dpavlin 14 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 dpavlin 1 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 dpavlin 7 var wikiRegExp = this.makePhraseRegExp('^([^%O]+)?%O([0-9]*)([#!])?([:\/\*_-])([^%C]+)[:\/\*_-]%C', '');
936 dpavlin 4
937 dpavlin 1 var montaRegExp = this.makePhraseRegExp('^([^%O]+)?%O([^%C]+)%C', '');
938    
939     var inBlock = false,
940     blockClass = '',
941     blockContents = [];
942    
943 dpavlin 14 var inGrid = false,
944     gridContents = null;
945    
946 dpavlin 1 var fragment = document.createDocumentFragment();
947    
948 dpavlin 14 var lineBox;
949 dpavlin 1 for (var i = 0, max = text.length; i < max; i++)
950     {
951 dpavlin 14 lineBox = document.createElement('hbox');
952     lineBox.setAttribute('align', 'center');
953     lineBox.setAttribute('pack', this.data[this.offset].align);
954 dpavlin 1
955     line = text[i];
956     image_width = 0;
957     image_height = 0;
958     if (!line) line = ' ';
959    
960     if (inBlock) {
961 dpavlin 14 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 dpavlin 1 preEndRegExp.test(line)) {
975     inBlock = false;
976     blockContents.push(RegExp.$1);
977     line = line.substring((RegExp.$1+RegExp.$2).length);
978    
979 dpavlin 14 lineBox.appendChild(document.createElement('description'));
980     lineBox.lastChild.setAttribute('class', 'preformatted-text block');
981     lineBox.lastChild.appendChild(document.createTextNode(
982 dpavlin 1 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 dpavlin 14 lineBox.appendChild(document.createElement('vbox'));
1000     lineBox.lastChild.setAttribute('class', blockClass+' block');
1001     lineBox.lastChild.setAttribute('align', this.data[this.offset].align);
1002 dpavlin 1 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 dpavlin 14 lineBox.lastChild.appendChild(document.createElement('description'));
1009     lineBox.lastChild.lastChild.setAttribute('value', blockContents[j]);
1010 dpavlin 1 }
1011    
1012     blockClass = '';
1013     blockContents = [];
1014     }
1015     else {
1016     blockContents.push(line);
1017     continue;
1018     }
1019     }
1020    
1021 dpavlin 14 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 dpavlin 1 while (line.match(lineRegExp))
1064     {
1065     if (RegExp.$1) {
1066 dpavlin 14 lineBox.appendChild(document.createElement('description'));
1067     lineBox.lastChild.setAttribute('value', RegExp.$1);
1068 dpavlin 1 }
1069     newLine = line.substring((RegExp.$1+RegExp.$2).length);
1070    
1071 dpavlin 14 // 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 dpavlin 1 // Preformatted Text
1084     if (preRegExp.test(line)) {
1085 dpavlin 14 lineBox.appendChild(document.createElement('description'));
1086     lineBox.lastChild.setAttribute('value', RegExp.$2);
1087     lineBox.lastChild.setAttribute('class', 'preformatted-text');
1088 dpavlin 1 }
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 dpavlin 14 lineBox.appendChild(document.createElement('description'));
1099     lineBox.lastChild.setAttribute('value', RegExp.$2);
1100     lineBox.lastChild.setAttribute('class', 'em-text');
1101 dpavlin 1 }
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 dpavlin 14 lineBox.appendChild(document.createElement('description'));
1112     lineBox.lastChild.setAttribute('value', RegExp.$3);
1113     lineBox.lastChild.setAttribute('class', RegExp.$2);
1114 dpavlin 1 }
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 dpavlin 14 lineBox.appendChild(document.createElement('image'));
1125 dpavlin 1 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 dpavlin 14 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 dpavlin 1 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 dpavlin 14 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 dpavlin 1
1148 dpavlin 14 this.clickableNodes.push(lineBox.lastChild);
1149 dpavlin 1 }
1150    
1151 dpavlin 4 // modify font size and wiki-style
1152     else if (wikiRegExp.test(line)) {
1153 dpavlin 14 lineBox.appendChild(document.createElement('description'));
1154     lineBox.lastChild.setAttribute('value', RegExp.$5);
1155 dpavlin 4 var style = 'font-size:'+ ( RegExp.$2 || 100 ) +'%';
1156 dpavlin 5 if (RegExp.$4 == '*') {
1157 dpavlin 4 style += '; font-weight: bold;';
1158 dpavlin 5 } else if (RegExp.$4 == '/') {
1159 dpavlin 4 style += '; font-style: italic;';
1160 dpavlin 5 } else if (RegExp.$4 == '_') {
1161 dpavlin 4 style += '; text-decoration: underline;';
1162 dpavlin 7 } else if (RegExp.$4 == '-') {
1163     style += '; text-decoration: line-through;';
1164 dpavlin 4 }
1165 dpavlin 14 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 dpavlin 4 }
1169    
1170 dpavlin 1 // Monta
1171     else if (montaRegExp.test(line)) {
1172 dpavlin 14 lineBox.appendChild(document.createElement('stack'));
1173 dpavlin 1
1174 dpavlin 14 lineBox.lastChild.appendChild(document.createElement('description'));
1175     lineBox.lastChild.lastChild.setAttribute('value', RegExp.$2);
1176     lineBox.lastChild.lastChild.setAttribute('class', 'monta-text');
1177 dpavlin 1
1178 dpavlin 14 lineBox.lastChild.appendChild(document.createElement('spacer'));
1179     lineBox.lastChild.lastChild.setAttribute('flex', 1);
1180     lineBox.lastChild.lastChild.setAttribute('class', 'monta-label');
1181 dpavlin 1
1182 dpavlin 14 lineBox.lastChild.lastChild.setAttribute('label-id', 'label-' + (++labelId));
1183 dpavlin 1
1184 dpavlin 14 lineBox.lastChild.lastChild.setAttribute('monta-hidden', 'true');
1185 dpavlin 1
1186 dpavlin 14 this.clickableNodes.push(lineBox.lastChild.lastChild);
1187 dpavlin 1 }
1188    
1189     line = newLine;
1190     }
1191    
1192     if (line) {
1193 dpavlin 14 lineBox.appendChild(document.createElement('description'));
1194     lineBox.lastChild.setAttribute('value', line);
1195 dpavlin 1 }
1196    
1197 dpavlin 14 retVal.offsetWidth = Math.max(retVal.offsetWidth, image_width);
1198     retVal.offsetHeight += image_height;
1199    
1200     if (lineBox.hasChildNodes())
1201     fragment.appendChild(lineBox);
1202 dpavlin 1 }
1203    
1204 dpavlin 14 retVal.fragment = fragment;
1205     return retVal;
1206     },
1207 dpavlin 1
1208     fitToCanvas : function(aContent, aCanvas, aOffsetWidth, aOffsetHeight)
1209     {
1210     aContent.removeAttribute('style');
1211     aContent.setAttribute('style', 'font-size:10px;');
1212    
1213 dpavlin 14 var grids = aContent.getElementsByTagName('grid');
1214     var gridsCount = grids.length;
1215    
1216 dpavlin 1 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 dpavlin 14 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 dpavlin 1 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 dpavlin 14
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 dpavlin 1 }
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 dpavlin 14
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 dpavlin 1 }
1256     },
1257 dpavlin 14 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 dpavlin 1
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 dpavlin 8 request.open('GET', path + '?rand=' + Math.random() );
1280 dpavlin 1 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 dpavlin 14 if (!this.canForward) return;
1296 dpavlin 1 this.offset++;
1297     this.takahashi();
1298     },
1299     forwardStep : function(){
1300 dpavlin 14 if (!this.canForward) return;
1301     var monta = document.getElementsByAttribute('monta-hidden', 'true');
1302     if (monta && monta.length) {
1303     this.showMontaKeyword(monta[0]);
1304 dpavlin 1 }
1305     else
1306     this.forward();
1307     },
1308     back : function(){
1309 dpavlin 14 if (!this.canBack) return;
1310 dpavlin 1 this.offset--;
1311     if(this.offset < 0){this.offset = 0}
1312     this.takahashi();
1313     },
1314     home : function(){
1315 dpavlin 14 if (!this.canMove) return;
1316 dpavlin 1 this.offset = 0;
1317     this.takahashi();
1318     },
1319     end : function(){
1320 dpavlin 14 if (!this.canMove) return;
1321 dpavlin 1 this.offset = this.data.length-1;
1322     this.takahashi();
1323     },
1324     showPage : function(aPageOffset){
1325 dpavlin 14 if (!this.canMove) return;
1326 dpavlin 1 this.offset = aPageOffset ? aPageOffset : 0 ;
1327     this.takahashi();
1328     },
1329    
1330 dpavlin 14 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 dpavlin 1 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 dpavlin 14 aNode.value = [value.substring(0, pos), aString, value.substring(pos, value.length)].join('');
1390     aNode.selectionEnd = aNode.selectionStart = pos + (aPosOffset || 0);
1391 dpavlin 1 },
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 dpavlin 14 this.logo.removeAttribute('eva');
1409 dpavlin 1 check.checked = false;
1410     }
1411     else {
1412     this.canvas.setAttribute('eva', true);
1413 dpavlin 14 this.logo.setAttribute('eva',true);
1414 dpavlin 1 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 dpavlin 14 if (Presentation.offset == Presentation.data.length-1) {
1452     if (Presentation.canMove)
1453     Presentation.home();
1454 dpavlin 1 }
1455     else {
1456 dpavlin 14 if (Presentation.canForward)
1457     Presentation.forwardStep();
1458 dpavlin 1 }
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 dpavlin 14 showMontaKeyword : function(aNode, aWithoutAnimation) {
1482 dpavlin 1 if (aNode.getAttribute('monta-hidden') != 'true') return;
1483    
1484 dpavlin 14 if (aWithoutAnimation) {
1485     aNode.setAttribute('monta-hidden', 'false');
1486     return;
1487     }
1488    
1489 dpavlin 1 aNode.setAttribute('monta-hidden', 'progress');
1490    
1491 dpavlin 14 this.montaAnimating = true;
1492    
1493 dpavlin 1 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 dpavlin 14 Presentation.montaAnimating = false;
1503 dpavlin 1 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 dpavlin 14 montaAnimating : false,
1511 dpavlin 1
1512    
1513    
1514     onPresentationClick : function(aEvent)
1515     {
1516 dpavlin 14 if (this.isPrinting) {
1517     if (confirm('Do you want printing operation to be stopped?')) {
1518     this.stopPrint();
1519     }
1520     return;
1521     }
1522    
1523 dpavlin 1 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 dpavlin 14 if (this.isPrinting) return;
1563    
1564 dpavlin 1 this.scroller.dragging = true;
1565     },
1566     onScrollerDragMove : function(){
1567 dpavlin 14 if (this.isPrinting) return;
1568    
1569 dpavlin 1 if (this.scroller.dragging)
1570     this.showPage(parseInt(this.scroller.getAttribute('curpos')));
1571     },
1572     onScrollerDragDrop : function(){
1573 dpavlin 14 if (this.isPrinting) return;
1574    
1575 dpavlin 1 this.onScrollerDragMove();
1576     this.scroller.dragging = false;
1577     },
1578    
1579     onIndicatorBarClick : function(aEvent)
1580     {
1581 dpavlin 14 if (this.isPrinting) return;
1582    
1583 dpavlin 1 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 dpavlin 14 if (this.isPrinting) return;
1589    
1590 dpavlin 1 this.indicatorBar.dragging = true;
1591     },
1592     onIndicatorBarDragMove : function(aEvent)
1593     {
1594 dpavlin 14 if (this.isPrinting) return;
1595    
1596 dpavlin 1 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 dpavlin 14 if (this.isPrinting) return;
1602    
1603 dpavlin 1 this.onIndicatorBarDragMove(aEvent);
1604     this.indicatorBar.dragging = false;
1605     },
1606    
1607     onEdit : function() {
1608 dpavlin 14 if (this.isPrinting) return;
1609    
1610 dpavlin 1 this.data = this.textbox.value;
1611     this.init();
1612     },
1613    
1614     onKeyPress : function(aEvent) {
1615 dpavlin 14 if (this.isPrinting) return;
1616    
1617 dpavlin 1 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 dpavlin 14 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 dpavlin 1 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 dpavlin 14 if (inRawContents) return;
1670 dpavlin 1 this.dragStartX = -1;
1671     this.dragStartY = -1;
1672     if (this.indicatorBar.dragging)
1673     this.onIndicatorBarDragEnd(aEvent);
1674     break;
1675    
1676     case 'mousedown':
1677 dpavlin 14 if (inRawContents) return;
1678 dpavlin 1 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 dpavlin 14 if (inRawContents) return;
1692 dpavlin 1 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 dpavlin 14 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 dpavlin 1
1715 dpavlin 14 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 dpavlin 1 }
1733     },
1734     dragStartX : -1,
1735     dragStartY : -1,
1736 dpavlin 14 scrollCounter : 0,
1737     scrollThreshold : 10,
1738 dpavlin 1
1739    
1740    
1741     onToolbarArea : false,
1742     toolbarHeight : 0,
1743     toolbarDelay : 300,
1744     toolbarTimer : null,
1745     isToolbarHidden : false,
1746     checkShowHideToolbar : function(aEvent) {
1747 dpavlin 14 if (!this.scroller || this.scroller.dragging || this.preventToShowHideToolbar) return;
1748 dpavlin 1
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 dpavlin 14 showHideToolbar : function(aWithoutAnimation)
1766 dpavlin 1 {
1767 dpavlin 14 if (this.isPrinting) return;
1768    
1769 dpavlin 1 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 dpavlin 14 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 dpavlin 1 },
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 dpavlin 14 var codes = document.getElementById('builtinCode');
1832 dpavlin 1 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 dpavlin 14 for (var i = 0; i < codes.childNodes.length; i++) {
1837     this.textbox.value += codes.childNodes[i].nodeValue;
1838 dpavlin 1 }
1839    
1840     this._data = this.textbox.value.split(/----+/);
1841     this.initData();
1842     }
1843 dpavlin 14 if (codes)
1844     codes.parentNode.removeChild(codes);
1845 dpavlin 1
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 dpavlin 14 var hiddenRegExp = /^(HIDDEN|IGNORE)::true\n?/im;
1887    
1888     var loadRegExp = /^LOAD::(.+)\n?/im;
1889    
1890 dpavlin 1 var dataObj;
1891     var i, j,
1892     max = this._data.length;
1893     var fragment = document.createDocumentFragment();
1894     var popup;
1895 dpavlin 14 var dataPath;
1896 dpavlin 1 for (i = 0; i < max; i++)
1897     {
1898     image_src = null;
1899     align = null;
1900 dpavlin 14 dataPath = '';
1901 dpavlin 1
1902     this._data[i] = this._data[i]
1903     .replace(regexp[0], '')
1904     .replace(regexp[1], '')
1905     .replace(regexp[2], '\n');
1906    
1907 dpavlin 14 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 dpavlin 1 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 dpavlin 14 load : dataPath,
1966 dpavlin 1 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 dpavlin 14 this.loadData(RegExp.$1);
2101 dpavlin 1 return false;
2102     }
2103     }
2104     return true;
2105     },
2106 dpavlin 14 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 dpavlin 1
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 dpavlin 2 var rest = prompt('Remaining Time (minits)');
2136     if (rest == '') {
2137     this.resetTimer();
2138 dpavlin 1 return;
2139 dpavlin 2 }
2140 dpavlin 1 else {
2141     rest = Number(rest);
2142 dpavlin 2 if (!rest || isNaN(rest)) return;
2143 dpavlin 1 }
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 dpavlin 14 timerTimer : null,
2187 dpavlin 1
2188 dpavlin 14
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 dpavlin 1 };
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 dpavlin 14
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 dpavlin 1 ]]></script>
2798    
2799     </page>

Properties

Name Value
svn:eol-style CRLF

  ViewVC Help
Powered by ViewVC 1.1.26