--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="chrome://global/skin/" type="text/css"?><?xml-stylesheet href="takahashi.css" type="text/css"?><page xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" id="presentation" xmlns:html="http:/www.w3.org/1999/xhtml" orient="vertical" onkeypress="Presentation.onKeyPress(event);">
+<html:textarea id="builtinCode" style="visibility: collapse"><![CDATA[
+The Case for
+Switching
+to Python
+----
+or
+----
+A Manager's
+Guide
+to Moose
+----
+Python is
+----
+Simple
+----
+Clean
+----
+Object
+Oriented
+----
+Easy to
+Learn
+----
+Easy to
+Maintain
+----
+Executable
+Pseudo-Code
+----
+Batteries
+Included
+----
+General
+Purpose
+----
+"Keep It Simple Stupid"
+----
+〠
+----
+Perl is
+----
+Large
+----
+Ugly
+----
+Not
+Object
+Oriented
+----
+Impossible to
+Write Good Code
+----
+Executable
+Line-Noise
+----
+CPAN is full of
+redundant crap
+----
+TIMTOWTDI
+----
+☠
+----
+Moose
+----
+Postmodern
+Object System
+for Perl 5
+----
+TIMTOWTDI-BCINABT
+----
+There Is More Than
+One Way To Do It
+----
+But Consistency Is
+Not A Bad Thing
+----
+TIMTOWTDOOP
+----
+blessed-Hash blessed-Array
+Inside-Out blessed-Scalar
+XS blessed-TypeGlob
+blessed-Regexp Closures
+Tied-Objects AUTOLOAD ...
+----
+TIMTOWTWOOP
+----
+Class::Accessor Class::MakeMethods base.pm Spiffy
+Class::HPLOO Class::Base Object::Tiny Object::Lexical
+EO Class::Accessor::Fast Class::Closure Class::Meta
+Class::Simple Class::Gomor Rose::Object Class::Builder
+Class::InsideOut Object::LocalVars Oak::Object OOP
+Object::InsideOut Class::Dot Class::NamedParms Myco
+Class::Structured Class::Classless parent.pm Eobj
+Class::Prototyped Class::Init Class::Maker Class::Object
+Fukurama::Class Class::Declare Class::Std Object::Declare
+Class::Struct Class::AutoClass Class::Root Badger Oryx
+Object::Prototype Basset Object::Accessor Class::Lego
+Class::Container Tangram OO::Closures Class::Trait MOP
+Object::MultiType SLOOPS Class::TOM Class::PObject
+Moose
+... and many more
+----
+Choices
+----
+☺
+----
+Too Many
+Choices
+----
+☹
+----
+Consistency
+breeds
+Maintainability
+----
+...
+----
+Moose is built
+for extensibility
+----
+Moose plays
+well with CPAN
+----
+Mooseification
+is incremental
+----
+Moose is a
+bridge
+to Perl 6
+----
+Moose means less code
+(less code == less buggs)
+----
+Moose means less tests
+(why test what
+Moose already does)
+----
+Moose is
+a skill
+----
+Thank You
+----
+Questions?
+----
+]]></html:textarea>
+
+<deck flex="1" id="deck">
+
+<vbox flex="1"
+ onmousemove="Presentation.onMouseMoveOnCanvas(event);">
+ <toolbox id="canvasToolbar">
+ <toolbar>
+ <toolbarbutton oncommand="Presentation.home()" label="|<<"
+ observes="canBack"/>
+ <toolbarbutton oncommand="Presentation.back()" label="<"
+ observes="canBack"/>
+ <toolbarbutton oncommand="Presentation.forward()" label=">"
+ observes="canForward"/>
+ <toolbarbutton oncommand="Presentation.end()" label=">>|"
+ observes="canForward"/>
+ <toolbarseparator/>
+ <hbox align="center">
+ <textbox id="current_page" size="4"
+ oninput="if (this.value) Presentation.showPage(parseInt(this.value)-1);"/>
+ <description value="/"/>
+ <description id="max_page"/>
+ </hbox>
+ <toolbarseparator/>
+ <vbox flex="2">
+ <spacer flex="1"/>
+ <scrollbar id="scroller"
+ align="center" orient="horizontal"
+ oncommand="Presentation.showPage(parseInt(event.target.getAttribute('curpos')));"
+ onclick="Presentation.showPage(parseInt(event.target.getAttribute('curpos')));"
+ onmousedown="Presentation.onScrollerDragStart();"
+ onmousemove="Presentation.onScrollerDragMove();"
+ onmouseup="Presentation.onScrollerDragDrop();"/>
+ <spacer flex="1"/>
+ </vbox>
+ <toolbarseparator/>
+ <spacer flex="1"/>
+ <toolbarseparator/>
+ <toolbarbutton id="toggleEva" label="Eva"
+ type="checkbox"
+ autoCheck="false"
+ oncommand="Presentation.toggleEvaMode();"/>
+ <toolbarseparator/>
+ <toolbarbutton label="Edit"
+ oncommand="Presentation.toggleEditMode();"/>
+ <toolbarbutton oncommand="Presentation.reload();" label="Reload"/>
+ </toolbar>
+ </toolbox>
+ <vbox flex="1" id="canvas"
+ onclick="Presentation.onPresentationClick(event);">
+ <spacer flex="1"/>
+ <hbox flex="1">
+ <spacer flex="1"/>
+ <vbox id="content"/>
+ <spacer flex="1"/>
+ </hbox>
+ <spacer flex="1"/>
+ </vbox>
+</vbox>
+
+
+<vbox flex="1" id="edit">
+ <toolbox>
+ <toolbar>
+ <toolbarbutton label="New Page"
+ oncommand="Presentation.addPage()"/>
+ <spacer flex="1"/>
+ <toolbarseparator/>
+ <toolbarbutton label="View"
+ oncommand="Presentation.toggleEditMode();"/>
+ <toolbarbutton oncommand="Presentation.reload();" label="Reload"/>
+ </toolbar>
+ </toolbox>
+ <textbox id="textField" flex="1" multiline="true"
+ oninput="Presentation.onEdit()"/>
+ <hbox collapsed="true">
+ <iframe id="dataLoader" onload="if (window.Presentation) Presentation.onDataLoad();"/>
+ </hbox>
+</vbox>
+
+</deck>
+
+
+<broadcasterset>
+ <broadcaster id="canBack"/>
+ <broadcaster id="canForward"/>
+</broadcasterset>
+
+<commandset>
+ <command id="cmd_forward"
+ oncommand="if (Presentation.isPresentationMode) Presentation.forward();"/>
+ <command id="cmd_back"
+ oncommand="if (Presentation.isPresentationMode) Presentation.back();"/>
+ <command id="cmd_home"
+ oncommand="if (Presentation.isPresentationMode) Presentation.home();"/>
+ <command id="cmd_end"
+ oncommand="if (Presentation.isPresentationMode) Presentation.end();"/>
+</commandset>
+<keyset>
+ <key keycode="VK_ENTER" command="cmd_forward"/>
+ <key keycode="VK_RETURN" command="cmd_forward"/>
+ <key keycode="VK_PAGE_DOWN" command="cmd_forward"/>
+ <key keycode="VK_RIGHT" command="cmd_forward"/>
+ <key keycode="VK_DOWN" command="cmd_forward"/>
+ <!-- key keycode="VK_BACK_SPACE" command="cmd_back"/-->
+ <key keycode="VK_PAGE_UP" command="cmd_back"/>
+ <!-- <key keycode="VK_BACK_UP" command="cmd_back"/>-->
+ <!-- <key keycode="VK_BACK_LEFT" command="cmd_back"/>-->
+ <key keycode="VK_HOME" command="cmd_home"/>
+ <key keycode="VK_END" command="cmd_end"/>
+ <key key="n" modifiers="accel" oncommand="Presentation.addPage();"/>
+ <key key="r" modifiers="accel" oncommand="window.location.reload();"/>
+ <key key="e" modifiers="accel" oncommand="Presentation.toggleEditMode();"/>
+ <key key="a" modifiers="accel" oncommand="Presentation.toggleEvaMode();"/>
+</keyset>
+
+
+<script src="takahashi.js" type="application/x-javascript" />
+</page>
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is the Takahashi-Method-based Presentation Tool in XUL.
+ -
+ - The Initial Developer of the Original Code is SHIMODA Hiroshi.
+ - Portions created by the Initial Developer are Copyright (C) 2005
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): SHIMODA Hiroshi <piro@p.club.ne.jp>
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="chrome://global/skin/" type="text/css"?><?xml-stylesheet href="takahashi.css" type="text/css"?><page xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" id="presentation" xmlns:html="http:/www.w3.org/1999/xhtml" orient="vertical" onkeypress="Presentation.onKeyPress(event);">
+<html:textarea id="builtinCode" style="visibility: collapse"><![CDATA[
+Moose
+----
+A Postmodern
+Object System
+for Perl 5
+----
+Stevan Little
+stevan@cpan.org
+http://moose.perl.org/
+----
+What is
+Moose?
+----
+What is
+Class::MOP?
+----
+What is
+a MOP??
+----
+Meta
+Object
+Protocol
+----
+CLOS
+----
+20 year old
+LISP
+technology
+----
+Formalization
+of the
+object system
+----
+How
+classes
+work
+----
+How
+methods
+work
+----
+How objects
+are created
+... etc.
+----
+Class::MOP
+is CLOS for
+Perl 5
+----
+Class::MOP
+is a
+formalization
+of Perl 5 OO
+----
+Clarity &
+Structure
+----
+Class::MOP is
+a platform for
+----
+Moose
+----
+ package Person;
+ use Moose;
+
+ has name => (is => 'rw');
+ has age => (is => 'rw');
+
+ 1;
+----
+turns on
+strict &
+warnings
+----
+Moose::Object
+in the @ISA
+----
+`has` creates
+accessor
+called 'name'
+----
+`has` creates
+accessor
+called 'age'
+----
+*lots*
+of class
+metadata
+----
+ package Person;
+ use Moose;
+
+ has name => (is => 'rw');
+ has age => (is => 'rw');
+
+ 1;
+----
+Types
+----
+ has name => (
+ is => 'rw',
+ isa => 'Str',
+ required => 1
+ );
+----
+ has age => (
+ is => 'rw',
+ isa => 'DateTime::Duration',
+ lazy => 1,
+ default => sub {
+ DateTime::Duration->new
+ }
+ );
+----
+Custom
+Types
+----
+ use Moose::Util::TypeConstraints;
+----
+ subtype 'NonEmptyStr'
+ => as 'Str'
+ => where { length $_ > 0 };
+----
+ has name => (
+ is => 'rw',
+ isa => 'NonEmptyStr',
+ required => 1
+ );
+----
+ my $me = Person->new(
+ name => 'Stevan',
+ age => DateTime::Duration->new(
+ years => 35
+ )
+ );
+----
+ my $me = Person->new; # BOOM! name is required
+----
+ my $me = Person->new(
+ name => 'Stevan',
+ age => 35
+ ); # BOOM! age should be DateTime::Duration
+----
+Coercions
+----
+ class_type 'DateTime::Duration';
+ coerce 'DateTime::Duration'
+ => from 'Int'
+ => via {
+ DateTime::Duration->new(
+ years => $_
+ )
+ };
+----
+ has age => (
+ is => 'rw',
+ isa => 'DateTime::Duration',
+ coerce => 1,
+ lazy => 1,
+ default => sub {
+ DateTime::Duration->new
+ }
+ );
+----
+ my $me = Person->new(
+ name => 'Stevan',
+ age => 35
+ );
+----
+ coerce 'DateTime::Duration'
+ => from 'Int'
+ => via {
+ DateTime::Duration->new(
+ years => $_
+ )
+ }
+ => from 'HashRef'
+ => via {
+ DateTime::Duration->new(%$_)
+ };
+----
+ my $me = Person->new(
+ name => 'Stevan',
+ age => { years => 35, months => 2 }
+ );
+----
+ my $me = Person->new(
+ name => 'Stevan',
+ age => { years => 35, months => 2 }
+ );
+
+ $me->name # 'Stevan'
+ $me->age # DateTime::Duration object
+----
+ my $xoe = Person->new(name => 'Xoe');
+
+ $xoe->age(11);
+
+ $xoe->age({ years => 11, months => 10 });
+
+ $xoe->age(DateTime::Duration->new({
+ years => 11,
+ months => 10
+ }));
+----
+Delegation
+----
+ has age => (
+ is => 'rw',
+ isa => 'DateTime::Duration',
+ coerce => 1,
+ lazy => 1,
+ default => sub {
+ DateTime::Duration->new
+ },
+ handles => {
+ 'years_old' => 'years'
+ }
+ );
+----
+ $me->years_old # 35
+----
+Unconventional
+Delegation
+----
+ package Conference;
+ use Moose;
+ use MooseX::AttributeHelpers;
+
+ has attendees => (
+ metaclass => 'Collection::Array',
+ is => 'rw',
+ isa => 'ArrayRef[Person]',
+ provides => {
+ push => 'add_attendee',
+ count => 'number_of_attendees',
+ },
+ );
+----
+ my $ppw = Conference->new(
+ attendees => [ $me, @all_you_guys ]
+ );
+
+ $ppw->number_of_attendees; # lots of people
+ $ppw->add_attendee($some_slacker); # add a late comer
+----
+Method Modifiers
+----
+ before 'add_attendee' => sub {
+ my ($self, $attendee) = @_;
+ $self->setup_more_chairs(1);
+ };
+----
+ after 'add_attendee' => sub {
+ my ($self, $attendee) = @_;
+ $self->log("Attendee " . $attendee->name . " added");
+ };
+----
+ around 'add_attendee' => sub {
+ my ($next, $self, @args) = @_;
+ ...
+ my @return = $self->$next(@args);
+ ...
+ return @return;
+ };
+----
+Roles
+----
+≠
+----
+Classes
+----
+Roles
+do /not/
+inherit.
+----
+Inheritance is
+↕
+vertical reuse.
+----
+Roles
+compose.
+----
+Composition is
+↔
+horizontal reuse.
+----
+...
+----
+When
+to use
+Roles
+----
+My general rule
+of thumb is ...
+----
+s/MI/Roles/g
+----
+When
+to /not/ use
+Roles
+----
+When a class
+just makes
+more sense.
+----
+Roles are /not/ a
+replacement for
+inheritance.
+----
+How Roles
+Work
+----
+Roles are
+orphans.
+----
+Roles are
+composed.
+----
+Local class
+overrides role.
+----
+Role overrides
+inherited class.
+----
+Roles can
+conflict.
+----
+Method conflicts
+must be
+disambiguated.
+----
+Attribute conflicts
+cannot be
+disambiguated.
+----
+ package Age;
+ use Moose::Role;
+
+ # ... all that type stuff
+
+ has age => (
+ is => 'rw',
+ isa => 'DateTime::Duration',
+ coerce => 1,
+ lazy => 1,
+ default => sub {
+ DateTime::Duration->new
+ },
+ handles => {
+ 'years_old' => 'years'
+ }
+ );
+
+ 1;
+----
+ package Person;
+ use Moose;
+
+ with 'Age';
+
+ # ...
+----
+Conclusion
+----
+Moose code is shorter
+----
+less code == less bugs
+----
+Less testing
+needed
+----
+Moose/Class::MOP
+have +5400
+tests and growing
+----
+Why test, when
+Moose already does.
+----
+More Readable
+----
+Declarative code
+Descriptive code
+----
+The End
+----
+Questions?
+----
+]]></html:textarea>
+
+<deck flex="1" id="deck">
+
+<vbox flex="1"
+ onmousemove="Presentation.onMouseMoveOnCanvas(event);">
+ <toolbox id="canvasToolbar">
+ <toolbar>
+ <toolbarbutton oncommand="Presentation.home()" label="|<<"
+ observes="canBack"/>
+ <toolbarbutton oncommand="Presentation.back()" label="<"
+ observes="canBack"/>
+ <toolbarbutton oncommand="Presentation.forward()" label=">"
+ observes="canForward"/>
+ <toolbarbutton oncommand="Presentation.end()" label=">>|"
+ observes="canForward"/>
+ <toolbarseparator/>
+ <hbox align="center">
+ <textbox id="current_page" size="4"
+ oninput="if (this.value) Presentation.showPage(parseInt(this.value)-1);"/>
+ <description value="/"/>
+ <description id="max_page"/>
+ </hbox>
+ <toolbarseparator/>
+ <vbox flex="2">
+ <spacer flex="1"/>
+ <scrollbar id="scroller"
+ align="center" orient="horizontal"
+ oncommand="Presentation.showPage(parseInt(event.target.getAttribute('curpos')));"
+ onclick="Presentation.showPage(parseInt(event.target.getAttribute('curpos')));"
+ onmousedown="Presentation.onScrollerDragStart();"
+ onmousemove="Presentation.onScrollerDragMove();"
+ onmouseup="Presentation.onScrollerDragDrop();"/>
+ <spacer flex="1"/>
+ </vbox>
+ <toolbarseparator/>
+ <spacer flex="1"/>
+ <toolbarseparator/>
+ <toolbarbutton id="toggleEva" label="Eva"
+ type="checkbox"
+ autoCheck="false"
+ oncommand="Presentation.toggleEvaMode();"/>
+ <toolbarseparator/>
+ <toolbarbutton label="Edit"
+ oncommand="Presentation.toggleEditMode();"/>
+ <toolbarbutton oncommand="Presentation.reload();" label="Reload"/>
+ </toolbar>
+ </toolbox>
+ <vbox flex="1" id="canvas"
+ onclick="Presentation.onPresentationClick(event);">
+ <spacer flex="1"/>
+ <hbox flex="1">
+ <spacer flex="1"/>
+ <vbox id="content"/>
+ <spacer flex="1"/>
+ </hbox>
+ <spacer flex="1"/>
+ </vbox>
+</vbox>
+
+
+<vbox flex="1" id="edit">
+ <toolbox>
+ <toolbar>
+ <toolbarbutton label="New Page"
+ oncommand="Presentation.addPage()"/>
+ <spacer flex="1"/>
+ <toolbarseparator/>
+ <toolbarbutton label="View"
+ oncommand="Presentation.toggleEditMode();"/>
+ <toolbarbutton oncommand="Presentation.reload();" label="Reload"/>
+ </toolbar>
+ </toolbox>
+ <textbox id="textField" flex="1" multiline="true"
+ oninput="Presentation.onEdit()"/>
+ <hbox collapsed="true">
+ <iframe id="dataLoader" onload="if (window.Presentation) Presentation.onDataLoad();"/>
+ </hbox>
+</vbox>
+
+</deck>
+
+
+<broadcasterset>
+ <broadcaster id="canBack"/>
+ <broadcaster id="canForward"/>
+</broadcasterset>
+
+<commandset>
+ <command id="cmd_forward"
+ oncommand="if (Presentation.isPresentationMode) Presentation.forward();"/>
+ <command id="cmd_back"
+ oncommand="if (Presentation.isPresentationMode) Presentation.back();"/>
+ <command id="cmd_home"
+ oncommand="if (Presentation.isPresentationMode) Presentation.home();"/>
+ <command id="cmd_end"
+ oncommand="if (Presentation.isPresentationMode) Presentation.end();"/>
+</commandset>
+<keyset>
+ <key keycode="VK_ENTER" command="cmd_forward"/>
+ <key keycode="VK_RETURN" command="cmd_forward"/>
+ <key keycode="VK_PAGE_DOWN" command="cmd_forward"/>
+ <key keycode="VK_RIGHT" command="cmd_forward"/>
+ <key keycode="VK_DOWN" command="cmd_forward"/>
+ <!-- key keycode="VK_BACK_SPACE" command="cmd_back"/-->
+ <key keycode="VK_PAGE_UP" command="cmd_back"/>
+ <!-- <key keycode="VK_BACK_UP" command="cmd_back"/>-->
+ <!-- <key keycode="VK_BACK_LEFT" command="cmd_back"/>-->
+ <key keycode="VK_HOME" command="cmd_home"/>
+ <key keycode="VK_END" command="cmd_end"/>
+ <key key="n" modifiers="accel" oncommand="Presentation.addPage();"/>
+ <key key="r" modifiers="accel" oncommand="window.location.reload();"/>
+ <key key="e" modifiers="accel" oncommand="Presentation.toggleEditMode();"/>
+ <key key="a" modifiers="accel" oncommand="Presentation.toggleEvaMode();"/>
+</keyset>
+
+
+<script src="takahashi.js" type="application/x-javascript" />
+</page>
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is the Takahashi-Method-based Presentation Tool in XUL.
+ -
+ - The Initial Developer of the Original Code is SHIMODA Hiroshi.
+ - Portions created by the Initial Developer are Copyright (C) 2005
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): SHIMODA Hiroshi <piro@p.club.ne.jp>
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+
--- /dev/null
+@charset "UTF-8";
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Takahashi-Method-based Presentation Tool in XUL.
+ *
+ * The Initial Developer of the Original Code is SHIMODA Hiroshi.
+ * Portions created by the Initial Developer are Copyright (C) 2005
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): SHIMODA Hiroshi <piro@p.club.ne.jp>
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#canvas {
+ background: black !important;
+ color: white !important;
+ /* font-weight: bold; */
+ font-family:
+ "Georgia"
+ "DejaVu Serif Condensed"
+ "Arial"
+ "Bitstream Vera Sans"
+ "Verdana"
+ "Apple LiGothic"
+ "Arial Black"
+ "Bitstream Vera Sans"
+ sans-serif !important;
+}
+#canvas * {
+ cursor: pointer !important;
+}
+#canvas image {
+ width: auto;
+ height: auto;
+}
+.link-text {
+ color: #99CCFF !important;
+ text-decoration: none !important;
+}
+.link-text:hover {
+ color: #CCEEFF !important;
+/* border-bottom: dotted 1px; */
+}
+.link-text:active {
+ color: white !important;
+}
+.s {
+ text-decoration: line-through;
+}
+.iu {
+ text-decoration: underline;
+ font-style: italic;
+}
+.ui {
+/* text-decoration: underline; */
+ font-style: italic;
+}
+.u {
+ text-decoration: underline;
+}
+.i {
+ font-style: italic;
+ font-family: "Times New Roman"
+ "Bitstream Vera Serif"
+ serif;
+}
+.c {
+ font-family:
+ "Monaco"
+ "Andale Mono"
+ "Bitstream Vera Sans Mono"
+ monospace;
+}
+.t {
+ font-style: italic;
+}
+.tag {
+ color: #33ff33;
+}
+.att {
+ color: #9999cc;
+}
+.key {
+ color: #00ffff;
+}
+.hid {
+ color: #999999;
+}
+.hidt {
+ color: #999999;
+ font-style: italic;
+}
+.pre {
+ font-family: "Monaco"
+ "Lucida Console"
+ "Andale Mono"
+ "Bitstream Vera Sans Mono"
+ monospace;
+ padding-bottom: 8px;
+}
+#canvas[rendering="true"] image {
+ display: none;
+}
+#canvas[rendering="true"] *,
+#canvas[rendering="true"] .text-link {
+ color: white !important;
+}
+
+
+tabbox, tabpanels, tabpanel {
+ margin: 0;
+ padding: 0;
+}
+
+
+
+
+#canvas[eva="true"] {
+ background: white !important;
+ color: black !important;
+ font-family:
+ "Georgia"
+ "DejaVu Serif Condensed"
+ "Apple LiGothic"
+ "Arial Black"
+ serif !important;
+}
+#canvas[eva="true"] .link-text {
+ color: red !important;
+ text-decoration: none !important;
+}
+#canvas[eva="true"] .link-text:hover {
+ color: pink !important;
+}
+#canvas[eva="true"] .link-text:active {
+ color: orange !important;
+}
+#canvas[rendering="true"] *,
+#canvas[rendering="true"] .text-link {
+ color: black !important;
+}
+
+
+
+
+#canvasToolbar {
+ position: relative;
+}
+
+.smallfont { font-size: 20pt; }
\ No newline at end of file
--- /dev/null
+var Presentation = {
+ init : function(option){
+ this.size = 9;
+
+ this._offset = 0;
+ this.canvas = document.getElementById('canvas');
+ this.content = document.getElementById('content');
+ this.textbox = document.getElementById('textField');
+ this.deck = document.getElementById('deck');
+ this.scroller = document.getElementById('scroller');
+
+ this.toolbar = document.getElementById('canvasToolbar');
+ this.toolbarHeight = this.toolbar.boxObject.height;
+ this.isToolbarHidden = true;
+ this.toolbar.setAttribute('style', 'margin-top:'+(0-this.toolbarHeight)+'px;margin-bottom:0px;');
+
+ if(option){
+ for(var i in option){this[i] = option[i]}
+ }
+
+ if (this.readParameter()) {
+ this.takahashi();
+ }
+
+ document.documentElement.focus();
+ },
+
+ takahashi : function(){
+ if (!document.title)
+ document.title = this.data[0].replace(/[\r\n]/g, ' ');
+
+ if(!this.data[this.offset]){
+ this.offset = this.data.length-1;
+ }
+ document.getElementById("current_page").value = this.offset+1;
+ document.getElementById("max_page").value = this.data.length;
+
+ this.scroller.setAttribute('maxpos', this.data.length-1);
+ this.scroller.setAttribute('curpos', this.offset);
+
+ var broadcaster = document.getElementById('canBack');
+ if (!this.offset)
+ broadcaster.setAttribute('disabled', true);
+ else
+ broadcaster.removeAttribute('disabled');
+
+ var broadcaster = document.getElementById('canForward');
+ if (this.offset == this.data.length-1)
+ broadcaster.setAttribute('disabled', true);
+ else
+ broadcaster.removeAttribute('disabled');
+
+ this.canvas.setAttribute('rendering', true);
+
+ var text = this.data[this.offset].
+ replace(/^[\r\n]+/g,"").replace(/[\r\n]+$/g,"").replace(/(\r\n|[\r\n])/g,"\n")
+ .split('\n');
+ var range = document.createRange();
+ range.selectNodeContents(this.content);
+ range.deleteContents();
+ range.detach();
+
+ var line;
+ var newLine;
+ var uri;
+ var image_width;
+ var image_total_width = 0;
+ var image_height;
+ var image_total_height = 0;
+ var image_src;
+ var code_listing = 0;
+
+
+ var labelId = 0;
+
+ for (var i = 0; i < text.length; i++)
+ {
+ this.content.appendChild(document.createElement('hbox'));
+ this.content.lastChild.setAttribute('align', 'center');
+ this.content.lastChild.setAttribute('pack', 'center');
+
+ line = text[i];
+ image_width = 0;
+ image_height = 0;
+
+ if (line.match(/^ /)) {
+ code_listing = 1;
+ this.content.lastChild.setAttribute('align', 'left');
+ this.content.lastChild.setAttribute('class', 'pre');
+ line = line.substring(1)
+ }
+
+ while (line.match(/^([^\{]+)?(\{\{ima?ge? +src="([^"]+)" +width="([0-9]+)" +height="([0-9]+)"[^\}]*\}\}|\{\{(([^\|]+)?\||)([^\}]+)\}\})(.+)?/))
+ {
+ if (RegExp.$1) {
+ this.content.lastChild.appendChild(document.createElement('description'));
+ this.content.lastChild.lastChild.setAttribute('value', RegExp.$1);
+ }
+ newLine = line.substring((RegExp.$1+RegExp.$2).length);
+
+ // Images
+ if (/^([^\{]+)?\{\{ima?ge? +src="([^"]+)" +width="([0-9]+)" +height="([0-9]+)"[^\}]*\}\}/.test(line)) {
+ this.content.lastChild.appendChild(document.createElement('image'));
+ image_src = RegExp.$2;
+ if (image_src.indexOf('http://') < 0 &&
+ image_src.indexOf('https://') < 0)
+ image_src = this.dataFolder+image_src;
+ this.content.lastChild.lastChild.setAttribute('src', image_src);
+ this.content.lastChild.lastChild.setAttribute('width', parseInt(RegExp.$3 || '0'));
+ this.content.lastChild.lastChild.setAttribute('height', parseInt(RegExp.$4 || '0'));
+ image_width += parseInt(RegExp.$3 || '0');
+ image_height = Math.max(image_height, parseInt(RegExp.$4 || '0'));
+ }
+
+ // Styles
+ // else if (/^([^\{]+)?\{\{#([^\|]+)\|([^\}]+)\}\}/.test(line)) {
+ else if (/^([^\{]+)?\{\{(#([^\|]+)?\|)([^\}]+)\}\}/.test(line)) {
+ uri = RegExp.$4;
+ this.content.lastChild.appendChild(document.createElement('description'));
+ this.content.lastChild.lastChild.setAttribute('value', uri);
+ this.content.lastChild.lastChild.setAttribute('class', RegExp.$3);
+ }
+
+ // Links
+ else if (/^([^\{]+)?\{\{(([^\|]+)?\||)([^\}]+)\}\}/.test(line)) {
+ uri = RegExp.$4;
+ if (uri.indexOf('://') < 0)
+ uri = this.dataFolder+uri;
+ this.content.lastChild.appendChild(document.createElement('description'));
+ this.content.lastChild.lastChild.setAttribute('value', RegExp.$3 || RegExp.$4);
+ this.content.lastChild.lastChild.setAttribute('href', uri);
+ this.content.lastChild.lastChild.setAttribute('tooltiptext', uri);
+ this.content.lastChild.lastChild.setAttribute('statustext', uri);
+ this.content.lastChild.lastChild.setAttribute('class', 'link-text');
+ }
+
+ line = newLine;
+ }
+
+ if (line) {
+ this.content.lastChild.appendChild(document.createElement('description'));
+ this.content.lastChild.lastChild.setAttribute('value', line);
+ }
+
+ image_total_width = Math.max(image_total_width, image_width);
+ image_total_height += image_height;
+ }
+
+ this.content.setAttribute('style', 'font-size:10px;');
+
+ if (this.content.boxObject.width) {
+ var canvas_w = this.canvas.boxObject.width;
+ var canvas_h = this.canvas.boxObject.height-image_total_height;
+
+ var content_w = this.content.boxObject.width;
+ var new_fs = Math.round((canvas_w/content_w) * this.size);
+
+ new_fs = new_fs - (new_fs % 32);
+ if (code_listing) { new_fs = 48;}
+
+ this.content.setAttribute('style', 'top: 0');
+ this.content.setAttribute('style', 'font-size:'+ new_fs + "px");
+
+ if (this.content.boxObject.width < image_total_width) {
+ content_w = image_total_width;
+ new_fs = Math.round((canvas_w/content_w) * this.size);
+ this.content.setAttribute('style', 'font-size:'+ new_fs + "px");
+ }
+
+ var content_h = this.content.boxObject.height;
+ if(content_h >= canvas_h){
+ content_h = this.content.boxObject.height;
+ new_fs = Math.round((canvas_h/content_h) * new_fs);
+ this.content.setAttribute('style', 'font-size:'+ new_fs + "px");
+ }
+ }
+
+
+
+ this.canvas.removeAttribute('rendering');
+ },
+
+ reload : function() {
+ if (this.dataPath != location.href) {
+ var path = this.dataPath;
+ if (location.href.match(/^https?:/)) {
+ var request = new XMLHttpRequest();
+ request.open('GET', path);
+ request.onload = function() {
+ Presentation.textbox.value = request.responseText;
+ Presentation.data = Presentation.textbox.value.split('----');
+
+ Presentation.takahashi();
+
+ path = null;
+ request = null;
+ };
+ request.send(null);
+ }
+ else {
+ document.getElementById('dataLoader').setAttribute('src', 'about:blank');
+ window.setTimeout(function() {
+ document.getElementById('dataLoader').setAttribute('src', path);
+ path = null;
+ }, 10);
+ }
+ }
+ else
+ window.location.reload();
+ },
+
+ forward : function(){
+ this.offset++;
+ this.takahashi();
+ },
+ back : function(){
+ this.offset--;
+ if(this.offset < 0){this.offset = 0}
+ this.takahashi();
+ },
+ home : function(){
+ this.offset = 0;
+ this.takahashi();
+ },
+ end : function(){
+ this.offset = this.data.length-1;
+ this.takahashi();
+ },
+ showPage : function(aPageOffset){
+ this.offset = aPageOffset ? aPageOffset : 0 ;
+ this.takahashi();
+ },
+
+ addPage : function() {
+ if (this.textbox.value &&
+ !this.textbox.value.match(/(\r\n|[\r\n])$/))
+ this.textbox.value += '\n';
+ this.textbox.value += '----\n';
+ this.onEdit();
+ },
+
+ toggleEditMode : function(){
+ this.deck.selectedIndex = (this.deck.selectedIndex == 0) ? 1 : 0 ;
+ },
+ toggleEvaMode : function(){
+ var check = document.getElementById('toggleEva');
+ if (this.canvas.getAttribute('eva') == 'true') {
+ this.canvas.removeAttribute('eva');
+ check.checked = false;
+ }
+ else {
+ this.canvas.setAttribute('eva', true);
+ check.checked = true;
+ }
+ },
+
+ onPresentationClick : function(aEvent){
+ if (!this.isToolbarHidden)
+ this.showHideToolbar();
+
+ switch(aEvent.button)
+ {
+ case 0:
+ var uri = aEvent.target.getAttribute('href');
+ if (uri)
+ window.open(uri);
+ else {
+ this.forward();
+ document.documentElement.focus();
+ }
+ break;
+ case 2:
+ this.back();
+ document.documentElement.focus();
+ break;
+ default:
+ break;
+ }
+ },
+ onScrollerDragStart : function(){
+ this.scroller.dragging = true;
+ },
+ onScrollerDragMove : function(){
+ if (this.scroller.dragging)
+ this.showPage(parseInt(this.scroller.getAttribute('curpos')));
+ },
+ onScrollerDragDrop : function(){
+ if (this.scroller.dragging) {
+ this.showPage(parseInt(this.scroller.getAttribute('curpos')));
+ }
+ this.scroller.dragging = false;
+ },
+ onEdit : function() {
+ this.data = this.textbox.value.split('----');
+ this.takahashi();
+ },
+
+ onKeyPress : function(aEvent) {
+ switch(aEvent.keyCode)
+ {
+ case aEvent.DOM_VK_BACK_SPACE:
+ if (this.isPresentationMode) {
+ aEvent.preventBubble();
+ aEvent.preventDefault();
+ Presentation.back();
+ }
+ break;
+ default:
+ break;
+ }
+ },
+
+
+ onToolbarArea : false,
+ toolbarHeight : 0,
+ toolbarDelay : 300,
+ toolbarTimer : null,
+ isToolbarHidden : false,
+ onMouseMoveOnCanvas : function(aEvent) {
+ if (this.scroller.dragging) return;
+
+ this.onToolbarArea = (aEvent.clientY < this.toolbarHeight);
+
+ if (this.isToolbarHidden == this.onToolbarArea) {
+ if (this.toolbarTimer) window.clearTimeout(this.toolbarTimer);
+ this.toolbarTimer = window.setTimeout('Presentation.onMouseMoveOnCanvasCallback()', this.toolbarDelay);
+ }
+ },
+ onMouseMoveOnCanvasCallback : function() {
+ if (this.isToolbarHidden == this.onToolbarArea)
+ this.showHideToolbar();
+ },
+
+ toolbarAnimationDelay : 100,
+ toolbarAnimationSteps : 5,
+ toolbarAnimationInfo : null,
+ toolbarAnimationTimer : null,
+ showHideToolbar : function()
+ {
+ if (this.toolbarAnimationTimer) window.clearTimeout(this.toolbarAnimationTimer);
+
+ this.toolbarAnimationInfo = { count : 0 };
+ if (this.isToolbarHidden) {
+ this.toolbarAnimationInfo.start = 0;
+ this.toolbarAnimationInfo.end = this.toolbarHeight;
+ }
+ else {
+ this.toolbarAnimationInfo.start = this.toolbarHeight;
+ this.toolbarAnimationInfo.end = 0;
+ }
+ this.toolbarAnimationInfo.current = 0;
+
+ this.toolbar.setAttribute('style', 'margin-top:'+(0-(this.toolbarHeight-this.toolbarAnimationInfo.start))+'px; margin-bottom:'+(0-this.toolbarAnimationInfo.start)+'px;');
+
+ this.toolbarAnimationTimer = window.setTimeout('Presentation.animateToolbar()', this.toolbarAnimationDelay/this.toolbarAnimationSteps);
+ },
+ animateToolbar : function()
+ {
+ this.toolbarAnimationInfo.current += parseInt(this.toolbarHeight/this.toolbarAnimationSteps);
+
+ var top, bottom;
+ if (this.toolbarAnimationInfo.start < this.toolbarAnimationInfo.end) {
+ top = this.toolbarHeight-this.toolbarAnimationInfo.current;
+ bottom = this.toolbarAnimationInfo.current;
+ }
+ else {
+ top = this.toolbarAnimationInfo.current;
+ bottom = this.toolbarHeight-this.toolbarAnimationInfo.current;
+ }
+
+ top = Math.min(Math.max(top, 0), this.toolbarHeight);
+ bottom = Math.min(Math.max(bottom, 0), this.toolbarHeight);
+
+ this.toolbar.setAttribute('style', 'margin-top:'+(0-top)+'px; margin-bottom:'+(0-bottom)+'px');
+
+ if (this.toolbarAnimationInfo.count < this.toolbarAnimationSteps) {
+ this.toolbarAnimationInfo.count++;
+ this.toolbarAnimationTimer = window.setTimeout('Presentation.animateToolbar()', this.toolbarAnimationDelay/this.toolbarAnimationSteps);
+ }
+ else
+ this.isToolbarHidden = !this.isToolbarHidden;
+ },
+
+
+
+ get offset(){
+ return this._offset;
+ },
+ set offset(aValue){
+ this._offset = parseInt(aValue || 0);
+ document.documentElement.setAttribute('lastoffset', this.offset);
+ return this.offset;
+ },
+
+ get data(){
+ if (!this._data) {
+ // Make sure you break the text into parts smaller than 4096
+ // characters, and name them as indicated. Tweak as required.
+ // (What a hack. A JS programmer should find a better way.)
+ // Luc St-Louis, and email is lucs@pobox.com.
+
+ nodes = document.getElementById('builtinCode').childNodes;
+ content = '';
+ for (i in nodes) {
+ if (nodes[i].nodeValue) {
+ content = content + nodes[i].nodeValue;
+ }
+ }
+
+ this._data = content.split("----");
+ }
+
+ return this._data;
+ },
+ set data(aValue){
+ this._data = aValue;
+ return aValue;
+ },
+
+
+ get isPresentationMode(){
+ return (this.deck.selectedIndex == 0);
+ },
+
+
+ get dataPath(){
+ if (!this._dataPath)
+ this.dataPath = location.href;
+ return this._dataPath;
+ },
+ set dataPath(aValue){
+ var oldDataPath = this._dataPath;
+ this._dataPath = aValue;
+ if (oldDataPath != aValue) {
+ this._dataFolder = this._dataPath.split('?')[0].replace(/[^\/]+$/, '');
+ }
+ return this._dataPath;
+ },
+
+ get dataFolder(){
+ if (!this._dataFolder)
+ this.dataPath = this.dataPath;
+ return this._dataFolder;
+ },
+ set dataFolder(aValue){
+ this._dataFolder = aValue;
+ return this._dataFolder;
+ },
+
+ readParameter : function() {
+ if (location.search) {
+ var param = location.search.replace(/^\?/, '');
+
+ if (param.match(/page=([0-9]+)/i))
+ this.offset = parseInt(RegExp.$1)-1;
+
+ if (param.match(/edit=(1|true|yes)/i))
+ this.toggleEditMode();
+
+ if (param.match(/eva=(1|true|yes)/i))
+ this.toggleEvaMode();
+
+ if (param.match(/data=([^&;]+)/i)) {
+ var path = unescape(RegExp.$1);
+ this.dataPath = path;
+ if (location.href.match(/^https?:/)) {
+ var request = new XMLHttpRequest();
+ request.open('GET', path);
+ request.onload = function() {
+ Presentation.textbox.value = request.responseText;
+ Presentation.data = Presentation.textbox.value.split('----');
+
+ Presentation.takahashi();
+ };
+ request.send(null);
+ }
+ else {
+ document.getElementById('dataLoader').setAttribute('src', path);
+ }
+ return false;
+ }
+ }
+ return true;
+ },
+ onDataLoad : function() {
+ if (!window.frames[0].document.body.hasChildNodes()) return;
+ var data = window.frames[0].document.body.firstChild.innerHTML;
+ if (!data) return;
+
+ this.textbox.value = data;
+ this.data = this.textbox.value.split('----');
+
+ this.takahashi();
+ }
+};
+
+function init()
+{
+ window.removeEventListener('load', init, false);
+
+ Presentation.init();
+}
+window.addEventListener('load', init, false);