+++ /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);">\r
-<html:textarea id="builtinCode" style="visibility: collapse"><![CDATA[\r
-Antiquated
-Perl
-----
-Modern
-Perl?
-----
-Post
-Modern
-Perl
-----
-Enlightened
-Perl
-----
-everybody
-knows
-----
-Catalyst
-Moose
-DBIx::Class
-----
-Modern
-Perl?
-----
-perl5
-v10
-----
- given ($x) {
- when (3) {
- ...
-----
-~~
-----
-what's the
-opposite?
-----
-Old
-Perl?
-----
-if it
-works
-----
-Legacy
-Perl?
-----
-not
-interesting
-----
-Stupid
-Perl
-----
-*$&^*(^
-FormMail.PL
-----
-Antiquated
-Perl
-----
-Antique
-----
-Old *and*
-beautiful
-----
-Simple
-Elegant
-----
- $|++
-----
- use IO::Handle;
- STDOUT->autoflush(1);
-----
-it's core.
-it's fine.
-----
-but why
-think?
-----
- select((select(FOO),$|++)[0])
-----
- (select(FOO),$|++)
- ->
- ($old_selected_fh,$|)
-----
- (select(FOO),$|++)[0]
- ->
- $old_select_fh
-----
- select((select(FOO),$|++)[0])
- ->
- use IO::Handle;
- FOO->autoflush(1)
-----
-~~
-----
- ~~@x
-----
- ~(~(@x))
-----
-bitwise
-negation
-----
-so ...
-----
- ~@x
- ->
- ~(scalar @x)
-----
- ~~$number
- ->
- $number
-----
- ~~@x
- ->
- scalar @x
-----
- perl -MMoose -e'print ~~keys %INC'
- 84
-----
-overload::constant
-----
-lets you
-affect
-parsing
-----
-numbers
-strings
-----
-q qq qr
-t s qw
-----
-i18n.pm
-----
-~~"$foo bar"
-loc("_[0] bar", $foo)
-----
-for
-----
- for ($foo) {
- /bar/ and ...
-----
- for ($foo) {
- /bar/ and return do {
- <code here>
- }
-----
- /foo/gc
-----
- /\Gbar/gc
-----
- sub parse {
- my ($self, $str) = @_;
- for ($str) {
- /match1/gc and return
- $self->_subparse_1($_)
-----
- sub _subparse_1 {
- my ($self) = @_;
- for ($_[1]) {
- /\Gsubmatch1/gc ...
-----
-prototypes
-----
- sub foo (&) {
-----
- foo {
- ...
- };
-----
- prototype \&foo
-----
-typeglobs
-----
- *{"${package}::${name}"}
- = sub { ... }
-----
- local
-----
- local $_
-----
- local *Carp::croak
- = \&Carp::confess;
-----
- do {
- local (@ARGV, $/) = $file;
- <>
- }
-----
-strict
-and
-warnings
-----
- strict->import
-----
-affects
-compilation
-scope
-----
- sub strict_and_warnings::import {
- strict->import;
- warnings->import;
- }
-----
- use strict_and_warnings;
-----
-$^H
-%^H
-----
- $^H |= 0x120000;
- $^H{'foo'}
- = bless($foo, 'My::Foo');
-----
- sub My::Foo::DESTROY {
-----
- delete ${$package}{myimport}
-----
-B::Hooks::EndOfScope
-----
-tie
-----
- tie $var, 'Foo';
-----
- sub FETCH
- sub STORE
-----
-Scalar
-Array
-Hash
-Handle
-----
-now ...
-----
-mst: destruction
-testing technology
-since March 1983
-----
-3 days
-old
-----
-2 weeks
-early
-----
-incubator
-----
-glass box
-plastic tray
-heater
-----
-design
-flaw
-----
-BANG
-----
-so ...
-----
-interesting
-fact
-----
-prototypes
-only warn
-when parsed
-----
-error when
-compiled
-----
-so ...
-----
- dispatch [
- sub (GET + /) { ... },
- sub (GET + /user/*) { ... }
- ];
-----
- foreach my $sub (@$dispatch) {
- my $proto = prototype $sub;
- $parser->parse($proto);
- ...
-----
- PARSE: { do {
- push @match, $self->_parse_spec_section($spec)
- or $self->_blam("Unable to work out what the next section is");
- last PARSE if (pos == length);
- /\G\+/gc or $self->_blam('Spec sections must be separated by +');
- } until (pos == length) };
-----
- sub _blam {
- my ($self, $error) = @_;
- my $hat = (' ' x pos).'^';
- die "Error parsing dispatch specification: ${error}\n
- ${_}
- ${hat} here\n";
- }
-----
- Error parsing ...
- GET+/foo
- ^ here
-----
- sub (GET + /user/*) {
- my ($self, $user) = @_;
-----
-I hate
-fetching
-$self
-----
- *{"${app}::self"}
- = \${"${app}::self"};
-----
-use vars
-----
- sub _run_with_self {
- my ($self, $run, @args) = @_;
- my $class = ref($self);
- no strict 'refs';
- local *{"${class}::self"} = \$self;
- $self->$run(@args);
- }
-----
-HTML
-output
-----
-templates
-----
-HTML is
-NOT TEXT
-----
- <div>,
- $text,
- </div>;
-----
-<div>
-----
-<$fh>
-----
- tie *{"${app}::${name}"},
- 'XML::Tags::TIEHANDLE',
- "<${name}>";
-----
- sub TIEHANDLE { my $str = $_[1]; bless \$str, $_[0] }
- sub READLINE { ${$_[0]} }
-----
- sub DESTROY {
- my ($into, @names) = @$_[0];
- no strict 'refs';
- delete ${$into}{$_}
- for @names;
- }
-----
-</div>
-----
-glob('/div');
-----
- *CORE::GLOBAL::glob
- = sub { ... };
-----
- delete
- ${CORE::GLOBAL::}{glob};
-----
- sub foo {
- use XML::Tags qw(div);
- <div>, "foo!", </div>;
- }
-----
-what about
-interpolation
-----
- my $stuff = 'foo"bar';
- <a href="$stuff">
-----
-hmm ...
-----
-overload::constant!
-----
- glob('a href="'.$stuff.'"');
-----
- glob(
- bless(\'a href="', 'MagicTag')
- .$stuff
- .bless(\'"', 'MagicTag')
- )
-----
- use overload
- '.' => 'concat';
-
- sub concat {
-----
-hooking
-it up
-----
- sub (.html) {
- filter_response {
- $self->render_html($_[1])
- }
- }
-----
- bless(
- $_[1],
- 'Web::Simple::ResponseFilter'
- );
-----
- if ($self->_is_response_filter($result)) {
- return $self->_run_with_self(
- $result,
- $self->_run_dispatch_for($new_env, \@disp)
- );
- }
-----
-and the result?
-----
- goto &demo;
-----
-questions?
-----
-thank
-you
-]]></html:textarea>\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-<deck flex="1" id="deck">\r
-\r
-<vbox flex="1"\r
- onmousemove="Presentation.onMouseMoveOnCanvas(event);">\r
- <toolbox id="canvasToolbar">\r
- <toolbar>\r
- <toolbarbutton oncommand="Presentation.home()" label="|<<"\r
- observes="canBack"/>\r
- <toolbarbutton oncommand="Presentation.back()" label="<"\r
- observes="canBack"/>\r
- <toolbarbutton oncommand="Presentation.forward()" label=">"\r
- observes="canForward"/>\r
- <toolbarbutton oncommand="Presentation.end()" label=">>|"\r
- observes="canForward"/>\r
- <toolbarseparator/>\r
- <hbox align="center">\r
- <textbox id="current_page" size="4"\r
- oninput="if (this.value) Presentation.showPage(parseInt(this.value)-1);"/>\r
- <description value="/"/>\r
- <description id="max_page"/>\r
- </hbox>\r
- <toolbarseparator/>\r
- <vbox flex="2">\r
- <spacer flex="1"/>\r
- <scrollbar id="scroller"\r
- align="center" orient="horizontal"\r
- oncommand="Presentation.showPage(parseInt(event.target.getAttribute('curpos')));"\r
- onclick="Presentation.showPage(parseInt(event.target.getAttribute('curpos')));"\r
- onmousedown="Presentation.onScrollerDragStart();"\r
- onmousemove="Presentation.onScrollerDragMove();"\r
- onmouseup="Presentation.onScrollerDragDrop();"/>\r
- <spacer flex="1"/>\r
- </vbox>\r
- <toolbarseparator/>\r
- <spacer flex="1"/>\r
- <toolbarseparator/>\r
- <toolbarbutton id="toggleEva" label="Eva"\r
- type="checkbox"\r
- autoCheck="false"\r
- oncommand="Presentation.toggleEvaMode();"/>\r
- <toolbarseparator/>\r
- <toolbarbutton label="Edit"\r
- oncommand="Presentation.toggleEditMode();"/>\r
- <toolbarbutton oncommand="Presentation.reload();" label="Reload"/>\r
- </toolbar>\r
- </toolbox>\r
- <vbox flex="1" id="canvas"\r
- onclick="Presentation.onPresentationClick(event);">\r
- <spacer flex="1"/>\r
- <hbox flex="1">\r
- <spacer flex="1"/>\r
- <vbox id="content"/>\r
- <spacer flex="1"/>\r
- </hbox>\r
- <spacer flex="1"/>\r
- </vbox>\r
-</vbox>\r
-\r
-\r
-<vbox flex="1" id="edit">\r
- <toolbox>\r
- <toolbar>\r
- <toolbarbutton label="New Page"\r
- oncommand="Presentation.addPage()"/>\r
- <spacer flex="1"/>\r
- <toolbarseparator/>\r
- <toolbarbutton label="View"\r
- oncommand="Presentation.toggleEditMode();"/>\r
- <toolbarbutton oncommand="Presentation.reload();" label="Reload"/>\r
- </toolbar>\r
- </toolbox>\r
- <textbox id="textField" flex="1" multiline="true"\r
- oninput="Presentation.onEdit()"/>\r
- <hbox collapsed="true">\r
- <iframe id="dataLoader" onload="if (window.Presentation) Presentation.onDataLoad();"/>\r
- </hbox>\r
-</vbox>\r
-\r
-</deck>\r
-\r
-\r
-<broadcasterset>\r
- <broadcaster id="canBack"/>\r
- <broadcaster id="canForward"/>\r
-</broadcasterset>\r
-\r
-<commandset>\r
- <command id="cmd_forward"\r
- oncommand="if (Presentation.isPresentationMode) Presentation.forward();"/>\r
- <command id="cmd_back"\r
- oncommand="if (Presentation.isPresentationMode) Presentation.back();"/>\r
- <command id="cmd_home"\r
- oncommand="if (Presentation.isPresentationMode) Presentation.home();"/>\r
- <command id="cmd_end"\r
- oncommand="if (Presentation.isPresentationMode) Presentation.end();"/>\r
-</commandset>\r
-<keyset>\r
- <key keycode="VK_ENTER" command="cmd_forward"/>\r
- <key keycode="VK_RETURN" command="cmd_forward"/>\r
- <key keycode="VK_PAGE_DOWN" command="cmd_forward"/>\r
- <key keycode="VK_RIGHT" command="cmd_forward"/>\r
- <key keycode="VK_DOWN" command="cmd_forward"/>\r
- <!-- key keycode="VK_BACK_SPACE" command="cmd_back"/-->\r
- <key keycode="VK_PAGE_UP" command="cmd_back"/>\r
- <!-- <key keycode="VK_BACK_UP" command="cmd_back"/>-->\r
- <!-- <key keycode="VK_BACK_LEFT" command="cmd_back"/>-->\r
- <key keycode="VK_HOME" command="cmd_home"/>\r
- <key keycode="VK_END" command="cmd_end"/>\r
- <key key="n" modifiers="accel" oncommand="Presentation.addPage();"/>\r
- <key key="r" modifiers="accel" oncommand="window.location.reload();"/>\r
- <key key="e" modifiers="accel" oncommand="Presentation.toggleEditMode();"/>\r
- <key key="a" modifiers="accel" oncommand="Presentation.toggleEvaMode();"/>\r
-</keyset>\r
-\r
-\r
-<script src="takahashi.js" type="application/x-javascript" />\r
-</page>\r
-<!-- ***** BEGIN LICENSE BLOCK *****\r
- - Version: MPL 1.1\r
- -\r
- - The contents of this file are subject to the Mozilla Public License Version\r
- - 1.1 (the "License"); you may not use this file except in compliance with\r
- - the License. You may obtain a copy of the License at\r
- - http://www.mozilla.org/MPL/\r
- -\r
- - Software distributed under the License is distributed on an "AS IS" basis,\r
- - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\r
- - for the specific language governing rights and limitations under the\r
- - License.\r
- -\r
- - The Original Code is the Takahashi-Method-based Presentation Tool in XUL.\r
- -\r
- - The Initial Developer of the Original Code is SHIMODA Hiroshi.\r
- - Portions created by the Initial Developer are Copyright (C) 2005\r
- - the Initial Developer. All Rights Reserved.\r
- -\r
- - Contributor(s): SHIMODA Hiroshi <piro@p.club.ne.jp>\r
- -\r
- - ***** END LICENSE BLOCK ***** -->\r
-\r
-\r
+++ /dev/null
-@charset "UTF-8";\r
-\r
-/* ***** BEGIN LICENSE BLOCK *****\r
- * Version: MPL 1.1\r
- *\r
- * The contents of this file are subject to the Mozilla Public License Version\r
- * 1.1 (the "License"); you may not use this file except in compliance with\r
- * the License. You may obtain a copy of the License at\r
- * http://www.mozilla.org/MPL/\r
- *\r
- * Software distributed under the License is distributed on an "AS IS" basis,\r
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\r
- * for the specific language governing rights and limitations under the\r
- * License.\r
- *\r
- * The Original Code is the Takahashi-Method-based Presentation Tool in XUL.\r
- *\r
- * The Initial Developer of the Original Code is SHIMODA Hiroshi.\r
- * Portions created by the Initial Developer are Copyright (C) 2005\r
- * the Initial Developer. All Rights Reserved.\r
- *\r
- * Contributor(s): SHIMODA Hiroshi <piro@p.club.ne.jp>\r
- *\r
- * ***** END LICENSE BLOCK ***** */\r
-\r
-#canvas {\r
- background: black !important;\r
- color: white !important;\r
- /* font-weight: bold; */\r
- font-family:\r
- "Georgia"\r
- "DejaVu Serif Condensed"\r
- "Arial"\r
- "Bitstream Vera Sans"\r
- "Verdana"\r
- "Apple LiGothic"\r
- "Arial Black"\r
- "Bitstream Vera Sans"\r
- sans-serif !important;\r
-}\r
-#canvas * {\r
- cursor: pointer !important;\r
-}\r
-#canvas image {\r
- width: auto;\r
- height: auto;\r
-}\r
-.link-text {\r
- color: #99CCFF !important;\r
- text-decoration: none !important;\r
-}\r
-.link-text:hover {\r
- color: #CCEEFF !important;\r
-/* border-bottom: dotted 1px; */\r
-}\r
-.link-text:active {\r
- color: white !important;\r
-}\r
-.s {\r
- text-decoration: line-through;\r
-}\r
-.iu {\r
- text-decoration: underline;\r
- font-style: italic;\r
-}\r
-.ui {\r
-/* text-decoration: underline; */\r
- font-style: italic;\r
-}\r
-.u {\r
- text-decoration: underline;\r
-}\r
-.i {\r
- font-style: italic;\r
- font-family: "Times New Roman"\r
- "Bitstream Vera Serif"\r
- serif;\r
-}\r
-.c {\r
- font-family: "Anonymous"\r
- "Lucida Console"\r
- "Andale Mono"\r
- "Bitstream Vera Sans Mono"\r
- monospace;\r
-}\r
-.t {\r
- font-style: italic;\r
-}\r
-.tag {\r
- color: #33ff33;\r
-}\r
-.att {\r
- color: #9999cc;\r
-}\r
-.key {\r
- color: #00ffff;\r
-}\r
-.hid {\r
- color: #999999;\r
-}\r
-.hidt {\r
- color: #999999;\r
- font-style: italic;\r
-}\r
-.pre {\r
- font-family: "Anonymous"\r
- "Lucida Console"\r
- "Andale Mono"\r
- "Bitstream Vera Sans Mono"\r
- monospace;\r
- padding-bottom: 8px;\r
-}\r
-#canvas[rendering="true"] image {\r
- display: none;\r
-}\r
-#canvas[rendering="true"] *,\r
-#canvas[rendering="true"] .text-link {\r
- color: white !important;\r
-}\r
-\r
-\r
-tabbox, tabpanels, tabpanel {\r
- margin: 0;\r
- padding: 0;\r
-}\r
-\r
-\r
-\r
-\r
-#canvas[eva="true"] {\r
- background: white !important;\r
- color: black !important;\r
- font-family:\r
- "Georgia"\r
- "DejaVu Serif Condensed"\r
- "Apple LiGothic"\r
- "Arial Black"\r
- serif !important;\r
-}\r
-#canvas[eva="true"] .link-text {\r
- color: red !important;\r
- text-decoration: none !important;\r
-}\r
-#canvas[eva="true"] .link-text:hover {\r
- color: pink !important;\r
-}\r
-#canvas[eva="true"] .link-text:active {\r
- color: orange !important;\r
-}\r
-#canvas[rendering="true"] *,\r
-#canvas[rendering="true"] .text-link {\r
- color: black !important;\r
-}\r
-\r
-\r
-\r
-\r
-#canvasToolbar {\r
- position: relative;\r
-}\r
-\r
+++ /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);
--- /dev/null
+=head1 NAME
+
+Web::Simple::AntiquatedPerl - the slides from the talk
+
+=head1 WHAT?
+
+Web::Simple was originally introduced in a talk at the Italian Perl Workshop,
+entitled Antiquated Perl.
+
+The video is available on the Shadowcat site: <http://www.shadowcat.co.uk/archive/conference-video/ipw-2009/antiquated>
+
+If you don't particularly want to watch me confusing a bunch of Italian perl
+mongers, the slides are reproduced below.
+
+=head1 SLIDES
+
+ Antiquated
+ Perl
+ ----
+ Modern
+ Perl?
+ ----
+ Post
+ Modern
+ Perl
+ ----
+ Enlightened
+ Perl
+ ----
+ everybody
+ knows
+ ----
+ Catalyst
+ Moose
+ DBIx::Class
+ ----
+ Modern
+ Perl?
+ ----
+ perl5
+ v10
+ ----
+ given ($x) {
+ when (3) {
+ ...
+ ----
+ ~~
+ ----
+ what's the
+ opposite?
+ ----
+ Old
+ Perl?
+ ----
+ if it
+ works
+ ----
+ Legacy
+ Perl?
+ ----
+ not
+ interesting
+ ----
+ Stupid
+ Perl
+ ----
+ *$&^*(^
+ FormMail.PL
+ ----
+ Antiquated
+ Perl
+ ----
+ Antique
+ ----
+ Old *and*
+ beautiful
+ ----
+ Simple
+ Elegant
+ ----
+ $|++
+ ----
+ use IO::Handle;
+ STDOUT->autoflush(1);
+ ----
+ it's core.
+ it's fine.
+ ----
+ but why
+ think?
+ ----
+ select((select(FOO),$|++)[0])
+ ----
+ (select(FOO),$|++)
+ ->
+ ($old_selected_fh,$|)
+ ----
+ (select(FOO),$|++)[0]
+ ->
+ $old_select_fh
+ ----
+ select((select(FOO),$|++)[0])
+ ->
+ use IO::Handle;
+ FOO->autoflush(1)
+ ----
+ ~~
+ ----
+ ~~@x
+ ----
+ ~(~(@x))
+ ----
+ bitwise
+ negation
+ ----
+ so ...
+ ----
+ ~@x
+ ->
+ ~(scalar @x)
+ ----
+ ~~$number
+ ->
+ $number
+ ----
+ ~~@x
+ ->
+ scalar @x
+ ----
+ perl -MMoose -e'print ~~keys %INC'
+ 84
+ ----
+ overload::constant
+ ----
+ lets you
+ affect
+ parsing
+ ----
+ numbers
+ strings
+ ----
+ q qq qr
+ t s qw
+ ----
+ i18n.pm
+ ----
+ ~~"$foo bar"
+ loc("_[0] bar", $foo)
+ ----
+ for
+ ----
+ for ($foo) {
+ /bar/ and ...
+ ----
+ for ($foo) {
+ /bar/ and return do {
+ <code here>
+ }
+ ----
+ /foo/gc
+ ----
+ /\Gbar/gc
+ ----
+ sub parse {
+ my ($self, $str) = @_;
+ for ($str) {
+ /match1/gc and return
+ $self->_subparse_1($_)
+ ----
+ sub _subparse_1 {
+ my ($self) = @_;
+ for ($_[1]) {
+ /\Gsubmatch1/gc ...
+ ----
+ prototypes
+ ----
+ sub foo (&) {
+ ----
+ foo {
+ ...
+ };
+ ----
+ prototype \&foo
+ ----
+ typeglobs
+ ----
+ *{"${package}::${name}"}
+ = sub { ... }
+ ----
+ local
+ ----
+ local $_
+ ----
+ local *Carp::croak
+ = \&Carp::confess;
+ ----
+ do {
+ local (@ARGV, $/) = $file;
+ <>
+ }
+ ----
+ strict
+ and
+ warnings
+ ----
+ strict->import
+ ----
+ affects
+ compilation
+ scope
+ ----
+ sub strict_and_warnings::import {
+ strict->import;
+ warnings->import;
+ }
+ ----
+ use strict_and_warnings;
+ ----
+ $^H
+ %^H
+ ----
+ $^H |= 0x120000;
+ $^H{'foo'}
+ = bless($foo, 'My::Foo');
+ ----
+ sub My::Foo::DESTROY {
+ ----
+ delete ${$package}{myimport}
+ ----
+ B::Hooks::EndOfScope
+ ----
+ tie
+ ----
+ tie $var, 'Foo';
+ ----
+ sub FETCH
+ sub STORE
+ ----
+ Scalar
+ Array
+ Hash
+ Handle
+ ----
+ now ...
+ ----
+ mst: destruction
+ testing technology
+ since March 1983
+ ----
+ 3 days
+ old
+ ----
+ 2 weeks
+ early
+ ----
+ incubator
+ ----
+ glass box
+ plastic tray
+ heater
+ ----
+ design
+ flaw
+ ----
+ BANG
+ ----
+ so ...
+ ----
+ interesting
+ fact
+ ----
+ prototypes
+ only warn
+ when parsed
+ ----
+ error when
+ compiled
+ ----
+ so ...
+ ----
+ dispatch [
+ sub (GET + /) { ... },
+ sub (GET + /user/*) { ... }
+ ];
+ ----
+ foreach my $sub (@$dispatch) {
+ my $proto = prototype $sub;
+ $parser->parse($proto);
+ ...
+ ----
+ PARSE: { do {
+ push @match, $self->_parse_spec_section($spec)
+ or $self->_blam("Unable to work out what the next section is");
+ last PARSE if (pos == length);
+ /\G\+/gc or $self->_blam('Spec sections must be separated by +');
+ } until (pos == length) };
+ ----
+ sub _blam {
+ my ($self, $error) = @_;
+ my $hat = (' ' x pos).'^';
+ die "Error parsing dispatch specification: ${error}\n
+ ${_}
+ ${hat} here\n";
+ }
+ ----
+ Error parsing ...
+ GET+/foo
+ ^ here
+ ----
+ sub (GET + /user/*) {
+ my ($self, $user) = @_;
+ ----
+ I hate
+ fetching
+ $self
+ ----
+ *{"${app}::self"}
+ = \${"${app}::self"};
+ ----
+ use vars
+ ----
+ sub _run_with_self {
+ my ($self, $run, @args) = @_;
+ my $class = ref($self);
+ no strict 'refs';
+ local *{"${class}::self"} = \$self;
+ $self->$run(@args);
+ }
+ ----
+ HTML
+ output
+ ----
+ templates
+ ----
+ HTML is
+ NOT TEXT
+ ----
+ <div>,
+ $text,
+ </div>;
+ ----
+ <div>
+ ----
+ <$fh>
+ ----
+ tie *{"${app}::${name}"},
+ 'XML::Tags::TIEHANDLE',
+ "<${name}>";
+ ----
+ sub TIEHANDLE { my $str = $_[1]; bless \$str, $_[0] }
+ sub READLINE { ${$_[0]} }
+ ----
+ sub DESTROY {
+ my ($into, @names) = @$_[0];
+ no strict 'refs';
+ delete ${$into}{$_}
+ for @names;
+ }
+ ----
+ </div>
+ ----
+ glob('/div');
+ ----
+ *CORE::GLOBAL::glob
+ = sub { ... };
+ ----
+ delete
+ ${CORE::GLOBAL::}{glob};
+ ----
+ sub foo {
+ use XML::Tags qw(div);
+ <div>, "foo!", </div>;
+ }
+ ----
+ what about
+ interpolation
+ ----
+ my $stuff = 'foo"bar';
+ <a href="$stuff">
+ ----
+ hmm ...
+ ----
+ overload::constant!
+ ----
+ glob('a href="'.$stuff.'"');
+ ----
+ glob(
+ bless(\'a href="', 'MagicTag')
+ .$stuff
+ .bless(\'"', 'MagicTag')
+ )
+ ----
+ use overload
+ '.' => 'concat';
+
+ sub concat {
+ ----
+ hooking
+ it up
+ ----
+ sub (.html) {
+ filter_response {
+ $self->render_html($_[1])
+ }
+ }
+ ----
+ bless(
+ $_[1],
+ 'Web::Simple::ResponseFilter'
+ );
+ ----
+ if ($self->_is_response_filter($result)) {
+ return $self->_run_with_self(
+ $result,
+ $self->_run_dispatch_for($new_env, \@disp)
+ );
+ }
+ ----
+ and the result?
+ ----
+ goto &demo;
+ ----
+ questions?
+ ----
+ thank
+ you
+
+=head1 AUTHOR
+
+Matt S. Trout <mst@shadowcat.co.uk>
+
+=head1 COPYRIGHT
+
+Copyright (c) 2010 Matt S. Trout <mst@shadowcat.co.uk>
+
+=head1 LICENSE
+
+This text may be distributed under the GPL (v2 or later), the Artistic License
+(v1 or later), the Creative Commons Attribution (CC BY v3 or later), the
+Mozilla Public License (v1 or later, in honour of the license of the
+takahashi.xul system I used to write these slides originally), or the
+WTFPL (see <http://sam.zoy.org/wtfpl/COPYING>).
+
+If you'd like me to add another license, please ask.
+
+=cut