Move stevan's PPW slides
Shawn M Moore [Sat, 16 May 2009 05:33:18 +0000 (01:33 -0400)]
hosted-presentations/2008/stevan-PPW/._.DS_Store [new file with mode: 0644]
hosted-presentations/2008/stevan-PPW/._moose-manager.xul [new file with mode: 0644]
hosted-presentations/2008/stevan-PPW/._moose.xul [new file with mode: 0644]
hosted-presentations/2008/stevan-PPW/._takahashi.css [new file with mode: 0644]
hosted-presentations/2008/stevan-PPW/._takahashi.js [new file with mode: 0644]
hosted-presentations/2008/stevan-PPW/moose-manager.xul [new file with mode: 0644]
hosted-presentations/2008/stevan-PPW/moose.xul [new file with mode: 0644]
hosted-presentations/2008/stevan-PPW/takahashi.css [new file with mode: 0644]
hosted-presentations/2008/stevan-PPW/takahashi.js [new file with mode: 0644]

diff --git a/hosted-presentations/2008/stevan-PPW/._.DS_Store b/hosted-presentations/2008/stevan-PPW/._.DS_Store
new file mode 100644 (file)
index 0000000..460d887
Binary files /dev/null and b/hosted-presentations/2008/stevan-PPW/._.DS_Store differ
diff --git a/hosted-presentations/2008/stevan-PPW/._moose-manager.xul b/hosted-presentations/2008/stevan-PPW/._moose-manager.xul
new file mode 100644 (file)
index 0000000..d7a8b48
Binary files /dev/null and b/hosted-presentations/2008/stevan-PPW/._moose-manager.xul differ
diff --git a/hosted-presentations/2008/stevan-PPW/._moose.xul b/hosted-presentations/2008/stevan-PPW/._moose.xul
new file mode 100644 (file)
index 0000000..f925402
Binary files /dev/null and b/hosted-presentations/2008/stevan-PPW/._moose.xul differ
diff --git a/hosted-presentations/2008/stevan-PPW/._takahashi.css b/hosted-presentations/2008/stevan-PPW/._takahashi.css
new file mode 100644 (file)
index 0000000..a5e1c31
Binary files /dev/null and b/hosted-presentations/2008/stevan-PPW/._takahashi.css differ
diff --git a/hosted-presentations/2008/stevan-PPW/._takahashi.js b/hosted-presentations/2008/stevan-PPW/._takahashi.js
new file mode 100644 (file)
index 0000000..2431394
Binary files /dev/null and b/hosted-presentations/2008/stevan-PPW/._takahashi.js differ
diff --git a/hosted-presentations/2008/stevan-PPW/moose-manager.xul b/hosted-presentations/2008/stevan-PPW/moose-manager.xul
new file mode 100644 (file)
index 0000000..6f5fc39
--- /dev/null
@@ -0,0 +1,288 @@
+<?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="|&lt;&lt;"
+                               observes="canBack"/>
+                       <toolbarbutton oncommand="Presentation.back()" label="&lt;"
+                               observes="canBack"/>
+                       <toolbarbutton oncommand="Presentation.forward()" label="&gt;"
+                               observes="canForward"/>
+                       <toolbarbutton oncommand="Presentation.end()" label="&gt;&gt;|"
+                               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 ***** -->
+
+
diff --git a/hosted-presentations/2008/stevan-PPW/moose.xul b/hosted-presentations/2008/stevan-PPW/moose.xul
new file mode 100644 (file)
index 0000000..b1eb3c1
--- /dev/null
@@ -0,0 +1,533 @@
+<?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="|&lt;&lt;"
+                               observes="canBack"/>
+                       <toolbarbutton oncommand="Presentation.back()" label="&lt;"
+                               observes="canBack"/>
+                       <toolbarbutton oncommand="Presentation.forward()" label="&gt;"
+                               observes="canForward"/>
+                       <toolbarbutton oncommand="Presentation.end()" label="&gt;&gt;|"
+                               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 ***** -->
+
+
diff --git a/hosted-presentations/2008/stevan-PPW/takahashi.css b/hosted-presentations/2008/stevan-PPW/takahashi.css
new file mode 100644 (file)
index 0000000..591a815
--- /dev/null
@@ -0,0 +1,162 @@
+@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
diff --git a/hosted-presentations/2008/stevan-PPW/takahashi.js b/hosted-presentations/2008/stevan-PPW/takahashi.js
new file mode 100644 (file)
index 0000000..c5d6933
--- /dev/null
@@ -0,0 +1,503 @@
+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);