From: Shawn M Moore <sartak@gmail.com> Date: Sat, 16 May 2009 05:33:18 +0000 (-0400) Subject: Move stevan's PPW slides X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=b98e514844ce4866602e0ef2bbb2bde26b3b7be1;p=gitmo%2Fmoose-website.git Move stevan's PPW slides --- diff --git a/hosted-presentations/2008/stevan-PPW/._.DS_Store b/hosted-presentations/2008/stevan-PPW/._.DS_Store new file mode 100644 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 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 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 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 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 index 0000000..6f5fc39 --- /dev/null +++ b/hosted-presentations/2008/stevan-PPW/moose-manager.xul @@ -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="|<<" + 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 ***** --> + + diff --git a/hosted-presentations/2008/stevan-PPW/moose.xul b/hosted-presentations/2008/stevan-PPW/moose.xul new file mode 100644 index 0000000..b1eb3c1 --- /dev/null +++ b/hosted-presentations/2008/stevan-PPW/moose.xul @@ -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="|<<" + 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 ***** --> + + diff --git a/hosted-presentations/2008/stevan-PPW/takahashi.css b/hosted-presentations/2008/stevan-PPW/takahashi.css new file mode 100644 index 0000000..591a815 --- /dev/null +++ b/hosted-presentations/2008/stevan-PPW/takahashi.css @@ -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 index 0000000..c5d6933 --- /dev/null +++ b/hosted-presentations/2008/stevan-PPW/takahashi.js @@ -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);