+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 高橋メソッドなプレゼンツール in XUL リターンズ
- made by Piro
- http://piro.sakura.ne.jp/
-
- based on
- 高橋メソッドなプレゼン作成ツール ver.2 made by mala
- http://la.ma.la/blog/diary_200504080545.htm
- もんたメソッドなプレゼン作成ツール made by mala
- http://la.ma.la/blog/diary_200505310749.htm
--->
-
-<!-- ***** 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/Returns.
- -
- - The Initial Developer of the Original Code is SHIMODA Hiroshi.
- - Portions created by the Initial Developer are Copyright (C) 2005-2007
- - the Initial Developer. All Rights Reserved.
- -
- - Contributor(s): SHIMODA Hiroshi <piro@p.club.ne.jp>
- - dynamis <dynamis@mozilla-japan.org>
- - matobaa <matobaa@lily.freemail.ne.jp>
- -
- - ***** END LICENSE BLOCK ***** -->
-
-<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
-<?xml-stylesheet href="#builtinStyle" 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);">
-
-<!-- Built-in Content -->
-<html:textarea id="builtinCode" style="visibility: collapse">
-TITLE::Moose in the wild
-GLOBAL-SIZE::9
-riding
-wild
-Moose
-
-----
-%%%%EM:Moose%%%%?
-
-----
-hype:
-
-----
-'postmodern'
-object
-system
-for Perl 5
-<!--
-theres an explanation on the cpan page... It's a ref to Larry talking about perl as a postmodern language... let's move on.
--->
-
-----
-reality:
-
-----
-'academically'
-correct
-p5 OO
-<!--
-by 'borrowing' features
-from other OO systems
-- Lisp/CLOS
-- Perl6
-- ... ect
-- I do not really know these that well so I can not really speak to there cribbed features
--->
-
-----
-so what?
-<!--
-%%%%IMG src="http://bp2.blogger.com/_dH0q9hvpVHg/R86WXUE5b2I/AAAAAAAABh4/N9A5fc5KPnI/s320/thumb.jpg" height='*' width='*' %%%%
--->
-
-----
-my concept
-of OO was
-~off~
-<!--
-For me the biggest thing was to strictly wrap my head on how OO was ~meant~ to be.
-I have an art school background, I missed out on all the CS OO classes.
-I had been thinking of OO backwards
--->
-
-----
-package as a
-collection of subs
-with access to
-common data
-<!--
-My pre-moose days had a really hard time with OO. I understood the basics
-like a $car has $wheels, ect. But things were very fuzzy in my head.
-It's not really wrong, per say, but it's just not a very clear way to see the world.
-Basically my OO world view said that $car $wheels were completely different from $bike $wheels
--->
-
-----
-moose changed
-all that for me
-<!--
-Moose really flipped things for me.
-It forced me to think of objects as attributes and subs that modify them.
--->
-
-----
-build
-objects
-by attributes
-<!--
-It made me focus on the $wheels as the thing that defines the $car or the $bike.
-It's easy to talk about but, but for me, it was a completely different way to think about my code.
--->
-
-
-----
-different?
-how?
-<!--
-a quick blow thru on what features you will be hearing more about
--->
-
-
-----
-%%%%PRE:
-use strict;
-use warnings;
-%%%%
-included
-by default
-<!--
-first, simple things, like why should some one opt-in for the proper way to do something?
--->
-
-----
-%%%%PRE:
-sub new {}
-%%%%
-built-in
-<!--
-ever get tired of writing the same 7 lines of code, now you don't have to.
--->
-
-----
-free
-accessors
-<!--
-once you define an attribute, why not have a getter/setter built for you?
--->
-
-----
-types
-<!--
-Extend the basic perl data types to be much more specific
--->
-
-----
-roles
-<!--
-Hello eye opeining experence.
--->
-
-----
-... ehh, not convinced
-I'd have to see it in action.
-<!--
-don't worry it took me a while to wrap my head around all of this stuff too
--->
-
-----
-what does Moose look like?
-<!--
-let's look at some code
--->
-
-----
-let's define
-a simple
-example:
-<!--
-really simple example, but it will illustrate the general overview.
--->
-
-----
-describe
-a moose
-(the animal)
-
-----
-moose
-have
-names
-
-----
-if no name
-is given
-default to
-'Bullwinkle'
-
-----
-%%%%PRE:
-my $bullwinkle =
- Animal::Moose->new;
-print $bullwinkle->name;
- # 'Bullwinkle'
-
-my $skippy =
- Animal::Moose->new( name => 'Skippy' )
-print $skippy->name;
- # 'Skippy'
-%%%%
-<!--
-yup thats what we want, now let's take a look at what Animal::Moose looks like.
--->
-
-----
-pre-Moose:
-%%%%PRE:
-package Animal::Moose;
-use strict;
-use warnings;
-
-sub new {
- my ($class, %opts) = @_;
- my $self = {
- name => $opts{name} || 'Bullwinkle',
- };
- return bless $self, $class;
-}
-
-sub name {
- my ($self, $new_name) = @_;
- if ( defined $new_name ) {
- $self->{name} = $new_name;
- }
- return $self->{name};
-}
-1;
-%%%%
-<!--
-any questions?
--->
-
-----
-Moose:
-%%%%PRE:
-package Animal::Moose;
-use Moose;
-
-has name => (
- is => 'rw',
- isa => 'Str',
- default => 'Bullwinkle',
-);
-1;
-%%%%
-<!--
-see no constructor, no strict, no warnings
-if you want show the test
--->
-
-----
-what is
-this 'has'?
-<!--
-ok So there you have it... Moose in the... err... code.
-So, what is this 'has' thing? Moose runs with the
-theory that an object is a collection of attributes.
-A moose has a name, thus name is an attribute.
--->
-
-----
-all about
-attributes
-
-----
-standard format:
-%%%%PRE:
-has "attribute name" => (
- #attribute definition
-);
-%%%%
-<!--
-an attribute has a name, and it has to define something in some manner.
-Here are the definitions that I use the most:
-I think that these first three are required.
--->
-
-----
-access level
-%%%%PRE:
-is => 'rw',
-is => 'ro',
-%%%%
-<!--
-if you need something to be updated, then it's 'rw'.
-If it will never changed once set, it's 'ro'.
-really this just specifies what accessors are built for you.
--->
-
-----
-specify type
-%%%%PRE:
-isa => 'Str',
-isa => 'Int',
-isa => 'ArrayRef',
-isa => 'HashRef',
-isa => 'CGI::Simple',
-%%%%
-<!--
-let's moose know what type of thing to expect to be here
-we'll get in to types a bit more later
--->
-
-----
-need a default?
-%%%%PRE:
-default => 'string',
-default => 12,
-default => sub{ [] },
-default => sub{ {} },
-%%%%
-<!--
-scalars can just be specified any thing else needs to be wrapped in a sub {}
--->
-
-----
-required attribute
-%%%%PRE:
-required => 1,
-%%%%
-<!--
-If this attribute is not specified on construction then die
--->
-
-----
-'optional' attribute
-%%%%PRE:
-lazy => 1,
-%%%%
-<!--
-I use this mostly as a timing safety net, IE if one attribute needs another to be built, then make the second one lazy.
-Lazy attributes get built right be fore they are used, so this is also a really good way to keep your code 'lite' by
-setting things up so that you only use what you really need.
--->
-
-----
-%%%% there's more | http://search.cpan.org/~stevan/Moose-0.38/lib/Moose.pm %%%%
-<!--
-
--->
-
-----
-why types
-are cool?
-
-----
-built-in
-assertions
-<!--
-Moose's type structure is basically a built-in assertion for the content of an attribute.
--->
-----
-advantage?
-they make my code die!
-<!--
-This is super handy as Moose is making sure that you know what your dealing with,
-you do not have to have everything check to make sure that $input_data is going to be > 0 or what ever.
-At first this was really annoying for me. As I was porting my instal run of Search things would always die.
-it was another symptom of bad code, Again Moose is forcing me to think about what I really want, and staying on task.
--->
-
-----
-my options?
-%%%%PRE:
- Any
- Item
- Bool
- Maybe[`a]
- Undef
- Defined
- Value
- Num
- Int
- Str
- ClassName
- Ref
- ScalarRef
- ArrayRef[`a]
- HashRef[`a]
- CodeRef
- RegexpRef
- GlobRef
- FileHandle
- Object
- Role
-%%%%
-%%%% more info on types | http://search.cpan.org/~stevan/Moose-0.38/lib/Moose/Util/TypeConstraints.pm %%%%
-<!--
-There are many types that Moose provides by default, mostly there an extension of the existing perl data objects.
--->
-
-----
-... they're missing one ...
-<!--
-but theres more... You can write your own.
--->
-
-----
-... so make your own ...
-<!--
-Here are some examples from work, ignore the role bit for now.
--->
-
-----
-%%%%PRE:
-package PowellsData::Types::Web;
-use Moose::Role;
-use Moose::Util::TypeConstraints;
-
-type 'WebObject'
- => where {
- ref($_) =~
- m/^(Apache2::Request|CGI::Simple)$/
- }
- => message {
- sprintf(
- '(%s) needs to be an Apache2::Request
- object or a CGI::Simple object and
- it is a %s',
- $_,
- ref($_)
- ) }
- ;
-%%%%
-<!--
-OK so this is from the Search code... There are a many ways to access this code... many are web based, let's specify that the object that holds our CGI session is of the right type and not just some weird chunk of data.
-So as you can see, it's very much an assertion... is this thing the right type. ( I forget why I'm using ref vs isa there might be a reason, there might not be).
-A type has a {where} block that returns 0|1, if one were good, if 0 bail,
-you can also specify a {message} if you would like to gussy up your error log with more helpful errors.
--->
-----
-... you can also
-extend types
-via subtypes.
-
-----
-%%%%PRE:
-package PowellsData::Types::SQL;
-use Moose::Role;
-use Moose::Util::TypeConstraints;
-
-subtype 'SQL_Select'
- => as 'Str'
- => where {
- $_ =~ m/\bSELECT\b.+\bFROM\b/i
- };
-
-subtype 'SQL_Insert'
- => as 'Str'
- => where {
- $_ =~
- m/\bINSERT\b.+(?:\bINTO\b)?.+\b(?:VALUES|SET|SELECT)\b/i
- };
-
-subtype 'SQL_Update'
- => as 'Str'
- => where {
- $_ =~ m/\bUPDATE\b.+\bSET\b/i
- };
-
-subtype 'SQL_Delete'
- => as 'Str'
- => where {
- $_ =~ m/\bDELETE\b.+\bFROM\b/i };
-
-subtype 'SQL'
- => as q{SQL_Select|SQL_Insert|SQL_Update|SQL_Delete} ;
-%%%%
-<!--
-In this example, I just built out some regexes that sit on top of the string type.
-So if you were to pass in an arrayref for example, these would die long before the regex were to be checked.
-Things to note here:
-- subtypes just extend an existing type (as)
-- where is the same, something that returns (0|1)
-- you can extend any other defined type/subtype and even group them (SQL)
--->
-
-----
-so roles?
-
-----
-how to eat a moose
-
-----
-... small pieces
-
-----
-roles ~ includes
-<!--
-Roles are another thing that blew my mind. At it's most basic you can think of a role as
-a include in to the current file.
--->
-
-----
-usage (theory):
-1) abstract the common
-<!--
-Before we really jump to some example, theres basically two
-ways that I find my self using roles. The first is as
-an abstarction layer to something very common.
--->
-
-----
-example:
-%%%%PRE:
-package PowellsData::Setup::Database;
-use Moose::Role;
-use DBHost;
-
-sub d;
-has d => ( is => 'rw',
- isa => 'DBI::db',
- required => 1,
- default => sub{ my $d = _dbiconnect('current');
- $d->{mysql_auto_reconnect} = 1;
- $d->do("SET NAMES utf8");
- return $d;
- }
- );
-
-
-
-1;
-%%%%
-<!--
-So this basically sets up a database handle for us. It's an abstraction of
-DBHost, a Powells rapper around DBI that manages what server to use and
-what user:password to use. This layer does some minor set up on top of that.
-We check the type, we are saying that this is required and default will build
-one for us if there was not passed in at construction.
-Things to note:
-- use Moose::Role is the only thing that has changed from a 'Moose' Object.
-- this sub hack...
--->
-
-----
-now in our code just say:
-%%%%PRE:
-package My::Bad::DB::Example;
-use Moose;
-
-with q{PowellsData::Setup::Database};
-
-sub run_query {
- my ($self, $query) = @_;
- return $self->d->do($query);
-}
-%%%%
-<!--
-this one line now gives me an attribute 'd' that hast to be a 'DBI::db',
-everything gets set up for us, it's all in the role. So now I never have to
-remember specifics, I just get a DB handle.
-it's like I had written all of that code in-line.
--->
-
-----
-usage (theory):
-2) big idea as small chunks
-<!--
-the other way that I often find my self using roles is to really
-lean on on that 'include' nature. Because the code ends up as though
-its one big file, then I take large files and 'break-them-up'.
-It's got it's pros and cons, First why I like this:
--->
-
-----
-%%%%EM:pro:%%%%
-write only
-what you need
-<!--
-In that set up my DB example, we only had to write only the part
-about setting up the DB handle.
--->
-
-----
-%%%%PRE:
-package PowellsData::Setup::Database;
-use Moose::Role;
-use DBHost;
-
-sub d;
-has d => ( is => 'rw',
- isa => 'DBI::db',
- required => 1,
- default => sub{ my $d = _dbiconnect('current');
- $d->{mysql_auto_reconnect} = 1;
- $d->do("SET NAMES utf8");
- return $d;
- }
- );
-
-
-
-1;
-%%%%
-<!--
-Search is web based, but in this code we don't care, we can focus just on one
-simple part of a very complex problem.
--->
-
-----
-%%%%EM:con:%%%%
-lost context
-<!--
-with roles you just get stuff for 'free', it's almost like magic. Santa just showed up and you
-got a DB handle. ~Woo~.
--->
-
-----
-%%%%PRE:
-with q{PowellsData::Setup::Database};
-%%%%
-vs.
-%%%%PRE:
-use Some::Other::Magic::DB::Manager q{d};
-%%%%
-<!--
-when you set up a role next to the use qw{import} way of things, you can maintain context
-you are stating the origin of things. Theres so many times that ack has saved me time because
-I have completely lost track where method or attribute is.
--->
-
-----
-%%%%EM:pro:%%%%
-group logical actions
-<!--
-If I take advantage of the Roles as includes then I can take that section of code
-that does that one thing and pull it off to it's own file, even if it's only used
-once.
--->
-
-----
-%%%%PRE:
-package Search::Runtime::FPSearch::Section;
-use Moose;
-use Carp::Assert::More;
-
-with qw{
- Search::Runtime::Common
- PowellsData::Setup::Database
- PowellsData::Tools::String
-};
-
-
-sub find {
- my ( $self, $needle) = @_;
- if ( $self->_has_valid_value($needle) ) {
- my $needles = $self->array_of_words( lc( $needle ) );
- my $query = _query($needles);
- my $r = $self->d->selectall_arrayref($query, { Slice => {} }, @$needles, @$need
-les);
- my $score_limit = scalar( @$needles);
-
- if ( scalar( @$r ) > 0 ) {
- #we have resutls
- my $out = [];
- foreach my $s ( @$r ) {
- if ( $s->{score} >= $score_limit ) {
- push @$out, {$s->{name} => $s->{link}};
- }
- }
- return $out;
- }
- }
- return undef;
-}
-sub _query {
- my ($needles) = @_;
- assert_listref($needles);
- return sprintf( q{
- (
- SELECT DISTINCT X.MAJORSec as name,
- CONCAT( 'psection/',X.HTML ) AS link,
- X.score,
- X.type
- FROM (
- SELECT C.MAJORSec,
- C.MINORSec,
- count(SWC.word_id) AS score,
- SWC.type,
- C.HTML,
- C.sectionkey
- FROM Sections.section_word_category SWC
- JOIN Sections.category C
- ON (SWC.category_id = C.id)
- JOIN Sections.section_words SW
- ON (SWC.word_id = SW.id)
- WHERE SW.word IN (%s)
- AND C.MAJORSec NOT LIKE '%%Reader eBook%%'
- AND C.MAJORSec NOT LIKE '%%sale%%'
- AND C.MAJORSec != '$7 or Less'
- AND C.MAJORSec != 'At the Movies'
- AND C.MAJORSec != 'New Arrivals'
- AND C.MAJORSec != 'Coming Soon!'
- AND SWC.type = 'major'
- GROUP BY C.id
- ORDER BY score DESC
- ) AS X
- )
- UNION
- (
- SELECT CONCAT( Y.MAJORSec, ' - ', Y.MINORSec ) as name,
- CONCAT( 'subsecti on/', Y.sectionkey, '.html' ) AS link,
- Y.score,
- Y.type
- FROM (
- SELECT C.MAJORSec,
- C.MINORSec,
- count(SWC.word_id) AS score,
- SWC.type,
- C.HTML,
- C.sectionkey
- FROM Sections.section_word_category SWC
- JOIN Sections.category C
- ON (SWC.category_id = C.id)
- JOIN Sections.section_words SW
- ON (SWC.word_id = SW.id)
- WHERE SW.word IN (%s)
- AND C.MAJORSec NOT LIKE '%%Reader eBook%%'
- AND C.MAJORSec NOT LIKE '%%sale%%'
- AND C.MAJORSec != '$7 or Less'
- AND C.MAJORSec != 'At the Movies'
- AND C.MAJORSec != 'New Arrivals'
- AND C.MAJORSec != 'Coming Soon!'
- AND SWC.type = 'minor'
- GROUP BY C.id
- ORDER BY score DESC
- ) AS Y
-
- )
- ORDER BY type = 'major' DESC , score DESC
- },
- _soq(@$needles),
- _soq(@$needles),
- );
-}
-
-
-1;
-%%%%
-<!--
-I don't know if this is readable but what is going on here is a section search. I take in
-a $needle and then build up a query based on that $needle and try and find it in the DB.
-This code only does one specific thing, So I pulled it out. It could have become it's own object
-but it really doesn't need to hold on to any thing, it just needs a DB handle and a needle, this
-a quick handy way to keep things grouped by logical tasks.
--->
-
-----
-%%%%EM:con:%%%%
-things get
-messy fast
-<!--
-As cool as this is, you really need to be careful, things can get really messy really fast.
-Here let's just take a quick gander at the dir for Search:
--->
-
-----
-%%%%PRE:
-benh@noodleboy:~/svn/lib_common/dev/Search$ tree .
-.
-|-- CompleteResults.pm
-|-- CompleteResults_distance.pm
-|-- Core
-| |-- Actions
-| | |-- Pages.pm
-| | `-- Results.pm
-| |-- Actions.pm
-| |-- CompleteResults
-| | |-- Common.pm
-| | |-- LimitedQuery.pm
-| | |-- OLDQuery.pm
-| | |-- OrderBy.pm
-| | |-- Query.pm
-| | `-- Restrictions.pm
-| |-- CompleteResults.pm
-| `-- Shortcut.pm
-|-- Core.pm
-|-- DB
-| |-- Current
-| | |-- NoStem.pm
-| | |-- PublisherKw.pm
-| | |-- PublisherKwOld.pm
-| | |-- Search.pm
-| | |-- SearchCacheClasses.pm
-| | |-- SearchCacheCounter.pm
-| | |-- SearchCacheMeta.pm
-| | |-- SearchCacheParams.pm
-| | |-- SearchCacheResults.pm
-| | |-- SearchCacheSections.pm
-| | |-- SearchKw.pm
-| | |-- SearchKwOld.pm
-| | |-- SearchOld.pm
-| | |-- SearchTitle.pm
-| | |-- SearchTitleOld.pm
-| | |-- SectionsKw.pm
-| | |-- SectionsKwOld.pm
-| | |-- Stock.pm
-| | |-- StockOld.pm
-| | |-- ZqDb.pm
-| | |-- ZqKw.pm
-| | `-- ZqTitle.pm
-| |-- Current.pm
-| `-- Profiler.pm
-|-- DB.pm
-|-- Debug
-| `-- Stopwatch.pm
-|-- Debug.pm
-|-- Runtime
-| |-- Attr.pm
-| |-- Common.pm
-| |-- Cookies.pm
-| |-- Defaults.pm
-| |-- FPSearch
-| | |-- Author.pm
-| | |-- Help.pm
-| | `-- Section.pm
-| |-- FPSearch.pm
-| |-- Internal.pm
-| |-- Lookup.pm
-| |-- Promote.pm
-| |-- Spelling.pm
-| |-- Tracking.pm
-| |-- Translate.pm
-| |-- Values
-| | |-- Clean.pm
-| | `-- Organize.pm
-| |-- Values.pm
-| `-- Websearch.pm
-|-- Runtime.pm
-|-- Test
-| |-- pound.pl
-| `-- runsearch_lite.pl
-|-- Test.pm
-`-- playground.pl
-%%%%}
-<!--
-Lets see what is really an object in all of this...
-- Runtime
-- Runtime::Default
-- Core
-
-Runtime is called from Search Core, it extends Default, but everything else is a role, it is just included.
-I've tried to keep things organized, but roles are like kudzu. So just like most things, with great power comes great responsibly.
-This is one of the biggest reasons I've been in some level of constant refactoring of this code base.
--->
-
-----
-%%%%EM:pro:%%%%
-delegate code
-<!--
-Because there actions in separate files it's really handy to be able to hand out parts of the puzzle
-to other people and then just come back with a big working object. It's a dream that I have at work,
-so far not much has come of it.
--->
-
-----
-%%%%EM:con:%%%%
-moose roles
-are moose only
-<!--
-Moose roles are only use-able via moose. You can write mini-object thats collect your roles,
-It's not ~hard~ to get around, just need to mention it though. Also to note, Moose is not the only
-way to implement 'roles', check cpan for 'traits' or 'mix-ins'. There all kinda the same thing
--->
-
-----
-there's a lot more to roles
-%%%% CookBook Example | http://search.cpan.org/~stevan/Moose-0.38/lib/Moose/Cookbook/Recipe6.pod %%%%
-
-----
-<!--
-how we doing on time?
--->
-
-----
-kinda-FAQ
-<!--
-** possible filler if needed **
--->
-
-----
-how to extend a Moose?
-<!--
-let's see how am I doing on time... cause I can just skip this if I'm over
--->
-
-----
-It's easy:
-%%%%PRE:
-extends q{object};
-%%%%
-vs
-%%%%PRE:
-use base q{object};
-%%%%%
-<!--
-Basically does the same thing but makes sure that all the Moose stuff stays in the right place
-in the @ISA stack. Also I have not played with it, but extends will take an array of parents
-and should handle any weird multiple inheritance juju for you.
--->
-
-----
-with out new,
-how can I
-have something
-run on creation?
-<!--
-I still have not completely wrapped my head around what bits of Moose are compile time
-and what happens at run time. Theres so many layers to things.
-There are often times that you will find your self missing that constructor.
-just need something to be run at creation time?
--->
-
-----
-%%%%PRE:
-sub BUILD {
- #... code to be run on create
-};
-%%%%
-
-----
-wow free lunch?
-cost?
-<!--
-sadly no, this is not a free lunch. There is a hit on performance, I have not done any
-testing, no hard number. Though I have not really noticed any significant hit. Though
-this is mostly sidelined as Search runs in mod_perl so things only get built once.
-There are all sorts of warnings all over the place about not using Moose for a
-simple CGI.pm application.
--->
-
-
-----
-<!--
-step #{number}
-Things that I'm still learning
-- meta, it all just perl
-- coerce best uses.
-- triggers, almost a method modifier
-- method modification events
- - before
- - around
- - after
-- unimport ( 'no moose', when to use? )
- - mostly just a way to clean up things
- - %%%% namespace::clean | http://search.cpan.org/~phaylon/namespace-clean-0.08/lib/namespace/clean.pm %%%%
- - insure that there are no funky issues down stream
-- super?
-- override, makes sense just have not run in to a need to use
-- inner
-- augment
-- Moose specific testing
- - mostly how to test roles by them self?
- - %%%% Test::Moose | http://search.cpan.org/~stevan/Moose-0.38/lib/Test/Moose.pm %%%%
- - %%%% Test::Moose::MockObjectCompile | http://search.cpan.org/~zaphar/Test-Moose-MockObjectCompile-0.2.1/lib/Test/Moose/MockObjectCompile.pm %%%%
--->
-
-
-<!--
- * a perl object system
- * meta syntax for object/class declaration
- * simple example
- * not *that* weird
-* Ride the Moose (code in "the real world")
- * Constructors for free
- * BUILD
- * under the hood - the meta() method
- * getters and setters
- * example
- * possible name space collisions
- * 'rw' vs 'ro'
- * timing issues ( lazy => 1 )
- * strict types
- * things die if they are wrong, just like they should (assertion)
- * roles
- * less code to test
-* Love the Moose (techniques and practices)
- * composition / modularization / encapsulation
- * layout of logical file structure with roles
- * easier team workflow / merging
- * QA notes
--->
-
-----
-thanks to Stevan Little
-and the whole moose crew #moose
-<!--
-including eric
--->
-
-----
-Thanks for putting up with my yammering
-
-----
-More info:
-- %%%% CPAN | http://search.cpan.org/~stevan/Moose-0.38/ %%%%
-- %%%% Cookbook | http://search.cpan.org/~stevan/Moose-0.38/lib/Moose/Cookbook.pod %%%%
-- %%%% Moose Site | http://www.iinteractive.com/moose/ %%%%
-- IRC: irc.perl.org #moose
-
-----
--end-
-
-
-</html:textarea>
-
-<!-- Built-in Style -->
-<html:style id="builtinStyle" type="text/css" style="visibility: collapse">
-<![CDATA[
-@namespace url(http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul);
-@namespace html url(http:/www.w3.org/1999/xhtml);
-
-#canvas {
- background: white !important;
- color: black !important;
- font-family:
- "Florencesans Black"
- "futura"
- "ゴシックMB101U"
- "ニューセザンヌ-EB"
- "セザンヌ-EB"
- "DHP極太ゴシック体"
- "DFP極太ゴシック体"
- "DHPGothic UB"
- "DFPGothic UB"
- "DHP特太ゴシック体"
- "DFP特太ゴシック体"
- "DHPGothic EB"
- "DFPGothic EB"
- "セイビイサラゴUB-P"
- "AR Pゴシック体 S"
- "Arphic PGothic SuperBold JIS"
-/* "Arial Black"*/
- "DF特太ゴシック体"
- "DFGothic EB"
- "セイビイサラゴUB"
- "AR ゴシック体 S"
- "Arphic Gothic SuperBold JIS"
- "HGP創英角ゴシックUB"
- "HGPSoeiKakugothicUB"
- "HGS創英角ゴシックUB"
- "HG創英角ゴシックUB"
- "HGSoeiKakugothicUB"
- "小塚ゴシック Std H"
- "モトヤゴシック 6"
- "ヒラギノ角ゴ Std W8"
- sans-serif !important;
-}
-
-.em-text {
- color: red !important;
- font-size: 120%;
-}
-
-.link-text {
- color: blue !important;
- text-decoration: underline !important;
-}
-.link-text:hover {
- color: #3366FF !important;
-}
-.link-text:active {
- color: red !important;
-}
-
-.preformatted-text.block {
- border: 1px dashed gray;
- padding: 0.3em;
- margin: 0.3em;
- font-size: 80%;
-}
-
-.monta-label {
- background-color: white;
- background-repeat: no-repeat;
-/* background-image: url("./monta-label.png");*/
-}
-
-
-
-#canvas column,
-#canvas row {
- border: 1px solid gray;
-}
-
-#canvas grid .special {
- background: #CFCFCF;
-}
-
-
-
-
-
-#header,
-#footer {
- color: #666;
-}
-
-
-#indicatorBar {
- color: #BFBFBF;
- background: black;
-}
-
-progressmeter {
- margin: 0;
- padding: 0;
-}
-progressmeter,
-progressmeter .progress-bar,
-progressmeter .progress-remainder {
- -moz-appearance: none;
- background: transparent;
- border: none;
- outline: none;
- min-height: 0;
-}
-#remainingTimeIndicator .progress-bar {
- background: #333333;
-}
-#remainingPageIndicator .progress-bar {
- background: #444444;
-}
-
-
-#plainTextBox {
- background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH1wYGCSMfVbRtUAAAAB10RVh0Q29tbWVudABDcmVhdGVkIHdpdGggVGhlIEdJTVDvZCVuAAAAGElEQVR42mNkYGCoZyACMDEQCUYVUkchANsIAJN3G7QXAAAAAElFTkSuQmCC');
-}
-
-#plainTextField {
- font-family: monospace;
- font-size: medium;
- color: black;
- background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH1wYGCTURrpT1gAAAAB10RVh0Q29tbWVudABDcmVhdGVkIHdpdGggVGhlIEdJTVDvZCVuAAAAGUlEQVR42mP8////fgYiABMDkWBUIXUUAgAEGgPQ5w4kBAAAAABJRU5ErkJggg==');
- border: 2px solid gray;
- border-color: black white white black;
- -moz-appearance: none;
-}
-
-
-/* Eva Mode */
-
-#canvas[eva="true"] {
- background: black !important;
- color: white !important;
- font-family:
- "リュウミンU-KL"
- "リュウミンH-KL"
- "マティス-EB"
- "RFファイン-ME"
- "DHP極太明朝体"
- "DFP極太明朝体"
- "DHPMincho UB"
- "DFPMincho UB"
- "AR P明朝体U"
- "Arphic PMincho Ultra JIS"
- "AR明朝体U"
- "Arphic Mincho Ultra JIS"
- "HGP平成明朝体W9"
- "HGPHeiseiMinchotaiW9"
- "HGS平成明朝体W9"
- "HGSHeiseiMinchotaiW9"
- "HG平成明朝体W9"
- "HGHeiseiMinchotaiW9"
- "ヒラギノ明朝 Pro W6"
- serif !important;
-}
-#canvas[eva="true"] .em-text {
- color: red !important;
-/* color: green !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[eva="true"] #header,
-#canvas[eva="true"] #footer {
- color: #AAA;
-}
-
-
-#canvas[eva="true"] .monta-label {
- background-color: black;
-}
-
-
-
-
-
-.stroke-dot {
- background: red;
- width: 3px;
- height: 3px;
-}
-
-
-
-
-
-
-
-
-/* System:: DO NOT CHANGE FOLLOWING LINES!! */
-
-
-#canvas * {
- cursor: pointer !important;
-}
-
-#canvas image {
- width: auto;
- height: auto;
-}
-#canvas[rendering="true"] image {
- display: none;
-}
-
-#canvas[rendering="true"] *,
-#canvas[rendering="true"] .text-link {
- color: inherit !important;
-}
-
-#canvas[rendering="true"] #contentBox {
- visibility: hidden;
-}
-
-
-
-
-
-
-.preformatted-text {
- font-family: -moz-fixed !important;
- white-space: pre !important;
-}
-
-
-
-.raw {
- font-family: sans-serif !important;
- font-size: medium !important;
-}
-#canvas .raw * {
- cursor: default !important;
-}
-
-
-
-
-
-tabbox, tabpanels, tabpanel {
- margin: 0;
- padding: 0;
-}
-
-
-.dropmarker-button > image {
- display: none !important;
-}
-.dropmarker-button > label {
- width: 0 !important;
- overflow: hidden !important;
-}
-
-#pages-list-button {
- min-width: 0;
-}
-#pages-list-button > label {
- display: none;
-}
-#pages-list-button menupopup {
- max-width: 20em;
-}
-#pages-list-button menuitem image {
- max-width: 32px;
- max-height: 32px;
-}
-
-
-
-
-#headerBox,
-#footerBox {
- margin: 1em;
-}
-
-
-#indicatorBar,
-#indicatorBar hbox,
-#nextPage {
- -moz-box-align: center;
- -moz-box-pack: center;
-}
-
-
-
-.monta-label {
- padding: 0.05em;
- margin: -0.05em;
-}
-.monta-label[monta-hidden="true"],
-.monta-label[monta-hidden="progress"] {
- background-position: -100px 0;
-}
-.monta-label[monta-hidden="progress"] {
- background-color: transparent;
-}
-.monta-label[monta-hidden="false"] {
- background: transparent !important;
-}
-
-
-
-#canvas row description {
- border: 1px solid transparent;
- white-space: pre;
-}
-
-
-
-#canvasToolbar {
- position: relative;
- z-index: 1000;
-}
-
-#sourceEditField,
-#pageEditFields textbox {
- font-family: -moz-fixed !important;
- font-size: medium;
-}
-
-#pageEditFields {
- overflow: auto;
-}
-#pageEditFields textbox {
- height: 6em;
-}
-
-
-
-
-#stroke-canvas-box {
- position: relative;
- display: block;
-}
-#stroke-canvas-box,
-#stroke-canvas-box *|canvas {
- line-height: 1;
-}
-
-.stroke-dot {
- position: absolute;
- display: block;
- z-index: 100;
-}
-
-
-
-.monta-label {
- background-image: url("data:image/png;base64,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AAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwv60rDzN2YM6WgAAAABJRU5ErkJggg==");
-}
-
-]]>
-</html:style>
-
-<!-- Interface -->
-
-<deck flex="1" id="deck">
-
-<vbox flex="1">
- <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);"/>
- <toolbarbutton id="pages-list-button"
- type="menu"
- label="Select Page"
- tooltiptext="Select Page"
- class="dropmarker-button">
- <menupopup id="pages-list"
- onpopupshowing="if (event.target == this) Presentation.preventToShowHideToolbar = true;"
- onpopuphiding="if (event.target == this) Presentation.preventToShowHideToolbar = false;"
- oncommand="Presentation.showPage(parseInt(event.target.value));"/>
- </toolbarbutton>
- <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/>
- <toolbarbutton label="Pen"
- id="penButton"
- type="checkbox"
- autoCheck="false"
- oncommand="StrokablePresentationService.toggleCheck();"/>
- <spacer flex="1"/>
- <toolbarbutton id="func-menu-button"
- type="menu"
- label="Function">
- <menupopup
- onpopupshowing="if (event.target == this) { Presentation.preventToShowHideToolbar = true; Presentation.updateTimerItem(); }"
- onpopuphiding="if (event.target == this) Presentation.preventToShowHideToolbar = false;">
- <menuitem id="timerItem"
- label="Set Timer"
- label-normal="Set Timer"
- label-active="Reset Timer (rest %smin)"
- oncommand="Presentation.setTimer();" />
- <menuseparator/>
- <menuitem label="Start Auto-Cruise"
- id="autoButton"
- type="checkbox"
- autoCheck="false"
- oncommand="Presentation.toggleAutoCruiseMode();" />
- <menu id="auto-interval-button"
- label="Change Interval">
- <menupopup id="auto-interval-list"
- onpopupshowing="(this.getElementsByAttribute('value', Presentation.autoCruiseInterval)[0] || this.lastChild).setAttribute('checked', true);"
- oncommand="Presentation.changeAutoCruiseInterval(parseInt(event.target.value));">
- <menuitem type="radio" radiogroup="autocruise-interval"
- label="1 sec" value="1000"/>
- <menuitem type="radio" radiogroup="autocruise-interval"
- label="2 sec" value="2000"/>
- <menuitem type="radio" radiogroup="autocruise-interval"
- label="3 sec" value="3000"/>
- <menuitem type="radio" radiogroup="autocruise-interval"
- label="4 sec" value="4000"/>
- <menuitem type="radio" radiogroup="autocruise-interval"
- label="5 sec" value="5000"/>
- <menuseparator/>
- <menuitem type="radio" radiogroup="autocruise-interval"
- label="1 min" value="60000"/>
- <menuitem type="radio" radiogroup="autocruise-interval"
- label="2 min" value="120000"/>
- <menuitem type="radio" radiogroup="autocruise-interval"
- label="3 min" value="180000"/>
- <menuitem type="radio" radiogroup="autocruise-interval"
- label="4 min" value="240000"/>
- <menuitem type="radio" radiogroup="autocruise-interval"
- label="5 min" value="300000"/>
- <menuseparator/>
- <menuitem type="radio" radiogroup="autocruise-interval"
- label="Custom"
- oncommand="
- var current = Presentation.autoCruiseInterval;
- var val = parseInt(prompt('input interval (sec)', parseInt(current/1000)));
- if (isNaN(val)) {
- event.preventBubble();
- return;
- }
- else
- val = val * 1000;
- this.value = val;
- "/>
- </menupopup>
- </menu>
- <menuseparator/>
- <menuitem oncommand="Presentation.print();" label="Print"/>
- <menu id="auto-interval-button"
- label="Thumbnail Format">
- <menupopup
- onpopupshowing="(this.getElementsByAttribute('value', Presentation.imageType)[0] || this.firstChild).setAttribute('checked', true);"
- oncommand="Presentation.imageType = event.target.value;">
- <menuitem type="radio" radiogroup="print-image-type"
- label="PNG" value="png"/>
- <menuitem type="radio" radiogroup="print-image-type"
- label="JPEG (50%)" value="jpeg"/>
- </menupopup>
- </menu>
- <menuseparator/>
- <menuitem id="showPlainText" label="View Source"
- key="key_plainText"
- oncommand="Presentation.showPlainText();"/>
- <menuseparator/>
- <menuitem id="toggleEva" label="Eva Mode"
- key="key_toggleEvaMode"
- type="checkbox"
- autoCheck="false"
- oncommand="Presentation.toggleEvaMode();"/>
- </menupopup>
- </toolbarbutton>
- <toolbarseparator/>
- <toolbarbutton label="Edit"
- oncommand="Presentation.toggleEditMode();"/>
- <toolbarbutton oncommand="Presentation.reload();" label="Reload"/>
- </toolbar>
- </toolbox>
- <vbox flex="1" id="canvas">
- <stack flex="1">
- <vbox flex="1">
- <hbox id="headerBox" flex="1">
- <label id="header"/>
- <spacer flex="1"/>
- <vbox>
- <image id="logo"/>
- <spacer flex="1"/>
- </vbox>
- </hbox>
- <spacer flex="19"/>
- <hbox id="footerBox" flex="1">
- <spacer flex="1"/>
- <label id="footer"/>
- </hbox>
- </vbox>
- <vbox id="canvasMain"
- flex="1"
- onmouseup="Presentation.handleEvent(event);"
- onmousedown="Presentation.handleEvent(event);"
- onmousemove="Presentation.handleEvent(event);"
- onclick="Presentation.onPresentationClick(event);">
- <spacer flex="1"/>
- <hbox flex="1" id="contentBox">
- <spacer flex="1"/>
- <vbox id="content"/>
- <spacer flex="1"/>
- </hbox>
- <spacer flex="1"/>
- </vbox>
- <vbox id="plainTextBox"
- hidden="true"
- flex="1"
- onclick="Presentation.hidePlainText();"
- align="center"
- pack="center">
- <textbox id="plainTextField" multiline="true"
- onkeypress="if (event.keyCode == event.DOM_VK_ESCAPE) Presentation.hidePlainText();"
- onclick="event.stopPropagation();"/>
- </vbox>
- </stack>
- </vbox>
- <hbox id="indicatorBar"
- onclick="Presentation.onIndicatorBarClick(event);">
- <stack flex="1">
- <vbox>
- <progressmeter id="remainingPageIndicator"
- type="determined" value="0"
- flex="1"/>
- <progressmeter id="remainingTimeIndicator"
- type="determined" value="0"
- flex="1"
- collapsed="true"/>
- </vbox>
- <hbox flex="1">
- <label value="Next:"/>
- <description id="nextPage" flex="1" crop="end"/>
- </hbox>
- </stack>
- </hbox>
-</vbox>
-
-<vbox flex="1" id="edit">
- <toolbox>
- <toolbar>
- <menubar flex="1">
- <menu label="File">
- <menupopup>
- <menuitem label="Save"
- key="key_save"
- oncommand="Presentation.output()"/>
- <menuitem label="Reload"
- key="key_reload"
- oncommand="Presentation.reload()"/>
- </menupopup>
- </menu>
- <menu label="Insert">
- <menupopup>
- <menuitem label="New Page"
- key="key_insert_newpage"
- oncommand="Presentation.insert('page')"/>
- <menuseparator/>
- <menuitem label="Header"
- oncommand="Presentation.insert('header')"/>
- <menuitem label="Footer"
- oncommand="Presentation.insert('footer')"/>
- <menuseparator/>
- <menuitem label="Link"
- oncommand="Presentation.insert('link')"/>
- <menuitem label="Emphasis"
- oncommand="Presentation.insert('em')"/>
- <menuitem label="Preformatted"
- oncommand="Presentation.insert('pre')"/>
- <menuitem label="Monta"
- oncommand="Presentation.insert('monta')"/>
- <menuitem label="Image"
- oncommand="Presentation.insert('img')"/>
- </menupopup>
- </menu>
- </menubar>
- <toolbarseparator/>
- <toolbarbutton label="View"
- oncommand="Presentation.toggleEditMode();"/>
- <toolbarbutton oncommand="Presentation.reload();" label="Reload"/>
- </toolbar>
- </toolbox>
- <tabbox id="editTabBox" flex="1">
- <tabs onselect="Presentation.toggleEditStyle(event);">
- <tab label="Page Edit" id="editTab-pages"/>
- <tab label="Source" id="editTab-source"/>
- </tabs>
- <tabpanels flex="1">
- <scrollbox id="pageEditFields"
- orient="vertical"
- flex="1"/>
- <textbox id="sourceEditField"
- flex="1"
- multiline="true"
- oninput="Presentation.onEditSource()"/>
- </tabpanels>
- </tabbox>
-</vbox>
-
-</deck>
-
-<data style="visibility: collapse;">
- <hbox id="pageEditBoxTemplate">
- <textbox multiline="true"
- class="page-edit-box-main"
- flex="1"
- oninput="Presentation.onEditPage(Number(this.parentNode.parentNode.id.match(/\d+/)))"/>
- <vbox>
- <toolbarbutton label="×"
- oncommand="Presentation.removePage(Number(this.parentNode.parentNode.id.match(/\d+/)));"/>
- </vbox>
- </hbox>
-</data>
-
-<broadcasterset>
- <broadcaster id="canBack"/>
- <broadcaster id="canForward"/>
-</broadcasterset>
-
-<commandset>
- <command id="cmd_forward"
- oncommand="if (Presentation.isPresentationMode) Presentation.forward();"/>
- <command id="cmd_forwardStep"
- oncommand="if (Presentation.isPresentationMode) Presentation.forwardStep();"/>
- <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_forwardStep"/>
- <key keycode="VK_RETURN" command="cmd_forwardStep"/>
- <key keycode="VK_PAGE_DOWN" command="cmd_forwardStep"/>
- <key keycode="VK_RIGHT" command="cmd_forwardStep"/>
- <key keycode="VK_DOWN" command="cmd_forwardStep"/>
- <!--key keycode="VK_BACK_SPACE" command="cmd_back"/-->
- <key keycode="VK_PAGE_UP" command="cmd_back"/>
- <key keycode="VK_UP" command="cmd_back"/>
- <key keycode="VK_LEFT" command="cmd_back"/>
- <key keycode="VK_HOME" command="cmd_home"/>
- <key keycode="VK_END" command="cmd_end"/>
-
- <key id="key_insert_newpage"
- key="n" modifiers="accel" oncommand="Presentation.insert('page');"/>
-
- <key id="key_save"
- key="s" modifiers="accel" oncommand="Presentation.output();"/>
- <key id="key_reload"
- key="r" modifiers="accel" oncommand="Presentation.reload();"/>
- <key id="key_reload"
- key="p" modifiers="accel" oncommand="Presentation.print();"/>
-
- <key id="key_toggleEditMode"
- key="e" modifiers="accel" oncommand="Presentation.toggleEditMode();"/>
- <key id="key_toggleEvaMode"
- key="e" modifiers="accel,shift" oncommand="Presentation.toggleEvaMode();"/>
-
- <key id="key_plainText"
- key="u" modifiers="accel" oncommand="Presentation.showPlainText();"/>
- <key keycode="VK_ESCAPE" oncommand="Presentation.hidePlainText();"/>
-</keyset>
-
-<!-- Implementation -->
-<script type="application/x-javascript; e4x=1"><![CDATA[
-
-const XULNS = 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul';
-const XHTMLNS = 'http://www.w3.org/1999/xhtml';
-
-var Presentation = {
-
- baseSize : 9,
- montaLabelImage : 'monta-label.png',
-
- //phraseOpenParen : '[',
- //phraseCloseParen : ']',
- phraseOpenParen : '%%',
- phraseCloseParen : '%%',
- makePhraseRegExp : function(aPattern, aFlags)
- {
- return new RegExp(
- aPattern.replace(/%o(pen)?/gi, '\\'+this.phraseOpenParen)
- .replace(/%c(lose)?/gi, '\\'+this.phraseCloseParen),
- aFlags
- );
- },
-
- dragStartDelta : 8,
-
- imageType : 'jpeg',
-
- EDIT_BOX_ID_PREFIX : 'editPageBox-',
-
- initialized : false,
-
- preventToShowHideToolbar : false,
-
- showMontaKeywordTimeout : 100,
- autoCruiseInterval : 2000,
- timerUpdatingInterval : 30000,
-
- cachedContents : [],
- sourceData : [],
-
- init : function(option){
- if (this.initialized) {
- this.startPresentation();
- return;
- }
- this.initialized = true;
-
-
- this._offset = 0;
- this.canvas = document.getElementById('canvas');
- this.canvasMain = document.getElementById('canvasMain');
- this.content = document.getElementById('content');
- this.header = document.getElementById('header');
- this.footer = document.getElementById('footer');
- this.logo = document.getElementById('logo');
- this.next = document.getElementById('nextPage');
-
- this.indicatorBar = document.getElementById('indicatorBar');
- this.remainder = document.getElementById('remainingPageIndicator');
- this.timer = document.getElementById('remainingTimeIndicator');
-
- this.list = document.getElementById('pages-list');
- this.source = document.getElementById('sourceEditField');
- this.pages = document.getElementById('pageEditFields');
- 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;');
-
- this.preloadImage(this.montaLabelImage);
-
- window.addEventListener('resize', this, false);
- window.addEventListener('contextmenu', this, false);
- window.addEventListener('CanvasContentAdded', this, false);
-
- this.canvasMain.addEventListener('DOMMouseScroll', this, false);
- this.indicatorBar.addEventListener('DOMMouseScroll', this, false);
-
- if(option){
- for(var i in option){this[i] = option[i]}
- }
-
- this.cachedContents = [];
-
- if (this.readParameter()) {
- this.startPresentation();
- }
-
- document.documentElement.focus();
- },
-
-/* core */
-
- startPresentation : function()
- {
- if (this.data.length)
- document.title = this.data[0].title || this.data[0].header || this.data[0].text.join(' ');
-
- this.takahashi();
- },
-
-/* rendering */
-
- takahashi : function() {
- this.isRendering = true;
-
- 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);
-
-
- this.header.removeAttribute('style');
- this.footer.removeAttribute('style');
- this.content.removeAttribute('style');
-
- this.clickableNodes = [];
-
-
- if ('title' in this.data[this.offset])
- document.title = this.data[this.offset].title;
-
- this.header.setAttribute('style', 'font-size:10px;');
- this.header.value = this.data[this.offset].header;
- this.footer.setAttribute('style', 'font-size:10px;');
- this.footer.value = this.data[this.offset].footer;
-
- var page = this.content.getAttribute('page');
- var range = document.createRange();
- range.selectNodeContents(this.content);
- this.cachedContents[page] = !this.content.hasChildNodes() ? null : {
- fragment : range.extractContents(),
- offsetWidth : parseInt(this.content.getAttribute('offsetWidth')),
- offsetHeight : parseInt(this.content.getAttribute('offsetHeight'))
- };
- range.detach();
-
-
- if (this.data[this.offset].load) {
- this.isRendering = false;
- location.replace(location.href.split('?')[0] + '?'+this.data[this.offset].load);
- return;
- }
-
- var content = (this.offset in this.cachedContents && this.cachedContents[this.offset]) ?
- this.cachedContents[this.offset] :
- this.createContent();
-
- this.content.setAttribute('style', 'font-size:10px;');
- this.content.setAttribute('page', this.offset);
- this.content.setAttribute('offsetWidth', content.offsetWidth);
- this.content.setAttribute('offsetHeight', content.offsetHeight);
-
- this.content.appendChild(content.fragment);
-
- this.clickableNodes.push(this.content);
-
-
- this.fitHeaderFooterToCanvas();
- this.fitMainContentToCanvas();
-
-
- try {
- var checkedItems = this.list.getElementsByAttribute('checked', 'true');
- max = checkedItems.length;
- for (i = max-1; i > -1 ; i--)
- checkedItems[i].removeAttribute('checked');
- }
- catch(e) {
- }
-
- this.list.getElementsByAttribute('value', this.offset)[0].setAttribute('checked', true);
-
- this.canvas.removeAttribute('rendering');
- this.isRendering = false;
- this.setHash('page', 'page'+(this.offset+1));
-
- this.next.value = (this.offset <= this.data.length-2) ? (this.data[this.offset+1].plain.join('') || this.data[this.offset+1].text.join('')).replace(/\s+/g, ' ') : '(no page)' ;
- this.remainder.setAttribute('value', this.offset == 0 ? 0 : parseInt(((this.offset)/(this.data.length-1))*100));
-
- var event = document.createEvent('Events');
- event.initEvent('PresentationRedraw', false, true);
- this.canvas.dispatchEvent(event);
- },
-
- createContent : function()
- {
- var retVal = {
- offsetWidth : 0,
- offsetHeight : 0
- };
- var text = this.data[this.offset].text;
- var line;
- var newLine;
- var uri;
- var image_width;
- var image_height;
- var image_src;
-
- var labelId = 0;
- var lineRegExp = this.makePhraseRegExp('^([^%O]+)?(%O%Oem:((.+?)(:em)?%C%C)?|%O%O(raw|encoded):((.+?)(:raw|:encoded)?%C%C)?|%O%Opre:((.+?)(:pre)?%C%C)?|%O%O\#[^:]+:((.+?)%C%C)?|%O%Oima?ge? +src="([^"]+)" +width="([0-9]+)" +height="([0-9]+)"[^%C]*%C%C|%O%O(([^\|]+)?\\||)([^%C]+)%C%C|%O([^%C]+)%C)(.+)?', 'i');
-
- var emRegExp = this.makePhraseRegExp('^([^%O]+)?%O%Oem({([^}]*)})?:(.+?)()?%C%C', 'i');
- var emStartRegExp = this.makePhraseRegExp('^([^%O]+)?%O%Oem({([^}]*)})?:(.*)', 'i');
- var emEndRegExp = this.makePhraseRegExp('^(.*?)((:em)?%C%C)', 'i');
-
- var preRegExp = this.makePhraseRegExp('^([^%O]+)?%O%Opre({([^}]*)})?:(.+?)(:pre)?%C%C', 'i');
- var preStartRegExp = this.makePhraseRegExp('^([^%O]+)?%O%Opre({([^}]*)})?:(.*)', 'i');
- var preEndRegExp = this.makePhraseRegExp('^(.*?)((:pre)?%C%C)', 'i');
-
- var rawRegExp = this.makePhraseRegExp('^([^%O]+)?%O%O(raw|encoded)({([^}]*)})?:(.+?)(:raw|:encoded)?%C%C', 'i');
- var rawStartRegExp = this.makePhraseRegExp('^([^%O]+)?%O%O(raw|encoded)({([^}]*)})?:(.*)', 'i');
- var rawEndRegExp = this.makePhraseRegExp('^(.*?)((:raw|:encoded)?%C%C)', 'i');
-
- var styleRegExp = this.makePhraseRegExp('^([^%O]+)?%O%O(#([^:{]*))?({([^}]*)})?:(.+?)%C%C', '');
- var styleStartRegExp = this.makePhraseRegExp('^([^%O]+)?%O%O(#([^:{]*))?({([^}]*)})?:(.*)', '');
- var styleEndRegExp = this.makePhraseRegExp('^(.*?)(%C%C)', '');
-
- var imagesRegExp = this.makePhraseRegExp('^([^%O]+)?%O%Oima?ge? +src="([^"]+)" +width="([0-9]+)" +height="([0-9]+)"[^%C]*%C%C', 'i');
-
- var linksRegExp = this.makePhraseRegExp('^([^%O]+)?%O%O(([^|]+)?\\||)([^%C]+)%C%C', '');
-
- var montaRegExp = this.makePhraseRegExp('^([^%O]+)?%O([^%C]+)%C', '');
-
- var inBlock = false,
- blockClass = '',
- blockStyle = '',
- blockContents = [];
-
- var inGrid = false,
- gridContents = null;
-
- var fragment = document.createDocumentFragment();
-
- var lineBox;
- for (var i = 0, max = text.length; i < max; i++)
- {
- lineBox = document.createElement('hbox');
- lineBox.setAttribute('align', 'center');
- lineBox.setAttribute('pack', this.data[this.offset].align);
-
- line = text[i];
- image_width = 0;
- image_height = 0;
- if (!line) line = ' ';
-
- if (inBlock) {
- if (blockClass == 'raw' &&
- rawEndRegExp.test(line)) {
- inBlock = false;
- blockContents.push(RegExp.$1);
- line = line.substring((RegExp.$1+RegExp.$2).length);
-
- eval('var xml = <hbox class="raw" style="blockStyle" onclick="event.stopPropagation();" onkeypress="event.stopPropagation();">'+blockContents.join('\n')+'</hbox>;');
- importNodeTreeWithDelay(importE4XNode(xml, document, XULNS), lineBox, XULNS);
-
- blockClass = '';
- blockStyle = '';
- blockContents = [];
- }
- else if (blockClass == 'preformatted-text' &&
- preEndRegExp.test(line)) {
- inBlock = false;
- blockContents.push(RegExp.$1);
- line = line.substring((RegExp.$1+RegExp.$2).length);
-
- lineBox.appendChild(document.createElement('description'));
- lineBox.lastChild.setAttribute('class', 'preformatted-text block');
- if (blockStyle)
- lineBox.lastChild.setAttribute('style', blockStyle);
- lineBox.lastChild.appendChild(document.createTextNode(
- blockContents.join('\n')
- .replace(/^[\r\n\s]+/, '')
- .replace(/[\r\n\s]+$/, '')
- .replace(/&/g, '&')
- .replace(/"/g, '"')
- .replace(/>/g, '>')
- .replace(/</g, '<')
- ));
-
- blockClass = '';
- blockStyle = '';
- blockContents = [];
- }
- else if (emEndRegExp.test(line) || styleEndRegExp.test(line)) {
- inBlock = false;
- blockContents.push(RegExp.$1);
- line = line.substring((RegExp.$1+RegExp.$2).length);
-
- lineBox.appendChild(document.createElement('vbox'));
- lineBox.lastChild.setAttribute('class', blockClass+' block');
- if (blockStyle)
- lineBox.lastChild.setAttribute('style', blockStyle);
- lineBox.lastChild.setAttribute('align', this.data[this.offset].align);
- blockContents = blockContents.join('\n')
- .replace(/^[\r\n\s]+/, '')
- .replace(/[\r\n\s]+$/, '')
- .split('\n');
- for (var j = 0, jmax = blockContents.length; j < jmax; j++)
- {
- lineBox.lastChild.appendChild(document.createElement('description'));
- lineBox.lastChild.lastChild.setAttribute('value', blockContents[j]);
- }
-
- blockClass = '';
- blockStyle = '';
- blockContents = [];
- }
- else {
- blockContents.push(line);
- continue;
- }
- }
-
- if (line.indexOf('|') == 0) {
- fragment.appendChild(lineBox);
-
- if (fragment.childNodes.length == 1 ||
- !fragment.childNodes[fragment.childNodes.length-2] ||
- !fragment.childNodes[fragment.childNodes.length-2].lastChild ||
- fragment.childNodes[fragment.childNodes.length-2].lastChild.localName != 'grid') {
- fragment.lastChild.appendChild(document.createElement('grid'));
- fragment.lastChild.lastChild.appendChild(document.createElement('columns'));
- fragment.lastChild.lastChild.appendChild(document.createElement('rows'));
- }
- else {
- fragment.removeChild(fragment.lastChild);
- }
- fragment.lastChild.lastChild.lastChild.appendChild(document.createElement('row'));
- fragment.lastChild.lastChild.lastChild.lastChild.setAttribute('flex', 1);
-
- line = line.split('|');
- for (var j = 1, jmax = line.length; j < jmax; j++)
- {
- fragment.lastChild.lastChild.lastChild.lastChild.appendChild(document.createElement('vbox'));
- fragment.lastChild.lastChild.lastChild.lastChild.lastChild.setAttribute('align', this.data[this.offset].align);
- fragment.lastChild.lastChild.lastChild.lastChild.lastChild.setAttribute('pack', 'center');
- if (line[j].charAt(0) == '~') {
- fragment.lastChild.lastChild.lastChild.lastChild.lastChild.setAttribute('class', 'special');
- line[j] = line[j].substring(1);
- }
- line[j] = line[j].split(/<br\s*\/>/g);
- for (var k = 0, kmax = line[j].length; k < kmax; k++)
- {
- fragment.lastChild.lastChild.lastChild.lastChild.lastChild.appendChild(document.createElement('description'));
- fragment.lastChild.lastChild.lastChild.lastChild.lastChild.lastChild.appendChild(document.createTextNode(line[j][k].replace(/^\s+|\s+$/g, '')));
- }
- if (fragment.lastChild.lastChild.firstChild.childNodes.length < j) {
- fragment.lastChild.lastChild.firstChild.appendChild(document.createElement('column'));
- fragment.lastChild.lastChild.firstChild.lastChild.setAttribute('flex', 1);
- }
- }
- continue;
- }
-
-
- while (line.match(lineRegExp))
- {
- if (RegExp.$1) {
- lineBox.appendChild(document.createElement('description'));
- lineBox.lastChild.setAttribute('value', RegExp.$1);
- }
- newLine = line.substring((RegExp.$1+RegExp.$2).length);
-
- // Raw Codes: Parsed as XML
- if (rawRegExp.test(line)) {
- eval('var xml = <hbox class="raw" style="'+RegExp.$4+'" onclick="event.stopPropagation();" onkeypress="event.stopPropagation();">'+RegExp.$5+'</hbox>;');
- importNodeTreeWithDelay(importE4XNode(xml, document, XULNS), lineBox, XULNS);
- }
- else if (rawStartRegExp.test(line)) {
- inBlock = true;
- blockClass = 'raw';
- blockStyle = RegExp.$4;
- blockContents = [RegExp.$5];
- newLine = '';
- }
-
- // Preformatted Text
- if (preRegExp.test(line)) {
- lineBox.appendChild(document.createElement('description'));
- if (RegExp.$3)
- lineBox.lastChild.setAttribute('style', RegExp.$3);
- lineBox.lastChild.setAttribute('value', RegExp.$4);
- lineBox.lastChild.setAttribute('class', 'preformatted-text');
- }
- else if (preStartRegExp.test(line)) {
- inBlock = true;
- blockClass = 'preformatted-text';
- blockStyle = RegExp.$3;
- blockContents = [RegExp.$4];
- newLine = '';
- }
-
- // Emphasis
- else if (emRegExp.test(line)) {
- lineBox.appendChild(document.createElement('description'));
- if (RegExp.$3)
- lineBox.lastChild.setAttribute('style', RegExp.$3);
- lineBox.lastChild.setAttribute('value', RegExp.$4);
- lineBox.lastChild.setAttribute('class', 'em-text');
- }
- else if (emStartRegExp.test(line)) {
- inBlock = true;
- blockClass = 'em-text';
- blockStyle = RegExp.$3;
- blockContents = [RegExp.$4];
- newLine = '';
- }
-
- // User-defined Styles
- else if (styleRegExp.test(line)) {
- lineBox.appendChild(document.createElement('description'));
- lineBox.lastChild.setAttribute('class', RegExp.$3);
- if (RegExp.$5)
- lineBox.lastChild.setAttribute('style', RegExp.$5);
- lineBox.lastChild.setAttribute('value', RegExp.$6);
- }
- else if (styleStartRegExp.test(line)) {
- inBlock = true;
- blockClass = RegExp.$3;
- blockStyle = RegExp.$5;
- blockContents = [RegExp.$6];
- newLine = '';
- }
-
- // Images
- else if (imagesRegExp.test(line)) {
- lineBox.appendChild(document.createElement('image'));
- image_src = RegExp.$2;
- if (image_src.indexOf('http://') < 0 &&
- image_src.indexOf('https://') < 0 &&
- image_src.indexOf('data:') < 0)
- image_src = this.dataFolder+image_src;
- lineBox.lastChild.setAttribute('src', image_src);
- lineBox.lastChild.setAttribute('width', parseInt(RegExp.$3 || '0'));
- lineBox.lastChild.setAttribute('height', parseInt(RegExp.$4 || '0'));
- image_width += parseInt(RegExp.$3 || '0');
- image_height = Math.max(image_height, parseInt(RegExp.$4 || '0'));
- }
-
- // Links
- else if (linksRegExp.test(line)) {
- uri = RegExp.$4;
- if (uri.indexOf('://') < 0)
- uri = this.dataFolder+uri;
- lineBox.appendChild(document.createElement('description'));
- lineBox.lastChild.setAttribute('value', RegExp.$3 || RegExp.$4);
- lineBox.lastChild.setAttribute('href', uri);
- lineBox.lastChild.setAttribute('tooltiptext', uri);
- lineBox.lastChild.setAttribute('statustext', uri);
- lineBox.lastChild.setAttribute('class', 'link-text');
-
- this.clickableNodes.push(lineBox.lastChild);
- }
-
- // Monta
- else if (montaRegExp.test(line)) {
- lineBox.appendChild(document.createElement('stack'));
-
- lineBox.lastChild.appendChild(document.createElement('description'));
- lineBox.lastChild.lastChild.setAttribute('value', RegExp.$2);
- lineBox.lastChild.lastChild.setAttribute('class', 'monta-text');
-
- lineBox.lastChild.appendChild(document.createElement('spacer'));
- lineBox.lastChild.lastChild.setAttribute('flex', 1);
- lineBox.lastChild.lastChild.setAttribute('class', 'monta-label');
-
- lineBox.lastChild.lastChild.setAttribute('label-id', 'label-' + (++labelId));
-
- lineBox.lastChild.lastChild.setAttribute('monta-hidden', 'true');
-
- this.clickableNodes.push(lineBox.lastChild.lastChild);
- }
-
- line = newLine;
- }
-
- if (line) {
- lineBox.appendChild(document.createElement('description'));
- lineBox.lastChild.setAttribute('value', line);
- }
-
- retVal.offsetWidth = Math.max(retVal.offsetWidth, image_width);
- retVal.offsetHeight += image_height;
-
- if (lineBox.hasChildNodes())
- fragment.appendChild(lineBox);
- }
-
- retVal.fragment = fragment;
- return retVal;
- },
-
- fitToCanvas : function(aContent, aCanvas, aOffsetWidth, aOffsetHeight)
- {
- aContent.removeAttribute('style');
- aContent.setAttribute('style', 'font-size:10px;');
-
- var grids = aContent.getElementsByTagName('grid');
- var gridsCount = grids.length;
-
- if (!aContent.boxObject.width) return;
-
- var canvas_w = aCanvas.boxObject.width;
- var canvas_h = aCanvas.boxObject.height-aOffsetHeight;
-
- var content_w = aContent.boxObject.width;
- var new_fs = Math.round((canvas_w/content_w) * this.data[this.offset].size);
- aContent.setAttribute('style', 'font-size:'+ new_fs + "px");
-
- for (var i = 0; i < gridsCount; i++)
- {
- grids[i].firstChild.lastChild.removeAttribute('flex', 1);
- grids[i].firstChild.lastChild.setAttribute('flex', 1);
- }
-
- if (aContent.boxObject.width < aOffsetWidth) {
- content_w = aOffsetWidth;
- new_fs = Math.round((canvas_w/content_w) * this.data[this.offset].size);
- aContent.setAttribute('style', 'font-size:'+ new_fs + "px");
-
- for (var i = 0; i < gridsCount; i++)
- {
- grids[i].firstChild.lastChild.removeAttribute('flex', 1);
- grids[i].firstChild.lastChild.setAttribute('flex', 1);
- }
- }
-
- var content_h = aContent.boxObject.height;
- if(content_h >= canvas_h){
- state='height';
- content_h = aContent.boxObject.height;
- new_fs = Math.round((canvas_h/content_h) * new_fs);
- aContent.setAttribute('style', 'font-size:'+ new_fs + "px");
-
- for (var i = 0; i < gridsCount; i++)
- {
- grids[i].firstChild.lastChild.removeAttribute('flex', 1);
- grids[i].firstChild.lastChild.setAttribute('flex', 1);
- }
- }
- },
-
- fitMainContentToCanvas : function()
- {
- this.fitToCanvas(
- this.content,
- this.canvas,
- parseInt(this.content.getAttribute('offsetWidth')),
- parseInt(this.content.getAttribute('offsetHeight'))
- +this.header.boxObject.height
- +this.footer.boxObject.height
- );
- },
-
- fitHeaderFooterToCanvas : function()
- {
- this.fitToCanvas(this.header, this.header.parentNode, 0, 0);
- this.fitToCanvas(this.footer, this.footer.parentNode, 0, 0);
- },
-
- get offset(){
- return this._offset;
- },
- set offset(aValue){
- this._offset = parseInt(aValue || 0);
- document.documentElement.setAttribute('lastoffset', this.offset);
- return this.offset;
- },
-
-/* data I/O */
-
- setHash : function(aKey, aValue)
- {
- aKey = String(aKey).toLowerCase();
- var hashArray = String(location.hash).replace(/^#/, '').toLowerCase().split(',');
-
- for (var i = hashArray.length-1; i > -1; i--)
- if (!hashArray[i] || hashArray[i].indexOf(aKey) == 0)
- hashArray.splice(i, 1);
-
- if (aValue) hashArray.push(aValue);
- hashArray.sort();
-
- location.replace(location.href.replace(/#.*$/, '') + (hashArray.length ? '#' + hashArray.join(',') : '' ));
- },
-
- get data(){
- var codes = document.getElementById('builtinCode');
- if (!this._data) {
- // mozilla splits very long text node into multiple text nodes whose length is less than 4096 bytes.
- // so, we must concat all the text nodes.
- this.source.value = "";
- this.sourceData = [];
- for (var i = 0; i < codes.childNodes.length; i++) {
- this.source.value += codes.childNodes[i].nodeValue;
- }
-
- this._data = this.source.value.split(/----+/);
- this.initData();
- }
- if (codes)
- codes.parentNode.removeChild(codes);
-
- return this._data;
- },
- set data(aValue){
- this._data = aValue.split(/----+/);
- this.initData();
- return this._data;
- },
-
- initData : function()
- {
- var range = document.createRange();
-
- range.selectNodeContents(this.list);
- range.deleteContents();
-
-
- this.sourceData = [];
-
-
- var regexp = [
- /^[\r\n\s]+|[\r\n\s]+$/g,
- /(\r\n|[\r\n])/g
- ];
-
- var title;
- var titleRegExp = /^(TITLE::)([^\n]*)\n?/im;
- var header = '';
- var headerRegExp = /^(HEADER::)([^\n]*)\n?/im;
- var footer = '';
- var footerRegExp = /^(FOOTER::)([^\n]*)\n?/im;
- var chapter = '';
- var chapterRegExp = /^(CHAPTER::)([^\n]*)\n?/im;
- var lastChapter;
- var alignGlobal = 'center';
- var align;
- var alignRegExp = /^((GLOBAL-)?ALIGN::)(left|right|center|start|end)?\n?/im;
- var size;
- var sizeGlobal = 9;
- var sizeRegExp = /^((GLOBAL-)?SIZE::)(\d+(\.\d+)?)\n?/im;
-
- var imageMatchResults;
- var imagesRegExp = this.makePhraseRegExp('%O%Oima?ge? +src="[^"]+" +width="[0-9]+" +height="[0-9]+"[^%C]*%C%C', 'gi');
- var imagesRegExp2 = this.makePhraseRegExp('%O%Oima?ge? +src="([^"]+)"', 'i');
- var image_src;
-
- var plainTextRegExp = this.makePhraseRegExp('(%O%O\#[^:]+:(.+)%C%C|%O%OEM:(.+)(:EM)?%C%C|%O%OPRE:(.+)(:PRE)?%C%C|%O%Oima?ge? +src="[^"]*"[^%C]+%C%C|%O%O([^\\|%C]+)(\\|[^%C]+)?%C%C|%O([^%O]+)%C)', 'gi');
-
- var hiddenRegExp = /^(HIDDEN|IGNORE)::true\n?/im;
-
- var loadRegExp = /^LOAD::(.+)\n?/im;
- var timerRegExp = /^SET-TIMER::(\d+)(.*)\n?/im;
-
- var dataObj;
- var i, j,
- max = this._data.length;
- var menuContents = document.createDocumentFragment();
- var popup;
-
- var dataPath;
- for (i = 0; i < max; i++)
- {
- image_src = null;
- align = null;
- size = null;
- dataPath = '';
-
- this._data[i] = this._data[i]
- .replace(regexp[0], '')
- .replace(regexp[1], '\n');
-
- this.sourceData[i] = this._data[i];
-
- if (loadRegExp.test(this._data[i])) {
- this._data[i] = this._data[i].replace(loadRegExp, '');
- dataPath = RegExp.$1;
- }
-
- if (timerRegExp.test(this._data[i])) {
- this._data[i] = this._data[i].replace(timerRegExp, '');
- window.setTimeout(function(aSelf, aTime, aUnit) {
- if (!aSelf.timerTimer) {
- switch(aUnit)
- {
- case 's':
- case 'sec':
- case 'sec.':
- case 'second':
- case 'seconds':
- aTime = aTime / 60;
- break;
-
- case 'h':
- case 'hour':
- case 'hours':
- aTime = aTime * 60;
- break;
-
- default:
- break;
- }
- aSelf.setTimer(aTime);
- }
- }, 100, this, parseInt(RegExp.$1), (RegExp.$2 || '').toLowerCase());
- }
-
- if (hiddenRegExp.test(this._data[i])) {
- this._data.splice(i, 1);
- max--;
- i--;
- continue;
- }
-
- while (titleRegExp.test(this._data[i])) {
- this._data[i] = this._data[i].replace(titleRegExp, '');
- if (String(RegExp.$1).toUpperCase() == 'TITLE::')
- title = RegExp.$2 || '' ;
- }
-
- while (headerRegExp.test(this._data[i])) {
- this._data[i] = this._data[i].replace(headerRegExp, '');
- if (String(RegExp.$1).toUpperCase() == 'HEADER::')
- header = RegExp.$2 || '' ;
- }
-
- while (footerRegExp.test(this._data[i])) {
- this._data[i] = this._data[i].replace(footerRegExp, '');
- if (String(RegExp.$1).toUpperCase() == 'FOOTER::')
- footer = RegExp.$2 || '' ;
- }
-
- while (chapterRegExp.test(this._data[i])) {
- this._data[i] = this._data[i].replace(chapterRegExp, '');
- if (String(RegExp.$1).toUpperCase() == 'CHAPTER::')
- chapter = RegExp.$2 || '' ;
- }
-
- while (alignRegExp.test(this._data[i])) {
- this._data[i] = this._data[i].replace(alignRegExp, '');
-
- align = (RegExp.$3 || '').toLowerCase();
- if (align == 'left')
- align = 'start';
- else if (align == 'right')
- align = 'end';
-
- if (String(RegExp.$1).toUpperCase() == 'GLOBAL-ALIGN::') {
- alignGlobal = align;
- align = null;
- }
- }
-
- while (sizeRegExp.test(this._data[i])) {
- this._data[i] = this._data[i].replace(sizeRegExp, '');
- size = Math.max(0, Number(RegExp.$3 || this.baseSize));
- if (String(RegExp.$1).toUpperCase() == 'GLOBAL-SIZE::') {
- sizeGlobal = size;
- size = null;
- }
- }
-
- imageMatchResults = this._data[i].match(imagesRegExp);
- if (imageMatchResults) {
- for (j = imageMatchResults.length-1; j > -1; j--)
- image_src = this.preloadImage(imageMatchResults[j].match(imagesRegExp2)[1]);
- }
-
- this._data[i] = {
- load : dataPath,
- header : header,
- footer : footer,
- text : this._data[i].split('\n'),
- image : image_src,
- align : align || alignGlobal,
- size : size || sizeGlobal
- };
- this._data[i].plain = this._data[i].text
- .join('\n')
- .replace(plainTextRegExp, '$2$3$5$7$9')
- .split('\n');
- if (title !== void(0))
- this._data[i].title = title;
-
- this._data[i].chapter = chapter || title || '';
- if (lastChapter === void(0) ||
- lastChapter != this._data[i].chapter) {
- lastChapter = this._data[i].chapter;
-
- if (popup && popup.childNodes.length == 1) {
- menuContents.removeChild(menuContents.lastChild);
- menuContents.appendChild(popup.removeChild(popup.lastChild));
- }
-
- popup = document.createElement('menupopup');
- menuContents.appendChild(document.createElement('menu'));
- menuContents.lastChild.setAttribute('label', this._data[i].chapter);
- menuContents.lastChild.appendChild(popup);
- }
-
- popup.appendChild(document.createElement('menuitem'));
- popup.lastChild.setAttribute('type', 'radio');
- popup.lastChild.setAttribute('radiogroup', 'pages');
- popup.lastChild.setAttribute('label', (i+1)+': '+(
- (this._data[i].plain.join('') || this._data[i].text.join(' ')).replace(/\s+/g, ' ')
- ));
- popup.lastChild.setAttribute('value', i);
-
-// if (image_src) {
-// popup.lastChild.setAttribute('image', image_src);
-// popup.lastChild.setAttribute('class', 'menuitem-iconic');
-// }
- }
-
- if (menuContents.childNodes.length == 1) {
- range.selectNodeContents(menuContents.firstChild.firstChild);
- menuContents = range.extractContents();
- }
- this.list.appendChild(menuContents);
-
- range.detach();
-
-
- this.shownMontaLabels = [];
- },
-
- get dataPath(){
- if (!this._dataPath)
- this.dataPath = String(location.href).replace(/#.+$/, '');
- 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;
- },
-
- loadData : function(aPath)
- {
- this.dataPath = aPath;
- var request = new XMLHttpRequest();
- request.open('GET', aPath);
- request.onload = function() {
- Presentation.data = request.responseText;
- Presentation.init();
- };
- request.send(null);
- },
-
- readParameter : function() {
- if (location.search || location.hash) {
- var param = location.search.replace(/^\?/, '');
-
- if (location.hash.match(/page([0-9]+)/i) ||
- param.match(/page=([0-9]+)/i))
- this.offset = parseInt(RegExp.$1)-1;
-
- if (location.hash.match(/edit/i) ||
- param.match(/edit=(1|true|yes)/i)) {
- window.setTimeout('Presentation.toggleEditMode();', 0);
- }
-
- if (location.hash.match(/eva/i) ||
- param.match(/eva=(1|true|yes)/i))
- this.toggleEvaMode();
-
- if (location.hash.match(/timer(\d+)\-(\d+)/i))
- this.setTimer(RegExp.$1, RegExp.$2);
-
- if (param.match(/(style|css)=([^&;]+)/i)) {
- var style = unescape(RegExp.$2);
- var pi = document.createProcessingInstruction('xml-stylesheet', 'href="'+style+'" type="text/css"');
- document.insertBefore(pi, document.documentElement);
- }
-
- if (param.match(/data=([^&;]+)/i)) {
- this.loadData(RegExp.$1);
- return false;
- }
- }
- return true;
- },
-
- preloadImage : function(aURI)
- {
- if (aURI in this.imageRequests) return;
-
- if (aURI.indexOf('http://') < 0 &&
- aURI.indexOf('https://') < 0)
- aURI = this.dataFolder+aURI;
-
- this.imageRequests[aURI] = new XMLHttpRequest();
- try {
- this.imageRequests[aURI].open('GET', aURI);
- this.imageRequests[aURI].onload = function() {
- Presentation.imageRequests[aURI] = null;
- };
- this.imageRequests[aURI].send(null);
- }
- catch(e) {
- this.imageRequests[aURI] = null;
- }
- return aURI;
- },
- imageRequests : {},
-
-/* commands */
-
- reload : function() {
- var file = String(location.href).replace(/#.+$/, '');
- if (this.dataPath != file) {
- var path = this.dataPath;
- var request = new XMLHttpRequest();
- request.open('GET', path);
- request.onload = function() {
- Presentation.data = request.responseText;
- Presentation.init();
-
- path = null;
- request = null;
- };
- request.send(null);
- }
- else
- window.location.reload();
- },
-
- forward : function(){
- if (!this.canForward) return;
- this.offset++;
- this.takahashi();
- },
-
- forwardStep : function(){
- if (!this.canForward) return;
- var monta = document.getElementsByAttribute('monta-hidden', 'true');
- if (monta && monta.length) {
- this.showMontaKeyword(monta[0]);
- }
- else
- this.forward();
- },
-
- back : function(){
- if (!this.canBack) return;
- this.offset--;
- if(this.offset < 0){this.offset = 0}
- this.takahashi();
- },
-
- home : function(){
- if (!this.canMove) return;
- this.offset = 0;
- this.takahashi();
- },
-
- end : function(){
- if (!this.canMove) return;
- this.offset = this.data.length-1;
- this.takahashi();
- },
-
- showPage : function(aPageOffset){
- if (!this.canMove) return;
- this.offset = aPageOffset ? aPageOffset : 0 ;
- this.takahashi();
- },
-
- toggleEditMode : function()
- {
- if (this.deck.selectedIndex == 1) {
- if (document.getElementById('editTabBox').selectedTab.id == 'editTab-pages') {
- this.source.value = this.sourceData.join('\n----\n');
- }
- this.data = this.source.value;
- this.cachedContents = [];
- var range = document.createRange();
- range.selectNodeContents(this.content);
- range.deleteContents();
- range.detach();
- this.init();
- }
- else {
- this.initEditPages();
- }
-
- this.deck.selectedIndex = this.deck.selectedIndex == 0 ? 1 : 0 ;
- this.setHash('edit', this.deck.selectedIndex == 0 ? '' : 'edit' );
- },
-
- toggleEvaMode : function()
- {
- var check = document.getElementById('toggleEva');
- if (this.canvas.getAttribute('eva') == 'true') {
- this.canvas.removeAttribute('eva');
- this.logo.removeAttribute('eva');
- check.checked = false;
- }
- else {
- this.canvas.setAttribute('eva', true);
- this.logo.setAttribute('eva',true);
- check.checked = true;
- }
- this.setHash('eva', check.checked ? 'eva' : '' );
- },
-
-/* auto cruise */
-
- toggleAutoCruiseMode : function()
- {
- var autoCruise = document.getElementById('autoButton');
- if(!autoCruise.checked)
- this.startAutoCruise();
- else
- autoCruise.checked = false;
- },
-
- startAutoCruise : function()
- {
- var autoCruise = document.getElementById('autoButton');
- autoCruise.checked = true;
-
- if (this.autoCruiseTimer) {
- window.clearTimeout(this.autoCruiseTimer);
- }
- this.autoCruiseTimer = window.setTimeout(this.autoCruise, this.autoCruiseInterval);
- },
-
- changeAutoCruiseInterval : function(aInterval)
- {
- this.autoCruiseInterval = aInterval;
- this.startAutoCruise();
- },
-
- autoCruise : function()
- {
- var autoCruise = document.getElementById('autoButton');
- if (!autoCruise.checked) return;
-
- if (Presentation.offset == Presentation.data.length-1) {
- if (Presentation.canMove)
- Presentation.home();
- }
- else {
- if (Presentation.canForward)
- Presentation.forwardStep();
- }
- Presentation.autoCruiseTimer = window.setTimeout(arguments.callee, Presentation.autoCruiseInterval);
- },
- autoCruiseTimer : null,
-
-/* timer */
-
- resetTimer : function()
- {
- if (this.timerTimer) {
- window.clearInterval(this.timerTimer);
- this.timerTimer = null;
- }
- this.timer.setAttribute('value', 0);
- this.timer.setAttribute('collapsed', true);
- this.setHash('timer', '');
- },
-
- setTimer : function(aStart, aEnd)
- {
- var now = (new Date()).getTime();
- if (aStart !== void(0) && aEnd === void(0)) {
- var rest = Math.abs(aStart);
- this.timerStart = now;
- this.timerEnd = this.timerStart + (rest * 60000);
- }
- else if (aStart === void(0) && aEnd === void(0)) {
- var rest = prompt('Remaining Time (minits)');
- if (rest == '') {
- this.resetTimer();
- return;
- }
- else {
- rest = Number(rest);
- if (!rest || isNaN(rest)) return;
- }
-
- rest = Math.abs(rest);
- this.timerStart = now;
- this.timerEnd = this.timerStart + (rest * 60000);
- }
- else {
- aStart = Number(aStart);
- aEnd = Number(aEnd);
- if (isNaN(aStart) || isNaN(aEnd)) return;
-
- this.timerStart = Math.min(aStart, aEnd);
- this.timerEnd = Math.max(aStart, aEnd);
-
- if (this.timerStart >= now || this.timerEnd <= now) return;
- }
-
- this.resetTimer();
-
- this.timer.removeAttribute('collapsed');
- this.setHash('timer', 'timer'+this.timerStart+'-'+this.timerEnd);
-
- if (now != this.timerStart)
- this.updateTimer(this);
-
- this.timerTimer = window.setInterval(this.updateTimer, Math.min(this.timerUpdatingInterval, (this.timerEnd-this.timerStart)/(this.data.length*2)), this);
- },
-
- timerStart : 0,
- timerEnd : 0,
- timerTimer : null,
-
- updateTimer : function(aThis)
- {
- var now = (new Date()).getTime();
- if (now >= aThis.timerEnd) {
- aThis.resetTimer();
- aThis.timer.setAttribute('value', 100);
- aThis.timer.removeAttribute('collapsed');
- aThis.setHash('timer', '');
- }
- else {
- var value = parseInt(((now - aThis.timerStart) / (aThis.timerEnd - aThis.timerStart)) * 100);
- aThis.timer.setAttribute('value', value);
- }
- },
-
- updateTimerItem : function()
- {
- var item = document.getElementById('timerItem');
- if (this.timerTimer) {
- item.setAttribute('label', item.getAttribute('label-active').replace(/%s/gi, Math.round((this.timerEnd - (new Date()).getTime()) / 60000)));
- }
- else {
- item.setAttribute('label', item.getAttribute('label-normal'));
- }
- },
-
-/* print */
-
- print : function()
- {
- if (!this.canMove) {
- alert('Please wait for a while, and retry later.');
- return;
- }
-
- this.stopPrint();
- if (this.printWindow) {
- this.printWindow.close();
- this.printWindow = null;
- }
-
- if (!this.isToolbarHidden)
- this.showHideToolbar(true);
-
- this.printWindow = window.open('output.htm', 'PresentationPrint', 'dependent=yes,hotkeys=yes,location=yes,menubar=yes,personalbar=yes,scrollbars=yes,status=yes,toolbar=yes');
- if (!this.printWindow) return;
-
- this.isPrinting = true;
-
- if (!this.printCanvas)
- this.printCanvas = document.createElementNS(XHTMLNS, 'canvas');
-
- this.printWindow.document.write('<html><head><title>'+document.title+'</title></head><body></body></html>');
- this.home();
- this.printTimer = window.setInterval(this.printCallback, 0, this);
- },
-
- printCallback : function(aThis)
- {
- if (
- !aThis.canMove
- )
- return;
-
- var monta = document.getElementsByAttribute('monta-hidden', 'true');
- if (monta && monta.length) {
- for (var i = monta.length-1; i > -1; i--)
- aThis.showMontaKeyword(monta[i], true);
- }
-
- var doc = aThis.printWindow.document;
- var body = doc.getElementsByTagName('body')[0];
- var img = doc.createElement('img');
-
- if ((aThis.offset+1) % 2 == 1) {
- body.appendChild(doc.createElement('div'));
-// body.lastChild.style.clear = 'both';
- }
- var box = doc.createElement('div');
- box.appendChild(doc.createElement('div'));
- box.lastChild.appendChild(document.createTextNode(aThis.offset+1));
- body.lastChild.appendChild(box);
-
- var w = window.innerWidth;
- var h = window.innerHeight;
- var canvasW = parseInt(w * aThis.printSize);
- var canvasH = parseInt(h * aThis.printSize);
-
- aThis.printCanvas.width = canvasW;
- aThis.printCanvas.height = canvasH;
- aThis.printCanvas.style.border = 'black solid medium';
-
- img.style.border = 'black solid medium';
- img.style.width = canvasW+'px';
- img.style.height = canvasH+'px';
-
- box.style.margin = '1em';
- box.style.width = parseInt(w * aThis.printSize)+'px';
- box.style.cssFloat = ((aThis.offset+1) % 2 == 1) ? 'left' : 'right' ;
-
- try {
- netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead');
-
- var ctx = aThis.printCanvas.getContext('2d');
- ctx.clearRect(0, 0, canvasW, canvasH);
- ctx.save();
- ctx.scale(aThis.printSize, aThis.printSize);
- ctx.drawWindow(window, 0, 0, w, h, 'rgb(255,255,255)');
- ctx.restore();
- try {
- if (aThis.imageType == 'jpeg')
- img.src = aThis.printCanvas.toDataURL('image/jpeg', 'quality=50');
- else
- img.src = aThis.printCanvas.toDataURL('image/png', 'transparency=none');
-
- box.appendChild(img);
- }
- catch(e) {
- box.appendChild(aThis.printCanvas.cloneNode(true));
- ctx = box.lastChild.getContext('2d');
- ctx.clearRect(0, 0, canvasW, canvasH);
- ctx.save();
- ctx.scale(aThis.printSize, aThis.printSize);
- ctx.drawWindow(window, 0, 0, w, h, 'rgb(255,255,255)');
- ctx.restore();
- }
- }
- catch(e) {
- alert('Error: Failed to create a document for printing.\n\n------\n'+e);
- aThis.stopPrint();
- return;
- }
-
- if (aThis.offset == aThis.data.length-1) {
- aThis.stopPrint();
- aThis.printWindow.focus();
- }
- else {
- aThis.forward();
- }
- },
-
- stopPrint : function()
- {
- window.clearInterval(this.printTimer);
- this.printTimer = null;
- this.isPrinting = false;
- },
-
- printSize : 0.4,
- printTimer : null,
- printWindow : null,
- printCanvas : null,
-
-/* view source */
-
- plainTextShown : false,
-
- get plainTextBox()
- {
- return document.getElementById('plainTextBox');
- },
-
- get plainTextField()
- {
- return document.getElementById('plainTextField');
- },
-
- showPlainText : function()
- {
- if (this.plainTextShown) return;
- this.plainTextShown = true;
- this.plainTextBox.removeAttribute('hidden');
- this.plainTextField.style.width = parseInt(this.canvas.boxObject.width * 0.8)+'px';
- this.plainTextField.style.height = parseInt(this.canvas.boxObject.height * 0.8)+'px';
- this.plainTextField.value = this.data[this.offset].text.join('\n').replace(/\u200b/g, '');
- this.plainTextField.select();
- this.plainTextField.focus();
- },
-
- hidePlainText : function()
- {
- if (!this.plainTextShown) return;
- this.plainTextShown = false;
- this.plainTextBox.setAttribute('hidden', true);
- this.plainTextField.value = '';
- this.plainTextField.blur();
- },
-
-/* state */
-
- get canMove()
- {
- return (
- this.isRendering ||
- importNodeTreeWithDelayTimers ||
- this.montaAnimating
- ) ? false : true ;
- },
-
- get canBack()
- {
- return this.canMove;
- },
-
- get canForward()
- {
- return this.canMove;
- },
-
- get isPresentationMode(){
- return (this.deck.selectedIndex == 0);
- },
-
-/* event handling */
-
- handleEvent : function(aEvent)
- {
- if (this.isPrinting) return;
-
- var node = aEvent.target;
- var inRawContents = false;
- do {
- if (node.nodeType == Node.ELEMENT_NODE &&
- /\braw\b/i.test(node.getAttribute('class'))) {
- inRawContents = true;
- break;
- }
-
- node = node.parentNode;
- }
- while (node.parentNode)
-
-
- switch (aEvent.type)
- {
- default:
- break;
-
- case 'resize':
- this.takahashi(); // redrwa
- break;
-
- case 'contextmenu':
- aEvent.stopPropagation();
- aEvent.preventCapture();
- aEvent.preventDefault();
- aEvent.preventBubble();
- break;
-
-
- case 'mouseup':
- if (inRawContents) return;
- this.dragStartX = -1;
- this.dragStartY = -1;
- if (this.indicatorBar.dragging)
- this.onIndicatorBarDragEnd(aEvent);
- break;
-
- case 'mousedown':
- if (inRawContents) return;
- if (this.dragStartX < 0) {
- this.dragStartX = aEvent.clientX;
- this.dragStartY = aEvent.clientY;
- }
- var box = this.indicatorBar.boxObject;
- if (!(aEvent.screenX < box.screenX ||
- aEvent.screenY < box.screenY ||
- aEvent.screenX > box.screenX+box.width ||
- aEvent.screenY > box.screenY+box.height))
- this.onIndicatorBarDragStart();
- break;
-
- case 'mousemove':
- if (inRawContents) return;
- this.checkShowHideToolbar(aEvent);
- if (this.indicatorBar.dragging) {
- this.onIndicatorBarDragMove(aEvent);
- return;
- }
- if (this.dragStartX > -1) {
- if (Math.abs(this.dragStartX-aEvent.clientX) > Math.abs(this.dragStartDelta) ||
- Math.abs(this.dragStartY-aEvent.clientY) > Math.abs(this.dragStartDelta)) {
- var event = document.createEvent('Events');
- event.initEvent('StartDragOnCanvas', false, true);
- this.canvas.dispatchEvent(event);
- }
- }
- break;
-
- case 'CanvasContentAdded':
- if (this.fitToCanvasTimer) {
- window.clearTimeout(this.fitToCanvasTimer);
- this.fitToCanvasTimer = null;
- }
- this.fitToCanvasTimer = window.setTimeout('Presentation.fitMainContentToCanvas()', 100);
- break;
-
- case 'DOMMouseScroll':
- if (
- (aEvent.detail > 0 && this.scrollCounter < 0) ||
- (aEvent.detail < 0 && this.scrollCounter > 0)
- )
- this.scrollCounter = 0;
-
- this.scrollCounter += aEvent.detail;
- if (Math.abs(this.scrollCounter) >= this.scrollThreshold) {
- if (aEvent.detail > 0)
- Presentation.forwardStep();
- else
- Presentation.back();
-
- this.scrollCounter = 0;
- }
- break;
- }
- },
-
- dragStartX : -1,
- dragStartY : -1,
- scrollCounter : 0,
- scrollThreshold : 10,
-
- onKeyPress : function(aEvent) {
- if (this.isPrinting) return;
-
- switch(aEvent.keyCode)
- {
- case aEvent.DOM_VK_BACK_SPACE:
- if (this.isPresentationMode) {
- aEvent.preventBubble();
- aEvent.preventDefault();
- Presentation.back();
- }
- break;
- default:
- break;
- }
- },
-
-/* actions on presentation */
-
- onPresentationClick : function(aEvent)
- {
- if (this.isPrinting) {
- if (confirm('Do you want printing operation to be stopped?')) {
- this.stopPrint();
- }
- return;
- }
-
- if (!this.isToolbarHidden)
- this.showHideToolbar();
-
- switch(aEvent.button)
- {
- case 0:
- switch (aEvent.target.getAttribute('class'))
- {
- case 'link-text':
- var uri = aEvent.target.getAttribute('href');
- if (uri) {
- window.open(uri);
- return;
- }
- break;
-
- case 'monta-label':
- if (aEvent.target.getAttribute('monta-hidden') == 'true') {
- this.showMontaKeyword(aEvent.target);
- aEvent.preventBubble();
- return;
- }
-
- default:
- break;
- }
- this.forward();
- document.documentElement.focus();
- break;
- case 2:
- this.back();
- document.documentElement.focus();
- break;
- default:
- break;
- }
- },
-
-/* scrollbar */
-
- onScrollerDragStart : function(){
- if (this.isPrinting) return;
-
- this.scroller.dragging = true;
- },
-
- onScrollerDragMove : function(){
- if (this.isPrinting) return;
-
- if (this.scroller.dragging)
- this.showPage(parseInt(this.scroller.getAttribute('curpos')));
- },
-
- onScrollerDragDrop : function(){
- if (this.isPrinting) return;
-
- this.onScrollerDragMove();
- this.scroller.dragging = false;
- },
-
-/* indicator bar */
-
- onIndicatorBarClick : function(aEvent)
- {
- if (this.isPrinting) return;
-
- var bar = this.indicatorBar;
- this.showPage(Math.round((aEvent.screenX - bar.boxObject.screenX) / bar.boxObject.width * this.data.length));
- },
-
- onIndicatorBarDragStart : function()
- {
- if (this.isPrinting) return;
-
- this.indicatorBar.dragging = true;
- },
-
- onIndicatorBarDragMove : function(aEvent)
- {
- if (this.isPrinting) return;
-
- var bar = this.indicatorBar;
- this.showPage(Math.round((aEvent.screenX - bar.boxObject.screenX) / bar.boxObject.width * this.data.length));
- },
-
- onIndicatorBarDragEnd : function(aEvent)
- {
- if (this.isPrinting) return;
-
- this.onIndicatorBarDragMove(aEvent);
- this.indicatorBar.dragging = false;
- },
-
- showMontaKeyword : function(aNode, aWithoutAnimation) {
- if (aNode.getAttribute('monta-hidden') != 'true') return;
-
- if (aWithoutAnimation) {
- aNode.setAttribute('monta-hidden', 'false');
- return;
- }
-
- aNode.setAttribute('monta-hidden', 'progress');
-
- this.montaAnimating = true;
-
- window.setTimeout(this.showMontaKeywordCallback, 0, {
- position : -100,
- node : aNode,
- interval : this.showMontaKeywordTimeout/10
- });
- },
-
- showMontaKeywordCallback : function(aInfo) {
- if (aInfo.position >= aInfo.node.boxObject.width) {
- aInfo.node.setAttribute('monta-hidden', 'false');
- Presentation.montaAnimating = false;
- return;
- }
-
- aInfo.position += (aInfo.node.boxObject.width/10);
- aInfo.node.setAttribute('style', 'background-position: '+aInfo.position+'px 0 !important;');
- window.setTimeout(arguments.callee, aInfo.interval, aInfo);
- },
- montaAnimating : false,
-
-/* toolbar animation */
-
- onToolbarArea : false,
- toolbarHeight : 0,
- toolbarDelay : 300,
- toolbarTimer : null,
- isToolbarHidden : false,
-
- checkShowHideToolbar : function(aEvent) {
- if (!this.scroller || this.scroller.dragging || this.preventToShowHideToolbar) return;
-
- this.onToolbarArea = (aEvent.clientY < this.toolbarHeight);
-
- if (this.isToolbarHidden == this.onToolbarArea) {
- if (this.toolbarTimer) window.clearTimeout(this.toolbarTimer);
- this.toolbarTimer = window.setTimeout('Presentation.checkShowHideToolbarCallback()', this.toolbarDelay);
- }
- },
-
- checkShowHideToolbarCallback : function() {
- if (this.isToolbarHidden == this.onToolbarArea)
- this.showHideToolbar();
- },
-
- showHideToolbar : function(aWithoutAnimation)
- {
- if (this.isPrinting) return;
-
- 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;');
-
- if (aWithoutAnimation) {
- this.toolbarAnimationInfo.current = this.toolbarHeight;
- Presentation.animateToolbar();
- }
- else {
- 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;
- },
-
- toolbarAnimationDelay : 100,
- toolbarAnimationSteps : 5,
- toolbarAnimationInfo : null,
- toolbarAnimationTimer : null,
-
-/* edit mode */
-
- initEditPages : function()
- {
- var range = document.createRange();
- range.selectNodeContents(this.pages);
- range.deleteContents();
- range.detach();
-
- var editBox = document.getElementById('pageEditBoxTemplate');
- var contents = document.createDocumentFragment();
- for (var i = 0, maxi = this.sourceData.length; i < maxi; i++)
- {
- var newBox = editBox.cloneNode(true);
- newBox.firstChild.setAttribute('value', this.sourceData[i])
- newBox.setAttribute('id', this.EDIT_BOX_ID_PREFIX+i);
- contents.appendChild(newBox);
- }
-
- this.pages.appendChild(contents);
- },
-
- toggleEditStyle : function(aEvent)
- {
- var tabbox = document.getElementById('editTabBox');
- var tab = tabbox.selectedTab;
- if (tab.id == 'editTab-pages') {
- this.sourceData = this.source.value.split(/\n?----+\n?/);
- this.initEditPages();
- }
- else {
- this.source.value = this.sourceData.join('\n----\n');
- }
- },
-
- insert : function(aType) {
- switch (aType)
- {
- case 'page':
- this.insertTextFor('\n----\n', this.source, 6);
- break;
- case 'header':
- this.insertTextFor('\nHEADER::\n', this.source, 9);
- break;
- case 'footer':
- this.insertTextFor('\nFOOTER::\n', this.source, 9);
- break;
-
- case 'em':
- case 'emphasis':
- this.insertTextFor(this.phraseOpenParen+this.phraseOpenParen+'EM:'+this.phraseCloseParen+this.phraseCloseParen, this.source, 5);
- break;
- case 'pre':
- case 'preformatted':
- this.insertTextFor(this.phraseOpenParen+this.phraseOpenParen+'PRE:'+this.phraseCloseParen+this.phraseCloseParen, this.source, 6);
- break;
- case 'monta':
- this.insertTextFor(this.phraseOpenParen+this.phraseCloseParen, this.source, 1);
- break;
- case 'link':
- this.insertTextFor(this.phraseOpenParen+this.phraseOpenParen+'|http://'+this.phraseCloseParen+this.phraseCloseParen, this.source, 2);
- break;
- case 'img':
- case 'image':
- this.insertTextFor(this.phraseOpenParen+this.phraseOpenParen+'image src="" width="" height=""'+this.phraseCloseParen+this.phraseCloseParen, this.source, 13);
- break;
-
- default:
- return;
- }
- this.onEditSource();
- },
-
- insertTextFor : function(aString, aNode, aPosOffset)
- {
- var pos = aNode.selectionStart;
- var value = aNode.value;
- aNode.value = [value.substring(0, pos), aString, value.substring(pos, value.length)].join('');
- aNode.selectionEnd = aNode.selectionStart = pos + (aPosOffset || 0);
- },
-
- removePage : function(aPage)
- {
- if (aPage === void(0) || this.pages.childNodes.length == 1) return;
-
- var target = document.getElementById(this.EDIT_BOX_ID_PREFIX+aPage);
-
- var next = target;
- while (next = next.nextSibling)
- {
- next.setAttribute('id', this.EDIT_BOX_ID_PREFIX + (Number(next.id.match(/\d+/)) - 1));
- }
- this.pages.removeChild(target);
-
- this.sourceData.splice(aPage, 1);
-
- var maxPage = this.pages.childNodes.length-1;
- if (this.offset > maxPage) this.offset = maxPage;
-
- this.onEditPage();
- },
-
- onEditSource : function() {
- if (this.isPrinting) return;
- },
-
-
- onEditPage : function(aPage)
- {
- if (aPage !== void(0)) {
- var target = document.getElementById(this.EDIT_BOX_ID_PREFIX+aPage);
- if (target) {
- target = getNodesByXPath('descendant::*[@class="page-edit-box-main"]', target).snapshotItem(0);
- this.sourceData[aPage] = target.value;
- }
- }
- },
-
- output : function()
- {
- location.href = 'data:application/octet-stream,'+encodeURIComponent(this.source.value);
- }
-
-};
-
-var StrokeService = {
-
- className : 'stroke-dot',
- dragStartDelta : 10,
- lineColor : 'red',
- lineWidth : 3,
-
- initialized : false,
-
-
- mode : null,
- canvas : null,
- canvasContext : null,
- startX : -1,
- startY : -1,
-
- init : function(aCanvas)
- {
- this.initialized = true;
-
- this.canvas = aCanvas;
- this.canvasElement = aCanvas;
-
- var canvas = document.createElementNS('http://www.w3.org/1999/xhtml', 'canvas');
- canvas.width = this.canvas.boxObject.width;
- canvas.height = this.canvas.boxObject.height;
- this.canvas.appendChild(canvas);
- if (!('getContext' in canvas) || !canvas.getContext) {
- this.canvas.removeChild(canvas);
- this.mode = 'box';
- }
- else {
- this.canvasElement = canvas;
- this.canvasContext = canvas.getContext('2d');
- this.mode = 'canvas';
- }
-
- document.documentElement.addEventListener('PresentationRedraw', this, false);
- window.addEventListener('resize', this, false);
- this.canvasElement.addEventListener('mouseup', this, false);
- this.canvasElement.addEventListener('mousedown', this, false);
- this.canvasElement.addEventListener('mousemove', this, false);
-
- this.canvasElement.addEventListener('click', this, false);
- this.canvasElement.addEventListener('dblclick', this, false);
-
- this.clear();
- },
-
- destroy : function()
- {
- document.documentElement.removeEventListener('PresentationRedraw', this, false);
- window.removeEventListener('resize', this, false);
- if (this.canvasElement) {
- this.canvasElement.removeEventListener('mouseup', this, false);
- this.canvasElement.removeEventListener('mousedown', this, false);
- this.canvasElement.removeEventListener('mousemove', this, false);
- this.canvasElement.removeEventListener('click', this, false);
- }
-
- this.cliclableNodesManager = null;
- this.canvasElement = null;
- this.canvas = null;
-
- this.initialized = false;
- },
-
- handleEvent : function(aEvent)
- {
- switch(aEvent.type)
- {
- default:
- break;
-
- case 'mouseup':
- this.finish(aEvent);
- this.startX = -1;
- this.startY = -1;
- window.setTimeout('StrokeService.preventToSendClickEvent = false', 10);
- break;
-
- case 'mousedown':
- if (this.startX < 0) {
- this.startX = aEvent.clientX;
- this.startY = aEvent.clientY;
- }
- break;
-
- case 'mousemove':
- if (this.startX > -1 && !this.active) {
- if (Math.abs(this.startX-aEvent.clientX) > Math.abs(this.dragStartDelta) ||
- Math.abs(this.startY-aEvent.clientY) > Math.abs(this.dragStartDelta)) {
- this.start(aEvent, this.startX, this.startY);
- this.preventToSendClickEvent = true;
- }
- }
- else
- this.trace(aEvent);
-
- break;
-
- case 'PresentationRedraw':
- case 'resize':
- this.clear();
- break;
-
- case 'click':
- if (this.preventToSendClickEvent) {
- aEvent.stopPropagation();
- aEvent.preventCapture();
- aEvent.preventDefault();
- aEvent.preventBubble();
- this.preventToSendClickEvent = false;
- }
- else if (this.cliclableNodesManager && this.cliclableNodesManager.clickableNodes) {
- var nodes = this.cliclableNodesManager.clickableNodes;
- var max = nodes.length;
- var x, y, width, height
- for (var i = 0; i < max; i++)
- {
- if (nodes[i].boxObject) {
- x = nodes[i].boxObject.x;
- y = nodes[i].boxObject.y;
- width = nodes[i].boxObject.width;
- height = nodes[i].boxObject.height;
- }
- else {
- x = nodes[i].offsetLeft;
- y = nodes[i].offsetTop;
- width = nodes[i].offsetWidth;
- height = nodes[i].offsetHeight;
- }
- if (aEvent.clientX < x ||
- aEvent.clientX > x+width ||
- aEvent.clientY < y ||
- aEvent.clientY > y+height)
- continue;
-
- var event = document.createEvent('MouseEvents');
- event.initMouseEvent(
- aEvent.type, aEvent.canBubble, aEvent.cancelable, aEvent.view,
- aEvent.detail,
- aEvent.screenX, aEvent.screenY, aEvent.clientX, aEvent.clientY,
- aEvent.ctrlKey, aEvent.altKey, aEvent.shiftKey, aEvent.metaKey,
- aEvent.button,
- aEvent.relatedTarget
- );
- nodes[i].dispatchEvent(event);
- break;
- }
- }
- break;
- }
- },
- preventToSendClickEvent : false,
-
- start : function(aEvent, aX, aY)
- {
- this.active = true;
- this.trace(aEvent, aX, aY);
- },
-
- finish : function(aEvent)
- {
- if (!this.active) return;
- this.trace(aEvent);
- this.finishStroke();
- },
-
- trace : function(aEvent, aX, aY)
- {
- if (!this.active) return;
- this.addPoint((aX === void(0) ? aEvent.clientX : aX ), (aY === void(0) ? aEvent.clientY : aY ));
- },
-
- finishStroke : function()
- {
- this.active = false;
- this.lastX = -1;
- this.lastY = -1;
- },
-
- addPoint : function(aX, aY)
- {
- if (this.lastX != -1)
- this.drawLine(this.lastX, this.lastY, aX, aY);
- else
- this.drawDot(aX, aY);
-
- this.lastX = aX;
- this.lastY = aY;
- },
-
- clear : function()
- {
- this.active = false;
- this.lastX = -1;
- this.lastY = -1;
-
- if (this.mode == 'canvas') {
- if (this.canvasElement.lastWindowWidth != window.innerWidth ||
- this.canvasElement.lastWindowHeight != window.innerHeight) {
- this.canvasElement.width = this.canvasElement.parentNode.boxObject.width-2;
- this.canvasElement.height = this.canvasElement.parentNode.boxObject.height-2;
-
- this.canvasElement.lastWindowWidth = window.innerWidth;
- this.canvasElement.lastWindowHeight = window.innerHeight;
- }
- this.canvasContext.clearRect(0, 0, this.canvasElement.width, this.canvasElement.height);
- this.canvasContext.strokeStyle = this.lineColor;
- this.canvasContext.lineWidth = this.lineWidth;
- }
- else {
- var dotes = this.canvasElement.getElementsByAttribute('class', this.className);
- if (!dotes.length) return;
-
- var range = document.createRange();
- range.selectNodeContents(this.canvasElement);
- range.setStartBefore(dotes[0]);
- range.setEndAfter(dotes[dotes.length-1]);
- range.deleteContents();
- range.detach();
- }
- },
-
- drawDot : function(aX, aY, aParent)
- {
- if (this.mode == 'canvas') {
- this.canvasContext.strokeRect(aX, aY, 0, 0);
- this.canvasContext.stroke();
- }
- else {
- var dot = document.createElement('spacer');
- dot.setAttribute('style', 'left:'+aX+'px; top:'+aY+'px');
- dot.setAttribute('class', this.className);
- (aParent || this.canvasElement).appendChild(dot);
- }
- },
-
- drawLine : function(aX1, aY1, aX2, aY2)
- {
- if (aX1 == aX2 && aY1 == aY2) return;
-
-
- if (this.mode == 'canvas') {
- this.canvasContext.beginPath();
- this.canvasContext.moveTo(aX1, aY1);
- this.canvasContext.lineTo(aX2, aY2);
-/*
- this.canvasContext.bezierCurveTo(
- parseInt(aX1+((aX2-this.lastX)*0.3)), parseInt(aY1+((aY2-this.lastY)*0.3)),
- parseInt(aX1+((aX2-this.lastX)*0.6)), parseInt(aY1+((aY2-this.lastY)*0.6)),
- aX2, aY2
- );
-*/
- this.canvasContext.closePath();
- this.canvasContext.stroke();
- }
- else {
- var x_move = aX2 - aX1;
- var y_move = aY2 - aY1;
- var x_diff = x_move < 0 ? 1 : -1;
- var y_diff = y_move < 0 ? 1 : -1;
-
- var fragment = document.createDocumentFragment();
- if (Math.abs(x_move) >= Math.abs(y_move)) {
- for (var i = x_move; i != 0; i += x_diff)
- this.drawDot(aX2 - i, aY2 - Math.round(y_move * i / x_move), fragment);
- }
- else {
- for (var i = y_move; i != 0; i += y_diff)
- this.drawDot(aX2 - Math.round(x_move * i / y_move), aY2 - i, fragment);
- }
- this.canvasElement.appendChild(fragment);
- }
- }
-
-};
-
-var StrokablePresentationService = {
-
- id : 'stroke-canvas-box',
-
- strokeService : null,
- cliclableNodesManager : null,
- canvasContainer : null,
- canvas : null,
-
- autoStart : false,
-
- init : function(aPresentation, aStrokeService)
- {
- this.cliclableNodesManager = aPresentation;
- this.strokeService = aStrokeService;
- this.canvasContainer = document.getElementById('canvas').firstChild;
- this.check = document.getElementById('penButton');
-
- document.documentElement.addEventListener('StartDragOnCanvas', this, false);
- document.documentElement.addEventListener('PresentationRedraw', this, false);
- },
-
- toggle : function(aEnable)
- {
- if (aEnable)
- this.start();
- else
- this.end();
- },
-
- start : function()
- {
- if (!this.strokeService || !this.canvasContainer) return;
-
- this.strokeService.cliclableNodesManager = this.cliclableNodesManager;
- var box = document.createElement('vbox');
- box.setAttribute('flex', 1);
- box.setAttribute('id', this.id);
- box.style.width = this.canvasContainer.boxObject.width+'px';
- box.style.height = this.canvasContainer.boxObject.height+'px';
- this.canvas = this.canvasContainer.appendChild(box);
- this.strokeService.init(this.canvas);
-
- this.canvas.addEventListener('dblclick', this, false);
- },
-
- end : function()
- {
- this.strokeService.destroy();
- if (this.canvas) {
- this.canvas.removeEventListener('dblclick', this, false);
- this.canvasContainer.removeChild(this.canvas);
- this.canvas = null;
- }
- },
-
- handleEvent : function(aEvent)
- {
- switch (aEvent.type)
- {
- default:
- break;
-
- case 'StartDragOnCanvas':
- if (!this.check.checked) {
- this.toggleCheck();
- this.strokeService.startX = Presentation.dragStartX;
- this.strokeService.startY = Presentation.dragStartY;
-
- this.autoStart = true;
- }
- break;
-
- case 'PresentationRedraw':
- if (this.autoStart && this.check.checked) {
- this.autoStart = false;
- this.toggleCheck();
- }
- break;
-
- case 'dblclick':
- if (this.canvas)
- this.end();
- break;
- }
- },
-
- toggleCheck : function()
- {
- var enable = !this.check.checked;
- this.toggle(enable);
- this.check.checked = enable;
-
- this.autoStart = false;
- }
-
-};
-
-function init()
-{
- window.removeEventListener('load', init, false);
-
- Presentation.init();
- StrokablePresentationService.init(Presentation, StrokeService);
-}
-window.addEventListener('load', init, false);
-
-function getNodesByXPath(aExpression, aContext, aLive)
-{
- var d = aContext.ownerDocument || aContext;
- var type = aLive ? XPathResult.ORDERED_NODE_ITERATOR_TYPE : XPathResult.ORDERED_NODE_SNAPSHOT_TYPE ;
- var nodes;
- try {
- nodes = d.evaluate(aExpression, aContext, null, type, null);
- }
- catch(e) {
- nodes = document.evaluate(aExpression, aContext, null, type, null);
- }
- return nodes;
-}
-
-// Import Node from E4X to DOM
-// http://ecmanaut.blogspot.com/2006/03/e4x-and-dom.html
-
-function importE4XNode( e4x, doc, aDefaultNS )
-{
- aDefaultNS = aDefaultNS || XHTMLNS;
- var root, domTree, importMe;
- this.Const = this.Const || { mimeType: 'text/xml' };
- this.Static = this.Static || {};
- this.Static.parser = this.Static.parser || new DOMParser;
- eval('root = <testing xmlns="'+aDefaultNS+'" />;');
- root.test = e4x;
- domTree = this.Static.parser.parseFromString( root.toXMLString(),
- this.Const.mimeType );
- importMe = domTree.documentElement.firstChild;
- while( importMe && importMe.nodeType != 1 )
- importMe = importMe.nextSibling;
- if( !doc ) doc = document;
- return importMe ? doc.importNode( importMe, true ) : null;
-}
-
-function appendE4XTo( e4x, node, doc, aDefaultNS )
-{
- return node.appendChild( importE4XNode( e4x, (doc || node.ownerDocument), aDefaultNS ) );
-}
-
-function setE4XContent( e4x, node, aDefaultNS )
-{
- while( node.firstChild )
- node.removeChild( node.firstChild );
- appendE4XTo( e4x, node, aDefaultNS );
-}
-
-// importE4XNodeで得たノードツリーを埋め込むと、XULでバインディングが適用されないことがある。
-// 遅延処理でこの問題を一部避けることができる(が、これでもまだダメな場合がある。menuとか。)
-// とりあえずXULとSVGとXHTMLはいけた。MathMLはダメだった。
-function importNodeTreeWithDelay(aNode, aParent, aDefaultNS, aFromTimeout)
-{
- if (aFromTimeout) {
- importNodeTreeWithDelayTimers--;
- }
-
- var node;
- var delay = 1;
- switch (aNode.nodeType)
- {
- case Node.ELEMENT_NODE:
- var ns = (aNode.namespaceURI || aDefaultNS);
- node = document.createElementNS(ns, aNode.localName);
- aParent.appendChild(node);
-
- var attr = aNode.attributes;
- for (var i = 0, maxi = attr.length; i < maxi; i++)
- node.setAttribute(attr[i].name, attr[i].value);
-
- if (ns == XULNS) delay = 1; else delay = 0;
-
- var children = aNode.childNodes;
- for (var i = 0, maxi = children.length; i < maxi; i++)
- if (delay) {
- importNodeTreeWithDelayTimers++;
- window.setTimeout(importNodeTreeWithDelay, delay, children[i], node, aDefaultNS, true);
- }
- else
- importNodeTreeWithDelay(children[i], node, aDefaultNS);
- break;
-
- default:
- if (
- aNode.nodeType == Node.TEXT_NODE &&
- /^\s*$/.test(aNode.nodeValue) &&
- (aNode.parentNode.namespaceURI || aDefaultNS) != XHTMLNS
- )
- return;
- node = aParent.appendChild(aNode.cloneNode(true));
- break;
- }
-
- var event = document.createEvent('Events');
- event.initEvent('CanvasContentAdded', true, true);
- node.dispatchEvent(event);
-
- return node;
-}
-var importNodeTreeWithDelayTimers = 0;
-
-]]></script>
-
-</page>
-